Fix 25 audit issues: memory leaks, concurrency, performance, accessibility

Address findings from comprehensive audit across 5 workstreams:

- Memory: Token-based DataController listeners (prevent closure leaks),
  static DateFormatters, ImageCache observer cleanup, MotionManager
  reference counting, FoundationModels dedup guard
- Concurrency: Replace Task.detached with Task in FeelsApp (preserve
  MainActor isolation), wrap WatchConnectivity handler in MainActor
- Performance: Cache sortedGroupedData in DayViewViewModel, cache demo
  data in MonthView/YearView, remove broken ReduceMotionModifier
- Accessibility: VoiceOver support for LockScreen, DemoHeatmapCell
  labels, MonthCard button labels, InsightsView header traits,
  Smart Invert protection on neon headers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-19 09:11:48 -06:00
parent b58dfd5093
commit c22d246865
18 changed files with 175 additions and 73 deletions

View File

@@ -47,6 +47,7 @@ class FoundationModelsInsightService: ObservableObject {
private var cachedInsights: [String: (insights: [Insight], timestamp: Date)] = [:]
private let cacheValidityDuration: TimeInterval = 3600 // 1 hour
private var inProgressPeriods: Set<String> = []
// MARK: - Initialization
@@ -199,6 +200,14 @@ class FoundationModelsInsightService: ObservableObject {
return cached.insights
}
// Prevent duplicate concurrent generation for the same period
guard !inProgressPeriods.contains(periodName) else {
// Already generating for this period, wait for cache
return cachedInsights[periodName]?.insights ?? []
}
inProgressPeriods.insert(periodName)
defer { inProgressPeriods.remove(periodName) }
guard isAvailable else {
throw InsightGenerationError.modelUnavailable(reason: lastError?.localizedDescription ?? "Model not available")
}