Keep a durable notification inbox with current action status #22

Open
opened 2026-11-01 20:11:40 +00:00 by viacheslavshuka · 0 comments

Outcome

Users need durable notifications even when Telegram is disabled or unreachable. Add event ingestion, account-scoped inbox reads, read state, and notification-only retention.

The core accepts a stable event identity and intended recipient. Product workflows own event emission and action validity. This ticket owns inbox consumption and its public contracts.

Acceptance criteria

  • Reprocessing an event creates at most one inbox record per event and recipient. Telegram attempts do not create extra inbox records.
  • The inbox shows an unread count, newest-first paginated results, and All, Unread, and Awaiting action filters. It does not load all history on entry.
  • Awaiting action reflects the current underlying offer or invitation. Reading a notification cannot accept, decline, or extend that action.
  • Opening one item marks it read. Opening the inbox alone does not. Provide mark-as-read and mark-all-as-read actions.
  • Read status persists across browser sessions. Accepting or declining an associated action on either interface marks its notification read.
  • Telegram delivery alone neither marks an item read nor resolves its action.
  • Notifications remain available for 90 days after creation, including unread items. An older notification remains while its action is available.
  • After an old action resolves, age-based cleanup may remove its notification. Cleanup never deletes session, attendance, familiarity, statistics, or moderation history.
  • One account cannot read or mark another account's notifications. Private reasons and links remain subject to current viewer permissions.
  • Event-consumer registration permits later product workflows to integrate without changing deduplication or inbox semantics.

Validation design

Replay one event concurrently through independent PostgreSQL connections and assert one record. Use current-action stubs to detect stale Awaiting action labels. Verify read-state differences between opening the inbox, opening an item, and completing an action. Exercise the 90-day boundary with unresolved and resolved actions, and assert unrelated history remains intact.

Dependencies

## Outcome Users need durable notifications even when Telegram is disabled or unreachable. Add event ingestion, account-scoped inbox reads, read state, and notification-only retention. The core accepts a stable event identity and intended recipient. Product workflows own event emission and action validity. This ticket owns inbox consumption and its public contracts. ## Acceptance criteria - Reprocessing an event creates at most one inbox record per event and recipient. Telegram attempts do not create extra inbox records. - The inbox shows an unread count, newest-first paginated results, and All, Unread, and Awaiting action filters. It does not load all history on entry. - Awaiting action reflects the current underlying offer or invitation. Reading a notification cannot accept, decline, or extend that action. - Opening one item marks it read. Opening the inbox alone does not. Provide mark-as-read and mark-all-as-read actions. - Read status persists across browser sessions. Accepting or declining an associated action on either interface marks its notification read. - Telegram delivery alone neither marks an item read nor resolves its action. - Notifications remain available for 90 days after creation, including unread items. An older notification remains while its action is available. - After an old action resolves, age-based cleanup may remove its notification. Cleanup never deletes session, attendance, familiarity, statistics, or moderation history. - One account cannot read or mark another account's notifications. Private reasons and links remain subject to current viewer permissions. - Event-consumer registration permits later product workflows to integrate without changing deduplication or inbox semantics. ## Validation design Replay one event concurrently through independent PostgreSQL connections and assert one record. Use current-action stubs to detect stale Awaiting action labels. Verify read-state differences between opening the inbox, opening an item, and completing an action. Exercise the 90-day boundary with unresolved and resolved actions, and assert unrelated history remains intact. ## Dependencies - [#14: Authenticate Telegram users through protected Quorum sessions](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/14). Supplies recipient identity and account-scoped authorization. - [#16: Run durable PostgreSQL jobs with atomic effects](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/16). Supplies recoverable ingestion and age-based cleanup. ## Related work - [#52: Register individual testers with approval, tentative status, and capacity checks](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/52) - [#47: Manage test co-organizers through accepted invitations](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/47) - [#57: Preserve bookings and prevent stale overwrites when test details change](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/57) - [#69: Restrict participation and organizing capabilities with reversible expiry](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/69) - [#65: Correct attendance and group familiarity without erasing history](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/65) - [#29: Deliver Telegram notifications with bounded retries and current permissions](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/29) - [#24: Keep browser data useful during slow or lost connections](https://code.viacheslavshuka.com/viacheslavshuka/quorum/issues/24)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
viacheslavshuka/quorum#22
No description provided.