Conversation
…co capture [STORY-055] Adds the `interactions` table, Zod wire schemas, batched ingestion endpoint, and client-side cursor / edit / revert capture wired into the playground Monaco editor. Voice opt-in toggle UI lands; voice capture itself is deferred to STORY-056 (raw transcripts can't be persisted without redaction). - packages/db: migration `0003_interactions.sql` adds the `interaction_type` pgEnum (9 event kinds), the `interactions` table with `(episode_id, t)` and `(user_id, t)` indexes, and `episodes.interactions_summary jsonb`. `DrizzleInteractionStore` bulk-inserts a batch in a single round-trip; 5 DATABASE_URL-gated integration tests. - packages/shared: `InteractionEventSchema` discriminated union, `InteractionsBatchSchema` with a 200-event cap, and the abstract `InteractionStore` interface. 12 unit tests. - apps/api: `POST /v1/interactions` Zod-validates, stamps server `t`, returns 202 / 400 / 503; `NoopInteractionStore` is the default so tests + the dev playground don't need a DB. 6 endpoint tests. - apps/web: Next.js proxy at `/api/interactions` mirrors the sandbox proxy. Pure `InteractionBatcher` (size + idle flush, `keepalive: true`), pure `CursorFocusTracker` (debounced cursor_focus emission), pure `RevertDetector` (sliding 30 s snapshot window), and the `useInteractionCapture` React hook that wires Monaco's `onDidChangeCursorPosition` + `onDidChangeModelContent` to those trackers. Voice opt-in toggle in PlaygroundClient. 24 unit tests. 3 of 6 ACs land in this PR; voice redaction defers to STORY-056 per the spec. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
interactionstable (Drizzle migration0003_interactions.sql) with a 9-valueinteraction_typepgEnum +episodes.interactions_summary jsonbfor fast tutor-time reads.user_idandepisode_idare nullable until auth lands (STORY-005).@learnpro/sharedowns the wire protocol:InteractionEventSchemadiscriminated union over the 9 event kinds,InteractionsBatchSchemawith a 200-event cap, abstractInteractionStoreinterface.@learnpro/dbshipsDrizzleInteractionStore(single-round-trip bulk insert).POST /v1/interactionsFastify endpoint Zod-validates, stamps servert, returns 202/400/503. DefaultNoopInteractionStoreso tests + dev don't need a DB.InteractionBatcher(size + idle flush,keepalive: true), pureCursorFocusTracker+RevertDetector,useInteractionCaptureReact hook wired into the playground Monaco editor. Voice opt-in toggle UI lands; voice capture defers to STORY-056 (redaction prerequisite).ACs landed (4 of 6)
interactionsschema + migrationuseRef)Test plan
pnpm -r typecheckclean across the workspacepnpm -r lintcleanpnpm -r test— all green (237 passed, 14 skipped, 0 failed)pnpm format:checkcleanDATABASE_URL=postgresql://learnpro:learnpro@localhost:5432/learnpro pnpm --filter @learnpro/db test🤖 Generated with Claude Code