"""MCP Auth Admin — FastAPI 主入口 启动时自动建默认管理员(admin/admin123,仅当 admin_user 表为空时)。 静态文件由前端构建产物提供(STATIC_DIR 指向)。 """ import os from contextlib import asynccontextmanager from pathlib import Path from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from app.core import security from app.core.config import settings from app.core.db import close_pool, get_pool from app.routers import auth, services, stats, tokens, verify async def _ensure_default_admin() -> None: """首次启动时建默认管理员 admin/admin123(仅当表为空)。""" pool = await get_pool() count = await pool.fetchval("SELECT COUNT(*) FROM admin_user") if count == 0: hashed = security.hash_password("admin123") await pool.execute( "INSERT INTO admin_user (username, password_hash, display_name) VALUES ($1, $2, $3)", "admin", hashed, "默认管理员", ) print("[初始化] 已创建默认管理员 admin/admin123,请尽快修改密码") @asynccontextmanager async def lifespan(app: FastAPI): await _ensure_default_admin() yield await close_pool() app = FastAPI( title="MCP Auth Admin", description="MCP 服务 Bearer Token 动态鉴权管理后台", version="1.0.0", lifespan=lifespan, ) # CORS(开发期前端 dev server 跨域;生产同源可不配) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # API 路由 app.include_router(auth.router) app.include_router(tokens.router) app.include_router(services.router) app.include_router(stats.router) app.include_router(verify.router) @app.get("/api/health") async def health(): return {"status": "ok"} # 静态文件(前端构建产物),必须在所有 API 路由之后挂载 static_dir = Path(settings.STATIC_DIR) if static_dir.exists(): app.mount("/", StaticFiles(directory=str(static_dir), html=True), name="static")