diff --git a/backend/app/main.py b/backend/app/main.py new file mode 100644 index 0000000..5c15d69 --- /dev/null +++ b/backend/app/main.py @@ -0,0 +1,67 @@ +"""AI Worker Platform - FastAPI Application Entry Point.""" +import os +from contextlib import asynccontextmanager +from fastapi import FastAPI, Request +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +from app.config import settings +from app.database import init_db +from app.api.v1 import api_router +from app.core.exceptions import AppException + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """Initialize database on startup.""" + init_db() + # Seed default tenant if not exists + from app.database import SessionLocal + from app.models.tenant import Tenant + db = SessionLocal() + try: + existing = db.query(Tenant).filter(Tenant.slug == "default").first() + if not existing: + tenant = Tenant(name="Default Tenant", slug="default") + db.add(tenant) + db.commit() + print("[Startup] Created default tenant") + finally: + db.close() + print(f"[Startup] {settings.APP_NAME} v{settings.APP_VERSION} ready") + yield + + +app = FastAPI( + title=settings.APP_NAME, + version=settings.APP_VERSION, + description="AI Worker Project Management Platform - MVP", + lifespan=lifespan, +) + +# CORS +app.add_middleware( + CORSMiddleware, + allow_origins=settings.cors_origins_list, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +# Exception handler +@app.exception_handler(AppException) +async def app_exception_handler(request: Request, exc: AppException): + return JSONResponse( + status_code=exc.status_code, + content={"detail": exc.detail}, + ) + + +# Health check +@app.get("/health") +def health(): + return {"status": "ok", "version": settings.APP_VERSION} + + +# API routes +app.include_router(api_router)