"""FastAPI 应用入口""" from contextlib import asynccontextmanager from pathlib import Path from fastapi import FastAPI from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from app.config import settings from app.database import get_db, close_db, seed_from_config @asynccontextmanager async def lifespan(app: FastAPI): await get_db() await seed_from_config() from app.services.scheduler import start_scheduler await start_scheduler() Path(settings.storage.path).mkdir(parents=True, exist_ok=True) yield from app.services.scheduler import stop_scheduler await stop_scheduler() await close_db() app = FastAPI( title="Plan Manager", description="多平台 Coding Plan 统一管理系统", version="0.1.0", lifespan=lifespan, ) # 挂载 API / 代理路由 from app.routers import plans, quota, queue, proxy # noqa: E402 app.include_router(plans.router, prefix="/api/plans", tags=["Plans"]) app.include_router(quota.router, prefix="/api/quota", tags=["Quota"]) app.include_router(queue.router, prefix="/api/queue", tags=["Queue"]) app.include_router(proxy.router, tags=["Proxy"]) # 前端: 用显式路由而非 mount("/") 以避免遮盖 /docs, /api, /v1 _static_dir = Path(__file__).parent / "static" @app.get("/", include_in_schema=False) async def serve_index(): return FileResponse(_static_dir / "index.html") @app.get("/health", tags=["Health"]) async def health_check(): """健康检查端点,用于容器健康检查""" return {"status": "healthy", "service": "plan-manager"}