Skip to content

fix(fronts): use the single-front replace endpoint for co-front changes - #56

Merged
SiteRelEnby merged 2 commits into
mainfrom
feat/single-front-replace
Aug 3, 2026
Merged

fix(fronts): use the single-front replace endpoint for co-front changes#56
SiteRelEnby merged 2 commits into
mainfrom
feat/single-front-replace

Conversation

@SiteRelEnby

Copy link
Copy Markdown
Collaborator

Client side of the server's new POST /v1/fronts/{id}/replace.

What was wrong

Adding or removing a member from a co-front PATCHed the front's member list in place. Two problems:

  1. History. Editing the list rewrites one row, so each member's stint stops being its own history entry. A front that was A+B and became A+C reads as though C had been there all along.
  2. Scope. The alternative, ending everything and starting fresh, is wrong when someone unrelated is fronting in another front and should be left alone. This is how the bug surfaced, via "remove from current front".

What changed

Six call sites now use replace, which ends the old front and opens its replacement in one transaction, keeps per-member history, and leaves every other open front untouched:

where action
Members list add to front, remove from front
Member profile add to front, remove from front
Home remove from front
Offline queue replay remove from front

The offline replay passes the queued removal time as the boundary, so a removal made offline lands in history where the user actually made it, not when the queue happened to drain.

Removing the last member of a front still ends it rather than replacing it. Replace requires a non-empty member list, and ending is what that action means.

Separately: "set as sole fronter"

This ended every open front in a loop and then created the new one - a stop notification per front, then a start. It is now a single create with replace_fronts, which the server does in one transaction and reports as one aggregated change.

What did not need changing

The switch sheet and the quick-switch carousel already issue a single create with replace_fronts, and the server takes one before/after snapshot around it, so those were already emitting a single notification. I checked before touching them.

Testing

:app:assemblePlayRelease + :app:testPlayReleaseUnitTest green. Needs a device pass against a server with the endpoint, ideally with a notification channel set up so the notification count is observable:

  • A+B fronting, remove B: front becomes A, one notification, and A's history shows two entries (A+B, then A)
  • A+B fronting and D fronting separately, remove B: D is untouched
  • Add C to a front of A: becomes A+C, one notification
  • Remove the only member of a front: the front ends
  • "Set as sole fronter" with two open fronts: one notification, everything else ended
  • Remove a member while offline, then reconnect: same result, and history shows the removal at the time it was made

Adds POST /v1/fronts/{id}/replace and routes every "change who is in this one
front" path through it.

Adding or removing a member from a co-front used to PATCH the front's member
list in place. That has two problems the new endpoint exists to solve: editing
the list rewrites one row, so each member's stint stops being its own history
entry, and the change carries no notion of a boundary between the old
composition and the new. Replacing ends the old front and opens its
replacement in one transaction, keeping per-member history intact, and leaves
every other open front alone - which matters when the member being removed is
in one co-front and someone unrelated is fronting in another.

Six call sites move over: add-to-front and remove-from-front on both the
members list and the member profile, remove-from-front on Home, and the
offline queue's replay of a removal (which passes the queued removal time as
the boundary, so a switch made offline lands where the user actually made it).

Removing the last member of a front still ends it rather than replacing it;
replace requires a non-empty member list, and ending is what that action means.

Separately, "set as sole fronter" ended every open front in a loop and then
created the new one, which is a stop notification per front followed by a
start. It is now a single create with replace_fronts, which the server does in
one transaction and reports as one aggregated change.

Not changed: the switch sheet and the quick-switch carousel already issue a
single create with replace_fronts, and the server takes one before/after
snapshot around it, so those were already emitting one notification.
@SiteRelEnby
SiteRelEnby enabled auto-merge August 3, 2026 04:31
@SiteRelEnby
SiteRelEnby merged commit 4bc8994 into main Aug 3, 2026
1 check passed
@SiteRelEnby
SiteRelEnby deleted the feat/single-front-replace branch August 3, 2026 04:35
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