4.8 KiB
4.8 KiB
TASK METADATA
- Target Files:
server/routes/events.tsui/components/sessions/EventCockpitDeck.tsxui/components/sessions/EventGuestsDrawer.tsxui/components/sessions/SessionsScript.tsxui/components/SessionsPage.tsxserver/tests/events.test.tsui/ui_scripts.test.ts
- Core Objective: Clean up the Sessions & Events dashboard by archiving
expired passes into a collapsible
<details>accordion with a 1-click[ 🔄 Reopen (+1h) ]action, and enrich the Guest Drawer with real-time attendee telemetry and activity logs. - Dependencies: None.
- Additional Important Notes:
- Must remain 100% pure React-free Hono SSR JSX.
- Distinguish between naturally expired events (
expires_at < NOW(),is_active = TRUE, reopenable) vs manually terminated events (is_active = FALSE, permanent archive).
2. Architectural Considerations & Risks
Risks
- Dashboard Clutter & Information Overload: As organizers host dozens of
workshops over weeks, active and dead events pile up on the main screen,
pushing active management tools below the fold.
- Mitigation: Partition the SQL query and SSR view into two decks:
activePasses(top priority grid/compact cards) andexpiredPasses(collapsed under a clean<details>drawer showing count[ 📁 Expired Passes (N) ]).
- Mitigation: Partition the SQL query and SSR view into two decks:
- Re-opening State Ambiguity: If an organizer re-opens an event that
expired 3 days ago, adding 1 hour via
expires_at + interval '1h'leaves it in the past.- Mitigation: Use
SET expires_at = GREATEST(expires_at, NOW()) + interval '1 hour'in PostgreSQL to guarantee the event opens immediately for 60 minutes from the moment clicked.
- Mitigation: Use
- Telemetry Performance in Large Guest Drawers: Querying full session
activity logs for 100+ attendees could slow down
GET /api/events/:id/attendees.- Mitigation: Select only
last_activity_action,last_activity_at, andis_agentjoined directly onsessionsindexed byuser_id.
- Mitigation: Select only
Alternatives
- Permanent Deletion of Expired Events: We considered automatically dropping expired events from the database. However, organizers frequently need to audit past workshop attendees or re-open events that ran over schedule. Keeping expired passes in an archived state maintains audit integrity.
3. Proposed Implementation
Phase 1: Split Active vs. Expired Events Query (ui/components/SessionsPage.tsx)
- Update
event_passesquery inSessionsPage.tsx:- Split passes into
activeEvents = eventPasses.filter(e => e.is_active && (!e.expires_at || new Date(e.expires_at) > new Date())). expiredEvents = eventPasses.filter(e => !e.is_active || (e.expires_at && new Date(e.expires_at) <= new Date())).
- Split passes into
- Pass both arrays into
EventCockpitDeck.tsx.
Phase 2: Collapsible Expired Deck & 1-Click Reopen (ui/components/sessions/EventCockpitDeck.tsx)
- Active Deck:
- Render active events in standard Grid or 2-Row Compact view.
- Archived Deck (
[ 📁 Expired Passes (N) ]):- Render a native
<details>element below the active deck. - For each expired pass with
is_active = TRUE, display an amber/gray card with an instant[ 🔄 Reopen (+1h) ]button. - For manually ended events (
is_active = FALSE), show a muted[ Terminated ]badge without a reopen button.
- Render a native
- Client Script Handler (
SessionsScript.tsx):- Add
reopenEvent(eventId)callingPOST /api/events/:id/extendwith{ extendHours: 1 }. - Dynamically transition the card or reload to place it back into the active deck.
- Add
Phase 3: Rich Attendee Telemetry in Guest Drawer (ui/components/sessions/EventGuestsDrawer.tsx)
- Backend Payload Enrichment (
server/routes/events.ts):- In
GET /api/events/:id/attendees, select:s.last_activity_ats.last_activity_action(e.g.ForwardAuth Ingress (ed-droid),API Token Read)s.is_agent
- In
- UI Card Formatting:
- On each attendee card in the drawer, render:
- Header:
Seat #[N]+🟢 Active / ⏸️ Pausedbadge + inline[ 🗑️ Revoke ]. - Line 1 (Inverted Join Time):
Joined Today · 2:15 PM · [ Active 1h 45m ]. - Line 2 (Action Telemetry):
Last Action: ForwardAuth (ed-droid) · 2m ago · 💻 Web(with device icon or agent robot emoji ifis_agent = true).
- Header:
- On each attendee card in the drawer, render:
Phase 4: Quality Gates & Verification
- Unit tests in
server/tests/events.test.ts:- Test reopening naturally expired events with
GREATEST(expires_at, NOW()) + 1h. - Test telemetry fields in
/attendeesendpoint.
- Test reopening naturally expired events with
- UI syntax tests in
ui/ui_scripts.test.ts. - Run
deno fmt,deno task lint,deno task check, anddeno test -A --no-check.