Phase 2: Round Scoring - iOS Roadmap
Phase: 2 Status: In Progress (2a complete, 2b-2f planned) Start Date: 2025-11-20 Estimated Completion: 2-3 weeks (part-time) or 1 week (full-time)
Overview
Phase 2 implements complete round scoring functionality for iOS, achieving feature parity with the Android app. This phase builds on the shared KMP code that provides 90-95% of the business logic, requiring only UI implementation and platform bridging.
Core Objective: Enable iOS users to create rounds, score arrows during practice sessions, view round history, and analyze performance statistics.
Current Status
✅ Phase 2a: Round Creation (PR #284)
Status: In review Completed: 2025-11-21 Effort: 8 hours
What Was Built:
RoundCreationViewModel.swift- Swift wrapper around KMP Round entity with Combine-based form validationRoundCreationView.swift- Comprehensive 6-section form (407 lines)- Quick Start templates (18m Indoor, 70m Outdoor)
- Auto-selection of scoring systems based on target size
- Real-time validation with disabled submit when invalid
- Summary card with Total Arrows and Max Possible Score calculations
- Mock repository implementation (save doesn’t persist yet)
Testing Complete:
- ✅ Quick Start templates auto-fill correctly
- ✅ Manual entry with validation works
- ✅ Target size changes auto-update scoring system
- ✅ Form reset via Cancel works
- ✅ Validation prevents invalid submission
Known Limitations:
- Uses mock repository (rounds don’t persist)
- No navigation to active scoring
- Bow setup defaults to 0 (no selection UI)
- Single user only (no multi-participant support)
PR: https://github.com/blamechris/archery-apprentice/pull/284
Remaining Phases
📋 Phase 2b: Round Persistence & Repository Integration
Status: Planned Estimated Effort: 4-6 hours Dependencies: RoundRepository KMP migration Priority: High (unblocks 2c-2e)
Objective
Wire up Round Creation to actually save data by migrating RoundRepository to shared KMP module and integrating with RoundCreationViewModel.
Tasks
-
Migrate RoundRepository to KMP shared module
- Current location:
app/src/main/java/com/archeryapprentice/domain/repository/RoundRepository.kt(Android-only) - Target location:
shared/data/src/commonMain/kotlin/.../repositories/RoundRepository.kt - Expose to iOS via KMP framework
- Ensure RoundDao is also shared (if not already)
- Current location:
-
Update RoundCreationViewModel to use real repository
- Remove mock implementation (lines 192-198 in current PR)
- Inject RoundRepository via KMP
- Handle actual database saves with proper error handling
- Return real round IDs from database
-
Add error handling for database operations
- Network errors (if syncing to Firebase)
- Database constraint violations
- Disk space issues
- User-friendly error messages in UI
-
Test end-to-end round creation
- Create round via iOS UI
- Verify database persistence
- Confirm round appears in list (Phase 2c)
Success Criteria
- ✅ Rounds persist to database after creation
- ✅ Round IDs are returned from repository
- ✅ Error handling covers all failure modes
- ✅ iOS and Android share same repository code
Implementation Guide
See: Round Persistence Implementation Guide
📋 Phase 2c: Round History List
Status: Planned Estimated Effort: 6-8 hours Dependencies: Phase 2b (needs real data to display) Priority: High (core feature)
Objective
Display list of created rounds in RoundsTabView with filtering, sorting, and navigation to details/scoring.
Tasks
-
Create RoundListView component
- LazyVStack with round cards
- Each card shows: Round name, date, distance, target size, score summary
- Tap to view details or resume scoring
- Pull-to-refresh functionality
- Empty state (already exists)
-
Create RoundListViewModel
- Fetch rounds from RoundRepository
- Filter by status (planned, in-progress, completed)
- Sort by date (most recent first)
- Handle loading and error states
- Reactive updates when rounds change
-
Update RoundsTabView
- Replace empty state with RoundListView when rounds exist
- Keep “Create Round” button in toolbar
- Add filter/sort options (optional for MVP)
- Smooth navigation transitions
Success Criteria
- ✅ Round list displays all created rounds
- ✅ List updates reactively when rounds are added
- ✅ Tapping a round navigates to appropriate screen
- ✅ Empty state shown when no rounds exist
Design Reference
Android RoundListScreen.kt (if exists, otherwise design from scratch to match iOS patterns)
Implementation Guide
See: Round List Implementation Guide
📋 Phase 2d: Active Scoring Screen
Status: Planned Estimated Effort: 12-16 hours Dependencies: Phase 2b (needs persistence) Priority: High (core feature)
Objective
Allow users to score arrows during a round with a clean, tappable interface matching Android functionality.
Tasks
-
Create ActiveScoringView
- Large, tappable score buttons (0-10 + X) in grid layout
- Current progress display (End 1 of 10, Arrow 1 of 3)
- Running total score with end subtotal
- Undo last arrow button
- End completion button (advance to next end)
- Round completion detection and navigation
-
Create ActiveScoringViewModel
- Manage current end/arrow state
- Validate score entries (check against scoring system rules)
- Calculate running totals and averages
- Save scores to database via RoundRepository
- Handle end completion logic
- Support undo functionality
-
Navigation Integration
- After creating round in Phase 2a → navigate to ActiveScoringView
- From round list → tap in-progress round → resume scoring
- From round list → tap planned round → start scoring
- After completing round → navigate to Round Details
-
State Persistence
- Save arrow scores incrementally (don’t lose data on app close)
- Resume scoring at correct end/arrow position
- Handle app backgrounding gracefully
Success Criteria
- ✅ Score entry is fast and intuitive
- ✅ Running totals calculate correctly
- ✅ Undo functionality works
- ✅ End completion advances properly
- ✅ Round completion detected and navigates
- ✅ State persists across app sessions
Design Reference
Android ActiveScoringScreen.kt - match UI/UX patterns and behavior
Implementation Guide
See: Active Scoring Implementation Guide
📋 Phase 2e: Round Details & Statistics
Status: Planned Estimated Effort: 10-12 hours Dependencies: Phase 2d (needs completed rounds) Priority: Medium (nice-to-have for MVP)
Objective
View completed rounds with comprehensive statistics and end-by-end breakdown.
Tasks
-
Create RoundDetailsView
- Round summary header (name, date, distance, target, total score)
- End-by-end breakdown table
- Statistics section:
- Average per arrow
- Accuracy percentage
- X-count and 10-count
- Consistency metrics
- Share/export button (optional)
- Charts/graphs (future enhancement)
-
Create RoundDetailsViewModel
- Fetch round by ID from repository
- Fetch all ends and arrows for round
- Calculate statistics (leverage shared KMP logic if available)
- Format data for display
- Handle sharing/export functionality
-
Navigation Integration
- From round list → tap completed round → RoundDetailsView
- Breadcrumb navigation back to list
- Option to view in-progress rounds (show stats so far)
Success Criteria
- ✅ Round details display all relevant information
- ✅ Statistics calculate correctly
- ✅ End-by-end breakdown is clear
- ✅ Navigation flows smoothly
Design Reference
Android RoundDetailsScreen.kt
Implementation Guide
See: Round Details Implementation Guide
📋 Phase 2f: iOS UI Testing
Status: Planned Estimated Effort: 8-10 hours Dependencies: Phases 2a-2e complete Priority: Medium (deferred but recommended)
Objective
Add automated UI tests for Round Creation and Scoring to ensure quality and prevent regressions.
Tasks
-
Set up XCUITest framework
- Create UI test target in Xcode
- Configure test schemes
- Set up test data fixtures
-
Write UI tests for Round Creation (Phase 2a)
- Test Quick Start templates fill correctly
- Test manual entry with validation
- Test error states and alerts
- Test form reset functionality
- Test auto-selection logic
-
Write UI tests for Active Scoring (Phase 2d)
- Test score entry workflow
- Test end completion
- Test undo functionality
- Test running total calculations
- Test round completion
-
Write UI tests for Round List (Phase 2c)
- Test list displays rounds
- Test navigation to details/scoring
- Test empty state
- Test pull-to-refresh
Success Criteria
- ✅ Test coverage matches Android test coverage level
- ✅ All critical paths have automated tests
- ✅ Tests run reliably in CI/CD (if configured)
Implementation Guide
See: iOS Testing Strategy
Timeline Estimates
By Phase
| Phase | Description | Effort | Status |
|---|---|---|---|
| 2a | Round Creation | 8 hours | ✅ Complete (in review) |
| 2b | Round Persistence | 4-6 hours | 📋 Planned |
| 2c | Round History List | 6-8 hours | 📋 Planned |
| 2d | Active Scoring | 12-16 hours | 📋 Planned |
| 2e | Round Details | 10-12 hours | 📋 Planned |
| 2f | UI Testing | 8-10 hours | 📋 Planned |
| Total | 48-60 hours |
Timeline Scenarios
Part-Time Development (10-15 hours/week):
- Optimistic: 3-4 weeks
- Realistic: 4-5 weeks
- Conservative: 5-6 weeks (accounting for blockers and iteration)
Full-Time Development (40 hours/week):
- Optimistic: 1.5 weeks
- Realistic: 2 weeks
- Conservative: 2.5 weeks
Recommended Approach: Incremental PRs for each phase (2b → 2c → 2d → 2e → 2f)
Dependencies & Blockers
Critical Dependencies
-
RoundRepository KMP Migration (Phase 2b)
- Current State: Android-only repository
- Required: Move to shared module for iOS access
- Effort: 4-6 hours
- Can Be Parallel: Yes (Android-focused dev can handle)
-
KMP-NativeCoroutines Configuration
- Current State: Likely already configured from Phase 1
- Required: For Flow-based repository methods
- Blocker: Low risk (should already work)
Nice-to-Have Dependencies
-
Shared Statistics Logic
- Current State: Unknown if exists in shared module
- Impact: Phase 2e implementation effort
- Fallback: Implement statistics in Swift if needed
-
Shared Validation Logic
- Current State: Some exists (ScoringSystem validation)
- Impact: Phase 2d score validation
- Fallback: Minimal Swift validation code
Key Decisions & Recommendations
1. Should RoundRepository migration block PR #284?
Question: Should we merge PR #284 (Round Creation with mock) before migrating RoundRepository?
Options:
- Option A: Merge #284 with mock, then do repository migration in Phase 2b PR
- Option B: Block #284 until RoundRepository is ready
Recommendation: Option A - Merge with mock first
Rationale:
- Incremental delivery is better than big-bang PRs
- Mock is acceptable for MVP validation
- UI can be reviewed independently of persistence
- Reduces risk of merge conflicts
- Allows Phase 2b to focus solely on repository integration
Decision: Merge PR #284, tackle persistence in Phase 2b
2. What’s the priority order for Phase 2b-2f?
Question: Should phases be implemented sequentially or can some be parallelized?
Recommendation: Sequential: 2b → 2c → 2d → 2e → 2f
Rationale:
- 2b must be first (all others need real data persistence)
- 2c builds on 2b (list needs persisted rounds)
- 2d builds on 2c (scoring needs round selection from list)
- 2e builds on 2d (details need completed rounds)
- 2f can be parallel (testing can start once features are stable)
Alternative: 2f (testing) can begin in parallel with 2d/2e implementation
3. Should iOS testing be required before Phase 2 is “done”?
Question: Is Phase 2f mandatory or nice-to-have?
Recommendation: Yes, add basic XCUITest coverage
Rationale:
- Quality bar should match Android
- Automated tests prevent regressions
- iOS UI tests are straightforward with XCTest
- Establishes testing pattern for future phases
Minimum Coverage:
- Round creation (Quick Start + manual entry)
- Score entry workflow
- Round list display
Decision: Phase 2f is required for Phase 2 completion
4. How long will full Phase 2 iOS implementation take?
Question: What’s a realistic timeline?
Estimate: 48-60 hours total
- 2a: 8 hours ✅ (complete)
- 2b-2f: 40-52 hours (remaining)
Timeline:
- Part-time (10-15 hrs/week): 4-5 weeks
- Full-time (40 hrs/week): 1.5-2 weeks
Recommendation: Plan for 4-5 weeks with incremental PRs
5. Are there any KMP migrations needed?
Question: What shared code needs to be migrated/exposed?
Required:
- ✅ RoundRepository - Must move to shared module (Phase 2b blocker)
Already Available:
- ✅ Round entity (shared/database)
- ✅ ScoringSystem, Distance, TargetSize enums (shared/presentation)
- ✅ KMP-NativeCoroutines (Phase 1)
Unknown:
- ❓ Statistics calculation logic (may need investigation for Phase 2e)
Recommendation: Tackle RoundRepository in Phase 2b, investigate statistics during Phase 2e planning
Success Criteria
Phase 2 is complete when:
- ✅ Users can create rounds via iOS app
- ✅ Rounds persist to database
- ✅ Round list displays all created rounds
- ✅ Users can score arrows during a round
- ✅ Completed rounds show detailed statistics
- ✅ Basic UI test coverage exists
- ✅ iOS functionality matches Android parity for round scoring
Related Documentation
Implementation Guides
- Round Persistence Implementation Guide
- Round List Implementation Guide
- Active Scoring Implementation Guide
- Round Details Implementation Guide
- iOS Testing Strategy
iOS Phase Documentation
GitHub References
Next Steps
Immediate (This Week)
- Review and merge PR #284 (Round Creation)
- Begin Phase 2b planning (RoundRepository migration)
- Create Phase 2b implementation PR
Short-Term (Next 2 Weeks)
- Complete Phase 2b (Round Persistence)
- Complete Phase 2c (Round List)
- Begin Phase 2d (Active Scoring)
Medium-Term (Next 3-5 Weeks)
- Complete Phase 2d (Active Scoring)
- Complete Phase 2e (Round Details)
- Complete Phase 2f (UI Testing)
- Mark Phase 2 as complete
Last Updated: 2025-11-21 Status: Phase 2a complete, 2b-2f planned Estimated Completion: 4-5 weeks (part-time)