Skip to content

refactor(metadata): split MetadataService patch, upsert and filter checks into named steps - #1072

Open
rubenvdlinde wants to merge 2 commits into
developmentfrom
quality/i40-metadata-steps
Open

rubenvdlinde wants to merge 2 commits into
developmentfrom
quality/i40-metadata-steps

Conversation

@rubenvdlinde

@rubenvdlinde rubenvdlinde commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

What changed

MetadataService reads as named steps instead of seven branchy methods:

  • updateFieldDefinition refuses a key rename, loads the field and applies patchLabel, patchSortOrder, patchRequired and patchOptions in the original order before stamping and saving.
  • setMetadataForDashboard resolves each key with fieldForKey (empty / unknown key messages unchanged), validates the value and hands it to a new MetadataValueWriter, a small final run object built for this one write, which clears the row of an empty optional value or upserts it.
  • extractUuid → entityUuid / rowUuid; matchesNumberRange → withinNumberRange; matchesDateRange → withinDateRange (isOnOrAfter, isOnOrBefore); assertOptionsShape → isSelectType; assertSelectOptions → assertOptionEntries.

Behaviour is unchanged: the same validation messages in the same precedence, the same deletes and upserts in the same order, the same filter matches.

Characterisation tests

tests/Unit/Service/MetadataServiceBranchesTest.php was committed first, against the old code, and passes before and after: a rename refused before the field is read, every patch key (and an ignored one), the required casting, the invalid patches with their exact messages and order (label before options, scalar / null / empty / non-string / empty-string options, options on a text field), the empty and unknown metadata keys, the clear-versus-upsert sequence across optional, absent, required and integer keys, the number and date range criteria (each bound alone, both, empty range, exact, non-numeric) and UUID lookup on entities, null-UUID entities, plain objects and rows.

What ran

  • vendor/bin/phpunit -c phpunit.xml --no-coverage tests/Unit: 2776 tests OK (13 skipped, as on development).
  • vendor/bin/phpcs and vendor/bin/phpstan analyse on the touched lib files: clean.
  • vendor/bin/phpmd on MetadataService: one new finding, TooManyMethods (29 methods against a limit of 25), the cost of turning long methods into named private steps; composer phpmd is already red on development for other classes.

Figures (touched files lib/Service/MetadataService.php, lib/Service/MetadataValueWriter.php)

before after
units over complexity 5 7 units, 160 lines 0
units over 15 lines of code 10 units, 256 lines 6 units, 136 lines (untouched methods)
units over 2 parameters 3 units, 61 lines 3 units, 61 lines

MetadataValueWriter depends on MetadataValueMapper (already used by MetadataService) and MetadataField; nothing else depends on it but MetadataService. App-wide: unit complexity 4.02 → 4.10, unit size 3.40 → 3.42, module coupling unchanged.

Maintainability floor: compare against development holds.

AI-assisted: prepared with Claude Code (claude-opus-5-5); reviewed by a maintainer before merge.


Generated by Claude Code

… before the split

Assisted-by: ClaudeCode:claude-opus-5-5
…ge checks into named steps

Assisted-by: ClaudeCode:claude-opus-5-5
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.

2 participants