import asyncio from contextlib import asynccontextmanager from datetime import datetime, timezone from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from sqlalchemy import select from app.core.config import get_settings from app.core.database import init_db, async_session from app.core.security import hash_password from app.models.user import User from app.models.instance import Instance from app.models.ticket import Ticket from app.models.audit_log import AuditLog from app.api.v1.router import api_router settings = get_settings() async def seed_workflows(): """创建默认审批流程。""" async with async_session() as db: from app.services.workflow_seeds import seed_default_workflows try: await seed_default_workflows(db) except Exception: pass # 可能已存在 async def seed_data(): """Create default users with different roles.""" from app.core.security import hash_password default_users = [ {"username": "admin", "display_name": "超级管理员", "role": "admin", "password": "admin123"}, {"username": "dba", "display_name": "张三", "role": "dba", "password": "admin123"}, {"username": "auditor", "display_name": "老六", "role": "auditor", "password": "admin123"}, {"username": "developer", "display_name": "路人甲", "role": "developer", "password": "admin123"}, ] async with async_session() as db: for u in default_users: result = await db.execute(select(User).where(User.username == u["username"])) if not result.scalar_one_or_none(): db.add(User( username=u["username"], display_name=u["display_name"], role=u["role"], hashed_password=hash_password(u["password"]), )) await db.commit() @asynccontextmanager async def lifespan(app: FastAPI): # Startup from app.core.database import Base # Import all models so create_all picks them up import app.models.user # noqa import app.models.instance # noqa import app.models.ticket # noqa import app.models.audit_log # noqa import app.models.audit_rule # noqa import app.models.announcement # noqa import app.models.notification # noqa import app.models.ldap_config # noqa import app.models.backup # noqa import app.models.instance_group # noqa import app.models.masking_rule # noqa import app.models.workflow # noqa import app.models.notification_template # noqa import app.models.scheduled_task # noqa import app.models.schema_revision # noqa import app.models.query_history # noqa await init_db() await seed_data() await seed_workflows() yield app = FastAPI( title="SQL-Platform API", version="1.0.0", description="数据审核平台 API", lifespan=lifespan, docs_url="/docs" if settings.DEBUG else None, ) # CORS: development allows *, production uses CORS_ORIGINS env var _cors_origins = ["*"] if settings.DEBUG else [ o.strip() for o in settings.CORS_ORIGINS.split(",") if o.strip() ] app.add_middleware( CORSMiddleware, allow_origins=_cors_origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(api_router) @app.get("/health") async def health_check(): return {"status": "ok", "version": "1.0.0", "time": datetime.now(timezone.utc).isoformat()} if __name__ == "__main__": import uvicorn uvicorn.run("app.main:app", host="0.0.0.0", port=9000, reload=True)