Commit Graph

219 Commits

Author SHA1 Message Date
Thomas Hallock 2b5d66f776 perf(worksheets): use Suspense streaming for preview generation
Problem: The worksheet page had 1.7-2.3s TTFB because the 1.25MB SVG
preview was being serialized into the initial HTML response, blocking
first paint.

Solution: Use React Suspense to stream the preview separately:
- Page shell renders immediately with settings (~200ms TTFB)
- Preview generates async and streams in when ready (~1.5s later)
- User sees the UI instantly, preview appears with loading skeleton

New components:
- StreamedPreview: async server component that generates preview
- PreviewSkeleton: loading placeholder while streaming
- StreamedPreviewContext: shares streamed data with PreviewCenter
- PreviewDataInjector: bridges server-streamed data to client context

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 18:54:17 -06:00
Thomas Hallock 1f1083773d perf: add timing instrumentation to worksheet page SSR
Track where time is spent during worksheet page render:
- loadWorksheetSettings (DB query + getViewerId)
- generateWorksheetPreview (problem generation + Typst compilation)
- Total page render time

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:21:12 -06:00
Thomas Hallock 3d835d67cd feat(flowchart-workshop): add version history with preview mode
- Add flowchart_version_history table to store snapshots after generate/refine
- Create versions API endpoint (GET list, POST restore)
- Add History tab with version list showing source, validation status, timestamp
- Implement inline preview mode to view historical versions without restoring
- Preview mode shows amber banner and updates diagram, examples, worksheet, tests
- Hide structure/input tabs (not useful currently)
- Add preview notice in refinement panel clarifying behavior
- Update React Query documentation with comprehensive patterns
- Add versionHistoryKeys to central query key factory

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 13:52:59 -06:00
Thomas Hallock ae276455fa feat(flowcharts): implement unified computation model (Phases 1-2)
Transform the flowchart system from "compute everything upfront" to
"walk IS the computation". This is the foundation for the new unified
computation model.

Phase 1 - Schema & Core Runtime:
- Add TransformExpression, StateSnapshot, DisplayTemplate, AnswerDefinition
- Add StructuredTestCase for primitive-based test validation
- Update FlowchartState with values, snapshots, hasError fields
- Mark variables as deprecated (optional) for transition period
- Add interpolateTemplate() for {{name}} and {{=expr}} syntax
- Add applyTransforms(), extractAnswer(), simulateWalk() to loader
- Add createContextFromValues() for transform execution

Phase 2 - Walker Integration:
- Apply transforms when entering each node during walk
- Initialize entry node transforms on state creation
- Snapshots now accumulate as nodes are visited

All existing flowcharts continue to work via backwards compatibility
with the legacy variables section.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 15:39:20 -06:00
Thomas Hallock 6c51182c15 refactor(flowchart): remove legacy schema-specific formatting, add display.problem check
- Remove legacy schema-specific formatting fallbacks in formatting.ts and example-generator.ts
- All flowcharts now require explicit display.problem and display.answer expressions
- Add DISP-003 diagnostic for missing display.problem expressions
- Update doctor to treat missing display.answer as error (was warning)

Also includes:
- Terraform: generate LiteFS config at runtime, add AUTH_TRUST_HOST, add volume mounts for vision-training and uploads data
- Terraform: add storage.tf for persistent volume claims
- Add Claude instructions for terraform directory
- Various UI component formatting updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 11:03:15 -06:00
Thomas Hallock c29388df30 refactor(docs): consolidate .claude instructions (53% reduction)
- Delete 10 obsolete files (roadmaps, specs, historical artifacts)
- Merge 5 arcade docs into ARCADE_SYSTEM.md (2,274 → 309 lines)
- Condense merge conflicts (707 → 126 lines)
- Rewrite CLAUDE.md (262 → 94 lines)
- Update README.md with new structure

