docs(test): generated living behaviour spec + FE/BE seam drift check (WP-71)
Gherkin/Cucumber was considered and rejected for business-readable BDD scenarios: step-binding by runtime string match undoes the compile-time guarantees WP-70 just added, and needs two frameworks for .NET+TS with no non-technical co-author in view. Instead scripts/gen-behaviour-spec.mjs (modeled on the existing gen-snippets.mjs) extracts every describe/it and [Fact]/[Theory] name straight from the real suites into libs/shared/docs/behaviour-spec.mdx, gated for drift in CI exactly like gen-snippets/gen-api — the page can never diverge from the tests because it's generated from them, and test names stay the single source of truth. scripts/check-seam.sh guards the one FE/BE rule duplication most likely to silently diverge: IntakePolicy.cs's ScholingThreshold vs intake.machine.ts's SCHOLING_THRESHOLD_DEFAULT, two unlinked literals pinned separately in each side's own tests but never against each other. package.json/CI wiring for both (gen:behaviour-spec, check:seam) shipped in the prior commit alongside the typecheck gate, since all three touch the same few config files. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/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)"
|
||||
Reference in New Issue
Block a user