feat(brief): tolerate a 404 on GET /brief with a one-shot reset (RB-22)

BriefStore.load() now treats a 404 from GET /brief as "no brief exists
yet" and calls the existing reset() command once, instead of showing
the generic load-failed error. BriefAdapter.load() gains a
BriefLoadFailure error channel (notFound | error) so the store can
tell a 404 apart from every other failure; every other adapter method
stays on runSubmit, unchanged.

The once-only bound is a field on the store, not a comment: a second
404 (from a later load() call) always falls through to the ordinary
error path, and the recovery path never calls load() again, so no
loop can form.

This is the expand half of CQ-007's split (04-cqrs-light.md). Today's
backend never 404s GET /brief, so the new branch is dead code until
RB-23 (the backend contract half) ships in a later merge.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
eho
2026-08-27 18:43:27 +02:00
co-authored by Claude Opus 5
parent 7fbac8fca5
commit 7a29f5facc
6 changed files with 309 additions and 59 deletions
+6 -1
View File
@@ -20,7 +20,7 @@ tested where._
Every bullet below is a real test name from the suite — an `it()` title (frontend) or a test
method name (backend), read as a sentence. Nothing here is hand-written prose: this page
**is** the suite, reshaped for a business reader. 451 frontend behaviours across
**is** the suite, reshaped for a business reader. 453 frontend behaviours across
9 contexts; 236 backend behaviours across 41 test
classes.
@@ -180,6 +180,11 @@ classes.
- flushes a pending debounced edit immediately and clears the pending flag
- is a no-op when no edit is pending
#### BriefStore.load — 404 tolerance (RB-22)
- a 404 drives exactly one reset(), which populates the store
- a second 404 does not drive a second reset()
#### BriefStore.previewLetter
- opens the composed letter in a new tab on success