import CodexBarCore import Foundation enum ProviderStatusIndicator: String { case none case minor case major case critical case maintenance case unknown var hasIssue: Bool { switch self { case .none: false default: true } } var label: String { switch self { case .none: "Operational" case .minor: "Partial outage" case .major: "Major outage" case .critical: "Critical issue" case .maintenance: "Maintenance" case .unknown: "Status unknown" } } } struct ProviderStatus { let indicator: ProviderStatusIndicator let description: String? let updatedAt: Date? } /// Tracks consecutive failures so we can ignore a single flake when we previously had fresh data. struct ConsecutiveFailureGate { private(set) var streak: Int = 0 mutating func recordSuccess() { self.streak = 0 } mutating func reset() { self.streak = 0 } /// Returns true when the caller should surface the error to the UI. mutating func shouldSurfaceError(onFailureWithPriorData hadPriorData: Bool) -> Bool { self.streak += 1 if hadPriorData, self.streak == 1 { return false } return true } } #if DEBUG extension UsageStore { func _setSnapshotForTesting(_ snapshot: UsageSnapshot?, provider: UsageProvider) { self.snapshots[provider] = snapshot?.scoped(to: provider) } func _setTokenSnapshotForTesting(_ snapshot: CostUsageTokenSnapshot?, provider: UsageProvider) { self.tokenSnapshots[provider] = snapshot } func _setTokenErrorForTesting(_ error: String?, provider: UsageProvider) { self.tokenErrors[provider] = error } func _setErrorForTesting(_ error: String?, provider: UsageProvider) { self.errors[provider] = error } func _setCodexHistoricalDatasetForTesting(_ dataset: CodexHistoricalDataset?, accountKey: String? = nil) { self.codexHistoricalDataset = dataset self.codexHistoricalDatasetAccountKey = accountKey self.historicalPaceRevision += 1 } } #endif