Skip to content

feat(quality): the quality assessment is @self metadata, not object data - #3348

Merged
rubenvdlinde merged 1 commit into
developmentfrom
feat/quality-is-self-metadata
Sep 3, 2026
Merged

feat(quality): the quality assessment is @self metadata, not object data#3348
rubenvdlinde merged 1 commit into
developmentfrom
feat/quality-is-self-metadata

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Why

A per-object quality score is an assessment of the object's data, not a fact about the thing the object describes. It had nowhere to live except the object body, which forced every schema wanting a score to declare qualityScore and qualityStatus as ordinary properties. Three things followed, and all three are wrong:

  • The properties appear on every form the schema drives. A case handler filing a case in dossiq was shown a "Quality score" number field to fill in, for a value the platform overwrites on save. That is what surfaced this.
  • Removing the declaration silently deletes the values, because the store strips what the schema does not declare. So the mistake could not be undone without data loss.
  • Two schemas scoring the same way had to agree on property names by convention, with nothing to enforce it.

What

_quality becomes a metadata column of the same kind as _validation and _retention, surfaced in the @self envelope as quality:

"@self": { "quality": { "score": 0.5, "status": "fair", "scoredAt": "2026-09-03T…" } }

The change is additive on purpose. The listener still writes the body properties, but only where the schema actually declares them. Dropping that outright would freeze the stored value of every schema that has one, and a score that silently stops updating reads exactly like a score that is simply good. A schema that has migrated declares neither property, so nothing is written to its objects and the body stays clean.

That gives every app a migration path it can take on its own schedule: read @self.quality, then drop the declarations.

The migration

It sweeps every per-schema object table, adding the column where missing and skipping it where present, so re-running is a no-op. It identifies an object table by the _uuid column rather than by the name prefix alone, so a table that merely shares the prefix is never altered.

I verified that signature against a live database rather than only against the source: every oc_openregister_table_% carries _uuid and _validation, and none yet carries _quality.

Verification

  • 1886 unit tests pass across tests/Unit/Db and tests/Unit/Listener. The pristine tree runs 1881; the 5 added here are the difference, and the 3 pre-existing vendor warnings and 5 skips are unchanged
  • The listener had no test at all before this; there are now 5, covering the @self write, the schema that declares nothing, the schema that still declares both, a statusField naming a property the schema never declared, and a schema with no annotation
  • PHPCS (repo config, lib scope) and PHPStan clean on every changed file
  • Psalm reports one UnusedBaselineEntry on ObjectEntity, which reproduces identically on the pristine tree. It is an artifact of analysing single files, not something this branch introduces

Reviewer note

This touches the storage layer of the foundation repo, so the blast radius is every app. The two things worth your eyes are the migration's table-identification guard and the decision to keep writing declared body properties rather than cutting over hard.

🤖 Generated with Claude Code

A per-object quality score is an assessment OF the object's data, not a
fact about the thing the object describes. It had nowhere to live except
the object body, which forced every schema wanting a score to declare
`qualityScore` and `qualityStatus` as ordinary properties. Three things
followed, and all three are wrong:

- The properties appear on every form the schema drives. A case handler
  filing a case in dossiq was shown a "Quality score" number field to
  fill in, for a value the platform overwrites on save.
- Removing the declaration silently DELETES the values, because the
  store strips what the schema does not declare. So the mistake could
  not be undone without data loss.
- Two schemas scoring the same way had to agree on property names by
  convention, with nothing to enforce it.

`_quality` is now a metadata column of the same kind as `_validation`
and `_retention`, surfaced in the `@self` envelope as `quality` with
`score`, `status` and `scoredAt`.

The change is additive on purpose. The listener still writes the body
properties, but ONLY where the schema actually declares them: dropping
that outright would freeze the stored value of every schema that has
one, and a score that silently stops updating reads exactly like a score
that is simply good. A schema that has migrated declares neither, so
nothing is written to its objects and the body stays clean.

The migration sweeps every per-schema object table, adding the column
where it is missing and skipping it where present, so re-running is a
no-op. It identifies an object table by the `_uuid` column rather than
by the name prefix alone; verified against a live database, where every
`oc_openregister_table_%` carries `_uuid` and `_validation` and none yet
carries `_quality`.

Verified: 1886 unit tests in tests/Unit/Db and tests/Unit/Listener pass
(1881 before, plus the 5 added here), with the same 3 pre-existing
vendor warnings and 5 skips as the pristine tree. PHPCS, PHPStan clean
on every changed file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ b79012a

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-specs
test-l10n
test-l10n-parity
format
check-schema-l10n
check-l10n-js
composer ✅ 174/174
npm ✅ 543/543
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development
Hydra gates

Quality workflow — 2026-09-03 06:06 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 1eb6823 into development Sep 3, 2026
46 checks passed
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