import asyncio from contextlib import asynccontextmanager from datetime import datetime 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, get_db, async_engine from app.routers import auth, projects, folders, documents, tags, search, links, export from app.services.auth import cleanup_expired_blocklist @asynccontextmanager async def lifespan(app: FastAPI): # Startup: init database await init_db() yield # Shutdown await async_engine.dispose() app = FastAPI( title="Claudia Docs API", description="Gestor documental para agentes de IA", version="1.0.0", lifespan=lifespan, ) # CORS app.add_middleware( CORSMiddleware, allow_origins=settings.cors_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include routers app.include_router(auth.router) app.include_router(projects.router) app.include_router(folders.router) app.include_router(documents.router) app.include_router(tags.router) app.include_router(search.router) app.include_router(links.router) app.include_router(export.router) @app.get("/api/v1/health") async def health(): return {"status": "ok", "timestamp": datetime.utcnow().isoformat()} @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): import logging logger = logging.getLogger(__name__) logger.error(f"Unhandled exception: {exc}", exc_info=True) return JSONResponse( status_code=500, content={"detail": "Internal server error"}, )