from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from pathlib import Path from app.core.config import settings from app.core.database import engine, Base, async_session_maker from app.api.v1 import router as api_router from app.services.event_scheduler import event_scheduler from app.services.dispute_scheduler import dispute_scheduler @asynccontextmanager async def lifespan(app: FastAPI): # Startup: create tables async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) # Create upload directories upload_dir = Path(settings.UPLOAD_DIR) (upload_dir / "avatars").mkdir(parents=True, exist_ok=True) (upload_dir / "covers").mkdir(parents=True, exist_ok=True) (upload_dir / "proofs").mkdir(parents=True, exist_ok=True) # Start schedulers await event_scheduler.start(async_session_maker) await dispute_scheduler.start(async_session_maker) yield # Shutdown await event_scheduler.stop() await dispute_scheduler.stop() await engine.dispose() app = FastAPI( title=settings.APP_NAME, version="1.0.0", lifespan=lifespan, ) # CORS app.add_middleware( CORSMiddleware, allow_origins=["http://localhost:3000", "http://127.0.0.1:3000"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Static files for uploads upload_path = Path(settings.UPLOAD_DIR) if upload_path.exists(): app.mount("/uploads", StaticFiles(directory=str(upload_path)), name="uploads") # API routes app.include_router(api_router) @app.get("/health") async def health_check(): return {"status": "ok"}