# Wadsworth — Dashboard Operations Brief **From:** Daedalus 🎨 **Date:** 2026-04-28 **Purpose:** Routing, config, and monitoring for the Family Dashboard --- ## 1. Architecture Overview ``` family.hoffdesk.com ↓ Cloudflare Tunnel ↓ (Host: family.hoffdesk.com) ↓ titanium-butler:8000 ← main_v2.py (Starlette host routing) ├── family_app (when Host: family.hoffdesk.com) │ ├── SessionAuthMiddleware ← all routes except /login, /static/ │ ├── auth_router → GET /login, POST /login, GET /me, POST /logout │ ├── dashboard_router → GET / (dash HTML), GET /family/login/, GET /api/today │ ├── family_router → /admin/... (family automation) │ ├── imap_router → IMAP proxy dashboard │ └── WebSocket endpoints (future) │ └── blog app (all other hosts) ``` **There is also a second server on port 8001:** ``` titanium-butler:8001 ← Icarus staging API (icarus.core.api) ├── /api/today ← calendar + weather + health JSON ├── /api/event_graph/... ← Event Graph CRUD ├── /system/state ← System state dashboard HTML └── Jinja2 templates ← index.html.j2 (HTMX version) ``` **Current state:** The `family.hoffdesk.com` app (port 8000) serves a static `index.html` without the Event Graph cards. The Icarus server (port 8001) has the Jinja2 template with HTMX wiring but lacks auth middleware and isn't behind the tunnel. --- ## 2. Routes & Endpoints ### Auth (family_app, port 8000) | Method | Path | Purpose | Status | |--------|------|---------|--------| | GET | `/family/login/` | Login page | ✅ Live | | POST | `/login` | Login handler (JSON body) | ✅ Live | | GET | `/me` | Session check | ✅ Live | | POST | `/logout` | Clear session | ✅ Live | **Credentials (from `.env`):** - `matt` / `hoffdesk-matt-2026` — roles: admin, editor - `aundrea` / `hoffdesk-aundrea-2026` — roles: family ### Dashboard (family_app, port 8000) | Method | Path | Purpose | Status | |--------|------|---------|--------| | GET | `/` | Dashboard (requires auth) | ✅ Live | | GET | `/api/today` | JSON: calendar+weather+health | ✅ Live | ### Icarus API (port 8001, internal) | Method | Path | Purpose | Status | |--------|------|---------|--------| | GET | `/api/today` | Calendar + weather + health JSON | ✅ Live | | GET | `/api/event_graph/stats` | Event Graph aggregate stats | ✅ Live | | GET | `/api/event_graph/recent` | Recent events from graph | ✅ Live | | GET | `/api/event_graph/coordination` | Coordination items | ✅ Live | | GET | `/system/state` | System state dashboard HTML | ✅ Live | | GET | `/` or `/family/` | Dashboard HTML (Jinja2, HTMX) | ✅ Live | | GET | `/family/login/` | Login page | ✅ Live | ### Running the Icarus Server ```bash cd /home/hoffmann_admin/.openclaw/workspace/services/icarus ICARUS_ENV=staging \ PYTHONPATH=/home/hoffmann_admin/.openclaw/workspace/services:$PYTHONPATH \ nohup uvicorn icarus.core.api:app --host 0.0.0.0 --port 8001 --log-level info > /tmp/icarus-api.log 2>&1 & ``` --- ## 3. What's Working (Daedalus ✅) - Family dashboard served at `family.hoffdesk.com` with auth - Login flow: page → POST /login → session cookie → redirect to dashboard - `/api/today` returns calendar (Radicale), weather (wttr.in), health (live pings) - Static assets served at `/static/` (style.css, favicon.svg, system-state.css) - Event Graph API endpoints on port 8001 - CSS polish: Event Graph cards, IMAP proxy, iPad responsive (shared/project-docs/dashboard/static/style.css) --- ## 4. What Needs Routing / Config (Wadsworth) ### Critical - [ ] **Monitor the Icarus server process** on port 8001 — start it on boot, restart if it dies - [ ] **ICARUS_ENV** must be `staging` for the assert in api.py line 11 - [ ] **PYTHONPATH** must include `/home/hoffmann_admin/.openclaw/workspace/services` for the `icarus` package to resolve ### Config Management - [ ] **HOFFDESK_USERS** env var in `.env` contains the credential map — do NOT expose in logs - [ ] **SESSION_SECRET_KEY** should be set for production (currently defaults to dev-secret) - [ ] **RADICALE_HOST/PORT/USER/PASS** — used by dashboard router for calendar data - [ ] **Cloudflare tunnel** routes `family.hoffdesk.com` to `localhost:8000` ### Dashboard Template Path (important) The dashboard router on port 8000 reads templates from: ``` /home/hoffmann_admin/.openclaw/shared/project-docs/dashboard/templates/ ``` This is a shared path — if I update templates, they're live immediately. Don't move them. ### Event Graph The Event Graph API runs on port **8002** and feeds into the dashboard. If 8002 is down, `/api/today` returns empty events gracefully (no crash). --- ## 5. Monitoring ### Health Check Endpoints ``` GET http://localhost:8000/health → blog API health GET http://localhost:8001/api/today → Icarus health (check status fields) GET http://localhost:8002/health → Event Graph health GET http://localhost:5232/ → Radicale CalDAV health ``` ### What to Watch 1. **Port 8001** — Icarus API dies if PYTHONPATH is wrong 2. **Port 8002** — Event Graph API (needs separate startup) 3. **Radicale on 5232** — calendar source; dashboard degrades gracefully but quietly 4. **Cloudflare tunnel** — if it drops, `family.hoffdesk.com` is unreachable ### Model Health Watchdog See `shared/processes/model-health-watchdog.md` for the model ping spec. Not yet implemented. --- ## 6. Quick Commands ```bash # Check dashboard is alive curl -s -H "Host: family.hoffdesk.com" -o /dev/null -w "%{http_code}" http://localhost:8000/ # Check API response curl -s -H "Host: family.hoffdesk.com" http://localhost:8000/api/today | python3 -m json.tool # Restart Icarus API kill $(lsof -t -i:8001) sleep 2 cd /home/hoffmann_admin/.openclaw/workspace/services/icarus && \ ICARUS_ENV=staging PYTHONPATH=/home/hoffmann_admin/.openclaw/workspace/services:$PYTHONPATH \ nohup uvicorn icarus.core.api:app --host 0.0.0.0 --port 8001 --log-level info > /tmp/icarus-api.log 2>&1 & # Check logs tail -20 /tmp/icarus-api.log # Test auth flow curl -s -c /tmp/hcookie.txt -X POST http://localhost:8000/login \ -H "Content-Type: application/json" \ -d '{"username":"matt","password":"hoffdesk-matt-2026"}' curl -s -b /tmp/hcookie.txt -H "Host: family.hoffdesk.com" http://localhost:8000/ ``` --- ## 7. URLs | URL | Destination | Auth | |-----|-------------|------| | https://family.hoffdesk.com/ | Family dashboard | Session cookie | | https://family.hoffdesk.com/family/login/ | Login page | None | | https://hoffdesk.com/ | Blog (public) | None | | https://hook.hoffdesk.com/ | Webhooks | Token | --- *Questions? Ping @Daedalus89Bot on Telegram or drop a note in shared/project-docs/*