summaryrefslogtreecommitdiff
path: root/DomainDig/DiffService.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-17 10:25:53 -0500
committerChristian Cleberg <[email protected]>2026-07-17 10:57:30 -0500
commitd62480233819184db2e55741b05375818ebf3881 (patch)
treebc35d414be25c2ababe4c803f88eaaaba6fa46f7 /DomainDig/DiffService.swift
parent6f79345f8dc078b65d976079332cab3ddf7ec98b (diff)
downloaddomain-dig-d62480233819184db2e55741b05375818ebf3881.tar.gz
domain-dig-d62480233819184db2e55741b05375818ebf3881.tar.bz2
domain-dig-d62480233819184db2e55741b05375818ebf3881.zip
v4.7.0: Add domain-vs-domain comparison
- DiffService.compare(domainA:domainB:) reuses the existing section-diff builders to compare two distinct domains' latest reports, returning a new DomainComparisonResult (parallel to the time-based DomainDiff). - DomainCompareView: pick two tracked domains and render the comparison with the existing DomainDiffView section renderer. - Entry point: "Compare Domains" in the Watchlist toolbar menu, shown once at least two domains are tracked.
Diffstat (limited to 'DomainDig/DiffService.swift')
-rw-r--r--DomainDig/DiffService.swift51
1 files changed, 51 insertions, 0 deletions
diff --git a/DomainDig/DiffService.swift b/DomainDig/DiffService.swift
index 211a16e..cf25b6f 100644
--- a/DomainDig/DiffService.swift
+++ b/DomainDig/DiffService.swift
@@ -105,6 +105,32 @@ struct DomainDiff: Identifiable, Equatable, Codable {
typealias DomainDiffItem = DiffItem
typealias DomainDiffSection = DiffSection
+/// Result of comparing two distinct domains' latest reports side by side, as
+/// opposed to `DomainDiff`, which compares the same domain across time.
+struct DomainComparisonResult: Identifiable, Equatable {
+ let domainA: String
+ let domainB: String
+ let generatedAt: Date
+ let sections: [DiffSection]
+ let contextNote: String?
+
+ var id: String {
+ "\(domainA)-\(domainB)-\(generatedAt.timeIntervalSince1970)"
+ }
+
+ var changedSections: [DiffSection] {
+ sections.filter(\.hasChanges)
+ }
+
+ var changeCount: Int {
+ sections.reduce(0) { $0 + $1.changeCount }
+ }
+
+ var severity: ChangeSeverity {
+ sections.map(\.severity).max() ?? .low
+ }
+}
+
enum DiffService {
static func compare(from oldReport: DomainReport, to newReport: DomainReport) -> DomainDiff {
let sections = [
@@ -181,6 +207,31 @@ enum DiffService {
)
}
+ /// Compares two distinct domains' reports section by section. Reuses the same
+ /// field-level diff logic as time-based comparison; the two reports are simply
+ /// unrelated domains rather than the same domain at different times.
+ static func compare(domainA: DomainReport, domainB: DomainReport) -> DomainComparisonResult {
+ let sections = [
+ availabilitySection(from: domainA, to: domainB),
+ ownershipSection(from: domainA, to: domainB),
+ dnsSection(from: domainA, to: domainB),
+ webSection(from: domainA, to: domainB),
+ emailSection(from: domainA, to: domainB),
+ networkSection(from: domainA, to: domainB),
+ subdomainsSection(from: domainA, to: domainB),
+ intelligenceSection(from: domainA, to: domainB),
+ riskSection(from: domainA, to: domainB)
+ ]
+
+ return DomainComparisonResult(
+ domainA: domainA.domain,
+ domainB: domainB.domain,
+ generatedAt: Date(),
+ sections: sections,
+ contextNote: comparisonContextNote(from: domainA, to: domainB)
+ )
+ }
+
static func comparisonContextNote(from oldReport: DomainReport, to newReport: DomainReport) -> String? {
var notes: [String] = []
if oldReport.resolverURLString != newReport.resolverURLString {