Before: 42 files, ~13,600 lines
After: 25 files, 6,389 lines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:15:26 -06:00
Thomas Hallock 87e76a514b chore: update local settings with new allowed commands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:16:11 -06:00
Thomas Hallock 367edc8f82 refactor: rename .claude/skills to .claude/procedures
Avoid terminology confusion - "skills" refers to invokable commands
like /fix-css and /porkbun-dns. The documentation files are
step-by-step procedures, not invocable skills.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:14:42 -06:00
Thomas Hallock a36303be1c refactor: agent instructions Phase 4 - add index and restore merge conflicts
- Add .claude/README.md index categorizing all 34 docs
- Restore Merge Conflict section reference to CLAUDE.md
- Categorize docs: Skills, Reference, Architecture, Specs, Settings, Ops, Research, Roadmaps

Final CLAUDE.md: 262 lines (83% reduction from 1,531)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:09:57 -06:00
Thomas Hallock 69098e3038 refactor: agent instructions Phase 2+3 - CLAUDE.md now 258 lines
Phase 2:
- Extract React Query patterns to reference/react-query-mutations.md
- Extract TensorFlow debugging to reference/tensorflow-browser-debugging.md
- Extract Abacus Visualizations to reference/abacus-react.md
- Slim Production Dependencies (73→7 lines)
- Slim Code Factoring (75→9 lines)
- Slim Data Attributes (49→9 lines)

Phase 3:
- Consolidate 3 CRITICAL behavioral sections (92→12 lines)
- Slim Merge Conflict, Z-Index, Animation, Game Settings sections
- Slim Flowchart Walker, Daily Practice, Rithmomachia
- Remove duplicate package.json scripts section
- Consolidate workflow and dev server sections

Total reduction: 1,531 → 258 lines (83% smaller)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 10:07:09 -06:00
Thomas Hallock a3409fff38 refactor: agent instructions Phase 1 + dark mode modal fixes
Dark mode improvements:
- Fix DeploymentInfoModal background, title, footer colors
- Fix badge contrast (StatusBadge, CodeBadge) with raw rgba/hex values
- Fix padding syntax (Panda CSS gotcha: '1 2' → '4px 8px')

Agent instructions refactoring:
- Slim CLAUDE.md from 1,531 to 1,148 lines (-25%)
- Create .claude/skills/database-migrations.md (consolidated skill)
- Create .claude/reference/panda-css.md (styling gotchas)
- Delete 40+ stale plan/status docs (16k+ lines removed)
- Consolidate duplicate migration sections
- Add skills/ and reference/ directory structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 09:49:10 -06:00
Thomas Hallock e9c4bb1ed8 fix(flowchart): implement proper task queue for concurrent example generation
Replace sequential example generation with a proper task queue system that
correctly handles concurrent requests to the Web Worker pool.

Root cause of previous issues: Each worker stored only ONE resolve/reject
callback, so concurrent requests would overwrite each other's callbacks,
causing promises to never resolve or resolve with wrong data.

Solution:
- Add unique requestId to all worker messages for request/response matching
- Implement task queue with dispatch logic for pending work
- Track pending requests in a Map keyed by requestId
- Workers echo back requestId so responses match their originating requests
- Both /flowchart page and workshop page now generate concurrently

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 20:51:36 -06:00
Thomas Hallock 269321b4c4 feat(flowchart): add animated background tiles to FlowchartCards
- Add AnimatedProblemTile component with MathDisplay for proper math rendering
- Add AnimatedBackgroundTiles grid component for card backgrounds
- Update FlowchartCard to accept flowchart + examples props
- Generate examples client-side for both hardcoded and database flowcharts
- Use same formatting system (formatProblemDisplay + MathDisplay) as modal

