"""BadNote FastAPI server — main application.""" import os from contextlib import asynccontextmanager from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from .config import settings from .database import close_db, init_db from .routers.auth_router import router as auth_router from .routers.notes_router import router as notes_router from .routers.documents_router import router as documents_router from .routers.ocr_router import router as ocr_router from .routers.sync_router import router as sync_router @asynccontextmanager async def lifespan(app: FastAPI): """Startup: create directories and init DB. Shutdown: close DB.""" os.makedirs(settings.storage_path, exist_ok=True) for subdir in ("pending", "processing", "done", "failed"): os.makedirs(os.path.join(settings.queue_path, subdir), exist_ok=True) await init_db() yield await close_db() app = FastAPI(title="BadNote Server", version="1.0.0", lifespan=lifespan) # Authentication is Bearer-token based, so cookies/credentials are not needed. # `allow_origins=["*"]` together with `allow_credentials=True` is an invalid and # insecure combination, so we keep credentials disabled. Set BADNOTE_CORS_ORIGINS # (comma-separated) to lock the API down to specific front-end origins. _cors_origins = settings.cors_origins or ["*"] app.add_middleware( CORSMiddleware, allow_origins=_cors_origins, allow_credentials=False, allow_methods=["*"], allow_headers=["*"], ) app.include_router(auth_router, prefix="/api/auth", tags=["auth"]) app.include_router(notes_router, prefix="/api/notes", tags=["notes"]) app.include_router(documents_router, prefix="/api/documents", tags=["documents"]) app.include_router(ocr_router, prefix="/api/ocr", tags=["ocr"]) app.include_router(sync_router, prefix="/api/sync", tags=["sync"]) @app.get("/api/ping") async def ping() -> dict: """Health check endpoint.""" return {"status": "ok"}