from fastapi import FastAPI from .router import router from .recipes_router import router as recipes_router from .database import engine from sqlalchemy import text app = FastAPI(title="FFXI Item Browser API") # Ensure all_items view exists on startup @app.on_event("startup") async def ensure_view(): """Recreate the materialized view `all_items` each startup to ensure schema consistency. The view merges all *_items tables and exposes columns: id, name, description, icon_id, type_description. Some source tables may lack `description` or `icon_id`; NULLs are substituted in those cases. """ async with engine.begin() as conn: # Drop existing view if present await conn.execute(text("DROP VIEW IF EXISTS all_items")) # Discover item tables table_rows = await conn.execute( text( "SELECT tablename FROM pg_tables WHERE schemaname='public'" " AND tablename LIKE '%_items' AND tablename NOT IN ('inventory')" ) ) tables = [r[0] for r in table_rows] if not tables: return selects = [] for t in tables: desc_exists = await conn.scalar( text( """ SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name=:table AND column_name='description' ) """), {"table": t}, ) icon_exists = await conn.scalar( text( """ SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name=:table AND column_name='icon_id' ) """), {"table": t}, ) stack_exists = await conn.scalar( text( """ SELECT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name=:table AND column_name='stack_size' ) """), {"table": t}, ) desc_col = "description" if desc_exists else "NULL" icon_col = "icon_id" if icon_exists else "NULL" stack_col = "stack_size" if stack_exists else "NULL" selects.append( f"SELECT id, name, {desc_col} AS description, {icon_col} AS icon_id, type_description, {stack_col} AS stack_size FROM {t}" ) union_sql = " UNION ALL ".join(selects) await conn.execute(text(f"CREATE VIEW all_items AS {union_sql}")) await conn.commit() # Mount API routes app.include_router(router, prefix="/api") app.include_router(recipes_router, prefix="/api") @app.get("/health") async def health(): return {"status": "ok"} if __name__ == "__main__": import uvicorn uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)