Archery Apprentice - Checkpoint Investigation Findings
Investigation Date: October 4, 2025 Current Project Status: 97% Complete Purpose: Pre-next-epoch architecture and documentation audit
Note: This is a condensed version. Full document:
docs/CHECKPOINT_FINDINGS.md(962 lines)Update (Oct 7, 2025): Since this analysis, significant progress has been made. See Implementation-Status-10-07-25 for current status.
Executive Summary
Status: Investigation Phases 1-4 complete Critical Findings: 7 major architectural issues identified Recommendation: Address critical tech debt before next major features
Critical Issues Summary
-
🚨 LiveScoringViewModel: 2,808 lines (+60% growth) - URGENT extraction needed
- Update: ✅ 60% complete (3/5 services extracted, 2,304 lines as of Oct 7)
-
🚨 RoundViewModel refactoring created NEW god class (LiveScoringViewModel)
- Discovery: Refactoring WAS executed - 7 ViewModels successfully extracted from 3,000-line monolith
- Problem: LiveScoringViewModel became replacement god class
-
🚨 Documentation severely outdated (10+ files claiming complete features are “planned”)
-
🚨 N+1 query pattern confirmed (31 queries for 30-end round instead of 1)
- Update: ✅ FIXED per Tech-Debt
-
🚨 Repository god classes (5,959 total lines across TournamentRepository + RoundRepository)
-
🚨 Tie-breaking NOT implemented (docs claim complete, but xCount/tenCount fields missing)
- Update: ✅ FIXED per Tech-Debt
-
🚨 Average score always 0.0 (calculation never executed during scoring)
- Update: ✅ FIXED per Tech-Debt
Phase Progress
- ✅ Phase 1: Documentation Audit - COMPLETE
- ✅ Phase 2: Database Architecture - COMPLETE
- ✅ Phase 3: God Class Analysis (LiveScoringViewModel) - COMPLETE
- ✅ Phase 4: Feature Validation - COMPLETE
- ✅ Phase 5: Tech Debt Consolidation - COMPLETE
Critical Finding #1: LiveScoringViewModel Explosive Growth
Baseline: 1,753 lines (CLAUDE.md) Current (Oct 4): 2,808 lines (+1,055 lines, +60% growth) Current (Oct 7): 2,304 lines (504 lines extracted + 109 deduplication)
Key Findings
- 12 distinct architectural domains identified (should be 2-3!)
- 66 methods (should be <30)
- 24 StateFlow properties (should be <12)
- Tournament Phases 2.2-4.1 added ~1,300 lines without refactoring
- Complexity Score: 9.5/10 (CRITICAL)
Extraction Progress (Per Implementation-Status-10-07-25)
Completed Extractions (Oct 2025):
- ✅ TournamentSyncService (556 lines) - Oct 5
- ✅ ScoreConflictResolutionService (262 lines)
- ✅ EndCompletionService (400 lines) - Oct 6
- ✅ Code Deduplication (109 lines removed) - Oct 7
Remaining Work:
- ⏳ TournamentRoundLifecycleService (~200 lines)
- ⏳ StatisticsAggregationService (~150 lines)
Target: 1,200-1,400 lines (50-57% reduction) Current Progress: 62% complete (18% size reduction achieved)
Pattern Analysis: Why It Grew
- Incremental Addition: Each tournament phase added 200-400 lines directly
- “Just One More Method” Syndrome: Small additions accumulated to +1,055 lines
- State Proliferation: Each feature added its own StateFlow without consolidation
- No Extraction Discipline: “Refactor later” → Never happens
Key Lesson vs RoundViewModel
- RoundViewModel: 3 planning docs (1,302 lines), ZERO extraction work initially
- LiveScoringViewModel: MUST EXECUTE, NOT JUST PLAN!
- Proven Pattern: Copy-delegate-validate works (3/3 successful extractions)
See LiveScoringVM-Analysis for comprehensive 584-line analysis.
Critical Finding #2: RoundViewModel Refactoring WAS Executed
MAJOR DISCOVERY: Refactoring actually happened - just undocumented!
What Actually Occurred
Original RoundViewModel: ~3,000+ lines (single monolith god class)
Successfully extracted to 8 ViewModels: Total 5,987 lines distributed architecture
- RoundViewModel: 2,058 lines (core orchestration - legitimate coordination)
- LiveScoringViewModel: 1,753 lines ← NEW GOD CLASS CREATED!
- RoundAnalyticsViewModel: 605 lines ✅
- RoundManagementViewModel: 495 lines ✅
- RoundCreationViewModel: 480 lines ✅
- RoundDisplayViewModel: 216 lines ✅
- RoundNavigationViewModel: 192 lines ✅
- RoundScoringViewModel: 187 lines ✅
The Problem: Shifted, Not Solved
- ✅ Successfully extracted 7 specialized ViewModels
- ❌ Created LiveScoringViewModel as replacement god class
- ❌ LiveScoringViewModel grew from 1,753 → 2,808 lines (+60%)
- ⚠️ RoundViewModel still 2,058 lines (but legitimate - cross-ViewModel coordination)
Why Documentation Shows “Zero Execution”
September 22 planning docs were created AFTER initial extraction:
- Docs analyze 2,058-line RoundViewModel (post-extraction state)
- All recommend “further extraction” unaware major work already done
- No documentation of the ACTUAL extraction that created 7 ViewModels
- Planning docs conflict because they’re analyzing already-refactored code!
See Refactoring-Reality-Check for detailed analysis.
Critical Finding #3: README Severely Outdated
Issue: README stops at July 2025, omits 3 months of major work
Missing Features:
- Tournament system (Phases 1-5)
- Firebase real-time sync
- Multi-device scoring
- Cache system (5-10x performance)
- Guest participants
- Network status monitoring
- 97% completion status
Impact: HIGH - New developers/users get wrong picture Recommendation: Major README rewrite to reflect current state
Critical Finding #4: N+1 Query Pattern Confirmed ✅ FIXED
Status (Oct 4): CONFIRMED - Active performance issue Status (Oct 7): ✅ FIXED per Tech-Debt
Original Issue
Location: RoundRepository.kt:98-102, 138-143
Performance Impact:
- 30-end round: 31 queries (1 + 30) instead of 1
- 60-end round: 61 queries (1 + 60) instead of 1
- Multiplied by number of participants in multi-participant rounds
Fix Applied
- Refactored
getRoundWithDetails()to use optimized JOIN queries - Created similar optimized query for
getEndsWithArrowsForParticipant() - Result: 30-60x query reduction for typical rounds
Critical Finding #5: Repository God Classes
Total Repository Code: 5,959 lines
Repository Size Analysis
Tournament Repositories:
TournamentRepository.kt (interface): 395 lines, 51 methods 🚨
├── OfflineTournamentRepository.kt: 908 lines
├── FirebaseTournamentRepository.kt: 1,707 lines 🚨🚨
└── HybridTournamentRepository.kt: 1,506 lines 🚨🚨
Total: 4,516 lines
Round Repository:
RoundRepository.kt: 1,443 lines 🚨
Comparison to Industry Standards
- Good repository: 200-400 lines, 10-15 methods
- TournamentRepository interface: 395 lines, 51 methods (3.4x too many!)
- FirebaseTournamentRepository: 1,707 lines (4.3x too large!)
- HybridTournamentRepository: 1,506 lines (3.8x too large!)
- RoundRepository: 1,443 lines (3.6x too large!)
Recommended Refactoring
Split TournamentRepository into 4 focused repositories:
- TournamentCrudRepository (~300 lines)
- TournamentSyncRepository (~400 lines)
- TournamentScoreRepository (~500 lines)
- TournamentAnalyticsRepository (~200 lines)
Split RoundRepository into 3 focused repositories:
- RoundCrudRepository (~400 lines)
- RoundScoringRepository (~500 lines)
- RoundStatisticsRepository (~400 lines)
Effort Estimate: 6-7 weeks Priority: HIGH (but lower than LiveScoringViewModel extraction)
Critical Finding #6: Tie-Breaking Not Actually Implemented ✅ FIXED
Status (Oct 4): PLANNING DOCS CLAIM COMPLETE - ACTUALLY NOT IMPLEMENTED Status (Oct 7): ✅ FIXED per Tech-Debt
Original Issue
Documentation Claims: “Tie-breaking logic: Score → X count → 10 count - COMPLETE”
Actual Reality:
- TournamentParticipant had NO xCount or tenCount fields
- Firestore
orderBy("currentScore")without secondary sort key - When two participants have same score, order was NON-DETERMINISTIC
- Different devices could see different order for tied participants
Fix Applied
- Added
xCount: IntandtenCount: Intto TournamentParticipant model - Track X and 10 counts during score submission
- Updated Firestore query to use proper tie-breaking order
- Created Firestore composite indexes for multi-field sorting
Critical Finding #7: Average Score Never Calculated ✅ FIXED
Status (Oct 4): BUG CONFIRMED - averageScore field never updated during scoring Status (Oct 7): ✅ FIXED per Tech-Debt
Original Issue
User Report: “Avg” field on LiveLeaderboardCard displays 0.0 for participants
Root Cause:
- TournamentParticipant.averageScore defaults to 0.0
- Score submission never calculated or updated averageScore
- Leaderboard displayed default 0.0 value
Fix Applied
Added averageScore calculation to score submission:
val newAverageScore = if (newArrowsShot > 0) {
newTotal.toDouble() / newArrowsShot
} else {
0.0
}Database Index Analysis
Overall Status: GOOD coverage, 2 missing composite indexes
Existing Indexes: 14 indexes implemented across 3 core entities ✅
Missing Indexes (Performance Opportunities):
-
Arrow Scores Equipment Performance (MEDIUM PRIORITY)
- Suggested: Composite index
(bowSetupId, scoredAt) - Estimated improvement: 2-5x for equipment queries
- Suggested: Composite index
-
Rounds Historical Queries (LOW PRIORITY)
- Suggested: Composite index
(status, createdAt DESC) - Impact: Minor - most queries use fields separately
- Suggested: Composite index
Index Coverage Assessment: 90% ✅
God Class Scorecard (Oct 4 Snapshot)
| Class | Current Lines | Change from Baseline | Status |
|---|---|---|---|
| LiveScoringViewModel | 2,808 | +1,055 (+60%) | 🚨 CRITICAL |
| RoundViewModel | 2,079 | +21 (+1%) from 2,058* | 🟡 STABLE* |
| ActiveScoringScreen | 1,958 | +62 (+3%) | 🟠 HIGH |
| TOTAL | 6,845 | +1,138 (+20%) | SEVERE |
*RoundViewModel baseline was 2,058 AFTER successful extraction of 7 ViewModels from original 3,000-line monolith
Update (Oct 7):
- LiveScoringViewModel: 2,304 lines (down from 2,808)
- Progress: 18% reduction achieved, 62% of extraction plan complete
Documentation Audit Summary
Files Reviewed: 41/41 (100%) ✅
Severely Outdated Docs: 10+
- README (stops at July 2025)
- tournament/README.md (claims features “in progress” that are complete)
- TOURNAMENT_SYSTEM_DOCUMENTATION.md (8-9 months old)
- 3 RoundViewModel planning docs analyzing already-refactored code
- Firebase/README.md (shows features as “planned” that are complete)
Historical Documents Needing Archival:
- NETWORK_SCORING_SESSION_1_SUMMARY.md
- NETWORK_SCORING_SESSION_2_SUMMARY.md
- PHASE_2_TOURNAMENT_DISCOVERY.md
- Phase 2 cache docs (3 files)
Consolidation Needed:
- 3 RoundViewModel docs → 1 status doc documenting successful extraction
Key Discoveries
-
RoundViewModel refactoring WAS executed!
- Successfully extracted 7 ViewModels from 3,000-line monolith
- Created distributed architecture: 8 ViewModels totaling 5,987 lines
- But created LiveScoringViewModel as replacement god class
-
LiveScoringViewModel explosive growth
- Grew 60% (1,753 → 2,808) from tournament features
- Now being addressed: 3/5 services extracted (60% complete)
-
Documentation crisis
- 10+ severely outdated docs
- Planning docs analyzing wrong state
- Major features undocumented in README
-
Critical bugs identified and fixed
- N+1 query pattern → Fixed
- Tie-breaking missing → Implemented
- Average score calculation → Fixed
Immediate Action Items
Priority 1: URGENT (Before Any New Features) - ⏳ IN PROGRESS
LiveScoringViewModel Refactoring
- Status (Oct 4): 2,808 lines (60% growth)
- Status (Oct 7): 2,304 lines (18% reduction, 62% complete)
- Target: <1,500 lines
- Remaining: 2 services to extract (~350 lines)
- Timeline: 1-2 weeks to completion
Priority 2: HIGH - 🔄 PARTIALLY COMPLETE
- README Major Rewrite - ⏳ Pending
- Bug Fixes - ✅ Complete (N+1, tie-breaking, averages)
- Documentation Consolidation - ⏳ Pending
Priority 3: MEDIUM - ⏳ PENDING
- Repository god class refactoring (6-7 weeks)
- Complete documentation audit updates
- Archive historical documents
Lessons Learned
Pattern: Documentation Debt
Issue: Completed phases leave reference docs in root directory
Solution: Create docs/completed-phases/ or docs/COLD_STORAGE/ structure
Pattern: Refactoring Planning Debt
Issue: Extensive refactoring plans created but not executed Example: RoundViewModel (3 docs, 1,302 lines of planning analyzing wrong code) Success: LiveScoringViewModel EXECUTION pattern works (3/3 extractions successful)
Pattern: God Class Migration
Issue: Extracting god class creates NEW god class Example: RoundViewModel → LiveScoringViewModel Solution: Be aware when creating “coordinator” ViewModels - they can become new bottlenecks
Investigation Phases Completed
- ✅ Phase 1: Documentation Audit (41/41 files reviewed)
- ✅ Phase 2: Database Architecture Assessment
- ✅ Phase 3: God Class Analysis (LiveScoringViewModel deep dive)
- ✅ Phase 4: Feature Validation (found 3 critical bugs)
- ✅ Phase 5: Tech Debt Consolidation
Current Status (Oct 7, 2025)
Since this checkpoint investigation:
Completed:
- ✅ 3 of 7 critical issues FIXED (N+1 queries, tie-breaking, average scores)
- ✅ LiveScoringViewModel extraction 60% complete (3/5 services)
- ✅ Code deduplication (109 lines removed via delegation pattern)
- ✅ All 1,879 tests passing
In Progress:
- 🔄 LiveScoringViewModel extraction (2 services remaining)
- 🔄 Documentation updates
Pending:
- ⏳ Repository god class refactoring
- ⏳ README major rewrite
- ⏳ Documentation consolidation
See Implementation-Status-10-07-25 for detailed current status.
Investigation Date: October 4, 2025 Last Updated: October 7, 2025 (Progress tracking) Status: Historical reference - Most critical issues addressed
Full Source: docs/CHECKPOINT_FINDINGS.md (962 lines)
Related Documentation:
- LiveScoringVM-Analysis - Comprehensive 584-line analysis of god class
- Implementation-Status-10-07-25 - Current progress (97.5% complete, 3/7 critical issues fixed)
- Project-Journal-10-07-25 - Detailed session work (code deduplication, bug fixes)
- RoundViewModel-Audit - Similar god class audit
- Refactoring-Reality-Check - Documents successful 7-ViewModel extraction
- Tech-Debt - Technical debt tracking (shows N+1, tie-breaking, averages as FIXED)
- Architecture - Overall architecture documentation