Also includes:
- Fix migration 0076 timestamp ordering issue (linkedPublishedId column)
- Add migration-timestamp-fix skill documenting common drizzle-kit issue
- Update CLAUDE.md with migration timestamp ordering guidance
- Various flowchart workshop and vision training improvements

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:10:49 -06:00
Thomas Hallock 1b034749fb docs: add flowchart modification skill for future reference
- Create .claude/skills/FLOWCHART_MODIFICATIONS.md with patterns for:
  - Adding checkpoint nodes (variables, edges, Mermaid content)
  - Conditional skipping with skipIf and excludeSkipFromPaths
  - Understanding path enumeration and grid dimension stability
  - Working problem evolution
  - Debugging tips and modification checklist
- Add reference in CLAUDE.md under Flowchart Walker System section

This captures lessons learned from the fraction flowchart sprint where we
split CALCULATE into separate inputs and added conditional whole number skipping.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 08:29:22 -06:00
Thomas Hallock 54193f6d05 chore: add chrome-devtools MCP permissions 2026-01-19 06:19:06 -06:00
Thomas Hallock 5ebd3008f6 Add visual debug mode and documentation for flowchart system
- Add DebugMermaidDiagram component to visualize flowchart with current
  node highlighted in debug mode
- Add DebugStepTimeline for undo/redo navigation through flowchart steps
- Add rawMermaid field to ExecutableFlowchart schema for debug rendering
- Add comprehensive README.md documenting the flowchart walker system
- Add JSDoc comments to parser.ts, loader.ts, definitions/index.ts
- Add flowchart section to .claude/CLAUDE.md
- Add PageWithNav hamburger menu to flowchart page
- Fix MathDisplay to show implicit coefficient of 1 (1x → x)
- Install mermaid dependency for flowchart visualization

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 09:24:28 -06:00
Thomas Hallock 7e98a01a41 Add unit tests for KidNumberInput and FlowchartCheckpoint
Tests for KidNumberInput component:
- Rendering with different props and states
- Feedback state styling (correct/incorrect/none)
- Disabled state behavior
- Keypad interaction

Tests for useKidNumberInput hook:
- Initial state
- Adding/removing digits
- Auto-validation on max digits
- Correct/incorrect callbacks
- Clear on correct/incorrect options

Tests for FlowchartCheckpoint:
- KidNumberInput integration for number input type
- Native input preserved for text type
- Two-numbers input mode
- Feedback display
- Keyboard input handling
- Disabled state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:57:53 -06:00
Thomas Hallock 7c597e9079 Integrate KidNumberInput into FlowchartCheckpoint
- Replace native number inputs with KidNumberInput for kid-friendly touch targets
- Add global keyboard handler for physical keyboard support
- Support focused input switching for two-numbers mode with Tab/click
- Display inline keypad for number entry with visual feedback
- Keep native text input for text-type checkpoints

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 15:52:27 -06:00
Thomas Hallock e703e90875 chore: cleanup unused imports and apply formatting
- Remove unused `and` import from VisionRecorder.ts
- Remove unused `IncomingMessage` and `ws` imports from socket-server.ts
- Add `muted` attribute to video element in ProblemVideoPlayer
- Apply code formatting across vision and practice components
- Update documentation formatting in DEPLOYMENT.md and README

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 18:49:31 -06:00
Thomas Hallock 4733149497 chore: update local Claude settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 17:50:00 -06:00
Thomas Hallock b47992f770 feat(deploy): add blue-green deployment with health endpoint
- Add /api/health endpoint that checks database connectivity
- Set up blue-green deployment with two containers (abaci-blue, abaci-green)
- Add docker-compose.yaml with YAML anchors for DRY config
- Add generate-compose.sh to create blue/green compose files from main
- Update deploy.sh with NAS-specific fixes (scp -O, PATH for docker)
- Fix deploy.sh to not overwrite production .env by default

