Skip to content

refactor(procest): rename wettelijkeGrondslag to legalBasis across all six owners - #816

Merged
rubenvdlinde merged 5 commits into
developmentfrom
feat/english-vocabulary-legal-basis
Aug 12, 2026
Merged

refactor(procest): rename wettelijkeGrondslag to legalBasis across all six owners#816
rubenvdlinde merged 5 commits into
developmentfrom
feat/english-vocabulary-legal-basis

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

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.

Stacked on #815 (mandate-decision). Merge that first; this retargets to development afterwards.

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 wettelijkeGrondslag for 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_basis is safe to add to the map, and it is added here.

My first measurement was short

It ran against the shared checkout, where TermijnReportingService.php had not yet been renamed to DeadlineReportingService.php by #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 MandaatEditor binding inWerkingtreding onto 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: mandaat genuinely declares wettelijkeGrondslag, so the editor field, its validator, and the widget's legalLink() all bind something real. 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 — the new spelling is preferred, the old still accepted, so an existing import file does not break.

Verification

  • 1867 tests, 6347 assertions green (5 skipped — baseline)
  • Two tests failed on the first run and were fixed: an assertion in DwangsomUitbetalingServiceTest reading the old key, and four fixtures in TermijnServiceTest
  • php -l clean on every changed file; all four JSON files parse
  • phpcs: TermijnServiceTest ends 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.

…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.
Base automatically changed from feat/english-vocabulary-mandate-decision to development August 12, 2026 08:12
@rubenvdlinde
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.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ b6ae5ef

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.

@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 39a125e

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).
@rubenvdlinde
rubenvdlinde merged commit 14fa008 into development Aug 12, 2026
29 checks passed
@rubenvdlinde
rubenvdlinde deleted the feat/english-vocabulary-legal-basis branch August 12, 2026 08:49
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 820efbb

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.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant