"""Dashboard API: aggregated stats, health distribution, gateway trend, kanban overview, cron recent, and global search — all mock data for now.""" from datetime import datetime, timezone from fastapi import APIRouter, Depends, Query from app.middleware.auth import require_auth from app.models.user import User router = APIRouter(tags=["dashboard"]) @router.get("/dashboard/summary") async def dashboard_summary(_user: User = Depends(require_auth)): # TODO: replace with real data — hermes gateway status + kanban + cron return { "online_count": 12, "offline_count": 46, "total_profiles": 58, "running_tasks": 3, "cron_failures_today": 1, "updated_at": datetime.now(timezone.utc).isoformat(timespec="seconds"), } @router.get("/dashboard/health-distribution") async def health_distribution(_user: User = Depends(require_auth)): # TODO: replace with real health-score calculation (Phase 4) return { "A": 22, "B": 18, "C": 10, "D": 8, "total": 58, "d_profiles": ["ops-engineer", "monitor", "visualizer", "hebo", "..."], } @router.get("/dashboard/gateway-trend") async def gateway_trend(_user: User = Depends(require_auth)): # TODO: replace with real 24h aggregation from event store return [ {"hour": "2026-07-22T08:00", "restarts": 2, "feishu_disconnects": 1, "heartbeat_timeouts": 0}, {"hour": "2026-07-22T09:00", "restarts": 0, "feishu_disconnects": 0, "heartbeat_timeouts": 1}, {"hour": "2026-07-22T10:00", "restarts": 1, "feishu_disconnects": 0, "heartbeat_timeouts": 0}, {"hour": "2026-07-22T11:00", "restarts": 0, "feishu_disconnects": 2, "heartbeat_timeouts": 0}, {"hour": "2026-07-22T12:00", "restarts": 0, "feishu_disconnects": 0, "heartbeat_timeouts": 0}, {"hour": "2026-07-22T13:00", "restarts": 3, "feishu_disconnects": 1, "heartbeat_timeouts": 2}, {"hour": "2026-07-22T14:00", "restarts": 0, "feishu_disconnects": 0, "heartbeat_timeouts": 1}, {"hour": "2026-07-22T15:00", "restarts": 1, "feishu_disconnects": 0, "heartbeat_timeouts": 0}, ] @router.get("/dashboard/kanban-summary") async def kanban_summary(_user: User = Depends(require_auth)): # TODO: replace with real kanban task data return [ {"board": "europe-briefing", "running": "S4", "ready": "S5"}, {"board": "tech-weekly", "running": "S1", "ready": None}, {"board": "ops-review", "running": "M2", "ready": "M3"}, ] @router.get("/dashboard/cron-recent") async def cron_recent(_user: User = Depends(require_auth)): # TODO: replace with real cron execution history return [ {"job": "taiwan-briefing", "status": "success", "time": "07:15"}, {"job": "hindsight", "status": "failure", "time": "21:13"}, {"job": "guangxi-donation", "status": "paused"}, {"job": "daily-report", "status": "success", "time": "08:00"}, {"job": "weekly-digest", "status": "success", "time": "09:30"}, ] @router.get("/search") async def global_search( q: str = Query("", min_length=1), _user: User = Depends(require_auth), ): # TODO: replace with real full-text search across profiles, tasks, cron, events keyword = q.lower() profiles = [] if "gateway" in keyword or "monitor" in keyword: profiles.append({"name": "gateway-monitor", "status": "online"}) if "visual" in keyword: profiles.append({"name": "visualizer", "status": "online"}) if "hebo" in keyword or "ops" in keyword: profiles.append({"name": "ops-engineer", "status": "online"}) kanban_tasks = [] if "briefing" in keyword or "europe" in keyword: kanban_tasks.append({"title": "Europe Briefing S4", "column": "RUNNING"}) if "tech" in keyword or "weekly" in keyword: kanban_tasks.append({"title": "Tech Weekly S1", "column": "RUNNING"}) cron_jobs = [] if "taiwan" in keyword or "briefing" in keyword: cron_jobs.append({"job": "taiwan-briefing", "status": "active"}) if "hindsight" in keyword: cron_jobs.append({"job": "hindsight", "status": "active"}) if "donation" in keyword or "guangxi" in keyword: cron_jobs.append({"job": "guangxi-donation", "status": "paused"}) events = [] if "gateway" in keyword or keyword == "restart": events.append({"title": "Gateway restart detected", "status": "active"}) if "feishu" in keyword or "disconnect" in keyword: events.append({"title": "Feishu disconnect alert", "status": "active"}) return { "profiles": profiles, "kanban_tasks": kanban_tasks, "cron_jobs": cron_jobs, "events": events, }