import asyncio from contextlib import asynccontextmanager from fastapi import FastAPI, Depends from fastapi.middleware.cors import CORSMiddleware from app.internal.logger import logger from app.internal.mqtt_handler import mqtt_handler from app.internal.node_sweeper import sweeper_loop from app.internal.auth import require_firebase_token from app.routers import nodes, systems, calls, upload, tokens @asynccontextmanager async def lifespan(app: FastAPI): logger.info("DRB C2 Core starting.") await mqtt_handler.connect() sweeper_task = asyncio.create_task(sweeper_loop()) yield # --- app running --- logger.info("DRB C2 Core shutting down.") sweeper_task.cancel() await mqtt_handler.disconnect() app = FastAPI(title="DRB C2 Core", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) app.include_router(nodes.router, dependencies=[Depends(require_firebase_token)]) app.include_router(systems.router, dependencies=[Depends(require_firebase_token)]) app.include_router(calls.router, dependencies=[Depends(require_firebase_token)]) app.include_router(tokens.router, dependencies=[Depends(require_firebase_token)]) app.include_router(upload.router) # auth is per-node, handled inline @app.get("/health") async def health(): return {"ok": True, "mqtt_connected": mqtt_handler.is_connected}