from contextlib import asynccontextmanager from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse from slowapi import _rate_limit_exceeded_handler from slowapi.errors import RateLimitExceeded from app.middleware.audit import AuditMiddleware from app.core.scheduler import start_scheduler, shutdown_scheduler from app.core.rate_limiter import limiter @asynccontextmanager async def lifespan(app: FastAPI): """Manage application lifespan events.""" # Startup start_scheduler() yield # Shutdown shutdown_scheduler() from app.api.auth import router as auth_router from app.api.users import router as users_router from app.api.departments import router as departments_router from app.api.spaces import router as spaces_router from app.api.projects import router as projects_router from app.api.tasks import router as tasks_router from app.api.workload import router as workload_router from app.api.comments import router as comments_router from app.api.notifications import router as notifications_router from app.api.blockers import router as blockers_router from app.api.websocket import router as websocket_router from app.api.audit import router as audit_router from app.api.attachments import router as attachments_router from app.api.triggers import router as triggers_router from app.api.reports import router as reports_router from app.api.health import router as health_router from app.api.custom_fields import router as custom_fields_router from app.api.task_dependencies import router as task_dependencies_router from app.api.admin import encryption_keys as admin_encryption_keys_router from app.core.config import settings app = FastAPI( title="Project Control API", description="Cross-departmental project management system API", version="0.1.0", lifespan=lifespan, ) # Initialize rate limiter app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=settings.CORS_ORIGINS, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Audit middleware - extracts request metadata for audit logging app.add_middleware(AuditMiddleware) # Include routers app.include_router(auth_router.router, prefix="/api/auth", tags=["Authentication"]) app.include_router(users_router.router, prefix="/api/users", tags=["Users"]) app.include_router(departments_router.router, prefix="/api/departments", tags=["Departments"]) app.include_router(spaces_router) app.include_router(projects_router) app.include_router(tasks_router) app.include_router(workload_router, prefix="/api/workload", tags=["Workload"]) app.include_router(comments_router) app.include_router(notifications_router) app.include_router(blockers_router) app.include_router(websocket_router) app.include_router(audit_router) app.include_router(attachments_router) app.include_router(triggers_router) app.include_router(reports_router) app.include_router(health_router) app.include_router(custom_fields_router) app.include_router(task_dependencies_router) app.include_router(admin_encryption_keys_router.router) @app.get("/health") async def health_check(): return {"status": "healthy"}