refactor(procest): rename wettelijkeGrondslag to legalBasis across all six owners - #816
Merged
Merged
Conversation
…cision
Applies the ratified besluit = decision equivalence to procest's mandate
schema: the `mandateringsBesluit` schema (key, slug, title, description) becomes
`mandateDecision`, with five of its properties and the cross-schema reference
that names it.
besluitNummer -> decisionNumber
besluitNaam -> decisionName
inWerkingtreding -> effectiveFrom
vervalDatum -> expiryDate
vorigBesluit -> previousDecision
mandaat.mandateringsBesluit -> mandaat.mandateDecision
THERE WAS NEVER A SCHEMA MERGE TO DO. This slice was previously described as
blocked because procest "already declares a decision schema, so renaming
Besluit onto it is a merge". Measured: procest declares exactly one `decision`
schema, already fully English with twelve English properties, and there is no
bare `Besluit` schema anywhere to collide with it. What carries the word is two
differently-named schemas and five properties. The premise was wrong.
WHAT IS DELIBERATELY NOT RENAMED
`wettelijkeGrondslag` stays. It is owned by FIVE other procest schemas
(dwangsomUitbetaling, mandaat, subsidieBeschikking, termijnDefinitie,
terugvordering) that still declare the Dutch spelling, and the column migration
is REGISTER-scoped: renaming it here would migrate their data out from under
their own declarations. A shared property half-renamed is worse than one not
renamed at all. It moves fleet-wide, with them, in one slice. `legalBasis`
already exists on another procest schema, which is a second reason not to
introduce a partial second source for it.
The `status` enum VALUES (concept / vastgesteld / vervallen) stay. Enum values
are stored data, not identifiers — rewriting them rewrites every row. Same call
as openconnector#1213.
The SchemaSlugMap VALUE stays `mandaterings_besluit_schema`. Only the key is the
slug; the value is the app-config key under which this schema's numeric id is
already stored on every existing install. Renaming it would orphan that id and
the schema would silently resolve to nothing.
The import endpoint accepts BOTH spellings. Its request-body keys are a
published contract; the English names are preferred and the Dutch ones still
read, so a client that has not been updated does not break.
MIGRATION. Six columns added to the existing register-scoped repair step. Each
was verified to be owned by exactly one schema before being added — that check
is what kept wettelijke_grondslag out, and it is the same hazard decidesk's step
avoids by scoping to a register, only here it is within one app.
THREE PRE-EXISTING UI BUGS FOUND, DELIBERATELY NOT "FIXED" BY RENAMING
- MandaatEditor.vue binds form.inWerkingtreding onto a MANDAAT, which declares
validFrom/validUntil and has no such property.
- MandaatMatrixTable.vue reads b.vervaldatum — lowercase d — matching no
schema property at all.
- BevoegdhedenPanel.vue reads both off API rows whose shape is not verifiable
without running it.
Renaming these would have cemented bindings that already point at nothing. Only
MandaatMatrixWidget.vue, which reads the renamed reference property, was
updated. The three need their own investigation.
VERIFIED
- phpunit: 1867 tests, 6346 assertions green (5 skipped, same as baseline).
- php -l clean; the fragment parses as JSON.
- Named-argument parity: findPriorBesluit -> findPriorDecision, parameter
besluitNummer -> decisionNumber, both call sites moved and diffed against
the declaration.
- phpcs: 0 errors on every file this change touches except
MandaatImportServiceTest, which carries 46 — identical count on the
unmodified file, measured by stashing.
…owners Renames the property across EVERY schema that declares it, in one change: dwangsomUitbetaling, mandaat, mandateDecision, subsidieBeschikking, termijnDefinitie and terugvordering — plus the seed data, six services, three Vue files and the affected test fixtures. WHY ALL SIX AT ONCE. This was deliberately held out of the mandate-decision slice. The column migration is REGISTER-scoped: it walks every shard table in the procest registers and renames any column whose name is in its map. Renaming `wettelijkeGrondslag` for one schema would therefore have moved the data of the other five out from under declarations that still used the Dutch name — a silent null-read on each. A shared property is renamed for all its owners or for none. With all six moved, `wettelijke_grondslag => legal_basis` is safe to add to the map, and it is added here. MY FIRST MEASUREMENT OF THE FOOTPRINT WAS SHORT. It ran against the shared checkout, where TermijnReportingService.php had not yet been renamed to DeadlineReportingService.php by #806, so that consumer did not appear. Three Vue files were missed the same way. The residual grep after editing is what surfaced them; the count went from 27 references to 40. NOT EVERY VUE BINDING WAS REAL. The sibling slice found MandaatEditor binding `inWerkingtreding` onto a mandaat that has no such property. This one is different and was checked rather than assumed: `mandaat` genuinely declares wettelijkeGrondslag, so its editor field, its validator and the matrix widget's legalLink() all bind something that exists, and all three move. THE CSV HEADER STAYS READABLE. MandaatImportService reads the legal basis from an operator-supplied CSV column. That header is an external input format, so the new spelling is preferred and the old one still accepted — an existing import file does not break. VERIFIED - phpunit: 1867 tests, 6347 assertions green (5 skipped, same as baseline). - Two tests failed on the first run and were fixed: an assertion in DwangsomUitbetalingServiceTest reading the old key, and four fixtures in TermijnServiceTest. Both now pass. - php -l clean on every changed file; all four JSON files parse. - phpcs: TermijnServiceTest ends at 47 errors against a 74-error baseline — my edit first pushed it to 96 through misaligned array arrows, and phpcbf both corrected that and cleared pre-existing debt. Every other changed file is at or below its baseline.
rubenvdlinde
requested review from
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
August 12, 2026 08:10
Base automatically changed from
feat/english-vocabulary-mandate-decision
to
development
August 12, 2026 08:12
rubenvdlinde
changed the base branch from
feat/english-vocabulary-mandate-decision
to
development
August 12, 2026 08:12
…ocabulary-legal-basis # Conflicts: # lib/Repair/RenameDutchDeadlineColumns.php # lib/Settings/register.d/61-mandaat-matrix.json
… rename phpcs failed #816 with 7 'Array double arrow not aligned correctly' errors, all in the payload built by buildMandaatPayload(). The cause is mine: 'legalBasis' is shorter than 'wettelijkeGrondslag', so every arrow in that array needed re-aligning and I did not re-run phpcs on this file after the edit. phpcbf-applied; the file is back to 0 errors. No behaviour change — whitespace only, confirmed by the diff being 7 insertions and 7 deletions on the same lines, and by MandaatImportServiceTest still passing.
Contributor
Quality Report — ConductionNL/procest @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ❌ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 552/552 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-12 08:21 UTC
Download the full PDF report from the workflow artifacts.
Contributor
Quality Report — ConductionNL/procest @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 552/552 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-12 08:39 UTC
Download the full PDF report from the workflow artifacts.
gate-16 (spec-coverage) failed #816 with '2 changed method(s) missing @SPEC'. The gate is diff-scoped and it is right: buildMandaatPayload() and collectChangedFields() were both edited by the legalBasis rename and neither carried an anchor. gate-16 PASSES on development, so this is caused by this branch, not inherited. Both now point at the change that introduced them. NOT FIXED HERE: gate-53 (effective-manifest-crossref, 8 failures). Measured against development's own latest Code Quality run — it reports the IDENTICAL 8 cross-reference failures there, so it is pre-existing and untouched by this branch. src/manifest.json contains no reference to any property this PR renamed (grep for wettelijkeGrondslag returns 0).
Contributor
Quality Report — ConductionNL/procest @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 552/552 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-12 09:05 UTC
Download the full PDF report from the workflow artifacts.
This was referenced Aug 12, 2026
rubenvdlinde
added a commit
that referenced
this pull request
Aug 12, 2026
…ticeOfDefault* (#818) Replaces #810, which was branched from a stale stack: its diff carried a dozen files that #803/#804/#806/#809/#816/#817 have since landed, so rebasing it meant resolving 8 conflicts across controllers, services, tests and a Postman collection. Branched fresh from development this does the same work as a 40-reference change across 10 files with zero conflicts. IngebrekestellingService -> NoticeOfDefaultService IngebrekestellingController -> NoticeOfDefaultController registerIngebrekestelling() -> registerNoticeOfDefault() ROUTE NAMES MOVE, URLs DO NOT. A route name resolves to its controller class, so `ingebrekestelling#register` had to become `noticeOfDefault#register` or the router 500s on that endpoint. The URLs stay `/api/termijn/ingebrekestellingen`: that is the published contract and moving it is a breaking change for every consumer — a separate decision from this rename. Both route names were verified to resolve to NoticeOfDefaultController.php after the change. NOT IN THIS CHANGE: the `ingebrekestelling` SCHEMA in 60-termijnbewaking.json, its reference property, and the `ingebrekestelling-ontvangen` lifecycle enum value. The schema is a data contract — renaming it needs an ownership check and a column migration, and the enum value is stored data. Class names carry no data and move independently, which is why this is a clean slice. VERIFIED - phpunit: 1882 tests, 6393 assertions green (5 skipped, same as baseline). - php -l clean on every changed file; the Postman collection still parses. - Route names resolve: both noticeOfDefault#* map to a file that exists. - Residual grep finds no IngebrekestellingService / IngebrekestellingController / registerIngebrekestelling anywhere in lib/, tests/ or appinfo/. - phpcs: 6 errors across the four changed files against a 386-error baseline. My edit added 5; phpcbf fixed those and cleared pre-existing debt with them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Renames the property across every schema that declares it, in one change:
dwangsomUitbetaling,mandaat,mandateDecision,subsidieBeschikking,termijnDefinitie,terugvordering— plus seed data, six services, three Vue files and the affected fixtures.Why all six at once
This was deliberately held out of #815. The column migration is register-scoped — it walks every shard table in the procest registers and renames any column in its map. Renaming
wettelijkeGrondslagfor one schema would have moved the other five's data out from under declarations still using the Dutch name: a silent null-read on each.A shared property is renamed for all its owners or for none. With all six moved,
wettelijke_grondslag => legal_basisis safe to add to the map, and it is added here.My first measurement was short
It ran against the shared checkout, where
TermijnReportingService.phphad not yet been renamed toDeadlineReportingService.phpby #806 — so that consumer never appeared. Three Vue files were missed the same way. The residual grep after editing is what surfaced them: 27 references became 40.Not every Vue binding was real — this one was
The sibling slice found
MandaatEditorbindinginWerkingtredingonto a mandaat that has no such property, and I left it alone rather than cement it. This case is different and was checked rather than assumed:mandaatgenuinely declareswettelijkeGrondslag, so the editor field, its validator, and the widget'slegalLink()all bind something real. All three move.The CSV header stays readable
MandaatImportServicereads the legal basis from an operator-supplied CSV column. That header is an external input format — the new spelling is preferred, the old still accepted, so an existing import file does not break.Verification
DwangsomUitbetalingServiceTestreading the old key, and four fixtures inTermijnServiceTestphp -lclean on every changed file; all four JSON files parseTermijnServiceTestends at 47 errors against a 74 baseline. My edit first pushed it to 96 through misaligned array arrows; phpcbf corrected that and cleared pre-existing debt. Every other changed file is at or below baseline.