diff options
| author | Christian Cleberg <[email protected]> | 2026-07-24 23:45:56 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-25 00:00:29 -0500 |
| commit | e597cdf5b7084634e300af39b622c8552c9cc5e8 (patch) | |
| tree | 9c02254bbd50bf0772076857be69f50254dfe7b3 /DomainDig/DomainViewModel.swift | |
| parent | 99e4623af1b08f36120a01b67cbe60df99668651 (diff) | |
| download | domain-dig-e597cdf5b7084634e300af39b622c8552c9cc5e8.tar.gz domain-dig-e597cdf5b7084634e300af39b622c8552c9cc5e8.tar.bz2 domain-dig-e597cdf5b7084634e300af39b622c8552c9cc5e8.zip | |
refactor: extract audit surface into DomainViewModel+Audit (v5 step 4, 1/n)
First slice of the v5.0.0 god-file decomposition. DomainViewModel.swift is a
single ~4.9k-line class body; this begins splitting it into focused
`DomainViewModel+<Concern>.swift` extensions, one cohesive concern at a time,
with each move behavior-preserving and verified by build + the test net.
- Moves the audit read/CRUD/export surface (audits/auditSession/auditTimeline,
updateAuditStatus/Notes, toggleAuditChecklistItem, add/update/remove
AuditFinding, exportAuditData) into DomainViewModel+Audit.swift as an
extension. Pure move — no logic changes.
- `startAudit(for:)` intentionally stays on the main type: it drives a live
inspection to seed the session, so it belongs with the inspection pipeline
until that is extracted. `persistAuditSessions()` is promoted from private to
internal so both files can call it (its only cross-file dependency).
No project.pbxproj change is needed — DomainDig/ is a file-system-synchronized
group, so the new file is picked up automatically.
DomainViewModel.swift: 4864 -> 4761 lines. App builds clean; unit suite 58/58.
Diffstat (limited to 'DomainDig/DomainViewModel.swift')
| -rw-r--r-- | DomainDig/DomainViewModel.swift | 105 |
1 files changed, 1 insertions, 104 deletions
diff --git a/DomainDig/DomainViewModel.swift b/DomainDig/DomainViewModel.swift index b5f51c3..fdf6b84 100644 --- a/DomainDig/DomainViewModel.swift +++ b/DomainDig/DomainViewModel.swift @@ -1546,40 +1546,6 @@ final class DomainViewModel { return try? DomainReportExporter.data(for: currentReport, format: format) } - func audits(for domain: String) -> [AuditSession] { - auditSessions - .filter { $0.domain.caseInsensitiveCompare(domain) == .orderedSame } - .sorted { $0.createdAt > $1.createdAt } - } - - func auditSession(withID id: UUID) -> AuditSession? { - auditSessions.first(where: { $0.id == id }) - } - - func auditTimeline(for domain: String) -> [AuditTimelinePoint] { - let sessions = audits(for: domain).sorted { $0.createdAt > $1.createdAt } - return sessions.map { session in - let repeatedIssues = sessions - .filter { $0.id != session.id } - .flatMap(\.findings) - .map { $0.title.lowercased() } - let repeatedIssueCount = session.findings.filter { - repeatedIssues.contains($0.title.lowercased()) - }.count - - return AuditTimelinePoint( - id: session.id, - sessionID: session.id, - domain: session.domain, - createdAt: session.createdAt, - status: session.status, - findingCount: session.findings.count, - openHighSeverityCount: session.findings.filter { $0.severity == .high && $0.status != .resolved }.count, - repeatedIssueCount: repeatedIssueCount - ) - } - } - @discardableResult func startAudit(for domain: String, reviewer: String? = nil) async -> AuditSession? { let normalizedDomain = domain @@ -1625,75 +1591,6 @@ final class DomainViewModel { return session } - func updateAuditStatus(_ status: AuditStatus, sessionID: UUID) { - guard let index = auditSessions.firstIndex(where: { $0.id == sessionID }) else { return } - auditSessions[index].status = status - persistAuditSessions() - } - - func updateAuditNotes(_ notes: String, sessionID: UUID) { - guard let index = auditSessions.firstIndex(where: { $0.id == sessionID }) else { return } - auditSessions[index].notes = notes.trimmingCharacters(in: .whitespacesAndNewlines) - persistAuditSessions() - } - - func toggleAuditChecklistItem(sessionID: UUID, itemID: UUID) { - guard let sessionIndex = auditSessions.firstIndex(where: { $0.id == sessionID }), - let itemIndex = auditSessions[sessionIndex].checklist.firstIndex(where: { $0.id == itemID }) else { - return - } - - auditSessions[sessionIndex].checklist[itemIndex].isComplete.toggle() - auditSessions[sessionIndex].checklist[itemIndex].completedAt = auditSessions[sessionIndex].checklist[itemIndex].isComplete ? Date() : nil - persistAuditSessions() - } - - func addAuditFinding( - sessionID: UUID, - title: String, - severity: AuditFindingSeverity, - summary: String, - evidenceReferences: [String], - notes: String, - checklistAreas: [AuditChecklistArea] - ) { - guard let index = auditSessions.firstIndex(where: { $0.id == sessionID }) else { return } - let finding = AuditFinding( - title: title, - severity: severity, - summary: summary, - evidenceReferences: evidenceReferences, - notes: notes, - status: .open, - checklistAreas: checklistAreas - ) - auditSessions[index].findings.insert(finding, at: 0) - persistAuditSessions() - } - - func updateAuditFinding(_ finding: AuditFinding, sessionID: UUID) { - guard let sessionIndex = auditSessions.firstIndex(where: { $0.id == sessionID }), - let findingIndex = auditSessions[sessionIndex].findings.firstIndex(where: { $0.id == finding.id }) else { - return - } - - var updatedFinding = finding - updatedFinding.updatedAt = Date() - auditSessions[sessionIndex].findings[findingIndex] = updatedFinding - persistAuditSessions() - } - - func removeAuditFindings(at offsets: IndexSet, sessionID: UUID) { - guard let sessionIndex = auditSessions.firstIndex(where: { $0.id == sessionID }) else { return } - auditSessions[sessionIndex].findings.remove(atOffsets: offsets) - persistAuditSessions() - } - - func exportAuditData(sessionID: UUID, format: AuditExportFormat) -> Data? { - guard let session = auditSession(withID: sessionID) else { return nil } - return try? AuditExporter.data(for: session, format: format) - } - func loadOwnershipHistory() async { guard !searchedDomain.isEmpty else { return } guard DataAccessService.hasAccess(to: .ownershipHistory) else { @@ -2605,7 +2502,7 @@ final class DomainViewModel { DomainDebugLog.signpostEnd("DomainViewModel.persistHistory", start: persistStartedAt, extra: "count=\(history.count)") } - private func persistAuditSessions() { + func persistAuditSessions() { DomainDataPortabilityService.saveAuditSessions(auditSessions) refreshDataLifecycleSummary() } |
