Files
Mog-Squire/backend/app/main.py
2025-07-07 13:39:46 +01:00

78 lines
2.5 KiB
Python

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},
)
desc_col = "description" if desc_exists else "NULL"
icon_col = "icon_id" if icon_exists else "NULL"
selects.append(
f"SELECT id, name, {desc_col} AS description, {icon_col} AS icon_id, type_description 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)