diff options
| author | Christian Cleberg <[email protected]> | 2026-04-25 00:03:59 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-25 00:03:59 -0500 |
| commit | fd34553ab0e63b4d3bc22532b61f4fef32846f34 (patch) | |
| tree | 1317656b64970b113e195dcb29d71e443eb4354d /DomainDig/Models.swift | |
| parent | 3f0b7746b1bee4c2f626eb805e3fd13c5f2f5d22 (diff) | |
| download | domain-dig-fd34553ab0e63b4d3bc22532b61f4fef32846f34.tar.gz domain-dig-fd34553ab0e63b4d3bc22532b61f4fef32846f34.tar.bz2 domain-dig-fd34553ab0e63b4d3bc22532b61f4fef32846f34.zip | |
DomainDig v3.9.0 — Portfolio Dashboard
* Portfolio summary cards
* Recent activity feed across tracked domains
* Attention-required queue prioritized by severity
* Certificate expiry visibility and expiring-soon section
* Quick portfolio filters for triage
* Deterministic per-domain health scoring
* Local portfolio search
* Apex-domain grouping for tracked assets
Diffstat (limited to 'DomainDig/Models.swift')
| -rw-r--r-- | DomainDig/Models.swift | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/DomainDig/Models.swift b/DomainDig/Models.swift index f872aab..54bea10 100644 --- a/DomainDig/Models.swift +++ b/DomainDig/Models.swift @@ -176,6 +176,26 @@ enum CertificateWarningLevel: String, Codable { } } +enum DomainHealth: String, Codable, Sendable, CaseIterable { + case healthy + case warning + case critical + + var title: String { + rawValue.capitalized + } +} + +struct PortfolioSnapshot: Codable, Sendable { + var totalDomains: Int + var healthyCount: Int + var warningCount: Int + var criticalCount: Int + var changedLast24h: Int + var expiringSoonCount: Int + var unreachableCount: Int +} + struct DomainChangeSummary: Codable, Equatable { let hasChanges: Bool let changedSections: [String] @@ -656,6 +676,80 @@ enum WatchlistSortOption: String, CaseIterable, Identifiable { } } +enum PortfolioFilterOption: String, CaseIterable, Identifiable { + case all + case healthy + case warning + case critical + case changed + case expiring + case unreachable + + var id: String { rawValue } + + var title: String { + switch self { + case .all: + return "All" + case .healthy: + return "Healthy" + case .warning: + return "Warning" + case .critical: + return "Critical" + case .changed: + return "Changed" + case .expiring: + return "Expiring" + case .unreachable: + return "Unreachable" + } + } +} + +extension DomainHealth { + static func classify( + certificateExpiryState: CertificateWarningLevel, + isReachable: Bool, + recentMonitoringFailureCount: Int, + hasRecentDNSChange: Bool, + instabilityScore: Int, + hasRecentCriticalChange: Bool, + hasInvalidTLS: Bool + ) -> DomainHealth { + if !isReachable + || hasInvalidTLS + || certificateExpiryState == .critical + || recentMonitoringFailureCount >= 2 + || instabilityScore >= 70 + || hasRecentCriticalChange { + return .critical + } + + if certificateExpiryState == .warning + || recentMonitoringFailureCount == 1 + || hasRecentDNSChange + || instabilityScore >= 35 { + return .warning + } + + return .healthy + } + + static func instabilityScore( + recentChangeCount: Int, + recentFailureCount: Int, + pendingAlertCount: Int, + hasRecentDNSChange: Bool + ) -> Int { + let rawScore = (recentChangeCount * 12) + + (recentFailureCount * 24) + + (pendingAlertCount * 8) + + (hasRecentDNSChange ? 14 : 0) + return min(rawScore, 100) + } +} + enum PremiumCapability: String, Codable { case unlimitedTrackedDomains case automatedMonitoring |
