Skip to content

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.

LayerTechnology
RuntimeNode.js, TypeScript 5.8
API frameworkFastify 5.3
Frontend frameworkReact 19
Build toolVite 6
Routerreact-router v7
Server stateTanStack Query v5
Client stateZustand v5 (4 stores)
StylingTailwind CSS v4
Charts / visualizationGSAP 3, D3 force layout (web worker), Leaflet
Real-timePostgreSQL LISTEN/NOTIFY via SSE
PWAWorkbox (injectManifest strategy) + Web Push / VAPID
TestingVitest (unit), Playwright (E2E)

Three containers compose the dashboard stack.

ContainerPurpose
dashboard-apiFastify BFF — all /api/* endpoints, 512m / 0.5 CPU
dashboard-nginxStatic React SPA served by Nginx, 128m / 0.1 CPU
docker-socket-proxyRead-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).

PathDescription
/ / /briefingMorning briefing: calendar events, activity rings, email summary, system status, and weather
/dashboardBento grid of 27+ configurable widgets — the primary glanceable view
/reviewAI-suggested data corrections requiring human confirmation
PathDescription
/healthHealth rings, workout trends, body metrics, correlations, and nudges
/peopleRelationship graph, contact clusters, and attention queue
/cortexInteractive system topology graph — live service health with SSE-driven edge animations
/storyPersonal narrative view: pulse, constellation, mind, pillars, and life timeline
/photosPhoto library stats, camera breakdown, and type breakdown
/breweryHomebrewing tracker: recipes, sessions, fermentation status, and tap list
/intakeConversational biographical intake form
/timeTime Portrait — how time is distributed across life categories
PathDescription
/dispatchThe Panel: AI agent session monitoring, review queue, and escalations
/workshopWork ops: recent commits, CI pipeline status, service health, GitHub board
/councilCouncil session viewer and morning briefing
PathDescription
/chatLive AI chat interface with voice input and TTS output
/docsDocument library with collection and tag filtering
/docs/:slugDocument viewer (Markdown and HTML rendering, Mermaid diagrams)
/importsData import pipeline status and manual triggers
/settingsUser settings, push notification management, OIDC configuration

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.

WidgetWhat it shows
MorningBriefingFull AI-generated morning briefing
TodaysAgenda / PersonalAgendaCalendar agenda items
HealthRingsActivity ring visualization (move / exercise / stand)
FitnessTrackerWorkout summary
HealthCorrelationsHealth metric correlation matrix
PeakStateGaugePeak State composite score across 5 categories
HabitTrackerHabit completion grid
WeatherCurrent conditions
HomeStatusHome Assistant entity states
EmailSummaryUnread count and classified email summary
ReviewQueuePending data corrections
RelationshipsRelationship attention queue
WorkAttention / WorkBriefingWork items needing attention
WorkBoardGitHub project board snapshot
WorkCommitsRecent commit stream
WorkSessionsAI agent session list
WorkPipelinesCI pipeline health
WorkServicesDocker service health
SystemHealthInfrastructure health summary
PipelineHealthn8n pipeline health
BackupStatusR2 backup status
ClaudeUsageClaude API usage metrics
CornerstoneRadarCornerstone radar chart
TagExplorerKnowledge graph tag browser
DiscordActivityDiscord server activity
WeeklyScheduleWeekly calendar grid

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 /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.

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 EventCaches Invalidated
github:updatedGitHub data
calendar:updateCalendar data
briefing:updatedMorning briefing (full)
dispatch:updatedDispatch, 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.

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).

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.