The blue-green setup allows zero-downtime deployments via compose-updater,
which watches separate compose files and restarts containers independently.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 17:04:01 -06:00
Thomas Hallock 9b86739b46 feat(vision): add multi-attempt recording support for epoch retries and manual redos
- Add epoch/attempt tracking to vision_problem_videos schema (epochNumber, attemptNumber, isRetry, isManualRedo)
- Update VisionRecorder filename pattern to include epoch/attempt: problem_NNN_eX_aY.mp4
- Fix getRetryContext to use correct slot indices during manual redos
- Add answer-submitted marker for redo problems via handleRecordRedo wrapper
- Create attempt-tracking.ts utility for video attempt grouping and labeling
- Add attempt selector dropdown to ProblemVideoPlayer when multiple attempts exist
- Update API routes to accept epoch/attempt query params for video and metadata
- Add comprehensive documentation for vision recording system (README.md)

Multiple attempts at the same problem (from epoch retry rounds or manual redo clicks)
now save separate recordings instead of overwriting each other.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 07:55:24 -06:00
Thomas Hallock fbbbf9f50b fix(vision): fix problem video recording when camera starts mid-session
- Add effect to emit problem-shown marker when recording starts, ensuring
  the current problem gets a video entry even if camera was enabled late
- Improve DockedVisionFeed UX: show session ID, action buttons immediately
  for remote camera connections (not just after 15s timeout)
- Add .prettierignore to prevent prettier from corrupting Panda CSS
  generated styled-system directory
- Document styled-system fix procedure in CLAUDE.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 18:56:21 -06:00
Thomas Hallock 9fa95eca89 chore: update tsconfig, plans, lockfile, and templates
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 10:49:34 -06:00
Thomas Hallock cf45b86a28 feat(vision): add filtering and passive capture for boundary training data
Major changes:
- Add passive boundary capture during practice sessions via DockedVisionFeed
- Create BoundaryFrameFilters component with capture type, session, player,
  and time range filtering using TimelineRangeSelector
- Add sessionId/playerId metadata to boundary frame annotations
- Update boundary-samples API to store and return session/player context
- Improve boundary detector training pipeline with marker masking
- Add preprocessing pipeline preview in training data browser
- Update model sharding (2 shards instead of 1)

Files added:
- BoundaryFrameFilters.tsx - Filter UI component
- usePassiveBoundaryCapture.ts - Hook for passive training data collection
- saveBoundarySample.ts - Shared utility for saving boundary samples
- preview-augmentation/route.ts - API for preprocessing pipeline preview
- preview-masked/route.ts - API for marker masking preview
- marker_masking.py, pipeline_preview.py - Python training utilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 10:25:56 -06:00
Thomas Hallock f78eae1148 feat(vision): add boundary detector for marker-free calibration
- Add boundary detector ML model infrastructure (MobileNetV2-based)
- Add training script for boundary detector (train_model.py)
- Add useBoundaryDetector hook for browser inference
- Add BoundaryCameraTester for real-time camera testing
- Add BoundaryImageTester for static image testing
- Add sync API support for boundary detector training data
- Add model type selector on test page (column classifier vs boundary detector)
- Add marker inpainting for training data preprocessing
- Update training wizard to support both model types

The boundary detector aims to detect abacus corners without ArUco markers,
using ML to predict corner positions from raw camera frames. Currently
requires more training data for accurate predictions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 19:15:00 -06:00
Thomas Hallock 71c5321431 docs: add TensorFlow.js model debugging notes
Document lessons learned from debugging Keras → browser inference:
- Normalization mismatch (preprocessing layers are preserved)
- Quantization corruption (--quantize_uint8 corrupts weights)
- Output tensor ordering (detect by shape, not index)
- Debugging checklist and key files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 18:07:23 -06:00
Thomas Hallock 6b1fa85bb8 fix(vision): fix video ref timing bug preventing marker detection
The videoRef callback in VisionCameraFeed was only firing once on mount,
before the video element existed (due to early return when no videoStream).
Added videoStream to the effect dependency array so it re-runs when the
stream becomes available.

Also:
- Add willReadFrequently option to canvas contexts in frameProcessor
  and arucoDetection to fix console warnings about getImageData
