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:
@@ -83,7 +83,9 @@ enum ItineraryReorderingLogic {
|
||||
// nil is valid during initial display before travel is persisted.
|
||||
let lookedUp = findTravelSortOrder(segment)
|
||||
sortOrder = lookedUp ?? defaultTravelSortOrder
|
||||
#if DEBUG
|
||||
print("📋 [flattenDays] Travel \(segment.fromLocation.name)->\(segment.toLocation.name) on day \(day.dayNumber): lookedUp=\(String(describing: lookedUp)), using sortOrder=\(sortOrder)")
|
||||
#endif
|
||||
|
||||
case .games, .dayHeader:
|
||||
// These item types are not movable and handled separately.
|
||||
@@ -319,6 +321,7 @@ enum ItineraryReorderingLogic {
|
||||
}
|
||||
|
||||
// DEBUG: Log the row positions
|
||||
#if DEBUG
|
||||
print("🔢 [calculateSortOrder] row=\(row), day=\(day), gamesRow=\(String(describing: gamesRow))")
|
||||
print("🔢 [calculateSortOrder] items around row:")
|
||||
for i in max(0, row - 2)...min(items.count - 1, row + 2) {
|
||||
@@ -326,6 +329,7 @@ enum ItineraryReorderingLogic {
|
||||
let gMarker = (gamesRow == i) ? " [GAMES]" : ""
|
||||
print("🔢 \(marker) [\(i)] \(items[i])\(gMarker)")
|
||||
}
|
||||
#endif
|
||||
|
||||
// Strict region classification:
|
||||
// - row < gamesRow => before-games (negative sortOrder)
|
||||
@@ -333,10 +337,14 @@ enum ItineraryReorderingLogic {
|
||||
let isBeforeGames: Bool
|
||||
if let gr = gamesRow {
|
||||
isBeforeGames = row < gr
|
||||
#if DEBUG
|
||||
print("🔢 [calculateSortOrder] row(\(row)) < gamesRow(\(gr)) = \(isBeforeGames) → isBeforeGames=\(isBeforeGames)")
|
||||
#endif
|
||||
} else {
|
||||
isBeforeGames = false // No games means everything is "after games"
|
||||
#if DEBUG
|
||||
print("🔢 [calculateSortOrder] No games on day \(day) → isBeforeGames=false")
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get sortOrder from a movable item (custom item or travel)
|
||||
@@ -442,7 +450,9 @@ enum ItineraryReorderingLogic {
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
print("🔢 [calculateSortOrder] RESULT: \(result) (isBeforeGames=\(isBeforeGames))")
|
||||
#endif
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user