# Dashboard Admin dashboard for the didiAI platform. A single FastAPI service that serves a **React 19 + MUI 7 + Vite single-page app** (the admin UI) plus a JSON API for AI monitoring, a DB-backed Model & Extractor catalog, runtime config, RBAC and audit. It also tracks search-provider usage, costs and request history. ## What it does - **AI monitoring** — live health/status of platform modules (proxy to each module's health endpoint), provider quotas (SerpAPI, Tavily, Brave, LinkUp, Exa, OpenRouter), live KPIs and throughput - **Model & Extractor Catalog** — DB-backed CRUD over registered models and extractors, exposed under `/api/catalog` - **Request history** — 30-day rolling log of every gather/search/fetch request with drill-down - **Cost tracking** — per-provider spend, projections, cost per tier - **Runtime config** — config override store (`/api/config`) with schema validation and audit trail - **RBAC** — role-based access; in the shipped build the dashboard runs in **staging mode** with auth bypassed (see below) - **Brain admin** — fact-status browse/override and cache invalidation via a brain proxy ## Authentication / staging mode The build ships in **staging mode** (`DASHBOARD_STAGING_MODE=true`), so all auth is bypassed and Keycloak is **not** active. Keycloak (JWT) is supported but disabled in this delivery: JWT validation only turns on when `DASHBOARD_KEYCLOAK_URL` is set (empty = off). To go to authenticated mode, set `DASHBOARD_KEYCLOAK_URL` (e.g. an SSO URL), set `DASHBOARD_STAGING_MODE=false`, and rebuild the image (Keycloak config is baked into the JS bundle at build time). DB-backed bearer tokens remain as a legacy fallback. ## Prerequisites - Docker 24+ with Compose V2 - PostgreSQL 16 (provided by compose, `didiAI-dashboard-db` on `:15432`) - Internal network access to the platform modules and provider APIs ## Quick start ```bash cd deploy cp ../.env.example .env # edit with your secrets ./deploy.sh up ``` The dashboard API listens on `http://localhost:51300`. The admin SPA is served at `http://localhost:51300/admin-ai/`. ## Endpoints ### Admin UI (SPA) - `/admin-ai/` — React 19 + MUI SPA (overview, live status, history, cost, providers, catalog, config/schema, audit, brain admin). All client-side routes under `/admin-ai/` are served by the SPA with index fallback. > Legacy Jinja pages (`/`, `/providers`, `/history`, …) still exist server-side > but are not the primary UI; the SPA at `/admin-ai/` is the delivered UI. ### JSON API (selected) - `GET /health` — liveness + DB ping (health JSON at root) - `GET /api/stats/providers` — live provider stats - `GET /api/stats/summary?hours=24` — aggregated counters - `GET /api/stats/timeline?hours=24` — hourly buckets for charts - `GET /api/stats/cost` — cost + projection - `GET /api/history?limit=50&tier=premium` — filtered history - `GET /api/history/{request_id}` — single request with full payload - `GET|POST|PUT|DELETE /api/catalog/...` — Model & Extractor catalog CRUD - `GET /api/config`, `PUT|DELETE /api/config/{key}` — runtime config overrides - `GET /api/proxy/{module_id}/health` — module health proxy (AI monitoring) - `/api/brain/*` — brain proxy (fact status, cache invalidation) - `POST /api/ingest/event` — receives events from web-api middleware ## Architecture ``` web-api ────► POST /api/ingest/event ────► dashboard-api ────► PostgreSQL browser ────► GET /admin-ai/ (React SPA) ──┘ │ ├─ reads provider APIs live ├─ proxies module health + brain └─ serves SPA static (index fallback) ``` ## Tech stack - FastAPI + Pydantic (pydantic-settings, env prefix `DASHBOARD_`) - SQLAlchemy 2.0 async + asyncpg (tables created via `create_all` at startup) - React 19 + MUI 7 + Vite 7 + react-router 7 + TanStack Query + Recharts (built into `web_dist/`, served as static SPA) - PostgreSQL 16