Skip to content

feat(history): mirror detail page + rich day cards + review hardening#64

Merged
rezailmi merged 8 commits into
mainfrom
worktree-history-mirror-detail
May 24, 2026
Merged

feat(history): mirror detail page + rich day cards + review hardening#64
rezailmi merged 8 commits into
mainfrom
worktree-history-mirror-detail

Conversation

@rezailmi

Copy link
Copy Markdown
Collaborator

Summary

  • New routed sheet /history/mirror/$id shows the full mirror reflection (story reframe, validation, inferred meaning, transcript) with Confirm / Forget review actions
  • DayDetailCard now renders mirrors as rich cards (context badge, headline, highlight, transcript snippet) with a "Show more" affordance opening the detail page
  • Review pipeline hardened: mounted-ref + in-flight-ref guards in ReviewActions, shared Captures.acquireReview lock prevents concurrent submissions across surfaces, stale-status guard skips patches when the slice has moved past the in-flight call
  • Cold-load deep link first nudges refreshSnapshot, then falls back to a new loadMirrorEntry server fn so forgotten captures remain reachable by URL; distinct loading vs not-found UI
  • Five new shared modules consolidate the duplicated pieces between DayDetailCard and MirrorDetailSheet:
    • mirror-review.tsapplyMirrorReview() + CONTEXT_LABEL
    • mirror-review-types.ts — shared engine-state contract
    • format-date.tsformatLongDate / formatTime (plus toEntryDate exported from backend-snapshot)
    • use-mirror-engine-state.ts — centralizes the engine cast
    • use-overlay-body-class.ts — ref-counted body.has-overlay (replaces 6 duplicated useEffect copies; fixes a navigation-time class-stomp race)
  • usePageEscape now stops immediate propagation so stacked sheets don't both fire; surfaceFromPathname no-ops on /history/mirror/* so the engine doesn't open History behind the detail page
  • backend-snapshot.ts: validation flows from MirrorEntryRow into the capture (optional on the wire type to match incremental patches); updateReflectionReview return now carries validation and applyMirrorReview writes it through
  • Agents: validation added to ConnectorContextPayload.mirror and rendered in formatNewReflectionBlock so Connector/Cartographer see the same field the user does
  • CLAUDE.md routed-sheet inventory and Sheet primitive notes refreshed to match the actual PageSurface shape

Tests

  • New test/components/student-space/sheets/mirror-detail-sheet.test.tsx (10/10 passing): not-found, NaN guard, loading state, capture-found rendering, Confirm patch flow, capture-id fallback, error alert, refresh-failure swallow, post-mount hydration, body-class lifecycle
  • Extended TestCapture with validation? / reframe? and added two new cases for the MirrorRow Show-more link visibility
  • backend-snapshot mapping test now asserts validation round-trips
  • Managed-connector fixture updated for the new context field

Verification

  • pnpm typecheck: PASS
  • pnpm lint: PASS (warnings only, all pre-existing)
  • Targeted vitest: new + extended tests pass; 4 pre-existing date-drift failures in history-sheet.test.tsx (TODAY = '2026-05-22' vs system clock 2026-05-24) are unchanged from main and unrelated to this branch

Test plan

  • Open History → click a day with a mirror reflection → confirm rich card renders with context badge, headline, highlight, transcript snippet
  • Click "Show more →" → confirm /history/mirror/$id opens with sidebar meta (date, time, context, status, moods) and full detail (Story reframe / Validation / Inferred meaning / Transcript)
  • On the detail page: Confirm a pending mirror → confirm status badge updates and the day card stays in sync
  • On the detail page: Forget a pending mirror, navigate away, reload /history/mirror/$id → confirm the entry is still reachable (via loadMirrorEntry fallback) instead of showing "We couldn't find that mirror"
  • Navigate directly to /history/mirror/99999 (non-existent id) → confirm clean "couldn't find" copy, no console errors
  • Navigate to /history/mirror/abc (non-numeric id) → confirm same not-found copy
  • Open History on a cold engine, deep-link to /history/mirror/$id → confirm "Loading…" copy briefly, then the capture detail
  • Press Escape on the detail page → confirm it returns to /history (not /) and the engine History overlay does not flash open

@vercel

vercel Bot commented May 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sensemaking-agents Ready Ready Preview, Comment May 24, 2026 1:25pm

…r/$id

- DayDetailCard renders mirror reflections as rich rows: context badge,
  time, story-reframe headline, highlight-phrase pull quote, transcript
  snippet, plus a "Show more →" link for backend-backed entries
- New MirrorDetailSheet at /mirror/$id shows the full mirror: Story
  reframe, Validation, Inferred meaning, Transcript, with Confirm /
  Forget actions for pending reviews; sidebar carries date, time, context,
  status, and mood tags
- Route lives at /mirror/$id (not /history/mirror/$id) because TanStack's
  matcher picks /history/$tab over the more specific /history/mirror/$id
  when both sit under _app/history
- Distinguish "Loading…" (captures slice not yet hydrated) from "couldn't
  find that mirror" (genuinely missing)
- backend-snapshot: validation flows from MirrorEntryRow into the snapshot
  (optional on the type so incremental captures.patch writes are unaffected)
"Mirror" is the agent name; "reflection" is the student-facing capture.
The list heading is user-facing copy, so match the noun the user owns.
…t status line

- Shift all seed timestamps forward 182 days so demo data lands in
  the 2026-04 to 2026-05 window (was 2025-07 to 2025-11). Demo-a's
  8 reflections are then re-spread across May 18–30 so the calendar's
  default 'this week' view shows reflection markers on multiple days
- Day detail card: drop the literal `status: confirmed` text — review
  state is already implicit (Confirm/Forget appear only when pending),
  and the detail page surfaces the status badge explicitly
- Each reflection card is now itself a link to /mirror/$id (when
  backend-backed); no separate "Show more" button
- Drop the per-card "Reflection" label — the section heading already says
  "Reflections", repeating it on every row is noise
- Drop Confirm/Forget buttons + status text from the card; reviews live
  on the detail page where there's room for the full context
- Generic non-ask captures keep their text-only render with the kind
  label removed for the same reason
…hite when selected

DayDetailCard:
- Remove CaptureActions component, reviewCapture / retryCaptureSync
  handlers, patchReviewCapture, syncLine helper, and their state. All
  unused now that the day card is a passive list of clickable cards.

CalendarPane:
- Mood Smile icon flips to text-white when its day cell is selected,
  matching the reflection/event icons that already do.
resetSeedStudent ran unqualified DELETEs and relied on the RLS policy
to scope them to the current student. The seed CLI typically runs as
neondb_owner which has BYPASSRLS, so those DELETEs wiped every
student's rows on each iteration — only the last student's seed
survived. Same problem made the 'existing count' check see other
students' rows and skip them on subsequent runs.

Fix: filter every reset DELETE by studentId, and filter the existing
count query the same way. Correct under both RLS-enforced and
BYPASSRLS roles.
Replace the single lucide Smile icon (color-tinted per emotion) with
the existing 3D-style shape art from `mood-shapes.ts`:
- Calendar cell mood markers render the shape image (sphere / teardrop
  / octahedron / cube / torus / capsule / egg / halfcube / disk)
- Day-detail card "Moods" list shows the shape next to the emotion name
  in place of the small colored dot

Drop the local MOOD_HEX color maps in both files — the shape SVG owns
its own palette via EMOTIONS, so duplicated hex constants were stale
and prone to drift.
@rezailmi rezailmi merged commit 8192c6f into main May 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant