"""Seed DB dev: tenant "dev" + 1 bàn, in token QR + URL đầy đủ. IDEMPOTENT — chạy lại bao nhiêu lần cũng không nhân đôi (get-or-create theo tên). Cần `DATABASE_URL` (không đoán default — seed nhầm DB thật còn tệ hơn không seed): set DATABASE_URL=postgresql+psycopg://poolcoach:poolcoach@localhost:5432/poolcoach python scripts\\seed_db.py Chạy SAU `alembic upgrade head` — script không tự tạo bảng. """ from __future__ import annotations import os import sys from pathlib import Path # Repo không cài package: đẩy gốc repo (cho `app`) + src/ (quy ước chung của # scripts/, dù seed không đụng poolcoach_rl) vào path trước mọi import. ROOT = Path(__file__).resolve().parents[1] for _p in (ROOT / "src", ROOT): if str(_p) not in sys.path: sys.path.insert(0, str(_p)) import sqlalchemy as sa # noqa: E402 from app import db, qr # noqa: E402 TENANT_NAME = "dev" TABLE_NAME = "Bàn 1" def main() -> int: # Console Windows có thể là cp1252 — "Bàn" in ra phải không chết script. if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8", errors="replace") if not os.environ.get("DATABASE_URL"): print("Thiếu DATABASE_URL — set env rồi chạy lại, ví dụ:\n" " set DATABASE_URL=postgresql+psycopg://poolcoach:poolcoach" "@localhost:5432/poolcoach") return 2 db.setup() with db.session() as s: tenant = s.scalar(sa.select(db.Tenant) .where(db.Tenant.name == TENANT_NAME)) if tenant is None: tenant = db.Tenant(name=TENANT_NAME) s.add(tenant) s.flush() print(f"+ tạo tenant '{TENANT_NAME}' (id={tenant.id})") else: print(f"= tenant '{TENANT_NAME}' đã có (id={tenant.id})") table = s.scalar(sa.select(db.Table) .where(db.Table.tenant_id == tenant.id, db.Table.name == TABLE_NAME)) if table is None: table = db.Table(tenant_id=tenant.id, name=TABLE_NAME) s.add(table) s.flush() print(f"+ tạo bàn '{TABLE_NAME}' (id={table.id})") else: print(f"= bàn '{TABLE_NAME}' đã có (id={table.id})") token = qr.make_table_token(tenant.id, table.id) if qr.secret_is_default(): print("(POOLCOACH_SECRET chưa set — token ký bằng secret dev)") # URL dạng /?qr= — FE tự đổi token lấy phiên lúc mở trang (bàn giao 12); # URL /api/table-qr cũ vẫn gọi tay được nhưng mỗi GET là một session mới. print(f"\nToken QR : {token}") print(f"URL : http://localhost:8000/?qr={token}") return 0 if __name__ == "__main__": raise SystemExit(main())