Repository navigation
feat(example-sets): a fragment may put parties on its objects - #4766
Merged
Merged
Conversation
…y its confidentiality Assisted-by: ClaudeCode:claude-opus-5-5
…dy has Assisted-by: ClaudeCode:claude-opus-5-5
Party links live in the party model, not in a register, and the only write path needed a signed-in user, which occ does not have. A fragment's parties rows are now checked, linked through PartyRoleService::importParty with the fragment's app as the linker, proved and unlinked on remove. The API path still records only the signed-in user. Assisted-by: ClaudeCode:claude-opus-5-5
Contributor
Quality Report — ConductionNL/openregister @
|
| 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 | ✅ | ||||
| composer | ✅ | ✅ 173/173 | |||
| npm | ✅ | ✅ 648/648 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development. |
||||
| Hydra gates | ❌ |
Quality workflow — 2026-10-22 06:20 UTC
Download the full PDF report from the workflow artifacts.
Assisted-by: ClaudeCode:claude-opus-5-5
Contributor
Quality Report — ConductionNL/openregister @
|
| 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 | ✅ | ||||
| composer | ✅ | ✅ 173/173 | |||
| npm | ✅ | ✅ 648/648 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ✅ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development. |
||||
| Hydra gates | ❌ |
Quality workflow — 2026-10-22 14:38 UTC
Download the full PDF report from the workflow artifacts.
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.
What
A new example-set part,
parties. Each row gives one party a role on one of the set's objects:{objectUuid, partyUuid, role, validFrom?, validUntil?, note?, primary?}.PartyRoleService::importParty, which records the fragment's app as the linker.PartyLinkWriter::writetakes an optionallinkedBy, used only when nobody is signed in. The signed-in user always wins. The API path (addParty) never passes it, so a request cannot name its own linker.Why
dossiq's DqZaakBetrokkenen board draws the parties on a Woo case: a representative with a mandate until 31 December, a reporter without an account with an indicator, and a primary requester. Party links live in the party model, not in a register, and the only write path needed a signed-in user, which
occdoes not have.Confidentiality needed no new field. The party model already carries secrecy as an indicator with the effect
refuse-publication; see the openspec change.Verified
ExampleSetPartiesTest(a link written, kept, unlinked; a refused party dropped; 6 refusal cases) andPartyLinkWriterTest(named linker, signed-in user wins, 401 when neither is there).PartyRoleServiceTestcovers importParty against addParty.lib/Service/ExampleSetandlib/Service/Party. phpstan is clean, and phpcs is clean on the changed files.composer check:strict(local, on the commit before b35f701):ExampleSetEngineKinds, wrapped in b35f701.Who can name the linker
linkedByonly matters when nobody is signed in, and only one path passes it. I checked every caller on this branch:PartyLinkWriter::writehas exactly one caller:PartyRoleService::linkParty.PartyLinkWriteris injected nowhere else (grep -rn "PartyLinkWriter" lib).linkPartyis private. It is reached from:addParty, which always passeslinkedBy: null;importParty.addPartyis the API path. It is called byPartyController::addParty(lib/Controller/PartyController.php:124) and byPartyRoleService::replacePrimaryParty. Neither can pass a linker, and alinkedBykey in the request payload is not read.importPartyhas one caller:ExampleSetParties::write(lib/Service/ExampleSet/ExampleSetParties.php:132). That runs only fromocc openregister:example-set:install.$this->session->getUser()?->getUID()first, so even on the trusted path a signed-in user is recorded rather than the named one.Tests that prove it:
PartyRoleServiceTest::testImportNamesTheLinkerAndAddDoesNotsends'linkedBy' => 'spoofed'in anaddPartypayload and asserts the writer receivednull.PartyLinkWriterTest::testTheSignedInUserWinschecks a signed-in user beats the named linker.PartyLinkWriterTest::testNoLinkerIsRefusedchecks a 401 when neither is there.Merge order
This one is independent. dossiq
feat/woo-role-types-and-party-schemasand the portaliq party data that follows need it.AI-assisted: written with Claude Code (claude-opus-5-5) and reviewed before submission.