soroban-abacus-flashcards/apps/web/docs/MATCHING_PAIRS_AUDIT.md

8.8 KiB

Matching Pairs Battle - Pre-Migration Audit Results

Date: 2025-01-16 Phase: 1 - Pre-Migration Audit Status: Complete


Executive Summary

Canonical Location: /src/app/arcade/matching/ is clearly the more advanced, feature-complete version.

Key Findings:

  • Arcade version has pause/resume, networked presence, better player ownership
  • Utils are identical between locations (can use either)
  • ResultsPhase.tsx needs manual merge (arcade layout + games Performance Analysis)
  • 7 files currently import from /games/matching/ - must update during migration

File-by-File Comparison

Components

1. GameCard.tsx

Differences: Arcade has helper function getPlayerIndex() to reduce code duplication Decision: Use arcade version (better code organization)

2. PlayerStatusBar.tsx

Differences:

  • Arcade: Distinguishes "Your turn" vs "Their turn" based on player ownership
  • Arcade: Uses useViewerId() for authorization
  • Games: Shows only "Your turn" for all players Decision: Use arcade version (more feature-complete)

3. ResultsPhase.tsx

Differences:

  • Arcade: Modern responsive layout, exits via exitSession() to /arcade
  • Games: Has unique "Performance Analysis" section (strengths/improvements)
  • Games: Simple navigation to /games Decision: ⚠️ MERGE REQUIRED
  • Keep arcade's layout, navigation, responsive design
  • Add Performance Analysis section from games version (lines 245-317)

4. SetupPhase.tsx

Differences:

  • Arcade: Full pause/resume with config change warnings
  • Arcade: Uses action creators (setGameType, setDifficulty, setTurnTimer)
  • Arcade: Sophisticated "Resume Game" vs "Start Game" button logic
  • Games: Simple dispatch pattern, no pause/resume Decision: Use arcade version (much more advanced)

5. EmojiPicker.tsx

Differences: None (files identical) Decision: Use arcade version (same as games)

6. GamePhase.tsx

Differences:

  • Arcade: Passes hoverCard, viewerId, gameMode to MemoryGrid
  • Arcade: enableMultiplayerPresence={true}
  • Games: No multiplayer presence features Decision: Use arcade version (has networked presence)

7. MemoryPairsGame.tsx

Differences:

  • Arcade: Provides onExitSession, onSetup, onNewGame callbacks
  • Arcade: Uses router for navigation
  • Games: Simple component with just gameName prop Decision: Use arcade version (better integration)

Utilities

1. cardGeneration.ts

Differences: None (files identical) Decision: Use arcade version (same as games)

2. matchValidation.ts

Differences: None (files identical) Decision: Use arcade version (same as games)

3. gameScoring.ts

Differences: None (files identical) Decision: Use arcade version (same as games)

Context/Types

types.ts

Differences:

  • Arcade: PlayerMetadata properly typed (vs any in games)
  • Arcade: Better documentation for pause/resume state
  • Arcade: Hover state not optional (playerHovers: {} vs playerHovers?: {})
  • Arcade: More complete MemoryPairsContextValue interface Decision: Use arcade version (better types)

External Dependencies on /games/matching/

