Skip to content

Notifications chiclet (persisted + synced) + archive-on-import - #52

Merged
mayeack merged 1 commit into
mainfrom
claude/notifications-v2
Jun 4, 2026
Merged

mayeack merged 1 commit into
mainfrom
claude/notifications-v2

Conversation

@mayeack

@mayeack mayeack commented Jun 4, 2026

Copy link
Copy Markdown
Owner

The final two requested features (B3 + B4). Rebuilt cleanly on `main` (supersedes #50, which was orphaned when the stacked base branch was deleted on #48's merge). #48 and #51 are already merged.

New synced model: `AppNotification`

`id, kind, title, message, contactId, isRead, isDismissed` + standard sync/provenance. Wired like the other synced models: client + server schema, `ModelSyncApply`, `LocalServerSyncService` push/pull/flip, `BackupServer` push/pull/deletes.

Data safety: additive schema — no `currentSchemaVersion` bump (that path wipes the store). `AppNotification` has no relationship to `Contact` (scalar `contactId`), so SwiftData migrates additively; existing data is preserved.

Generation (`NotificationService`, deduped, idempotent)

  • Fading: contacts with 0 < score < fading threshold (mirrors the Dashboard rule so the ~1000 score-0 contacts don't flood it; capped 10/run), generated each sync pull after the score recalc.
  • Archive (B4): `ContactSyncService.mergeOrInsert`, full Import All only — flags contacts whose `cnContactIdentifier` left the live address book.

UI

Bell chiclet + count badge in the Overview toolbar → sheet listing non-dismissed notifications newest-first: tap / swipe-leading open, swipe-trailing dismiss, archive rows get inline Archive. `DashboardView` keeps its no-`@Query` crash-safe fetch.

Tests

`NotificationsTests` (generation scope/idempotency, archive dedup, sync round-trip + conflict). Full macOS suite green: 232 tests. macOS app + BlackbookServer build clean.

⚠️ After merge

Rebuild + reinstall `/Applications/BlackbookServer.app` (Release) so the server relays `appNotifications` (not on TestFlight; additive migration runs on first launch).

🤖 Generated with Claude Code

…tions

Implements the Overview Notifications chiclet (B3) and import archive suggestions (B4).
(Rebuilt cleanly on main after the stacked base branch was deleted; supersedes #50.)

New synced model AppNotification (id, kind, title, message, contactId, isRead,
isDismissed + sync/provenance). Additive migration — no schema-version bump (which
would wipe the store); AppNotification has no Contact relationship (scalar contactId),
so SwiftData migrates additively and existing data is preserved. Wired end-to-end like
the other synced models: ModelSyncApply (toDict/applyRemote), client LocalServerSyncService
push/pull/flip, server BackupServer pull/push/applySyncDeletes, both schemas + TestHelpers.

Generation (NotificationService, deduped one-per-contact-per-kind, idempotent):
- Fading: contacts with 0 < score < fading threshold (mirrors the Dashboard fading
  definition; capped 10/run), generated each sync pull after the score recalc.
- Archive (B4): ContactSyncService.mergeOrInsert, full Import All only, flags active
  contacts whose cnContactIdentifier left the live address-book set.

UI: bell chiclet + count badge in the Overview toolbar -> sheet NotificationsView
(swipe-leading open / trailing dismiss / inline Archive). DashboardView keeps its
manual-fetch (no @query) crash-safe pattern.

Tests: NotificationsTests (generation, dedup, sync round-trip + conflict). Full macOS
suite green (232 tests). macOS app + BlackbookServer build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mayeack
mayeack merged commit c911bf4 into main Jun 4, 2026
2 checks passed
@mayeack
mayeack deleted the claude/notifications-v2 branch June 4, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant