Files
jackboxpartypack-gamepicker/docs/superpowers/specs/2026-03-22-session-notes-read-edit-delete-design.md
2026-03-22 23:49:13 -04:00

6.7 KiB

Session Notes — Read, Edit, Delete

Date: 2026-03-22 Status: Approved

Problem

When an admin/host ends a session, they can write notes via the EndSessionModal. But after that, those notes are effectively invisible — the History page doesn't display them, and there's no way to read, edit, or delete them from the UI. Notes only surface in raw exports.

Solution

Add the ability to view, edit, and delete session notes through two surfaces:

  1. Notes preview on History page session cards — inline teaser showing the first paragraph
  2. New Session Detail page (/history/:id) — full rendered markdown notes with inline edit/delete, plus session management actions

Approach

Minimal extension of existing infrastructure (Approach A). No database schema changes. The sessions.notes TEXT column stays as-is. Frontend gets a new page and a markdown rendering dependency.

Backend API Changes

New Endpoints

PUT /api/sessions/:id/notes

  • Auth: Required (admin token)
  • Body: { "notes": "markdown string" }
  • Behavior: Overwrites sessions.notes for the given session (no COALESCE merge — full replacement)
  • Response: Updated session object
  • Errors: 404 if session not found, 401 if no auth header, 403 if token invalid/expired (consistent with existing authenticateToken middleware behavior)

DELETE /api/sessions/:id/notes

  • Auth: Required (admin token)
  • Body: None
  • Behavior: Sets sessions.notes = NULL
  • Response: { success: true }
  • Errors: 404 if session not found, 401 if no auth header, 403 if token invalid/expired

Modified Endpoints

GET /api/sessions (list)

Add two fields to each session object in the response:

  • has_notes (boolean) — true if notes IS NOT NULL AND notes != ''
  • notes_preview (string | null) — first paragraph of the markdown, truncated to ~150 characters. null if no notes.
  • Remove notes from list response — the full notes field must be omitted from list items. Use explicit column selection instead of SELECT s.* to avoid leaking full notes to unauthenticated clients. The list endpoint only returns has_notes and notes_preview.

These are computed server-side from the existing notes column.

GET /api/sessions/:id (single session)

Conditional notes visibility based on auth:

  • Authenticated request: Returns full notes field (plus has_notes and notes_preview)
  • Unauthenticated request: Returns notes_preview and has_notes only. notes field is omitted or null.

The endpoint currently does not require auth. It will remain publicly accessible but gate the full notes content behind an optional auth check.

Unchanged Endpoints

  • POST /api/sessions — session creation (unchanged)
  • POST /api/sessions/:id/close — session close with optional notes (unchanged)
  • DELETE /api/sessions/:id — session deletion (unchanged)

Frontend Changes

History Page (/historyHistory.jsx)

Session Cards (Sidebar)

  • Add notes preview teaser below the date/games-count line when has_notes is true
  • Visual treatment: indigo left-border accent, subtle background, truncated text with ellipsis
  • Clicking a session card navigates to /history/:id (instead of expanding the inline detail panel)

Action Buttons

  • Active sessions: "End Session" button stays on the card (opens EndSessionModal as before)
  • Closed sessions: Delete button removed from the card (moved to detail page only)

Removed from History Page

  • The inline session detail panel (right side, md:col-span-2) is replaced by navigation to the detail page
  • ChatImportPanel moves to the detail page
  • Export buttons move to the detail page

New Session Detail Page (/history/:idSessionDetail.jsx)

New route and component.

Layout

  • Back link — "← Back to History" navigates to /history
  • Session header — Session number, created date/time, games count, active badge if applicable
  • Notes section — Primary content area (see Notes Section below)
  • Games list — Same as current History detail panel (reuse existing game card markup)
  • Action buttons:
    • Export as TXT / Export as JSON (same as current)
    • Import Chat Log (active sessions only, admin only)
    • End Session (active sessions only, admin only — opens EndSessionModal)
    • Delete Session (closed sessions only, admin only — confirmation modal)

Notes Section — View Mode

  • Renders notes as formatted HTML via react-markdown
  • If no notes exist: shows "No notes" placeholder with "Add Notes" button (admin only)
  • Admin sees an "Edit" button in the section header

Notes Section — Edit Mode (Admin Only)

  • Triggered by clicking "Edit" (or "Add Notes" for empty notes)
  • Rendered markdown is replaced in-place by a textarea containing the raw markdown
  • "Supports Markdown formatting" hint below the textarea
  • Action buttons: Save (green), Cancel (gray), Delete Notes (red, with confirmation)
  • Save calls PUT /api/sessions/:id/notes
  • Delete Notes calls DELETE /api/sessions/:id/notes after a confirmation prompt
  • Cancel reverts to view mode without saving

Notes Section — Public View (Unauthenticated)

  • Shows notes_preview text (first paragraph, plain text — not markdown-rendered)
  • "Log in to view full notes" hint below the preview
  • No edit controls

Routing

Add new route in App.jsx:

/history/:id → <SessionDetail />

Existing /history route unchanged.

New Dependency

  • react-markdown — lightweight markdown-to-React renderer. Used only in SessionDetail.jsx for rendering notes.

What's NOT Changing

  • Database schema — no migration, no new tables, no new columns
  • EndSessionModal — still works as-is for writing notes at session close time
  • POST /api/sessions/:id/close — untouched
  • WebSocket events — no notes-related real-time updates
  • Home page — still shows activeSession.notes as plain text for active sessions (no changes)

Permission Model

Action Auth Required
View notes preview (list + detail) No
View full notes (detail page) Yes
Edit notes Yes
Delete notes Yes
Delete session Yes
End session Yes

This is consistent with the existing pattern where read-only session data is public and mutations require admin auth.

Notes Preview Computation

Server-side logic for notes_preview:

  1. If notes is null or empty, notes_preview = null, has_notes = false
  2. Split notes on the first double-newline (\n\n) to get the first paragraph
  3. Strip markdown formatting (bold, links, etc.) for a clean plain-text preview
  4. Truncate to 150 characters, append ... if truncated
  5. Return as notes_preview string