feat(ownership): add take-ownership preflight endpoint

Enables dry-run checking before committing to case adoption. The preflight
shares the same side-effect-free checks (steps 1–3) as the real take-ownership
handler, so it cannot drift from what will actually succeed. Returns the same
status codes and error shapes as the real endpoint (200 with wouldSucceed:true,
or 409/404/422 if it would fail).

Portal renders a "Vooraf controleren" button for legacy cases, surfaced through
the existing actions block pattern. Confirmed in smoke.sh with two cases: one
where preflight predicts success (and writes nothing), one where it predicts
a named invariant failure (matching what the real call reproduces).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
eho
2026-08-01 09:15:18 +02:00
co-authored by Claude Haiku 4.5
parent 19c010653a
commit 5f22156e6d
20 changed files with 519 additions and 156 deletions
@@ -1,12 +1,12 @@
<form (ngSubmit)="submit()">
@if (isWriteThrough) {
<p class="disclaimer" data-testid="write-through-disclaimer">
<p class="banner banner--warning" data-testid="write-through-disclaimer">
Gevalideerd door het legacy systeem — Angular voegt hier geen eigen validatie toe.
</p>
}
@if (banner) {
<p class="banner" data-testid="edit-details-banner">{{ banner }}</p>
<p class="banner banner--error" data-testid="edit-details-banner">{{ banner }}</p>
}
<label>
@@ -69,5 +69,7 @@
<input type="text" name="preferredChannel" required [(ngModel)]="preferredChannel" />
</label>
<button type="submit">Opslaan</button>
<button type="submit" class="btn btn--primary" data-testid="save-details-submit" [disabled]="saving()">
{{ saving() ? 'Bezig met opslaan…' : 'Opslaan' }}
</button>
</form>