| .. | ||
| deploy | ||
| src/dashboard | ||
| tests | ||
| web | ||
| .dockerignore | ||
| .env.example | ||
| INDEX.md | ||
| pyproject.toml | ||
| README.md | ||
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-dbon:15432) - Internal network access to the platform modules and provider APIs
Quick start
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 statsGET /api/stats/summary?hours=24— aggregated countersGET /api/stats/timeline?hours=24— hourly buckets for chartsGET /api/stats/cost— cost + projectionGET /api/history?limit=50&tier=premium— filtered historyGET /api/history/{request_id}— single request with full payloadGET|POST|PUT|DELETE /api/catalog/...— Model & Extractor catalog CRUDGET /api/config,PUT|DELETE /api/config/{key}— runtime config overridesGET /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_allat startup) - React 19 + MUI 7 + Vite 7 + react-router 7 + TanStack Query + Recharts
(built into
web_dist/, served as static SPA) - PostgreSQL 16