Commit Graph

23 Commits

Author SHA1 Message Date
Thomas Hallock e2816ae88b feat(vision): improve remote camera calibration UX
- Add dual-stream calibration: phone sends both raw and cropped preview
  frames during calibration so users can see what practice will look like
- Add "Adjust" button to modify existing manual calibration without
  resetting to auto-detection first
- Hide calibration quad editor overlay when not in calibration mode
- Fix rotation buttons to update cropped preview immediately
- Add rate limiting (10fps) for cropped preview frames during calibration
- Fix multiple bugs preventing dual-stream mode from working:
  - Don't mark calibration as complete during preview mode
  - Don't stop detection loop when receiving preview calibration
  - Sync refs properly in frame mode change effects

Also includes accumulated formatting and cleanup changes.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 10:51:59 -06:00
Thomas Hallock eaa1d11c65 chore: formatting and training data updates
- Apply code formatting across codebase
- Add new vision training boundary frames
- Update model configurations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 06:38:57 -06:00
Thomas Hallock 7d2756e3d7 feat(scoreboard): add skills metrics with classroom leaderboard
Add comprehensive skill metrics to the scoreboard that allow comparing
students across a classroom with "fun ways to compare across ability levels":

Skills Progress Section (individual view):
- Overall mastery % (weighted by BKT confidence)
- Category breakdown (basic, fiveComplements, tenComplements, etc.)
- Speed metric (normalized seconds per term) with trend arrows
- Accuracy with trend indicators
- Weekly/streak/total problem counts

Classroom Achievements Section (fair comparisons):
- Practice Warriors: most problems this week
- Streak Masters: longest practice streak
- Rising Stars: highest improvement rate (pKnown delta/week)
- Speed Champions: fastest per category (only mastered students compete)

Also includes:
- Remote camera session validation to prevent stale sessions
- Comprehensive Storybook stories for all skill metrics components

New files:
- src/lib/curriculum/skill-metrics.ts (core computation)
- src/app/api/curriculum/[playerId]/skills/metrics/route.ts
- src/app/api/classroom/[classroomId]/skills/leaderboard/route.ts
- src/hooks/useSkillMetrics.ts (React Query hooks)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 13:13:21 -06:00
Thomas Hallock f8861e6f8d fix(scripts): import classroom functions directly to fix build
The barrel export from @/lib/classroom pulls in all manager modules,
some of which have transitive dependencies on React components with
styled-system imports. Import directly from the specific manager files
(classroom-manager.ts and enrollment-manager.ts) to avoid the
dependency chain that breaks esbuild bundling for the seed script.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 11:38:21 -06:00
Thomas Hallock e419725037 feat(seeding): add classroom enrollment for test students
- Create classroom for current user if they don't have one
- Enroll all seeded test students in the teacher's classroom
- Enables testing of classroom leaderboard features

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 11:27:30 -06:00
Thomas Hallock c182756b80 feat(seeding): add game results generation to test student profiles
- Add gameHistory configs to all 21 test student profiles
- Implement generateGameResults function to create scoreboard data
- Each profile has appropriate game history matching their characteristics:
  - Struggling students get low scores (35-45)
  - Developing students get medium scores (55-75)
  - Strong students get high scores (78-95)
- Add accuracyMultiplier to TuningAdjustment interface (fixes TS error)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 10:48:51 -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 66e66209b0 fix(practice): prevent excessive problem count in session planning
Add MIN_SECONDS_PER_PROBLEM (10s) to clamp the average time calculation
and prevent generating 100+ problems when student timing data is
anomalously low (e.g., 2-3 seconds per problem).

- Add MIN_SECONDS_PER_PROBLEM constant in session-timing.ts
- Apply Math.max() clamp in generateSessionPlan()
- Fix seed script to use realistic 30s timing instead of 5s

A 5-minute session at 10 sec/problem = 30 problems (reasonable)
A 5-minute session at 2 sec/problem = 150 problems (too many)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 11:30:15 -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 518d9c6cb9 feat(worksheet-parsing): add cancel button for parsing and re-parsing
- Add cancel button to gallery thumbnails when parsing in progress
- Add cancel button to fullscreen PhotoViewerEditor when parsing
- Add cancel button for re-parsing in progress (fullscreen view)
- Track reparsingPhotoId to show correct status per-photo in both views
- Gallery shows "Re-parsing..." badge on specific photo being re-parsed
- DELETE endpoint resets parsing status for immediate retry

