Appearance
Platform Status Dashboard — Design Document ​
ADR: 0034
ADO: Feature "Admin Platform Status Dashboard" (under Epic AB#3074)
Status: Accepted
Last updated: 2026-06-23
Overview ​
The platform status dashboard is an admin-only page at /app/admin/status that shows the current health of the Heritage Virginia platform by querying the enriched /health API endpoint. It is the first stop for an administrator investigating a reported outage or degraded experience.
Data Model ​
/health API Response ​
typescript
interface HealthResponse {
status: 'ok' | 'degraded' | 'error';
version: string; // npm_package_version from package.json
commit: string; // COMMIT_SHA env var injected at Docker build time
uptime: number; // process.uptime() in seconds
timestamp: string; // ISO 8601
services: {
api: {
status: 'ok' | 'degraded' | 'error';
};
database: {
status: 'ok' | 'error';
latencyMs: number | null; // round-trip latency of SELECT 1 probe
};
};
}Status roll-up rules:
| Condition | Top-level status |
|---|---|
All services ok | ok |
Any service error | degraded |
| API itself failed | error (returned by load balancer) |
API Contract ​
GET /health ​
- Auth: None (public endpoint; consumed by Azure health probes and CI smoke checks)
- Rate limiting: Subject to global rate limiter (100 req/min per IP)
- Response:
HealthResponse(see above) - Implementation:
apps/api/src/app.ts—/healthroute
Database probe: SELECT 1 via Prisma $queryRaw. Failure sets services.database.status = 'error' and rolls top-level status to degraded. The route does not throw — health is always returned.
COMMIT_SHA injection:
# Dockerfile (runtime stage)
ARG COMMIT_SHA=unknown
ENV COMMIT_SHA=$COMMIT_SHA
# deploy.yml (docker/build-push-action)
build-args: |
COMMIT_SHA=${{ github.sha }}The full SHA is stored in process.env.COMMIT_SHA; the UI displays only the first 7 characters.
UI Layout ​
Route ​
/app/admin/status — protected by user.role !== 'admin' redirect to /app/profile.
Component ​
apps/web/src/pages/admin/AdminStatusPage.tsx
Layout structure ​
<div maxWidth=640 centered>
<h1>Platform Status</h1>
<!-- Overall status card -->
<card>
label: "Overall"
value: dot-indicator + status string (OK / DEGRADED / ERROR)
</card>
<!-- Services card -->
<card>
header: "Services"
row: API | dot + status
row: Database | dot + status (+ latencyMs if available)
</card>
<!-- Deployment card -->
<card>
header: "Deployment"
row: Version | npm_package_version
row: Commit | first 7 chars of SHA (monospace)
row: Uptime | Xh Ym format
row: Last checked | toLocaleTimeString of timestamp
</card>
<!-- App Insights link -->
<a href="Azure Portal App Insights resource">Open App Insights →</a>
</div>Status indicators ​
| Status | Indicator |
|---|---|
ok | Green circle |
degraded | Yellow circle |
error / unknown | Red circle |
States ​
- Loading: "Loading..." text while fetch is in flight
- Error: "Could not reach API health endpoint." — shown when the fetch rejects
- Loaded: Full card layout as above
Vite dev proxy ​
In development, fetch('/api/health') resolves via the Vite dev server proxy:
typescript
// vite.config.ts — server.proxy
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
}In production (Azure SWA), the SWA routing config proxies /api/* to the Container App API endpoint at https://api.heritageva.app.
Access Control ​
- Route guard:
AdminHubPagepattern —if (user && user.role !== 'admin') return <Navigate to="/app/profile" replace /> - The
/healthendpoint itself is public (no auth) to support Azure health probes and the CI smoke check.
App Insights Integration ​
The status page links to the App Insights resource in Azure Portal:
- Resource:
appi-heritageva-prod - Resource Group:
rg-heritageva-prod-eus - Subscription:
be069ae1-fc96-4a07-9f8e-5994d83a137d - Region: East US
Direct portal link format:
https://portal.azure.com/#resource/subscriptions/{subscriptionId}/resourceGroups/{rg}/providers/microsoft.insights/components/{name}/overviewThe status page does NOT embed App Insights charts — it links out. Embedding would require MSAL authentication which adds complexity inconsistent with ADR 0003.
AdminHubPage Integration ​
A "Platform Operations" ListSection is added to AdminHubPage with two rows:
| Label | Destination |
|---|---|
| Platform Status | /app/admin/status |
| CLI Tools | /app/admin/cli-tools |
Related ​
- ADR 0034 — governing decision
- ADR 0005 — observability (App Insights as primary telemetry)
docs/internal/design/platform-management-cli.md— CLI tool designapps/api/src/schemas/responses.ts—HealthResponseSchema(Zod, AB#4326)