Dashboard
The dashboard is the primary human interface to chris-os: a full-stack web application that surfaces health data, AI session activity, personal metrics, infrastructure state, and the document library in one place. It runs 24/7 on the production Pi as two containers (API + Nginx) behind Authelia SSO, and it’s also installable as a PWA on any device.
Tech Stack
Section titled “Tech Stack”| Layer | Technology |
|---|---|
| Runtime | Node.js, TypeScript 5.8 |
| API framework | Fastify 5.3 |
| Frontend framework | React 19 |
| Build tool | Vite 6 |
| Router | react-router v7 |
| Server state | TanStack Query v5 |
| Client state | Zustand v5 (4 stores) |
| Styling | Tailwind CSS v4 |
| Charts / visualization | GSAP 3, D3 force layout (web worker), Leaflet |
| Real-time | PostgreSQL LISTEN/NOTIFY via SSE |
| PWA | Workbox (injectManifest strategy) + Web Push / VAPID |
| Testing | Vitest (unit), Playwright (E2E) |
Architecture
Section titled “Architecture”Three containers compose the dashboard stack.
| Container | Purpose |
|---|---|
dashboard-api | Fastify BFF — all /api/* endpoints, 512m / 0.5 CPU |
dashboard-nginx | Static React SPA served by Nginx, 128m / 0.1 CPU |
docker-socket-proxy | Read-only Docker API proxy (containers listing only), 64m / 0.1 CPU |
All browser requests pass through Caddy, which runs Authelia forward_auth before forwarding. The API validates three authentication methods in order: API key (machine-to-machine, for n8n and HA write-backs), JWT Bearer (Hudson iOS app), and Authelia Remote-User headers (browser sessions). Rate limiting runs at 300 req/min, keyed on the authenticated user identity. Redis backs the rate limiter and response caches.
The API connects to PostgreSQL with two separate pools: a read-only pool for data queries and a write pool for document creation, dispatch updates, and health data ingestion.
21 pages total, organized into four categories. Every page except the login redirect renders inside a persistent shell with a collapsible sidebar (desktop) or bottom navigation (mobile).
| Path | Description |
|---|---|
/ / /briefing | Morning briefing: calendar events, activity rings, email summary, system status, and weather |
/dashboard | Bento grid of 27+ configurable widgets — the primary glanceable view |
/review | AI-suggested data corrections requiring human confirmation |
Personal
Section titled “Personal”| Path | Description |
|---|---|
/health | Health rings, workout trends, body metrics, correlations, and nudges |
/people | Relationship graph, contact clusters, and attention queue |
/cortex | Interactive system topology graph — live service health with SSE-driven edge animations |
/story | Personal narrative view: pulse, constellation, mind, pillars, and life timeline |
/photos | Photo library stats, camera breakdown, and type breakdown |
/brewery | Homebrewing tracker: recipes, sessions, fermentation status, and tap list |
/intake | Conversational biographical intake form |
/time | Time Portrait — how time is distributed across life categories |
| Path | Description |
|---|---|
/dispatch | The Panel: AI agent session monitoring, review queue, and escalations |
/workshop | Work ops: recent commits, CI pipeline status, service health, GitHub board |
/council | Council session viewer and morning briefing |
| Path | Description |
|---|---|
/chat | Live AI chat interface with voice input and TTS output |
/docs | Document library with collection and tag filtering |
/docs/:slug | Document viewer (Markdown and HTML rendering, Mermaid diagrams) |
/imports | Data import pipeline status and manual triggers |
/settings | User settings, push notification management, OIDC configuration |
The Dashboard Widget Grid
Section titled “The Dashboard Widget Grid”The /dashboard page is a fully configurable bento grid of 27+ widgets. The context switcher in the shell toggles between personal and work views, filtering which navigation items and widgets are active.
| Widget | What it shows |
|---|---|
MorningBriefing | Full AI-generated morning briefing |
TodaysAgenda / PersonalAgenda | Calendar agenda items |
HealthRings | Activity ring visualization (move / exercise / stand) |
FitnessTracker | Workout summary |
HealthCorrelations | Health metric correlation matrix |
PeakStateGauge | Peak State composite score across 5 categories |
HabitTracker | Habit completion grid |
Weather | Current conditions |
HomeStatus | Home Assistant entity states |
EmailSummary | Unread count and classified email summary |
ReviewQueue | Pending data corrections |
Relationships | Relationship attention queue |
WorkAttention / WorkBriefing | Work items needing attention |
WorkBoard | GitHub project board snapshot |
WorkCommits | Recent commit stream |
WorkSessions | AI agent session list |
WorkPipelines | CI pipeline health |
WorkServices | Docker service health |
SystemHealth | Infrastructure health summary |
PipelineHealth | n8n pipeline health |
BackupStatus | R2 backup status |
ClaudeUsage | Claude API usage metrics |
CornerstoneRadar | Cornerstone radar chart |
TagExplorer | Knowledge graph tag browser |
DiscordActivity | Discord server activity |
WeeklySchedule | Weekly calendar grid |
The Cortex Page
Section titled “The Cortex Page”The /cortex page is a live topology map of the entire infrastructure rendered as a force-directed graph. Each node represents a service; edges light up in real time when SSE events fire, reflecting actual data flowing between components. The D3 simulation runs in a dedicated web worker to keep the main thread responsive.
Node health is color-coded from the PostgreSQL topology query. A tabular fallback view is available for mobile. Switching between graph layers, drilling into node detail, and viewing the daily activity arc are all available from the same page.
The Panel (Dispatch)
Section titled “The Panel (Dispatch)”The /dispatch page is command-and-control for AI agent sessions. It shows:
- Active and recent agent sessions with timeline and waterfall charts
- Review items requiring human approval (approve, revert, dismiss)
- Escalations with history and bulk status updates
- Session highlights and metrics
- The morning report view
n8n and agent infrastructure write to the dispatch endpoints via API key auth. The sidebar badge polls /api/dispatch/pending-count and updates in real time.
Real-Time: SSE
Section titled “Real-Time: SSE”A single persistent PostgreSQL LISTEN connection fans out to all connected browser clients via Server-Sent Events at /api/events. The server sends a 15-second heartbeat comment to survive Cloudflare’s idle timeout. On client reconnect (exponential backoff from 1s to 30s), TanStack Query invalidates the relevant caches.
| SSE Event | Caches Invalidated |
|---|---|
github:updated | GitHub data |
calendar:update | Calendar data |
briefing:updated | Morning briefing (full) |
dispatch:updated | Dispatch, escalations, pending count |
Cortex edge animations are driven by the same SSE stream via a separate useSyncExternalStore subscription that maps event types to topology edge keys, triggering 2-second flash animations on the graph.
~130 endpoints across 15 functional groups: auth, briefing, calendar, email, health and fitness, home/weather/system, personal data, documents, work, brewing, review/claims, story, cortex/imports, council, dispatch, push notifications, voice, and SSE. The /api/v1/* prefix is supported for Hudson iOS compatibility (rewritten to /api/* inside Fastify).
Response caching via Cache-Control headers: weather (30 min), Peak State (60 min), health rings (5 min), briefing (1 min), email (2 min). All GET responses carry weak ETags for conditional requests.
PWA and Push Notifications
Section titled “PWA and Push Notifications”The dashboard installs as a standalone PWA (name: Ataraxis, theme: dark). The service worker precaches all static assets using Workbox and routes API calls as NetworkOnly to prevent stale authenticated data. HTML is explicitly excluded from precache to avoid conflicts with Authelia’s auth redirects.
Web Push uses VAPID. The browser subscribes through the Settings page; n8n delivers notifications via the API key-authenticated /api/push/send endpoint. APNs device token storage for Hudson iOS is also supported (delivery infrastructure pending).
Mobile (Hudson)
Section titled “Mobile (Hudson)”Hudson, the iOS companion app, authenticates with JWT Bearer tokens issued by Authelia’s OIDC provider. All mobile requests go to /api/v1/* and receive an X-API-Version: v1 header in every response. Navigation preferences are persistable and customizable from the mobile nav edit sheet.