didi-lot1-ai/ai_platform/modules/dashboard/README.md

94 lines
4 KiB
Markdown

# 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