Skip to content

fix(fronts): fall back to the in-place edit when the server has no replace route - #59

Merged
SiteRelEnby merged 1 commit into
mainfrom
fix/replace-front-fallback
Aug 5, 2026
Merged

fix(fronts): fall back to the in-place edit when the server has no replace route#59
SiteRelEnby merged 1 commit into
mainfrom
fix/replace-front-fallback

Conversation

@SiteRelEnby

@SiteRelEnby SiteRelEnby commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Release blocker found during 1.4.0 pre-flight. Follow-up to #56.

The problem

#56 switched add-to-front and remove-from-front to POST /v1/fronts/{id}/replace with no fallback. That endpoint is in no released server: the latest server tag is v1.3.4 and the route merged after it.

Sheaf is multi-instance. A phone can be pointed at any instance, and self-hosters upgrade on their own schedule. So shipping as-is would 404 both of those actions - core, everyday ones - against every instance that hadn't caught up, showing an error and doing nothing.

The fix

All six call sites now go through one helper, replaceFrontMembers, which tries replace and falls back to the in-place PATCH those servers have always had.

The fallback loses the per-member history split that #56 was about. That is precisely the behaviour those servers already had, so nothing is worse than before #56; instances that do have the route get the better semantics.

What falls back, and what doesn't

response behaviour why
404 fall back route missing on an older server
405 fall back route matched with a different method
409 fail the change itself was refused (duplicate member set). Retrying as a PATCH could quietly apply what the server just rejected
401 / 403 / 5xx fail not a capability question

404 is ambiguous between "no such route" and "no such front". That's harmless: if the front is genuinely gone, the PATCH fails the same way, costing one extra request on a path that was already failing.

Testing

6 unit tests cover: the happy path uses replace and never PATCHes; 404 and 405 fall back; 409 and 401 propagate without a fallback attempt; and the offline queue's boundary timestamp reaches the replace call.

:app:assemblePlayRelease, :wear:assemblePlayRelease, :app:testPlayReleaseUnitTest green.

Device checklist, ideally against both an upgraded and an older instance:

  • Old server: add a member to a co-front, and remove one; both work, no error
  • New server: same actions work, and history shows the per-member split
  • Removing the last member of a front still ends it on both
  • A genuine duplicate-member-set rejection still surfaces its error rather than silently doing something else

…place route

Add-to-front and remove-from-front were switched to POST /fronts/{id}/replace
with no fallback. That endpoint is in no released server yet, and Sheaf is
multi-instance: self-hosters upgrade on their own schedule, so a client that
hard-requires a brand-new route breaks two core actions outright against any
instance that has not caught up.

All six call sites now go through one helper that tries replace and, on 404 or
405, falls back to the in-place PATCH those servers have always had. The
fallback loses the per-member history split, which is exactly the behaviour
those servers already had; nothing gets worse than before the change.

Only 404 and 405 fall back. A 409 means the change itself was refused (a
duplicate member set), and retrying it as a PATCH could quietly apply something
the server had just rejected; auth failures likewise stay failures. A 404 is
ambiguous between "no such route" and "no such front", and that is harmless: if
the front is genuinely gone the PATCH fails the same way, costing one extra
request on a path that was already failing.
@SiteRelEnby
SiteRelEnby merged commit 9f04877 into main Aug 5, 2026
1 check passed
@SiteRelEnby
SiteRelEnby deleted the fix/replace-front-fallback branch August 5, 2026 16:46
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