- Add VISION_COMPONENTS.md documentation with required wiring checklist
- Add reference in CLAUDE.md to prevent this recurring mistake

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 15:45:12 -06:00
Thomas Hallock 02e91892f4 feat(vision): auto-setup Python venv for training on first API call
The vision training APIs now automatically set up the Python
environment when first called:

1. Detects if venv exists with tensorflow installed
2. If not, finds best Python (ARM on Apple Silicon for Metal GPU)
3. Creates venv and installs tensorflow (with Metal on M-series Macs)
4. Caches result so subsequent calls are instant

This eliminates the need to manually set up the venv before deployment.
The setup happens lazily on first hardware detection or training request.

Also includes various other working tree changes that were in progress.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 07:18:23 -06:00
Thomas Hallock be4b587520 chore: format codebase with Biome
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 16:34:42 -06:00
Thomas Hallock a771b1bb0c docs: add socket event distinction for game completion detection
Key insight from debugging: session-state only fires on join, not during
gameplay. Must listen to move-accepted to detect game phase transitions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 16:30:52 -06:00
Thomas Hallock 367a352f07 feat(practice): detect game completion to end breaks early
When a student completes a game during a practice game break, the break
now ends automatically instead of waiting for the timer to expire.

Implementation:
- PracticeGameModeProvider now listens for move-accepted socket events
  (not just session-state, which only fires on join)
- Detects transition to 'results' phase and fires onGameComplete callback
- GameBreakScreen wires up the callback to dismiss the break

Note: Not all games have a 'results' phase. Endless games like complement-race
will still end via timeout or manual skip, which is expected.

Also adds architecture documentation for arcade room + practice integration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 16:25:28 -06:00
Thomas Hallock 73a8314ed9 refactor(worksheet-parsing): centralize state with context + reducer
Major refactoring of worksheet parsing to use centralized state management:

New architecture:
- WorksheetParsingContext: React context provider for parsing state
- state-machine.ts: Typed reducer with actions for streaming lifecycle
- sse-parser.ts: Shared SSE parsing utility for OpenAI Responses API
- usePartialJsonParser.ts: Progressive JSON extraction during streaming

Streaming UI improvements:
- ParsingProgressOverlay: Dark overlay on photo tile during parsing
- ParsingProgressPanel: Collapsible reasoning text panel
- ProgressiveHighlightOverlay: Problem boxes light up as LLM parses
- New streaming API routes: /parse/stream and /parse-selected/stream

Bug fixes during testing:
- Fix TypeScript error: cast event.response for id access in sse-parser
- Fix reparse reasoning display: preserve "processing" status for reparse
- Fix concurrent parsing: revert previous attachment status when switching
- Fix problem count: track dispatched problems to prevent duplicates

Components updated to use context:
- SummaryClient: Wrapped with WorksheetParsingProvider
- OfflineWorkSection: Uses context instead of local streaming state
- PhotoViewerEditor: Uses context for coordinated parsing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 21:40:36 -06:00
Thomas Hallock ad321d39c5 refactor(practice): extract photo management and worksheet review components
SummaryClient Refactoring:
- Extract SessionAttachmentResponse type to src/types/attachments.ts
- Create usePhotoManagement hook consolidating 10+ callbacks and 7+ state vars
- Create usePhotoViewer hook for photo viewer modal state
- Extract CameraModal and DocumentAdjustmentModal components
- Add getPendingAttachmentId helper to useWorksheetParsing

Worksheet Review UI:
- Add ProblemReviewCard component for individual problem editing
- Add ProblemReviewFlow for swipeable problem navigation
- Add ReviewMiniMap for visual problem overview
- Add ReviewToolbar for review mode controls
- Add ReparseHintsModal for reparse with hints
- Add LLMDebugPanel for viewing raw LLM responses
- Add unapprove endpoint to revert approved worksheets

