summaryrefslogtreecommitdiff
path: root/DomainReportExporter.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-24 12:38:38 -0500
committerChristian Cleberg <[email protected]>2026-04-24 12:38:38 -0500
commitd0b3b7a15b59266b4ae4262fdb0364245092c17c (patch)
tree5adb0df9963caf78aa98fa17adfb2c175291ded9 /DomainReportExporter.swift
parentb35f1b432fc24fbab1fa05593c9a0bca7e4d95a6 (diff)
downloaddomain-dig-d0b3b7a15b59266b4ae4262fdb0364245092c17c.tar.gz
domain-dig-d0b3b7a15b59266b4ae4262fdb0364245092c17c.tar.bz2
domain-dig-d0b3b7a15b59266b4ae4262fdb0364245092c17c.zip
feat(v3.7.0): add timeline and advanced diffing system
- introduce TimelineView for historical snapshots - allow comparison between any two snapshots - implement DiffService for structured domain diffs - improve diff visualization with clear change indicators - add navigation across changes - optimize history loading for performance - extend CLI and export to support timeline data
Diffstat (limited to 'DomainReportExporter.swift')
-rw-r--r--DomainReportExporter.swift56
1 files changed, 56 insertions, 0 deletions
diff --git a/DomainReportExporter.swift b/DomainReportExporter.swift
index 4fa7470..55b7372 100644
--- a/DomainReportExporter.swift
+++ b/DomainReportExporter.swift
@@ -504,6 +504,62 @@ enum DomainReportExporter {
.joined(separator: "\n")
}
+ static func timelineText(for reports: [DomainReport], domain: String, includeDiffSummary: Bool) -> String {
+ guard !reports.isEmpty else {
+ return "Timeline Export\nNo snapshots available for \(domain)."
+ }
+
+ var lines = [
+ "DomainDig Timeline Export",
+ "Domain: \(domain)",
+ "Snapshots: \(reports.count)"
+ ]
+
+ for report in reports.sorted(by: { $0.timestamp > $1.timestamp }) {
+ lines.append("")
+ lines.append("\(textDateFormatter.string(from: report.timestamp))")
+ lines.append("Summary: \(report.changeSummary?.message ?? "No change summary")")
+ lines.append("Severity: \(report.changeSummary?.severity.title ?? "N/A")")
+ if includeDiffSummary, let changeSummary = report.changeSummary {
+ lines.append("Changed Sections: \(changeSummary.changedSections.joined(separator: ", ").nilIfEmpty ?? "None")")
+ }
+ }
+
+ return lines.joined(separator: "\n")
+ }
+
+ static func timelineData(for reports: [DomainReport], domain: String, includeDiffSummary: Bool) throws -> Data {
+ struct TimelineExportEntry: Codable {
+ let timestamp: Date
+ let summary: String?
+ let severity: String?
+ let changedSections: [String]?
+ }
+
+ struct TimelineExportPayload: Codable {
+ let domain: String
+ let exportedAt: Date
+ let snapshots: [TimelineExportEntry]
+ }
+
+ let payload = TimelineExportPayload(
+ domain: domain,
+ exportedAt: Date(),
+ snapshots: reports
+ .sorted(by: { $0.timestamp > $1.timestamp })
+ .map { report in
+ TimelineExportEntry(
+ timestamp: report.timestamp,
+ summary: report.changeSummary?.message,
+ severity: report.changeSummary?.severity.title,
+ changedSections: includeDiffSummary ? report.changeSummary?.changedSections : nil
+ )
+ }
+ )
+
+ return try jsonEncoder.encode(payload)
+ }
+
private static func appendSection(_ title: String, to lines: inout [String], body: () -> [String]) {
lines.append("")
lines.append(title)