Also includes codebase-wide formatting from biome.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 12:24:28 -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 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 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 d5e4c858db fix(seed): accurate BKT simulation for developing classifications
Fixed the seed script to reliably produce "developing" skill classifications
(pKnown 0.5-0.8) by correcting several issues:

- Fix BKT simulation to only apply learning transition after CORRECT answers
  (matching actual updateOnCorrect vs updateOnIncorrect behavior)
- Remove result shuffling to preserve designed correct/incorrect sequence order
- Force single-skill problem annotations to avoid multi-skill blame distribution
- Add multiple pattern generators for finding developing-range sequences

The simulation now accurately predicts actual BKT outcomes, enabling 10
developing classifications across 6 test profiles.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 09:27:59 -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 7d03d8c69b test(seed): update NaN stress test to cover missing helpLevelUsed root cause
- Add simulateLegacyData option to SkillConfig interface
- When set, generateSlotResults omits helpLevelUsed field to simulate legacy data
- Update NaN Stress Test profile to test 3 skills with legacy data format
- This tests the actual production issue where old sessions lack helpLevelUsed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 14:44:15 -06:00
Thomas Hallock f883fbfe23 feat(seed): add category field to all mock student profiles
All 15 profiles now have correct category assignments:
- 5 BKT profiles (category: 'bkt')
- 4 Session profiles (category: 'session')
- 6 Edge case profiles (category: 'edge')

This enables CLI filtering when seeding specific profile types.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 14:36:56 -06:00
Thomas Hallock 538718a814 feat(practice): add student organization with filtering and archiving
Implements comprehensive student organization system for /practice page:

Database:
- Add isArchived column to players table (migration 0039)
- Drop unused skill stat columns from playerSkillMastery (migration 0038)

New features:
- Search bar for filtering by student name or skill
- Skill filter pills with AND logic
- Hierarchical grouping: recency buckets → skill categories
- Archive/unarchive from notes modal
- Edit mode with bulk checkbox selection
- Bulk archive for selected students
- Show/hide archived students toggle

New files:
- src/constants/skillCategories.ts - shared skill category definitions
- src/utils/studentGrouping.ts - grouping/filtering logic
- src/utils/skillSearch.ts - skill search utilities
- src/components/practice/StudentFilterBar.tsx - filter bar component

Updated:
- PracticeClient.tsx - filter state management, grouped display
- StudentSelector.tsx - edit mode, archived badges
- NotesModal.tsx - archive button in footer
- ManualSkillSelector.tsx - uses shared skill categories
- server.ts - getPlayersWithSkillData() for enhanced queries

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 10:37:34 -06:00
Thomas Hallock f804d24a29 refactor(skills): compute skill stats from session results (single source of truth)
Previously, skill stats (attempts, correct, accuracy) were stored as
persisted aggregates in playerSkillMastery and updated incrementally.
This caused issues with seeded test data showing "0 correct".

Now:
- analyzeSkillPerformance() computes stats from session results on-the-fly
- findStrugglingSkills() computes accuracy from session results
- Seeder no longer needs to update aggregate columns

Benefits:
- Single source of truth (session results)
- No drift between aggregates and actual data
- Seeded data automatically works correctly

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 09:31:16 -06:00
Thomas Hallock 35720820f3 refactor(seeder): reframe problematic profiles for realistic data generation
- Rename "⚖️ Balanced Mix" → "⚖️ Multi-Weak Remediation" to match actual output
- Update intention notes to reflect BKT's natural tendency to push skills to extremes
- Remove tuning criteria that fought against realistic behavior
- Focus profiles on app feature coverage rather than perfect BKT states

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 09:10:34 -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 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 2702ec585f feat(practice): add student notes with animated modal + BKT improvements
Student Notes Feature:
- Add notes column to players table with migration
- Create NotesModal component with zoom animation from student tile
- Add notes button on each student card in StudentSelector
- Support viewing and editing notes directly in modal
- Fix modal reopening bug with pointerEvents during animation
- Fix spring animation to start from clicked tile position

BKT & Curriculum Improvements:
- Add configurable BKT thresholds via admin settings
- Add skill anomaly detection API endpoint
- Add next-skill recommendation API endpoint
- Add problem history API endpoint
- Improve skills page with BKT classifications display
- Add skill tutorial integration infrastructure

Dashboard & Session Improvements:
- Enhanced dashboard with notes tab
- Improved session summary display
- Add StartPracticeModal stories

Test Infrastructure:
- Add seedTestStudents.ts script for BKT manual testing
- Add generateTrajectoryData.ts for simulation data

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

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