Repository navigation
refactor(organisations): delete StackiqService's unused organisation sync, fix the contact backup entity (REVIEW) - #1412
Merged
Conversation
…acting organisation pinned Assisted-by: ClaudeCode:claude-opus-5-5
…to access, query and search steps getKoppelingenGebruikByUuid keeps its signature and its error envelope; the work moves into koppelingenGebruik, mayReadKoppelingen (ambtenaar, or the active organisation owns the object), searchKoppelingen, isOrganisationUuid and emptyKoppelingenPage, each with at most two parameters. Order of the lookups, the log lines and the results are unchanged (golden of the previous commit). Assisted-by: ClaudeCode:claude-opus-5-5
Assisted-by: ClaudeCode:claude-opus-5-5
…to find, fetch and process steps processRelatedContactPersons drops its unused organisation object parameter and hands the work to findRelatedContacts, contactsFromOrganisationList, fetchListedContact, processRelatedContact and completeRelatedContact, each with at most two parameters (the sync run array, stats held by reference). Lookups, saves, log lines and stats are unchanged (golden of the previous commit). Assisted-by: ClaudeCode:claude-opus-5-5
…of an organisatie object The OrganisationMapper stub gains findBySlug, as on OpenRegister's mapper. Assisted-by: ClaudeCode:claude-opus-5-5
…nto refresh, adopt-by-slug and create steps ensureOrganisationEntity takes the organisatie object and one run array (stats held by reference, and an explicit sendEmails at every call site) and hands the work to fullOrganisationObject, refreshOrganisationEntity, adoptOrganisationEntityBySlug, createOrganisationEntity, mailOrganisation and makeEntityOwner. The public wrapper keeps its signature. Lookups, saves, mails, log lines and stats are unchanged (golden of the previous commit). Assisted-by: ClaudeCode:claude-opus-5-5
… it behaves today Creating an organisation escapes with an Error on both paths: the signed-in path calls OrganisationMapper::createWithUuid, which OpenRegister does not have, and the anonymous path saves and then reads the absent user. Assisted-by: ClaudeCode:claude-opus-5-5
…m the OpenRegister create and update steps Neither createOrganisationInOpenRegisterInternal nor updateOrganisationInOpenRegister reads the OrganisationService it was handed. The public create wrapper still fetches it first, so a missing OpenRegister fails at the same point. The golden masks mock and anonymous class names, which depend on test order; it was re-recorded on the code before this commit. Assisted-by: ClaudeCode:claude-opus-5-5
…oppelingen-gebruik-params
…rg-sync-related-contacts
…contacts' and 'origin/refactor/sig-koppelingen-gebruik-params' into fix/stackiq-organisation-creation
…ationService StackiqService created a signed-in user's organisation with OrganisationMapper::createWithUuid(), which OpenRegister does not have, and an anonymous one by saving an admin-owned entity and then calling getUID() on the null user. Both ended in an Error that escaped catch (\Exception), so creation never returned an organisation. A signed-in creation now goes through OrganisationService::createOrganisation() with addCurrentUser, so the creator becomes owner and member, and the organisation's contact persons are added with addUserToOrganisation(). Without a signed-in user nothing is created: the specs do not say who would own it. ContactpersoonService passed orgObject: to ensureOrganisationEntityPublic(), whose parameter is organisationObject, so its backup entity creation always failed with an Error. Tests: golden cases recorded on the old code for the anonymous, forged owner and member, creator-as-contact and missing-service paths (the Organisation stub answers magic accessors like the Entity does, so the anonymous case reaches the save it really makes); the backfill sends no mail and processSpecificOrganization mails on create; the koppelingen lookup cases for a forged owner filter, owner lookalikes and forged @self/isAmbtenaar options. Assisted-by: ClaudeCode:claude-opus-5-5
…ganisation-creation
rubenvdlinde
marked this pull request as ready for review
November 3, 2026 17:37
…sync and creation Nothing calls StackiqService::handleNewOrganization, handleOrganizationUpdate, syncOrganizationWithOpenRegister or createOrganisationInOpenRegister: the background job creates organisations through OrganisatieService, and no class in lib/, src/ or appinfo/ references StackiqService at all. The 20 methods only those reach (1,800 lines) go, and with them the never-read OrganizationHandler, SymfonyEmailService, IUserSession, IUserManager and IGroupManager dependencies. That removes the creation path that called OpenRegister's createOrganisation() without a slug check, which would have handed an existing organisation with the same name to the caller, instead of fixing a path nothing uses. The golden test for that path, its stub additions and the stale tests/OrganizationSyncTest.php (outside every suite, against the old constructor) go too. Assisted-by: ClaudeCode:claude-opus-5-5
Contributor
Author
|
Rerun on the deletion head (37745e8): full unit suite (phpunit-unit.xml, pcov, --fail-on-risky) exit 0, 1630 tests, 0 failures, 0 risky, 59 skipped. Hydra gates --scope-to-diff --base origin/development: 37 of 37 applicable gates ran, 0 FAIL. |
Contributor
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ❌ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 127/127 | |||
| npm | ❌ | ✅ 807/807 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 1610/1610 · 20 skipped | ||||
| 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-11-04 00:54 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.
REVIEW (organisation ownership and membership). Held. This PR is stacked on #1404 and #1405. Their commits leave this diff as soon as they merge.
1. StackiqService's organisation sync and creation are deleted (no production caller)
RW118 found that the changed StackiqService methods have no production caller. I confirmed it:
OrganisatieService::createOrganisationInOpenRegister(), called fromOrganizationSyncService.handleNewOrganizationandhandleOrganizationUpdateexist onStackiq\OrganizationHandler, which is the class that is used.StackiqServiceat all. Only comments name it.So instead of fixing a path nothing runs, this PR deletes it:
handleNewOrganization,handleOrganizationUpdate,syncOrganizationWithOpenRegisterandcreateOrganisationInOpenRegister, plus the 16 private methods only those reach (1,800 lines, computed as the closure of callers);This removes the problem RW118 found: the first version of this PR called OpenRegister's
createOrganisation()without checking the slug, and on a slug collisionOrganisationMapper::save()updates the existing organisation, which would have handed it to the caller. It also removes the original bugs (createWithUuiddoes not exist,getUID()on null). RW118's low items (a non-string contact e-mail, an empty e-mail added as a member, the golden double that ignored theorganizationfilter) were all in the deleted code and its golden.The golden test of the deleted path (
StackiqServiceOrganisationSyncGoldenTest), the stub additions it needed, and the staletests/OrganizationSyncTest.phpgo too. That file sits outside every test suite and uses the old constructor.What stays in StackiqService (contact person processing, user groups, hierarchy) is unchanged. Its remaining tests pass:
StackiqServiceDecompositionTestandStackiqServiceOrganisationMapperTest.Not in this PR, for a decision: the whole StackiqService class (1,406 lines left) is unreferenced. Deleting it is a separate, larger PR.
Related, production path:
OrganizationSyncServicedeliberately adopts an existing entity with the same slug (adoptOrganisationEntityBySlug). ORX8 is fixing the slug overwrite in OpenRegister itself.2. ContactpersoonService backup entity (inherited, the same on both trees)
ensureOrganisationEntityPublic(orgObject: ...)used a named parameter that does not exist (the parameter isorganisationObject). TheErrorescapedcatch (\Exception), so creating the backup entity for a new contact person of an active organisation without an entity always failed. The fix renames the argument.sendEmailskeeps its default (true), as in the other two backup paths in OrganizationSyncService.ContactpersoonBackupEntityTestfailed on the old code withError: Unknown named parameter $orgObject.3. RW93 follow-ups for #1404 and #1405
organisationfilter that names the owner, owner lookalikes (other case, trailing space), forged@selfandisAmbtenaarin the options, and a forged@selffor the owner. ThebuildSearchQuerydouble carries@selfthrough like OpenRegister does. The old cases are unchanged. Mutants 5 of 5 killed.testTheBackfillSendsNoMail(performOrganizationsSync creates the entity and sends no mail) andtestProcessSpecificOrganizationMailsOnCreate. Mutants 2 of 2 killed (the backfill mails; processSpecificOrganization stays silent).Numbers (PHP, lizard, against development plus #1404 and #1405)
The parameter shares rise only because 1,717 mostly small-parameter lines leave the denominator. No unit gained parameters. #1413 (listener) takes params >= 3 down by about 1.1 points.
Verified locally
Assisted-by: ClaudeCode:claude-opus-5-5