
# 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](/en/docs/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.            |

```bash
# 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'
```

:::callout
**Period presets are shared, not per-endpoint.** Overview endpoints reuse one `periodPresetSchema` (`24h` \| `7d` \| `30d`) and one `resolvePeriodWindow()` helper rather than redeclaring the enum, so a window means the same thing everywhere. Sparse domains (user signups) and dense ones (automation runs) share the identical `totals + series` body.
:::

## 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](/en/docs/security-hardening). |
| **Audit log**        | Each call emits a canonical event (e.g. `form.detail.queried`) exactly once. See [Activity Monitoring](/en/docs/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](/en/docs/user-management).
- **Aggregated traffic analytics** → `GET /api/analytics/overview` and siblings. See [Analytics](/en/docs/analytics).
- **System-wide activity stream** → `GET /api/activity`. See [Activity Monitoring](/en/docs/activity-monitoring).

## Related Pages

- [User Management](/en/docs/user-management) — the mutating admin operations the dashboard reflects.
- [Activity Monitoring](/en/docs/activity-monitoring) — the audit-log stream every dashboard call writes to.
- [Analytics](/en/docs/analytics) — the traffic-analytics read surface.
- [Security Hardening](/en/docs/security-hardening) — RBAC, 404-not-403, rate limiting.
- [Buckets Overview](/en/docs/buckets-overview) — storage buckets surfaced by the buckets endpoints.
- [Forms Overview](/en/docs/forms-overview) — the forms surfaced by the forms endpoints.
