fix: codebase audit fixes — safety, accessibility, and production hygiene
Address 16 issues from external audit: - Move StoreKit transaction listener ownership to StoreManager singleton with proper deinit - Remove noisy VoiceOver announcements, add missing accessibility on StatPill and BootstrapLoadingView - Replace String @retroactive Identifiable with IdentifiableShareCode wrapper - Add crash guard in AchievementEngine getContributingVisitIds + cache stadium lookups - Pre-compute GamesHistoryViewModel filtered properties to avoid redundant SwiftUI recomputation - Remove force-unwraps in ProgressMapView with safe guard-let fallback - Add diff-based update gating in ItineraryTableViewWrapper to prevent unnecessary reloads - Replace deprecated UIScreen.main with UIWindowScene lookup - Add deinit task cancellation in ScheduleViewModel and SuggestedTripsGenerator - Wrap ~234 unguarded print() calls across 27 files in #if DEBUG Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,7 @@ enum ScenarioPlannerFactory {
|
||||
/// - Both start and end locations → ScenarioCPlanner
|
||||
/// - Otherwise → ScenarioAPlanner
|
||||
static func planner(for request: PlanningRequest) -> ScenarioPlanner {
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: Selecting planner...")
|
||||
print(" - planningMode: \(request.preferences.planningMode)")
|
||||
print(" - selectedTeamIds.count: \(request.preferences.selectedTeamIds.count)")
|
||||
@@ -50,11 +51,14 @@ enum ScenarioPlannerFactory {
|
||||
print(" - selectedGames.count: \(request.selectedGames.count)")
|
||||
print(" - startLocation: \(request.startLocation?.name ?? "nil")")
|
||||
print(" - endLocation: \(request.endLocation?.name ?? "nil")")
|
||||
#endif
|
||||
|
||||
// Scenario E: Team-First mode - user selects teams, finds optimal trip windows
|
||||
if request.preferences.planningMode == .teamFirst &&
|
||||
request.preferences.selectedTeamIds.count >= 2 {
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioEPlanner (team-first)")
|
||||
#endif
|
||||
return ScenarioEPlanner()
|
||||
}
|
||||
|
||||
@@ -62,30 +66,40 @@ enum ScenarioPlannerFactory {
|
||||
if request.preferences.planningMode == .teamFirst &&
|
||||
request.preferences.selectedTeamIds.count == 1 {
|
||||
// Single team in teamFirst mode → treat as follow-team
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioDPlanner (team-first single team)")
|
||||
#endif
|
||||
return ScenarioDPlanner()
|
||||
}
|
||||
|
||||
// Scenario D: User wants to follow a specific team
|
||||
if request.preferences.followTeamId != nil {
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioDPlanner (follow team)")
|
||||
#endif
|
||||
return ScenarioDPlanner()
|
||||
}
|
||||
|
||||
// Scenario B: User selected specific games
|
||||
if !request.selectedGames.isEmpty {
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioBPlanner (selected games)")
|
||||
#endif
|
||||
return ScenarioBPlanner()
|
||||
}
|
||||
|
||||
// Scenario C: User specified start and end locations
|
||||
if request.startLocation != nil && request.endLocation != nil {
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioCPlanner (start/end locations)")
|
||||
#endif
|
||||
return ScenarioCPlanner()
|
||||
}
|
||||
|
||||
// Scenario A: Date range only (default)
|
||||
#if DEBUG
|
||||
print("🔍 ScenarioPlannerFactory: → ScenarioAPlanner (default/date range)")
|
||||
#endif
|
||||
return ScenarioAPlanner()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user