feat: add notification persistence architecture and contract tests - #2
Open
johngallagher wants to merge 10 commits into
Open
feat: add notification persistence architecture and contract tests#2johngallagher wants to merge 10 commits into
johngallagher wants to merge 10 commits into
Conversation
- Update notifications_app_architecture.md with persistence requirements * Add Invariants 7-9 for persistence and per-location read status * Add notification-delivery.v1 schema definition * Update component specs for delivery and notification-history services * Add contract and property tests for persistence * Document per-location vs global read status design (Approach A selected) * Update pace layers to include new slow/mid layer concerns * Add provenance record for persistence design decisions - Add PERSISTENCE_ARCHITECTURE.md comprehensive design document * Three implementation approaches with trade-offs analysis * Recommended Approach A: per-location read status * Schema definition and implementation details * New durable evaluations for persistence contracts * Risk mitigation and non-goals * Implementation phases and backward compatibility - Add contract_persistence_test.go durable evaluations * Test delivered notifications persist across browser refresh * Test mark-read removes from unread list * Test per-location read status independence * Test idempotent mark-read operation * Test idempotent record (no duplicates) * Helper functions for persistence API testing Relates to: Notification persistence requirement for multi-session visibility
johngallagher
force-pushed
the
feature/notification-persistence
branch
from
August 5, 2026 23:19
074a5d9 to
8173200
Compare
- Add notification-history navigation link - Add full notification-history component pane with behavioral examples - Add INV-7, INV-8, INV-9 for persistence contracts - Include SQL schema, contract tests, and provenance record - Integrated into existing component documentation structure
- Add Invariants 9-10: mark-read publishes events, read events broadcast to all locations - Define notification-read.v1 event schema (event_id, user_id, notification_id, location, read_at) - Add notifications.read Pub/Sub topic for cross-device event broadcasting - Update notification-history to publish read events via Pub/Sub - Update delivery-service to subscribe to notifications.read and broadcast to SSE clients - Add contract test: TestContract_ReadEventBroadcasts - Document event-driven cross-device synchronization without requiring global read status - Update PERSISTENCE_ARCHITECTURE.md with event publishing contract and client-side handling
- Add Invariant 10: read events broadcast to all locations - Document notification-read event schema - Add cross-device synchronization explanation - Update navigation to reference read events - Explain why per-location storage + event broadcast works
- history pane now properly integrated into navigation system - Added to ORDER array (between delivery and system-properties) - Added to LABELS mapping for breadcrumb navigation
Key fixes: - Updated Approach A description to explain that events broadcast read changes (eliminating 'extra clicks' language that was outdated) - Clarified that storage is per-location but UX is synchronized via events - Fixed INV-8 description to acknowledge Invariant 10 event broadcasting - Updated Approach B disadvantages to note schema complexity vs event sync - Updated provenance record to explain why per-location + events is better than global read status in database - Fixed Phase 3 implementation notes to acknowledge that cross-device sync is already provided by Invariant 10 (read events) - Clarified in PERSISTENCE_ARCHITECTURE.md that Approach A rationale includes real-time UX via events and eventual consistency via per-location storage These changes ensure consistency between: - The new Invariants 9-10 (mark-read + event broadcasting) - The Approach A selection (per-location storage) - The documented user experience (immediate hiding on all connected devices) - The provenance and design rationale
Additional consistency fixes: - Updated PERSISTENCE_ARCHITECTURE.md contract item 5 to explain that: * Storage is per-location (independent read_at per device) * But read events broadcast to connected clients (Invariant 10) * Offline devices see correct state when reconnected - Updated Approach A title to include '+ Event Broadcasting' - Updated Philosophy statement for Approach A to mention real-time broadcast via events - Updated test comments to clarify 'per-location in storage' vs 'events broadcast to connected clients' distinction These changes ensure that nowhere in the documentation does it suggest that marking read on one device leaves other connected devices unaffected. The events (Invariant 10) guarantee real-time synchronization for connected clients, while per-location storage ensures eventual consistency for reconnected devices.
- Add notification-delivery.v1 schema (persistence layer) - Add notification-read.v1 schema (cross-device sync events) - Create unified Pub/Sub topics and events table - Add publishing constraints to clarify ownership - Document semantics for all event types - Update table to show all 5 topics and their message types - Reference Invariant 10 from notification-read event description
- Convert RuleChangedEvent from Go code to JSON schema (rule-changed.v1) - Show enum values: CREATED | UPDATED | DELETED - Document all 5 event schemas in consistent JSON format: * notification.v1 (notifications on all topics) * rule-changed.v1 (rules.changed topic) * notification-delivery.v1 (persistence) * notification-read.v1 (cross-device sync) - Update table header 'Message Type' → 'Message Schema' - Update table reference 'RuleChangedEvent' → 'rule-changed.v1' - Add schema versioning semantics section - Clarify backward compatibility rules for all schemas
Schema heading format is now: schema-name.v1 (Description) Changes: - notification.v1 (Notification Message) - rule.v1 (Rule Schema) [was: Rule schema] - rule-changed.v1 (Rule Lifecycle) - notification-delivery.v1 (Delivery Status & Persistence) - notification-read.v1 (Cross-Device Sync) Also: - Removed duplicate notification-read event documentation from history pane - Kept single authoritative version in contracts pane - Updated history pane to reference contracts section for full schema - Updated navigation label: 'notification-history & read events' → 'notification-history' - Added callout explaining per-location storage + event-driven broadcast pattern
There was a problem hiding this comment.
Gates Passed
6 Quality Gates Passed
See analysis details in CodeScene
Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Add comprehensive architecture for notification persistence across browser refreshes and client disconnections.
Changes
notification-delivery.v1schema (SLOW layer)contract_persistence_test.gowith 5 new contract testsDesign Highlights
✅ Per-location read status (simple schema, matches multi-device workflows)
✅ Idempotent Record and MarkRead operations (safe retries, no duplicates)
✅ No breaking changes to existing APIs (new endpoints are additive)
✅ Forward-compatible with future requirements (global sync optional later)
✅ Fully specified slow/mid layer with durable evaluations
Architecture Files Updated
Next Steps
notification-historyservice (SQLite schema + queries)delivery-serviceto persist notifications and handle mark-readSchema Preview
Related Issue
Requirement: Notifications should persist across browser refresh. Users should only see notifications disappear when they explicitly mark them as read.