Storybook:
- Add worksheet parsing stories with sample images
- Update preview configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 18:24:55 -06:00
Thomas Hallock 111e934129 feat(worksheet-parsing): add bulk exclude/restore and improve approve flow
- Remove per-problem Exclude/Restore buttons from EditableProblemRow
- Add bulk "Exclude Selected" and "Restore Selected" buttons to selection toolbar
- Add toast notifications for approve success/failure
- Close viewer and refresh page after successful approve to show updated session
- Fix mutation to properly await res.json() before returning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 21:39:43 -06:00
Thomas Hallock 830a48e74f feat(worksheet-parsing): add selective re-parsing and improve UI
Selective Re-parsing:
- Add parse-selected API endpoint for re-parsing specific problems
- Support user-adjusted bounding boxes that persist across re-parses
- Add crop-utils for extracting problem regions from worksheet images

LLM Metadata Tracking:
- Store JSON schema, prompt, and raw response in database
- Add debug panel in PhotoViewerEditor to inspect LLM details
- Add migrations for llm_metadata, llm_prompt, llm_json_schema columns

UI Improvements:
- Remove selection mode toggle - problems always selectable
- Show checkboxes on hover only (no layout jump)
- Move selection toolbar to fixed footer outside scrollable area
- Add BoundingBoxOverlay component for visual problem selection
- Add EditableProblemRow with hover-based checkbox visibility
- Unified hover highlighting across checkbox and problem cells

Also includes:
- Fix approve route to handle excluded problems correctly
- Add DebugContentModal for viewing prompts/responses
- Update LLM client to return metadata in responses

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 20:41:09 -06:00
Thomas Hallock d80601d162 chore: add vision planning doc, storybook story, and update gitignore
- Add VISION_DOCK_INTEGRATION_PLAN.md for vision dock architecture
- Add VisionCameraControls.stories.tsx for storybook
- Update .gitignore to exclude venv, uploads, and training data

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 20:43:06 -06:00
Thomas Hallock e52f94e4b4 fix(vision): fix remote camera calibration coordinate system
- Fix hook dependency issues in AbacusVisionBridge by using destructured
  stable function references instead of remoteCamera object
- Add proper container dimension tracking for remote camera calibration
  overlay to fix coordinate mismatch
- Add rotate180 option to perspectiveTransform to support both Desk View
  (camera pointing down, needs 180° rotation) and phone cameras (no rotation)
- Phone camera cropping now uses direct mapping without rotation

The main issues fixed:
1. Hook dependencies were causing effects to run repeatedly when navigating
   to remote camera URL in a different window
2. CalibrationOverlay was using hardcoded fallback dimensions instead of
   actual container dimensions for remote camera
3. Perspective transform was applying 180° rotation which is wrong for
   phone cameras held at normal angles

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 20:41:25 -06:00
Thomas Hallock 9124a3182e refactor(summary): restructure session report with two-column desktop layout
Major refactoring of the session summary page to match the redesign plan:

Layout changes:
- Desktop (≥1200px): Two-column layout with Hero+Evidence left, Skills+Review right
- Extract individual components from monolithic SessionSummary
- Add ScrollspyNav fixed at bottom for mobile/tablet navigation
- Add scrollspy section attributes for navigation tracking

New components extracted:
- SessionHero: Celebration header, stats, practice type badges, trend indicator
- SkillsPanel: Skills breakdown by category with human-readable names
- ProblemsToReviewPanel: Auto-pause timing + problems needing attention
- TrendIndicator: Comparison to previous session accuracy
- ScrollspyNav: Fixed bottom navigation with dot indicator
- OfflineWorkSection: Photo upload zone with lightbox
- PhotoLightbox: Full-screen photo viewer with navigation

Utilities added:
- skillDisplay.ts: Human-readable skill name resolution
- trends.ts: Session trend calculations

Known issues documented for follow-up:
- Mobile section order needs adjustment (Evidence before Skills)
- Tablet layout not yet implemented (Skills+Review side-by-side)
- ScrollspyNav visibility breakpoint needs tuning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 10:52:29 -06:00
Thomas Hallock a8f55c9f4f docs: document migration file modification failure pattern
Add CRITICAL section documenting the failure pattern where migration
files are modified after deployment, causing Drizzle to skip them
(it tracks by name, not content). This pattern has caused three
production outages in December 2025.

