Receive recent feed: store entries as atomic records #3

Open
opened 2026-05-06 04:58:52 +02:00 by jesse · 0 comments
Owner

Background

The owner recent-receives feed is stored as a capped JSON array under recentReceives:<ownerEmail>. This follow-up tracks moving feed entries to per-reservation records so concurrent finalizations cannot overwrite each other across Worker isolates.

Source: Deferred from receive links fix pass after PR multi-agent code review
File: worker.js:3041
Branch: feature/receive-links-foundation

Failure mode

  • appendRecentReceive reads the current JSON array, mutates it, and writes it back under an in-process lock.
  • The in-process lock does not serialize writes across Worker isolates.
  • Concurrent receive finalizations for the same owner can lose feed entries even though audit records and unread markers are keyed by reservation.
  • The durable fix changes the feed storage model and needs a migration or dual-read compatibility path.
  • The review-fix pass already made counters and unread markers idempotent, but did not change the owner-visible feed schema.

Proposed work

  • Add per-entry feed keys such as recentReceive:<ownerEmail>:<createdSort>:<reservationId> or an equivalent sortable schema.
  • Update owner recent-feed reads to page from per-entry keys and lazily ignore/delete stale entries.
  • Keep unread markers keyed by reservation and reconcile them with the new feed entries.
  • Add a migration or dual-read path for existing recentReceives:<ownerEmail> arrays.
  • Retain owner-visible IP scrubbing behavior for configured retention windows.

Acceptance

  • Tests simulate concurrent finalization writes and assert both feed entries remain visible.
  • Tests cover legacy array fallback or migration behavior.
  • Tests assert duplicate finalization for one reservation does not create duplicate feed entries.
  • Owner unread counts remain derived from reservation-specific markers.

References

  • Follow-up from feature/receive-links-foundation receive-links review fix pass.
  • docs/DATA_MODEL.md:153
  • docs/LOGIC.md:178
## Background The owner recent-receives feed is stored as a capped JSON array under `recentReceives:<ownerEmail>`. This follow-up tracks moving feed entries to per-reservation records so concurrent finalizations cannot overwrite each other across Worker isolates. **Source:** Deferred from receive links fix pass after PR multi-agent code review **File:** `worker.js:3041` **Branch:** `feature/receive-links-foundation` ## Failure mode - `appendRecentReceive` reads the current JSON array, mutates it, and writes it back under an in-process lock. - The in-process lock does not serialize writes across Worker isolates. - Concurrent receive finalizations for the same owner can lose feed entries even though audit records and unread markers are keyed by reservation. ## Why deferred from receive links fix pass - The durable fix changes the feed storage model and needs a migration or dual-read compatibility path. - The review-fix pass already made counters and unread markers idempotent, but did not change the owner-visible feed schema. ## Proposed work - [ ] Add per-entry feed keys such as `recentReceive:<ownerEmail>:<createdSort>:<reservationId>` or an equivalent sortable schema. - [ ] Update owner recent-feed reads to page from per-entry keys and lazily ignore/delete stale entries. - [ ] Keep unread markers keyed by reservation and reconcile them with the new feed entries. - [ ] Add a migration or dual-read path for existing `recentReceives:<ownerEmail>` arrays. - [ ] Retain owner-visible IP scrubbing behavior for configured retention windows. ## Acceptance - Tests simulate concurrent finalization writes and assert both feed entries remain visible. - Tests cover legacy array fallback or migration behavior. - Tests assert duplicate finalization for one reservation does not create duplicate feed entries. - Owner unread counts remain derived from reservation-specific markers. ## References - Follow-up from `feature/receive-links-foundation` receive-links review fix pass. - `docs/DATA_MODEL.md:153` - `docs/LOGIC.md:178`
Sign in to join this conversation.
No labels
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.

Dependencies

No dependencies set.

Reference
jesse/ycloud-cloudflare#3
No description provided.