Step 2 (code quality): dedup + stop FE recomputing a server rule

- H1: tasksFromProfile takes the server's eligibleForHerregistratie decision
  instead of recomputing isHerregistratieEligible — the FE renders the rule,
  doesn't own it (ADR-0001). Policy reference impl kept for tests.
- M1: one shared runSubmit(fn, fallback) wrapper; the 4 submit-* commands keep
  only their payload mapping. +spec.
- M2: whenTag() kernel helper removes 10 repeated `as Extract<U,{tag}>` casts
  across the wizard/form components.

M4 (shared JA_NEE) folded into the upcoming i18n pass (clean dedup needs
$localize labels to sit in shared without breaking the English-shared-UI rule).
L1 already resolved by the restyle commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-06-27 13:48:35 +02:00
co-authored by Claude Opus 4.8
parent 94ffcf3d41
commit 1c65025fef
14 changed files with 118 additions and 68 deletions
+20
View File
@@ -0,0 +1,20 @@
import { Result, ok, err } from '@shared/kernel/fp';
import { problemDetail } from '@shared/infrastructure/api-error';
/**
* Run a mutating API call and fold it into a `Result` — the one place the
* try/catch + ProblemDetails-mapping lives, so every `submit-*` command is just
* its own payload mapping. The backend re-validates and returns a 422
* ProblemDetails on rejection, surfaced here as the error string.
*/
export async function runSubmit<T>(fn: () => Promise<T>, fallback: string): Promise<Result<string, T>> {
try {
return ok(await fn());
} catch (e) {
return err(problemDetail(e, fallback));
}
}
// ponytail: i18n in Step 3/M3 wraps this in $localize with a stable @@id, which
// dedupes it at the translation layer; for now it's the single shared default.
export const SUBMIT_FAILED = 'Het indienen is niet gelukt. Probeer het later opnieuw.';