import threading from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from app.api.routes import auth, dashboard, settings as settings_routes, imports, detect, domains, exports, logs, runtime, juming, ops, ops_agent, ops_release, sensitive_words from app.core.config import settings as app_settings from app.services.build_info_service import get_runtime_build_info, remember_registered_route_paths from app.services.cluster_runtime_service import ensure_runtime_schema, register_local_control_heartbeat from app.services.ops_agent_service import ensure_ops_agent_schema from app.services.ops_job_service import ensure_ops_schema from app.services.ops_release_service import ensure_ops_release_schema _heartbeat_stop_event = threading.Event() def _control_heartbeat_loop() -> None: while not _heartbeat_stop_event.is_set(): try: register_local_control_heartbeat() except Exception: pass _heartbeat_stop_event.wait(30) app = FastAPI( title="domainCheck API", version="0.1.0", description="domainCheck 轻量 Web 管理后台后端骨架", ) app.add_middleware( CORSMiddleware, allow_origins=app_settings.cors_origins_list, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.on_event("startup") def on_startup() -> None: ensure_runtime_schema() ensure_ops_schema() ensure_ops_agent_schema() ensure_ops_release_schema() remember_registered_route_paths(route.path for route in app.routes) register_local_control_heartbeat() _heartbeat_stop_event.clear() threading.Thread(target=_control_heartbeat_loop, name="control-heartbeat", daemon=True).start() @app.on_event("shutdown") def on_shutdown() -> None: _heartbeat_stop_event.set() @app.get("/health") def health() -> dict: return { "status": "ok", "service": "domain-api", "version": "0.1.0", "api_prefix": app_settings.api_prefix, "worker_mode": app_settings.worker_mode, "api_host": app_settings.api_host, "api_port": app_settings.api_port, "build": get_runtime_build_info(route_paths=(route.path for route in app.routes)), } app.include_router(auth.router, prefix=app_settings.api_prefix) app.include_router(dashboard.router, prefix=app_settings.api_prefix) app.include_router(settings_routes.router, prefix=app_settings.api_prefix) app.include_router(imports.router, prefix=app_settings.api_prefix) app.include_router(detect.router, prefix=app_settings.api_prefix) app.include_router(domains.router, prefix=app_settings.api_prefix) app.include_router(exports.router, prefix=app_settings.api_prefix) app.include_router(logs.router, prefix=app_settings.api_prefix) app.include_router(runtime.router, prefix=app_settings.api_prefix) app.include_router(juming.router, prefix=app_settings.api_prefix) app.include_router(ops.router, prefix=app_settings.api_prefix) app.include_router(ops_agent.router, prefix=app_settings.api_prefix) app.include_router(ops_release.router, prefix=app_settings.api_prefix) app.include_router(sensitive_words.router, prefix=app_settings.api_prefix) remember_registered_route_paths(route.path for route in app.routes)