Skip to main content
View as Markdown

Admin Dashboard

Sovrium ships a built-in App Admin Dashboard: a family of read-only API endpoints that give operators and auditors a single, consistent surface over the running app's health and inventory. Every endpoint is RBAC-gated, emits a canonical audit-log event, and returns 404 (never 403) on unauthorized access to defeat enumeration.

The dashboard is a read surface. Mutating operations — creating users, changing roles, publishing schema — live in their own endpoints (User Management); the dashboard reflects state, it does not change it. Three audiences share the exact same response shapes: admins (drill-down decisions), operators (incident reports, on-call handoffs), and auditors (SOC2 / GDPR review documentation).

Two Response Shapes

Every dashboard endpoint is one of two shapes, so the contract generalizes cleanly across domains.

Shape Endpoint pattern Body
Overview GET /api/admin/{domain}/overview Period-aware aggregate counters (totals), a bucketed time series (series), and derived health metrics. Non-paginated.
List GET /api/admin/{domain} Cursor-paginated items, each carrying an operator-grade _admin block with metadata (counts, last-activity timestamps).

Overview endpoints accept a shared period preset (24h | 7d | 30d) via resolvePeriodWindow(); list endpoints accept cursor pagination, free-text search, and ?include_deleted=true.

Endpoint Surface

Domain Endpoint(s) Returns
Config GET /api/admin/config/version Running version, build commit, active database runtime, Bun version, process start time.
Automations GET /api/admin/automations/overview, GET /api/admin/automations/runs Run totals, failure counts, success_rate, bucketed series; paginated run list.
Users GET /api/admin/users/overview Total users, recently active, new signups for the period, role distribution, signup/session series.
Tables GET /api/admin/tables/overview Per-table rowCount, softDeletedCount, lastWriteAt, writesInPeriod, totals, write series.
Buckets GET /api/admin/buckets, GET /api/admin/buckets/overview Cursor-paginated bucket list with provider filter; quota/usage overview.
Forms GET /api/admin/forms, GET /api/admin/forms/:formName Configured forms with submission counts and last-submission timestamps; per-form detail.
# Version reflection — the smallest read endpoint, the cross-cutting shake-down test
curl -H 'Cookie: <admin session>' http://localhost:3000/api/admin/config/version

# Period-scoped overview
curl -H 'Cookie: <admin session>' 'http://localhost:3000/api/admin/tables/overview?period=7d'

# Cursor-paginated list with search
curl -H 'Cookie: <admin session>' 'http://localhost:3000/api/admin/forms?search=contact&limit=20'

Cross-Cutting Guarantees

Every dashboard endpoint inherits the same security and observability primitives:

Guarantee Behavior
RBAC Three-tier middleware gates each route on the caller's role.
Anti-enumeration Unauthorized access returns 404, never 403 — the id space is unguessable and the route's existence is unobservable. See Security Hardening.
Audit log Each call emits a canonical event (e.g. form.detail.queried) exactly once. See Activity Monitoring.
OpenAPI Routes are declared via the shared adminRoute helper, so the surface is documented and type-checked.
Forward contract ?include_deleted=true parses without 400 so auditors get a stable interface as deleted-row visibility lands.

Sibling Endpoints (Not the Dashboard)

Some operator-relevant reads live outside the /api/admin/{domain} dashboard family because they predate it or belong to another subsystem:

  • Per-user records (id, email, name) → GET /api/auth/admin/list-users. See User Management.
  • Aggregated traffic analyticsGET /api/analytics/overview and siblings. See Analytics.
  • System-wide activity streamGET /api/activity. See Activity Monitoring.