Includes:
- Explanation of why this happens
- The correct pattern (complete SQL before committing)
- How to fix with new migrations
- Emergency fix procedure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 07:56:09 -06:00
Thomas Hallock 1b3dcbe14f docs: add rule about never directly modifying database schema
This rule documents the failure pattern from December 2025 where
columns were added directly to the local dev database, causing
migration 0043 to be committed as a no-op. Production never got
the columns and crashed.

The rule requires all schema changes to go through the Drizzle
migration system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 12:41:39 -06:00
Thomas Hallock 1fc8949b06 feat(dashboard): add skill progress chart with trend analysis and timing awareness
Major changes:

1. Sentinel approach for skill recency refresh
   - Added 'recency-refresh' session status and SlotResult source field
   - BKT skips pKnown updates for sentinel records (zero-weight)
   - refreshSkillRecency() now inserts sentinel records instead of updating DB field
   - Single source of truth: all lastPracticedAt comes from problem history

2. Skill progress chart (new component)
   - 100% stacked area chart showing skill distribution over time
   - Clickable legend cards for filtering by classification
   - Adaptive time window presets (Recent, Last N, All)
   - Synthetic "current" snapshot ensures chart matches legend staleness

3. Trend-aware encouragement messages
   - Linear regression to detect improving/declining/stable trends
   - Session timing analysis (gap detection, frequency patterns)
   - Window-aware scope text ("over the past 2 weeks", "since Nov 15")
   - Priority-based message selection (urgent issues first)
   - Consistent "stale" terminology (not "rusty")

4. Dashboard improvements
   - Virtualized session history list for performance
   - Paginated session history API with cursor-based pagination
   - BKT-computed lastPracticedAt used throughout (single source of truth)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 14:37:15 -06:00
Thomas Hallock c522620e46 refactor(help): rename helpLevel terminology to hadHelp boolean
The codebase previously used "help level" terminology (HelpLevel type,
helpLevelUsed field, helpLevelWeight function) which implied a graduated
scale. Since the system now only tracks whether help was used or not,
this renames everything to use proper boolean terminology.

Changes:
- Delete HelpLevel type, use boolean directly
- Rename helpLevelUsed → hadHelp in SlotResult
- Rename lastHelpLevel → lastHadHelp in PlayerSkillMastery schema
- Rename helpLevelWeight() → helpWeight() with boolean parameter
- Update all components, tests, stories, and documentation
- Add database migration for column rename

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 07:04:52 -06:00
Thomas Hallock 446678799c refactor(help): simplify to binary help system + add seed script CLI
Help System Cleanup:
- Simplify HelpLevel from 0|1|2|3 to binary 0|1 (matching actual usage)
- Change BKT help weight from 0.8 to 0.5 for helped answers
- Delete unused PracticeHelpPanel.tsx (~540 lines)
- Delete unused usePracticeHelp.ts (~400 lines)
- Delete unused reinforcement-config.ts
- Remove reinforcement tracking (BKT handles skill weakness detection)
- Update all journey simulator profiles to use binary help arrays
- Update documentation (BKT_DESIGN_SPEC.md, decomposition README)

Seed Script Improvements:
- Add CLI argument parsing with node:util parseArgs
- Add --help, --list, --name, --category, --dry-run flags
- Add new "Forgotten Weaknesses" test profile (weak + stale skill mix)
- Enable seeding individual students or categories

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 06:28:27 -06:00
Thomas Hallock 430c46adb9 feat(session-summary): redesign ProblemToReview with BKT integration and animations
ProblemToReview component improvements:
- Use AnnotatedProblem for unified collapsed/expanded problem display
- Integrate BKT mastery data for weak skill detection and ordering
- Add smooth CSS Grid animations for expand/collapse transitions
- Make header row clickable (toggle moved from footer to header)
- Add purpose explanations and timing info in expanded mode
- Show up to 3 weak skills in collapsed mode with "+N more" indicator

