Add a fun, interactive flashcard display to the homepage's flashcard
generator section. Users can drag and throw 8-15 randomly generated
flashcards around with realistic physics-based momentum.
Features:
- Drag and drop flashcards with mouse/touch
- Throw cards with velocity-based physics
- 8-15 randomly generated flashcards (100-999 range)
- Real AbacusReact components for each card
- Client-side rendering to avoid hydration errors
Technical implementation:
- Uses @use-gesture/react for drag gesture handling
- Uses @react-spring/web for smooth physics animations
- Cards generated client-side with useEffect to prevent SSR mismatch
- Each card maintains its own spring-based position and rotation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
BREAKING CHANGE: Database schemas now accept any string for game names
This implements Critical Fix#1 from AUDIT_2_ARCHITECTURE_QUALITY.md
Changes:
- Remove hardcoded enums from all database schemas
- arcade-rooms.ts: gameName now accepts any string
- arcade-sessions.ts: currentGame now accepts any string
- room-game-configs.ts: gameName now accepts any string
Runtime Validation:
- Add isValidGameName() helper to validate against registry
- Add assertValidGameName() helper for fail-fast validation
- Update settings API to use runtime validation instead of hardcoded array
Benefits:
✅ No schema migration needed when adding new games
✅ No TypeScript compilation errors for new games
✅ Single source of truth: validator registry
✅ "Just register and go" - no database changes required
Migration Impact:
- Existing data is compatible (strings remain strings)
- No data migration needed
- TypeScript will now allow any string, but runtime validation enforces correctness
This eliminates the most critical architectural issue identified in the audit.
Future games can be added by:
1. Register validator in validators.ts
2. Register game in game-registry.ts
That's it! No database schema changes needed.
Create foundation for modular arcade game architecture:
**Game SDK** (`/src/lib/arcade/game-sdk/`):
- Stable API surface that games can safely import
- Type-safe game definition with `defineGame()` helper
- Controlled hook exports (useArcadeSession, useRoomData, etc.)
- Player ownership and metadata utilities
- Error boundary component for game crashes
**Manifest System**:
- YAML-based game manifests with Zod validation
- Game metadata (name, icon, description, difficulty, etc.)
- Type-safe manifest loading with `loadManifest()`
**Game Registry**:
- Central registry for all arcade games
- Explicit registration pattern via `registerGame()`
- Helper functions to query available games
**Type Safety**:
- Full TypeScript contracts for games
- GameValidator, GameState, GameMove, GameConfig types
- Compile-time validation of game implementations
This establishes the plugin system for drop-in arcade games.
Next: Create demo games to exercise the system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive access control system for arcade rooms with 6 modes:
- open: Anyone can join (default)
- locked: Only current members allowed
- retired: Room no longer functions
- password: Requires password to join
- restricted: Only users with pending invitations can join
- approval-only: Requires host approval via join request system
Database Changes:
- Add accessMode field to arcade_rooms (replaces isLocked boolean with enum)
- Add password field to arcade_rooms (hashed with bcrypt)
- Create room_join_requests table for approval-only mode
New API Endpoints:
- PATCH /api/arcade/rooms/:roomId/settings - Update room access mode and password (host only)
- POST /api/arcade/rooms/:roomId/transfer-ownership - Transfer ownership to another member (host only)
- POST /api/arcade/rooms/:roomId/join-request - Request to join approval-only room
- GET /api/arcade/rooms/:roomId/join-requests - Get pending join requests (host only)
- POST /api/arcade/rooms/:roomId/join-requests/:requestId/approve - Approve join request (host only)
- POST /api/arcade/rooms/:roomId/join-requests/:requestId/deny - Deny join request (host only)
Updated Endpoints:
- POST /api/arcade/rooms/:roomId/join - Now validates access modes before allowing join:
* locked: Rejects all joins
* retired: Rejects all joins (410 Gone)
* password: Requires password validation
* restricted: Requires valid pending invitation
* approval-only: Requires approved join request
* open: Allows anyone (existing behavior)
Libraries:
- Add room-join-requests.ts for managing join request lifecycle
- Ownership transfer updates room.createdBy and member.isCreator flags
- Socket.io events for join request notifications and ownership transfers
Migration: 0007_access_modes.sql
Next Steps (UI not included in this commit):
- RoomSettingsModal for configuring access mode and password
- Join request approval UI in ModerationPanel
- Ownership transfer UI in ModerationPanel
- Password input in join flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add tsconfig.server.json to compile server-side TypeScript
- Install tsc-alias to resolve path aliases (@/*) in compiled JS
- Update build script to run tsc + tsc-alias before Next.js build
- Update dev script to compile server files before starting
- Remove tsx runtime dependencies from server.js
- Add compiled JS files for socket-server, db, and arcade modules
This enables production builds to run with pure Node.js without
requiring tsx or ts-node at runtime, as required for Docker deployment.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive documentation and tooling to enforce code quality
checks before every commit. This regime persists across all Claude
Code sessions via `.claude/` directory files.
**The Regime** (mandatory before every commit):
1. TypeScript type checking (0 errors)
2. Biome formatting (auto-applied)
3. Linting with auto-fix (0 errors, 0 warnings)
4. Final verification
**Implementation:**
- `.claude/CLAUDE.md`: Quick reference for Claude Code sessions
- `.claude/CODE_QUALITY_REGIME.md`: Detailed regime documentation
- `npm run pre-commit`: Single command to run all checks
**Why no pre-commit hooks:**
Avoided for religious reasons. Claude Code is responsible for
enforcing quality checks through session-persistent documentation.
**Usage:**
```bash
# Before every commit
npm run pre-commit
# Or run steps individually
npm run type-check
npm run format
npm run lint:fix
npm run lint
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add Biome for formatting and general linting, with minimal ESLint
configuration for React Hooks rules only. This provides:
- Fast formatting via Biome (10-100x faster than Prettier)
- General JS/TS linting via Biome
- React Hooks validation via ESLint (rules-of-hooks)
- Import organization via Biome
Configuration files:
- biome.jsonc: Biome config with custom rule overrides
- eslint.config.js: Minimal flat config for React Hooks only
- .gitignore: Added Biome cache exclusion
- LINTING.md: Documentation for the setup
Scripts added to package.json:
- npm run lint: Check all files
- npm run lint:fix: Auto-fix issues
- npm run format: Format all files
- npm run check: Full Biome check
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove @myriaddreamin/typst-* packages that are no longer needed.
This eliminates Docker overlay conflicts with hoisted node_modules.
Removed packages (-365):
- @myriaddreamin/typst-all-in-one.ts
- @myriaddreamin/typst-ts-renderer
- @myriaddreamin/typst-ts-web-compiler
- @myriaddreamin/typst.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed CreateSessionOptions.activePlayers from number[] to string[]
- Updated socket-server.ts fallback from [1] to [data.userId]
- Added debug logging to validateFlipCard to diagnose turn validation issues
This ensures that when a session is created without explicit activePlayers,
it uses the actual UUID of the requesting player instead of the numeric value 1.
- Install @tanstack/react-query
- Create QueryClientProvider in ClientProviders with stable client instance
- Add queryClient.ts with createQueryClient() and api() helper
- Add api() helper that wraps fetch with automatic /api prefix
- Add example.ts with complete CRUD hook examples
- Configure sensible defaults (5min staleTime, retry once)
All API routes are now prefixed with /api automatically via api() helper.
Add script to capture deployment metadata (git commit, branch, timestamp, version) at build time and integrate it into the build process.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix duplicate color properties in single player mode styling
- Fix className prop passing to css() function in both single and multiplayer modes
- Replace undefined 'super-bounce' animation with 'gentle-bounce'
The make-plural pluralization integration is working correctly with proper
display of "1 pair" vs "2 pairs", "1 move" vs "3 moves", etc.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated AbacusDisplayDropdown to accept isFullscreen prop
- Added dark/cosmic styling that adapts to fullscreen mode
- Updated trigger button, content panel, and all form controls
- Enhanced FormField, SwitchField, and RadioGroupField components
- Integrated with AppNavBar to pass fullscreen state
- Ensures consistent cosmic theme across entire navigation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Restore @soroban/core and @soroban/client dependencies in apps/web
- Correct workspace configuration to include all existing packages
- Disable problematic example-server.ts to fix TypeScript build
- Update Dockerfile to copy all required package.json files
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix pnpm-workspace.yaml to use packages/* pattern
- Remove references to non-existent @soroban/core and @soroban/client packages
- Update Dockerfile to only copy existing package.json files
- Clean up dependencies after workspace changes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace @radix-ui/react-tooltip with @radix-ui/react-hover-card to enable
interactive tooltip content that users can mouse over. HoverCard provides
better timing control and hover persistence for complex tooltip interactions.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add DecompositionWithReasons component with interactive term groups
- Implement current step highlighting with amber glow animation
- Create compact tooltips with step-by-step breakdowns and expansion reasoning
- Remove visual noise: no default term styling, only current step and group hover
- Add unified hover targets spanning entire term groups with reasoning context
- Integrate with tutorial context for synchronized step progression
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add @radix-ui/react-tooltip package to replace custom tooltip implementation
with proper accessibility features and built-in pointer-events handling.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix highlighting logic bug where multiple beads in same column would overwrite each other
- Migrate TutorialStep interface from columnIndex to placeValue system
- Update tutorial data to use place values (0=ones, 1=tens, etc.)
- Fix bead validation logic to use place values instead of legacy columnIndex
- Enable proper multi-step tutorial highlighting for complement operations
Tutorial steps like "3 + 4 = 5 - 1" now correctly highlight both the heaven bead
(add 5) and earth bead (remove 1) simultaneously.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated styled-system CSS, package.json, and pnpm-lock.yaml to include
new dependencies and generated styles for the tutorial system components.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced TypstSoroban and InteractiveAbacus components with the new
@soroban/abacus-react package throughout the web application:
- Updated guide page: replaced all static TypstSoroban instances with AbacusReact
- Updated interactive demo: replaced InteractiveAbacus with AbacusReact
- Updated LivePreview: replaced TypstSoroban with AbacusReact
- Added @soroban/abacus-react dependency to web app package.json
Benefits:
- Unified abacus component across the entire application
- Better performance and smaller bundle size
- Consistent features (interactive prop, showNumbers, etc.)
- Modern React patterns with hooks and proper TypeScript support
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove duplicate templates from packages/core/templates/
- Update web app API routes to import from @soroban/templates
- Add @soroban/templates dependency to web app package.json
- Use getTemplatePath() for webpack-safe template resolution
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix column indexing bug where tens/ones columns were swapped
- Add boundary checks to prevent values exceeding abacus capacity
- Improve earth and heaven bead click logic with proper place value mapping
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add @react-spring/web for animation features and @types/jsdom for
development tooling. These support interactive UI components and
build processes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add missing @myriaddreamin/typst-all-in-one.ts package and peer dependencies.
This restores the working WASM loading functionality that was previously
working perfectly.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Vitest test framework setup with jsdom environment
- Create memory-quiz-utils.ts with testable prefix matching functions
- Add comprehensive test suite covering:
- Prefix matching logic with found/unfound number exclusion
- Edge cases for input validation
- 55/555 bug scenario reproduction and fix
- Integration test scenarios
Tests currently have 3 failures that need debugging in prefix logic.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Install @myriaddreamin/typst.ts package for WebAssembly Typst rendering
- Create server-side API endpoints for template loading and SVG generation
- Implement TypstSoroban React component with error handling and loading states
- Add test page for verifying typst.ts integration
- Configure webpack for WASM support and resolve browser compatibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Install concurrently package for running multiple processes
- Update dev script to run both Next.js dev and Panda CSS watch
- Automatically regenerate CSS when styles change during development
- Eliminates need to manually run panda codegen after CSS changes
Dev script now runs:
- Next.js development server
- Panda CSS file watcher for automatic style regeneration
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create /guide page with step-by-step tutorial for reading soroban numbers
- Add ServerSorobanSVG component using same API as LivePreview for consistency
- Implement proper viewBox correction for Typst-generated sorobans
- Design responsive layout with appropriate aspect ratios for soroban display
- Add navigation links between guide and flashcard creation
- Include examples for single digits (0,1,3,5,7) and multi-digit numbers (23,58,147)
- Provide educational content covering heaven/earth beads, place values, and practice tips
Technical improvements:
- Handle complex SVG transforms (matrix(4 0 0 4 -37.5 -180)) that push content outside viewBox
- Calculate precise content bounds to eliminate whitespace and show full soroban
- Use aspect-ratio containers and flexbox for graceful responsive display
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Set up Next.js 14 with App Router and TypeScript
- Implement Panda CSS for styling instead of Tailwind
- Create comprehensive configuration form using TanStack Forms and Radix UI
- Add live preview, generation progress, and download components
- Design responsive, accessible interface for flashcard generation
- Integrate with existing TypeScript bindings for Python calls
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>