Files
ehoandClaude Sonnet 5 6fa27d1c53 test: close the remaining FE/BE seams (WP-75)
Three seams WP-71 documented but left unguarded.

Deletes the FE's isHerregistratieEligible and isStatusConsistent — both
uncalled, the first dead by its own doc-comment. Their tests used fixtures
completely disjoint from the backend's (the backend even had an exact-window
boundary case the FE lacked), so the two sides could diverge indefinitely
without failing anything. CLAUDE.md's policy of keeping server-owned rules
as FE "reference impls" is what kept them alive, so it is amended: the FE may
mirror a server-supplied value for instant feedback, never reimplement the
algorithm. registration.policy.ts keeps its three live exports.

check-seam.sh now also guards the Besluit tag list — the C# enum and the TS
BESLUIT_TAGS array are identical ordered name lists with nothing linking
them, and Enum.TryParse fails at request time rather than build time. Anchored
on the full declaration so it avoids the "greps all matches" trap WP-69 hit.

The phone-format divergence turned out to be real, not latent as recorded:
the backend returned 422 for +31612345678 and (06) 12345678, both of which
the FE's own parseTelefoonnummer accepts. A grep check would have compared
the shared ^0\d{9}$ regex and reported all clear — the difference was in
stripping. RejectPhoneChange now strips what the FE strips, pinned by a
contract test.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 16:32:22 +02:00

66 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# WP-71 (Track E): fail if the backend's scholing-threshold policy default and the frontend's
# offline fallback default drift apart. ADR-0001's "config value" shape means the backend is
# the authority (GET /intake/policy) and the FE only keeps SCHOLING_THRESHOLD_DEFAULT as an
# offline/first-paint fallback (intake.machine.ts) — but the two literals are otherwise
# unlinked, so nothing stops them silently diverging. This is a cheap grep-based tripwire, not
# a build-time link between the two languages.
set -uo pipefail
BACKEND_FILE='backend/src/BigRegister.Api/Domain/Intake/IntakePolicy.cs'
FRONTEND_FILE='apps/ssp/src/app/herregistratie/domain/intake.machine.ts'
backend_value=$(grep -oE 'ScholingThreshold\s*=\s*[0-9]+' "$BACKEND_FILE" | grep -oE '[0-9]+$')
frontend_value=$(grep -oE 'SCHOLING_THRESHOLD_DEFAULT\s*=\s*[0-9]+' "$FRONTEND_FILE" | grep -oE '[0-9]+$')
if [ -z "$backend_value" ]; then
echo "FAIL: could not find IntakePolicy.ScholingThreshold in $BACKEND_FILE"
exit 1
fi
if [ -z "$frontend_value" ]; then
echo "FAIL: could not find SCHOLING_THRESHOLD_DEFAULT in $FRONTEND_FILE"
exit 1
fi
if [ "$backend_value" != "$frontend_value" ]; then
echo "FAIL: FE/BE seam drift on the scholing threshold default"
echo " $BACKEND_FILE: ScholingThreshold = $backend_value"
echo " $FRONTEND_FILE: SCHOLING_THRESHOLD_DEFAULT = $frontend_value"
echo 'Both literals represent the same intake policy default (ADR-0001 config value) and must match.'
exit 1
fi
echo "OK: scholing threshold default matches on both sides ($backend_value)"
# WP-75: fail if the backend's Besluit enum and the frontend's BESLUIT_TAGS list (the wire
# convention: a string, not a raw enum) drift apart. Enum.TryParse<Besluit> at Program.cs:494
# is the only coupling and it fails at REQUEST time, not build time — this is a build-time
# tripwire for the same names/order both sides assume.
BESLUIT_BACKEND_FILE='backend/src/BigRegister.Api/Domain/Applications/AanvraagStatus.cs'
BESLUIT_FRONTEND_FILE='apps/behandelportal/src/app/behandeling/domain/besluit.machine.ts'
besluit_backend_raw=$(grep -oE 'public enum Besluit \{[^}]*\}' "$BESLUIT_BACKEND_FILE" | grep -oE '\{[^}]*\}')
besluit_frontend_raw=$(grep -oE "const BESLUIT_TAGS = \[[^]]*\]" "$BESLUIT_FRONTEND_FILE" | grep -oE '\[[^]]*\]')
if [ -z "$besluit_backend_raw" ]; then
echo "FAIL: could not find 'public enum Besluit { ... }' in $BESLUIT_BACKEND_FILE"
exit 1
fi
if [ -z "$besluit_frontend_raw" ]; then
echo "FAIL: could not find 'const BESLUIT_TAGS = [ ... ]' in $BESLUIT_FRONTEND_FILE"
exit 1
fi
besluit_backend_value=$(echo "$besluit_backend_raw" | tr -d '{}' | tr -d ' ')
besluit_frontend_value=$(echo "$besluit_frontend_raw" | tr -d '[]' | tr -d "' " )
if [ "$besluit_backend_value" != "$besluit_frontend_value" ]; then
echo "FAIL: FE/BE seam drift on the Besluit tag list"
echo " $BESLUIT_BACKEND_FILE: Besluit { $besluit_backend_value }"
echo " $BESLUIT_FRONTEND_FILE: BESLUIT_TAGS = [ $besluit_frontend_value ]"
echo 'Both lists are the same wire-convention names/order (Enum.TryParse<Besluit> at Program.cs) and must match.'
exit 1
fi
echo "OK: Besluit tag list matches on both sides ($besluit_backend_value)"