import os from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from database import engine, Base from middleware.license_check import LicenseCheckMiddleware from services.cloud_sync import start_cloud_sync # Import all models so SQLAlchemy can create their tables import models.user # noqa: F401 import models.table # noqa: F401 import models.printer # noqa: F401 import models.product # noqa: F401 import models.order # noqa: F401 from routers import auth, tables, products, orders, waiters, reports, system def _run_migrations(): """Apply additive schema changes that create_all won't handle.""" from sqlalchemy import text with engine.connect() as conn: # Add extra_cost to product_ingredients if missing try: conn.execute(text("ALTER TABLE product_ingredients ADD COLUMN extra_cost REAL NOT NULL DEFAULT 0.0")) conn.commit() except Exception: pass # Add image_url to products if missing try: conn.execute(text("ALTER TABLE products ADD COLUMN image_url VARCHAR")) conn.commit() except Exception: pass # Add group_id to tables if missing (added in Phase 3 table groups) try: conn.execute(text("ALTER TABLE tables ADD COLUMN group_id INTEGER REFERENCES table_groups(id)")) conn.commit() except Exception: pass @asynccontextmanager async def lifespan(app: FastAPI): Base.metadata.create_all(bind=engine) _run_migrations() sync_task = await start_cloud_sync() yield sync_task.cancel() app = FastAPI(title="POS Local Backend", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(LicenseCheckMiddleware) # Serve product images as static files IMAGE_DIR = "/app/data/product_images" os.makedirs(IMAGE_DIR, exist_ok=True) app.mount("/static/product_images", StaticFiles(directory=IMAGE_DIR), name="product_images") app.include_router(auth.router, prefix="/api/auth", tags=["auth"]) app.include_router(tables.router, prefix="/api/tables", tags=["tables"]) app.include_router(products.router, prefix="/api/products", tags=["products"]) app.include_router(orders.router, prefix="/api/orders", tags=["orders"]) app.include_router(waiters.router, prefix="/api/waiters", tags=["waiters"]) app.include_router(reports.router, prefix="/api/reports", tags=["reports"]) app.include_router(system.router, prefix="/api/system", tags=["system"])