Merge RB-26 — extract planFileSelection from the upload controller

TE-004: createUploadController performed three inject() calls, an effect()
registration and a window listener before returning, so the real policy
buried inside it — deciding per file whether to reject or start an upload —
was reachable only through a TestBed. planFileSelection in upload.machine.ts
is now that decision as a pure function taking plain {name, type, size}
objects; the controller executes the plan and keeps the one impure step
(crypto.randomUUID()) it can't move. No change to the controller's public
surface.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

# Conflicts:
#	docs/project/refactor-backlog-setup/refactor-backlog/99-backlog.md
#	libs/shared/docs/behaviour-spec.mdx
This commit is contained in:
eho
2026-08-28 08:29:36 +02:00
6 changed files with 250 additions and 14 deletions
+11 -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. 467 frontend behaviours across
**is** the suite, reshaped for a business reader. 474 frontend behaviours across
9 contexts; 261 backend behaviours across 42 test
classes.
@@ -798,6 +798,16 @@ classes.
- maskTail keeps the requested tail length
- masks the whole value when it is not longer than the kept tail
#### planFileSelection
- plans nothing for an unknown category
- rejects the whole batch with reason "multiple" for a single-file category
- does not reject a single file against a single-file category
- rejects one file via rejectReason (wrong type)
- rejects one file via rejectReason (too large)
- plans a FileSelected entry for a file that passes format validation
- judges each file independently and preserves order for a mixed multiple-file category
#### problemDetail
- extracts the detail from an RFC-7807 ProblemDetails