12 tasks with TDD workflow:
- Domain, CloudKit, and SwiftData models
- PollService for CloudKit operations
- Creation and detail ViewModels
- SwiftUI views with vote ranking
- Deep link handling
Design for CloudKit-based group coordination feature:
- Ranked choice voting on trip options
- Share via link with 6-char codes
- Anonymous results (aggregate only)
- Real-time updates via CloudKit subscriptions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Design covers three improvements:
- Paginated CloudKit fetches to handle >400 records
- Graceful cancellation with per-entity progress saving
- NWPathMonitor for auto-sync on network restoration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CKSport model to parse CloudKit Sport records
- Add fetchSportsForSync() to CloudKitService for delta fetching
- Add syncSports() and mergeSport() to CanonicalSyncService
- Update DataProvider with dynamicSports support and allSports computed property
- Update MockAppDataProvider with matching dynamic sports support
- Add comprehensive documentation for adding new sports
The app can now sync sport definitions from CloudKit, enabling new sports
to be added without app updates. Sports are fetched, merged into SwiftData,
and exposed via AppDataProvider.allSports alongside built-in Sport enum cases.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Freemium model with StoreKit 2 local-only entitlement checking.
Pro features: unlimited trips, PDF export, progress tracking.
Monthly ($4.99) and annual ($49.99) pricing with Family Sharing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
13 tasks covering LoadingSpinner, LoadingPlaceholder, LoadingSheet
creation, ProgressView replacements, and deprecated component removal.
Includes TDD with 13 new tests.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Complete design spec for overhauling all loading views, progress
indicators, and spinners. Covers LoadingSpinner, LoadingPlaceholder,
and LoadingSheet components with Apple-style minimal aesthetic.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hybrid approach: keep Sport enum for existing 7 sports,
add DynamicSport struct for CloudKit-defined leagues.
Unified via AnySport protocol for seamless UI integration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Covers performance (launch freeze, list lag), UI polish (animations,
missing location info, timezone display), and scraper alias fix.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
16-task TDD implementation plan for:
- CloudKit delta sync using modificationDate
- Remove 90-day game browsing limit
- Rename fetch* to filter* for clarity
- Add allGames/allRichGames methods
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Addresses issue where Houston Astros only shows 7 games in "By Games" mode.
Documents plan to remove arbitrary date restrictions and implement proper
delta sync using CloudKit modificationDate.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Design to eliminate UUID layer and use canonical IDs as the single
stadium/team/game identifier throughout the client. Key changes:
- Domain models use String IDs (canonical IDs)
- Remove UUID mapping dictionaries from DataProvider
- Simplify AchievementEngine (delete resolution helper)
- StadiumVisit uses single stadiumId field
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Green Monster (Fenway) and Ivy League (Wrigley) achievements
weren't working because:
1. Symbolic IDs use lowercase sport (stadium_mlb_bos)
2. Sport enum uses uppercase raw values (MLB)
3. Visits store stadium UUIDs, not symbolic IDs
Added resolveSymbolicStadiumId() helper that:
- Uppercases the sport string before Sport(rawValue:)
- Looks up team by abbreviation and sport
- Returns the team's stadiumId as UUID string
Also fixed:
- getStadiumIdsForLeague returns UUID strings (not symbolic IDs)
- AchievementProgress.isEarned computed from progress OR stored record
- getStadiumIdsForDivision queries CanonicalTeam properly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Covers:
- Planning mode bugs (follow team location, must-stop filtering, date range)
- UI improvements (sort options, map locking, today highlight)
- Coast-to-coast filter to show top 2 by stops
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Plain English privacy policy and ToS for freemium iOS app.
Key decisions: 13+ age requirement, no accounts, CloudKit
analytics, Texas jurisdiction.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace all custom font sizes with Apple's built-in text styles
for accessibility compliance. Remove Theme.FontSize enum entirely.
Export files keep fixed sizes for consistent PDF output.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New 4th planning mode for fans to build trips around their team's
schedule (home + away games). Includes region/date filtering,
flexible start/end location, and repeat city handling.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
String Catalogs + AI translation pipeline for 5 languages:
Spanish, French, German, Japanese, Chinese (Simplified)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove CBB (~5,000+ games per season) to reduce complexity.
Changes:
- Remove .cbb enum case from Sport
- Remove CBB theme color (cbbMint)
- Update documentation to reflect 7 supported leagues
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement comprehensive test infrastructure and all 124 tests across 11 phases:
- Phase 0: Test infrastructure (fixtures, mocks, helpers)
- Phases 1-10: Core planning engine tests (previously implemented)
- Phase 11: Edge case omnibus (11 new tests)
- Data edge cases: nil stadiums, malformed dates, invalid coordinates
- Boundary conditions: driving limits, radius boundaries
- Time zone cases: cross-timezone games, DST transitions
Reorganize test structure under Planning/ directory with proper organization.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace monolithic scraping scripts with sportstime_parser package:
- Multi-source scrapers with automatic fallback for 7 sports
- Canonical ID generation for games, teams, and stadiums
- Fuzzy matching with configurable thresholds for name resolution
- CloudKit Web Services uploader with JWT auth, diff-based updates
- Resumable uploads with checkpoint state persistence
- Validation reports with manual review items and suggested matches
- Comprehensive test suite (249 tests)
CLI: sportstime-parser scrape|validate|upload|status|retry|clear
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Stadium Progress & Achievements:
- Add StadiumVisit and Achievement SwiftData models
- Create Progress tab with interactive map view
- Implement photo-based visit import with GPS/date matching
- Add achievement badges (count-based, regional, journey)
- Create shareable progress cards for social media
- Add canonical data infrastructure (stadium identities, team aliases)
- Implement score resolution from free APIs (MLB, NBA, NHL stats)
UI Improvements:
- Add ThemedSpinner and ThemedSpinnerCompact components
- Replace all ProgressView() with themed spinners throughout app
- Fix sport selection state not persisting when navigating away
Bug Fixes:
- Fix Coast to Coast trips showing only 1 city (validation issue)
- Fix stadium progress showing 0/0 (filtering issue)
- Remove "Stadium Quest" title from progress view
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Competitive analysis and feature recommendations for sports road trip planning,
including stadium bucket list tracking, AI planning, and group coordination.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>