๐Ÿ“„ REMOVED-WIDGET-SPEC.md 3,678 bytes Apr 24, 2026 ๐Ÿ“‹ Raw

Recently Removed Events โ€” Frontend Widget

For: Socrates ๐Ÿง 
From: Daedalus ๐ŸŽจ
Date: 2026-04-24
Status: Frontend complete โ€” awaiting backend wiring


What's Built

Dashboard Widget

A new "Recently Removed" card added to the HoffDesk family dashboard (dashboard/templates/index.html):

  • JS-driven polling โ€” calls GET /family/events/removed?hours=24&limit=5 every 60 seconds
  • Hidden by default โ€” card starts display: none, only appears when count > 0
  • Source icons: ๐Ÿ“ฐ newsletter, ๐Ÿ“ง appointment, ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ family, ๐Ÿ“… fallback
  • Strikethrough titles โ€” removed event summaries are visually struck through with muted opacity
  • Relative timestamps โ€” "removed 2h ago" format
  • Smart date display โ€” "Today 3:30 PM", "Tomorrow 10:00 AM", "Apr 28 3:30 PM"

CSS (in dashboard/static/style.css)

New classes added:
- .removed-list โ€” flex column layout matching .event-list
- .removed-item โ€” row with icon + details, hover state
- .removed-icon โ€” emoji source indicator
- .removed-summary โ€” struck-through event title
- .removed-meta โ€” time + relative removal timestamp


Integration Notes

Endpoint Expected

GET /family/events/removed?hours=24&limit=5
Header: X-Hoffdesk-Secret: <secret>

Response Format

{
  "removals": [
    {
      "uid": "dceb54d1-...",
      "summary": "Softball Tryouts",
      "start_time": "2026-04-28T15:30:00",
      "removed_at": "2026-04-24T01:35:22.184532",
      "removed_by": "telegram_user_-5296734042",
      "source": "newsletter",
      "reason": "User clicked REMOVE button",
      "can_undo": false
    }
  ],
  "count": 1,
  "hours": 24,
  "timestamp": "2026-04-24T01:36:00.000000"
}

Auth (Updated 2026-04-24 โ€” per Socrates' security review)

โš ๏ธ Never expose X-Hoffdesk-Secret in browser HTML or JavaScript.

Pattern How Security Status
Proxy (production) Dashboard server adds header when proxying to API โœ… Secret stays server-side Recommended
Session cookie (production) User logs in โ†’ session cookie โ†’ server validates โœ… Secret stays server-side Recommended
Meta tag (dev only) <meta name="x-hoffdesk-secret"> JS reads โŒ Visible in View Source Dev only

Current implementation: JS sends the request without a secret header. In production, the dashboard dev server should proxy the request and inject X-Hoffdesk-Secret server-side. For local dev, a <meta> tag can be added to the HTML.

For Aundrea's production access: Use session cookies or proxy pattern. She should never see API secrets.

Behavior Rules

Condition Behavior
count === 0 Hide card entirely (display: none)
count > 0 Show card with up to 5 items
Network error Hide card, log error to console
can_undo === true (Future) Show undo button โ€” not yet implemented

Files Changed

File Change
dashboard/templates/index.html Added removed-card section, JS fetch/renderer, helpers
dashboard/static/style.css Added .removed-* classes

No Backend Changes Needed From Socrates

The API spec in shared/api-specs/recently-removed-events.md already matches what the frontend expects. Just confirm the endpoint is live and returns the documented format.


Future Enhancements (v2)

  • Undo button when can_undo === true (currently always false per Radicale limitations)
  • "View All โ†’" link to expand beyond 5 items
  • Group by source with section headers