Found 7 imports that reference /games/matching/:

  1. /src/components/nav/PlayerConfigDialog.tsx

    • Imports: EmojiPicker
    • Action: Update to @/arcade-games/matching/components/EmojiPicker
  2. /src/lib/arcade/game-configs.ts

    • Imports: Difficulty, GameType types
    • Action: Update to @/arcade-games/matching/types
  3. /src/lib/arcade/__tests__/arcade-session-integration.test.ts

    • Imports: MemoryPairsState type
    • Action: Update to @/arcade-games/matching/types
  4. /src/lib/arcade/validation/MatchingGameValidator.ts (3 imports)

    • Imports: GameCard, MemoryPairsState, Player types
    • Imports: generateGameCards util
    • Imports: canFlipCard, validateMatch utils
    • Action: Will be moved to /src/arcade-games/matching/Validator.ts in Phase 3
    • Update imports to local ./types and ./utils/*

Migration Strategy

Canonical Source

Use: /src/app/arcade/matching/ as the base for all files

Exception: Merge Performance Analysis from /src/app/games/matching/components/ResultsPhase.tsx

Files to Move (from /src/app/arcade/matching/)

Components (7 files):

  • GameCard.tsx (as-is)
  • PlayerStatusBar.tsx (as-is)
  • ⚠️ ResultsPhase.tsx (merge with games version)
  • SetupPhase.tsx (as-is)
  • EmojiPicker.tsx (as-is)
  • GamePhase.tsx (as-is)
  • MemoryPairsGame.tsx (as-is)

Utils (3 files):

  • cardGeneration.ts (as-is)
  • matchValidation.ts (as-is)
  • gameScoring.ts (as-is)

Context:

  • types.ts (as-is)
  • RoomMemoryPairsProvider.tsx (convert to modular Provider)

Tests:

  • EmojiPicker.test.tsx
  • playerMetadata-userId.test.ts

Files to Delete (after migration)

From /src/app/arcade/matching/ (~13 files):

  • Components: 7 files + 1 test (move, then delete old location)
  • Context: LocalMemoryPairsProvider.tsx, MemoryPairsContext.tsx, index.ts
  • Utils: 3 files (move, then delete old location)
  • page.tsx (replace with redirect)

From /src/app/games/matching/ (~14 files):

  • Components: 7 files + 2 tests (delete)
  • Context: 2 files (delete)
  • Utils: 3 files (delete)
  • page.tsx (replace with redirect)

Validator:

  • /src/lib/arcade/validation/MatchingGameValidator.ts (move to modular location)

Total files to delete: ~27 files


Special Merge: ResultsPhase.tsx

Keep from Arcade Version

  • Responsive layout (padding, fontSize with base/md breakpoints)
  • Modern stat cards design
  • exitSession() navigation to /arcade
  • Better button styling with gradients

Add from Games Version

Lines 245-317: Performance Analysis section

{
  /* Performance Analysis */
}
<div
  className={css({
    background: "rgba(248, 250, 252, 0.8)",
    padding: "30px",
    borderRadius: "16px",
    marginBottom: "40px",
    border: "1px solid rgba(226, 232, 240, 0.8)",
    maxWidth: "600px",
    margin: "0 auto 40px auto",
  })}
>
  <h3
    className={css({
      fontSize: "24px",
      marginBottom: "20px",
      color: "gray.800",
    })}
  >
    Performance Analysis
  </h3>

  {analysis.strengths.length > 0 && (
    <div className={css({ marginBottom: "20px" })}>
      <h4
        className={css({
          fontSize: "18px",
          color: "green.600",
          marginBottom: "8px",
        })}
      >
         Strengths:
      </h4>
      <ul
        className={css({
          textAlign: "left",
          color: "gray.700",
          lineHeight: "1.6",
        })}
      >
        {analysis.strengths.map((strength, index) => (
          <li key={index}>{strength}</li>
        ))}
      </ul>
    </div>
  )}

  {analysis.improvements.length > 0 && (
    <div>
      <h4
        className={css({
          fontSize: "18px",
          color: "orange.600",
          marginBottom: "8px",
        })}
      >
        💡 Areas for Improvement:
      </h4>
      <ul
        className={css({
          textAlign: "left",
          color: "gray.700",
          lineHeight: "1.6",
        })}
      >
        {analysis.improvements.map((improvement, index) => (
          <li key={index}>{improvement}</li>
        ))}
      </ul>
    </div>
  )}
</div>;

Note: Need to ensure analysis variable is computed (may already exist in arcade version from analyzePerformance utility)


Validator Assessment

Location: /src/lib/arcade/validation/MatchingGameValidator.ts Status: Comprehensive and complete (570 lines)

Handles all move types:

  • FLIP_CARD (with turn validation, player ownership)
  • START_GAME
  • CLEAR_MISMATCH
  • GO_TO_SETUP (with pause state)
  • SET_CONFIG (with validation)
  • RESUME_GAME (with config change detection)
  • HOVER_CARD (networked presence)

Ready for migration: Yes, just needs import path updates


Next Steps (Phase 2)

  1. Create /src/arcade-games/matching/index.ts with game definition
  2. Register in game registry
  3. Add type inference to game-configs.ts
  4. Update validator imports

Risks Identified

Risk 1: Performance Analysis Feature Loss

Mitigation: Must manually merge Performance Analysis from games/ResultsPhase.tsx

Risk 2: Import References

Mitigation: 7 files import from games/matching - systematic update required

Risk 3: Test Coverage

Mitigation: Move tests with components, verify they still pass


Conclusion

Phase 1 audit complete. Clear path forward:

  • Arcade version is canonical for all files
  • Utils are identical - no conflicts
  • One manual merge required (ResultsPhase Performance Analysis)
  • 7 import updates required before deletion

Ready to proceed to Phase 2: Create Modular Game Definition.