Contract Refactor Summary โ UI Namespace Implementation
Completed: 2026-04-29
Task: Implement /ui/ namespace per CONTRACT.md specification
Files Created
1. UI Router
- Path:
workspace-socrates/hoffdesk-api/dashboard/ui_router.py - Description: New FastAPI router with
/ui/*endpoints - Routes:
GET /ui/weather-cardโ Returns HTML fragment using Jinja2 templateGET /ui/health-cardโ Returns HTML fragment using Jinja2 templateGET /ui/events-listโ Returns HTML fragment using Jinja2 template (moved from /api/events-list)GET /ui/events-weekโ Returns HTML fragment using Jinja2 template (moved from /api/events-week)
2. Jinja2 Templates (Icarus Templates Directory)
icarus/templates/dashboard/components/weather_card.html.j2icarus/templates/dashboard/components/health_card.html.j2icarus/templates/dashboard/components/events_list.html.j2icarus/templates/dashboard/components/events_week.html.j2
3. Updated Main Router
- Path:
workspace-socrates/hoffdesk-api/main.py - Changes:
- Added import:
from dashboard.ui_router import router as ui_router - Added to family_app:
family_app.include_router(ui_router, tags=["ui"]) - Added to dev_app:
dev_app.include_router(ui_router, prefix="/family/ui", tags=["ui"])
4. Updated Dashboard Router
- Path:
workspace-socrates/hoffdesk-api/dashboard/router.py - Changes:
- Added Jinja2Templates initialization pointing to
icarus/templates/ - Converted
/api/events-listto JSON response (deprecated, recommends/ui/events-list) - Converted
/api/events-weekto JSON response (deprecated, recommends/ui/events-week) - Note: Functions
_format_event_for_list,_get_day_label,_get_week_startare now shared helpers
Endpoint Mapping
| Old Endpoint | New Endpoint | Response Type | Status |
|---|---|---|---|
/api/events-list |
/ui/events-list |
HTMLResponse | Created |
/api/events-week |
/ui/events-week |
HTMLResponse | Created |
| โ | /ui/weather-card |
HTMLResponse | Created |
| โ | /ui/health-card |
HTMLResponse | Created |
/api/events-list |
/api/events-list |
JSONResponse | Deprecated |
/api/events-week |
/api/events-week |
JSONResponse | Deprecated |
/api/today |
โ | JSONResponse | Unchanged (for external consumers) |
Validation Checklist (from CONTRACT.md)
- [x]
/ui/weather-cardreturns HTML, not JSON - [x]
/ui/health-cardreturns HTML, not JSON - [x]
/ui/events-listreturns HTML (moved) - [x]
/ui/events-weekreturns HTML (moved) - [ ] Dashboard template HTMX calls work โ REQUIRES Daedalus to update templates
Next Steps (Daedalus)
Daedalus must update the dashboard HTML templates to use the new /ui/* endpoints:
File to update: icarus/templates/dashboard/index.html
Current HTMX calls (using /api/today):
<section class="card" id="weather-card" ... hx-get="/api/today" ...>
<section class="card" id="health-card" ... hx-get="/api/today" ...>
<section class="card" id="calendar-card" ... hx-get="/api/today" ...>
Should change to:
<section class="card" id="weather-card" ... hx-get="/ui/weather-card" ...>
<section class="card" id="health-card" ... hx-get="/ui/health-card" ...>
<section class="card" id="events-card" ... hx-get="/ui/events-list" ...>
Contract Compliance
Per CONTRACT.md Section 2: If HTMX calls it, it MUST be /ui/* and return HTML.
| Requirement | Status |
|---|---|
| No inline HTML generation in Python | โ Jinja2 templates used exclusively |
| JSON and HTML never mixed | โ /ui/* returns HTML, /api/* returns JSON |
Template paths use icarus/templates/ |
โ All templates in icarus/templates/dashboard/components/ |
HTMX endpoints in /ui/* namespace |
โ All new HTMX endpoints use /ui/ prefix |
Testing
To test the new endpoints:
# Test weather card (returns HTML)
curl http://family.hoffdesk.com/ui/weather-card
# Test health card (returns HTML)
curl http://family.hoffdesk.com/ui/health-card
# Test events list (returns HTML)
curl http://family.hoffdesk.com/ui/events-list
# Test events week (returns HTML)
curl http://family.hoffdesk.com/ui/events-week?start=2026-04-28
# Test deprecated endpoints (return JSON)
curl http://family.hoffdesk.com/api/events-list
curl http://family.hoffdesk.com/api/events-week
API Response Examples
/ui/weather-card (HTML)
<div class="weather-card-content">
<div class="weather-current">
<div class="weather-temp temp-mild">52ยฐ</div>
<div class="weather-details">
<div class="weather-condition">Partly cloudy</div>
<div class="weather-meta text-body-sm text-text-secondary">
Feels like 49ยฐ ยท 62% humidity ยท 10 mph wind
</div>
</div>
</div>
...
</div>
/api/events-list (deprecated, JSON)
{
"events": [...],
"meta": {
"note": "This endpoint is deprecated. Use /ui/events-list for HTML fragments.",
"count": 5
}
}
Enforced by: Wadsworth (Chief of Staff)
Approved by: Matt Hoffmann (Director)