React Query cache fix:
- Fix "Mark Current" button not updating UI (stale cache issue)
- Replace plain fetch + router.refresh() with useRefreshSkillRecency mutation
- Mutation properly invalidates curriculumKeys.detail(playerId)

Documentation:
- Add CLAUDE.md section on React Query mutation patterns
- Document the relationship between mutations and query cache invalidation
- Include checklist to prevent future cache invalidation bugs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 07:31:43 -06:00
Thomas Hallock 2977bd57df feat(session-summary): unify summary and debug views with progressive disclosure
Major changes:
- Merge SessionSummary and SessionOverview into unified experience
- Add "Problems Worth Attention" section with expandable problem details
- Add "All Problems" collapsible section with compact/detailed toggle
- Keep auto-pause timing info in unified view
- Remove debug view toggle from SummaryClient
- Delete SessionOverview.tsx (replaced by new components)

New components:
- AllProblemsSection.tsx - collapsible all-problems view
- ProblemToReview.tsx - expandable problem row with reason badges
- sessionSummaryUtils.ts - filtering utilities for attention-worthy problems

Bug fix:
- Fix ROTATION_MULTIPLIERS import in DashboardClient (was undefined due to re-export chain)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 21:15:14 -06:00
Thomas Hallock 3c9406afc5 fix(practice): improve mobile layout + floating abacus positioning
- Add bottomOffset/rightOffset to MyAbacusContext for virtual keyboard avoidance
- NumericKeypad sets offsets when mounted (48px bottom, 100px right)
- Floating abacus repositions above/beside keyboard in portrait/landscape
- PracticeSubNav: fix horizontal overflow with minWidth: 0 on flex children
- SessionProgressIndicator: allow proper flex shrinking
- ActiveSession: reduce padding/gaps, use flex layout to fill available space
- PracticeClient: use fixed positioning with proper insets for all orientations
  - Portrait: bottom 48px for keypad
  - Landscape: right 100px for keypad
  - Desktop: no offsets needed
- Prevent viewport scrolling during practice sessions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 19:49:59 -06:00
Thomas Hallock 4daf7b7433 feat(practice): add SkillUnlockBanner + session summary improvements
This commit includes accumulated work from the SessionMode system:

- Add SkillUnlockBanner component for celebrating skill mastery
- Improve SessionSummary to show skill unlock celebrations
- Add session detail page at /practice/[studentId]/session/[sessionId]
- Update seedTestStudents script with more realistic test data
- Extend skill-tutorial-config with more skill mappings
- Improve BKT compute with better uncertainty handling
- Update progress-manager with skill completion tracking
- Remove legacy sessions API routes (replaced by session-plans)
- Add migration 0037 for practice_sessions schema cleanup
- Add plan documents for celebration wind-down and SessionMode
- Update gitignore to exclude db backups

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 15:16:34 -06:00
Thomas Hallock 7d8bb2f525 feat(practice): add Remediation CTA for weak skill focus sessions
When a student is in remediation mode (has weak skills to strengthen),
the StartPracticeModal now shows a special amber-themed CTA similar to
the tutorial CTA:

- 💪 "Time to build strength!" heading
- Lists weak skills with pKnown percentages
- "Start Focus Practice →" amber button
- Shows up to 4 skills with "+N more" overflow

Includes Storybook stories for:
- Single weak skill
- Multiple weak skills (2)
- Many weak skills (6, with overflow)
- Dark theme variant

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 14:42:44 -06:00
Thomas Hallock 5735ff0810 docs: add drizzle statement-breakpoint lesson to CLAUDE.md
Documents the critical requirement for --> statement-breakpoint markers
between multiple SQL statements in drizzle migrations. References the
2025-12-18 production outage caused by missing breakpoint.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 07:37:00 -06:00