From 2f72d3d0736a6fac306d4e5d9406cb33b08bc2a0 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Fri, 17 Jul 2026 16:41:52 -0500 Subject: Add persistence, multi-repo watch list, and background polling Closes #1-#5 (milestones 0.2.0, 0.3.0). - Flat JSON persistence (PersistedState/PersistenceStore) in Application Support, chosen over SwiftData since the dataset is small and the existing model types are plain Codable value types passed across actor boundaries. - Repo watch list, per-event seen-state, and last-fetch timestamps are now persisted instead of living only in memory. - Configurable minimum severity filter, applied from a cached raw fetch so changing it doesn't require a network round-trip. - Multi-repo support: SecurityEventStore now loops over a persisted watch list instead of one hardcoded repo, with an in-popover UI (gear button) to add/remove repos. - Background polling every 15 minutes, layered on top of the existing refresh-on-open and manual refresh, so the feed stays fresh even while the popover is closed. --- octosentry/PersistedState.swift | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 octosentry/PersistedState.swift (limited to 'octosentry/PersistedState.swift') diff --git a/octosentry/PersistedState.swift b/octosentry/PersistedState.swift new file mode 100644 index 0000000..3ef4234 --- /dev/null +++ b/octosentry/PersistedState.swift @@ -0,0 +1,26 @@ +// +// PersistedState.swift +// octosentry +// +// Everything the app remembers across launches: the repo watch list, +// local-only seen-state per event, last-fetch timestamp per repo, and the +// minimum severity filter. Flat JSON over SwiftData (see #1) — small, +// inspectable, and these are already plain Codable values passed across +// actor boundaries, not reference types tied to a persistence context. +// + +import Foundation + +nonisolated struct PersistedState: Codable { + var watchedRepos: [String] + var seenEventIDs: Set + var lastFetchByRepo: [String: Date] + var minimumSeverity: SecurityEventSeverity + + static let placeholder = PersistedState( + watchedRepos: ["ccleberg/cleberg.net"], + seenEventIDs: [], + lastFetchByRepo: [:], + minimumSeverity: .low + ) +} -- cgit v1.2.3