Recently Removed Events API Spec
For: Home Dashboard "Recently Removed" widget
Status: Backend ready โ awaiting frontend implementation
Owner: Socrates (backend) / Daedalus (frontend)
Related Spec: See Daedalus' frontend implementation spec at
workspace-daedalus/dashboard/REMOVED-WIDGET-SPEC.md
Auth
For production, use session-based auth or proxy pattern โ never expose the secret in browser HTML. See "Security Notes" below.
Endpoint
GET /family/events/removed
Auth: X-Hoffdesk-Secret header (same as webhook)
Query Parameters
| Param | Type | Default | Description |
|---|---|---|---|
hours |
int | 24 | How far back to look |
limit |
int | 20 | Max results to return |
Response
{
"removals": [
{
"uid": "dceb54d1-2cc4-4d1c-9210-775a1c0c8442",
"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"
}
Fields
| Field | Type | Description |
|---|---|---|
uid |
string | Event unique ID (Radicale UID) |
summary |
string | Event title |
start_time |
ISO 8601 | When event was scheduled |
removed_at |
ISO 8601 | When it was deleted |
removed_by |
string | Who removed it (telegram_user_{chat_id}) |
source |
string | Where it came from: newsletter, appointment, family |
reason |
string | Why it was removed (optional) |
can_undo |
boolean | Always false โ Radicale doesn't support undo |
UI Suggestions
Widget Design:
- Compact list (max 5 items visible, scroll for more)
- Show: summary + start_time (formatted nicely)
- Subtle timestamp: "Removed 2 hours ago"
- Group by source with icons: ๐ฐ newsletter, ๐ง appointment, etc.
Example Layout:
โโ Recently Removed โโโโโโโโโโโโโโโโโโ
โ ๐ฐ Softball Tryups โ
โ Apr 28, 3:30 PM ยท 2h ago โ
โ ๐ฐ Spirit Week โ
โ Apr 28-30 ยท 5h ago โ
โ โ
โ [View All โ] โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Empty State:
- Hide widget entirely if count === 0
- Or show: "No events removed recently โ all good!"
Integration Notes
- Poll every 30-60 seconds if user is on dashboard
- Or refresh on dashboard load
- No real-time WebSocket (not needed for this)
Security Notes
โ ๏ธ Never expose X-Hoffdesk-Secret in browser HTML or JavaScript.
Recommended patterns:
| Pattern | How | Security |
|---|---|---|
| Session cookie (best) | User logs in โ session cookie โ server validates | Secret stays server-side |
| Proxy (good for dev) | Dashboard server adds header when proxying to API | Secret in env, not browser |
| Meta tag (dev only) | <meta name="secret" content="..."> JS reads |
โ Visible in View Source |
For production with Aundrea: Use session cookies or proxy pattern. She should never see API secrets.
Backend Behavior
- Events are logged when user clicks REMOVE button in Telegram
- Retained for 30 days then auto-purged
- Logs stored at:
hoffdesk-api/data/removed_events.jsonl