"""AI Knowledge Link — FastAPI 应用工厂。 Phase 1 只包含:配置校验、日志、异常处理器、健康检查、lifespan 资源管理。 后续 Phase 逐步挂载:auth、knowledge-bases、documents、public /k/ 路由。 """ from contextlib import asynccontextmanager from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.api.health import router as health_router from app.core.config import get_settings from app.core.db import dispose_engine from app.core.errors import register_exception_handlers from app.core.logging import get_logger, setup_logging logger = get_logger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): settings = get_settings() setup_logging() # 确保 data 目录存在 data_dir = settings.storage_root_path data_dir.mkdir(parents=True, exist_ok=True) logger.info("Starting backend (env=%s, data=%s)", settings.environment, data_dir) yield dispose_engine() logger.info("Backend shutdown complete") def create_app() -> FastAPI: settings = get_settings() app = FastAPI( title="AI Knowledge Link", version="0.1.0", lifespan=lifespan, docs_url="/api/docs" if not settings.is_production else None, openapi_url="/api/openapi.json" if not settings.is_production else None, ) # CORS(开发期允许 Vite dev server) app.add_middleware( CORSMiddleware, allow_origins=[settings.frontend_origin], allow_credentials=True, allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], allow_headers=["Content-Type", "X-Requested-With"], ) register_exception_handlers(app) # 路由挂载 app.include_router(health_router, prefix="/api", tags=["health"]) # Phase 3+: app.include_router(auth_router, prefix="/api/auth", tags=["auth"]) # Phase 4+: app.include_router(kb_router, prefix="/api/knowledge-bases", tags=["knowledge-bases"]) # Phase 10+: app.include_router(public_router, tags=["public"]) return app app = create_app()