from contextlib import asynccontextmanager from typing import AsyncIterator from dotenv import load_dotenv load_dotenv() # load .env before db.py reads DATABASE_URL from fastapi import FastAPI # noqa: E402 from fastapi.middleware.cors import CORSMiddleware # noqa: E402 from sqlmodel import Session # noqa: E402 from db import create_db_and_tables, engine # noqa: E402 from innercontext.api import ( # noqa: E402 ai_logs, health, inventory, profile, products, routines, skincare, ) from innercontext.services.pricing_jobs import enqueue_pricing_recalc # noqa: E402 @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncIterator[None]: create_db_and_tables() try: with Session(engine) as session: enqueue_pricing_recalc(session) session.commit() except Exception as exc: # pragma: no cover print(f"[startup] failed to enqueue pricing recalculation job: {exc}") yield app = FastAPI( title="innercontext API", lifespan=lifespan, redirect_slashes=False, ) app.add_middleware( CORSMiddleware, # ty: ignore[invalid-argument-type] allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) app.include_router(products.router, prefix="/products", tags=["products"]) app.include_router(inventory.router, prefix="/inventory", tags=["inventory"]) app.include_router(profile.router, prefix="/profile", tags=["profile"]) app.include_router(health.router, prefix="/health", tags=["health"]) app.include_router(routines.router, prefix="/routines", tags=["routines"]) app.include_router(skincare.router, prefix="/skincare", tags=["skincare"]) app.include_router(ai_logs.router, prefix="/ai-logs", tags=["ai-logs"]) @app.get("/health-check") def health_check(): return {"status": "ok"}