feat: rename the app id from softwarecatalog to stackiq - #708
Open
rubenvdlinde wants to merge 11 commits into
Open
feat: rename the app id from softwarecatalog to stackiq#708rubenvdlinde wants to merge 11 commits into
rubenvdlinde wants to merge 11 commits into
Conversation
…ackage, build + CI config
…ob classes across the app-id rename Nextcloud namespaces oc_appconfig and oc_preferences by app id and has no in-place app-id upgrade, so every stored row becomes unreachable when the id moves. Every reader supplies a default, so nothing errors -- settings just revert. oc_jobs has the same shape one level down: it stores the job CLASS NAME, so the namespace rename orphans all four job rows. Three IRepairSteps, registered FIRST in both <install> and <post-migration>. <install> matters because an app-id rename presents to Nextcloud as a FIRST install of stackiq, and installAppLastSteps() guards <post-migration> with $previousVersion !== '' -- so <install> is the only hook that fires on the very upgrade these steps exist for. FIRST matters because InitializeSettings writes config itself; running it first would make every key look already present and strand the operator's value in the old namespace. Exhaustive enumeration (getKeys / callForSeenUsers + getUserKeys, never getUsersForUserValue which matches on a VALUE and so migrates nothing over an open value set). Reserved keys enabled/installed_version/types are skipped -- copying 'enabled' as STRING makes the next app:enable fail permanently with AppConfigTypeConflictException. Idempotent, non-destructive, and every read AND write inside the try so a throw cannot abort the install. 28 unit tests covering all three.
…d dev scripts Also repoints this app's own badges and clone URL from the retired codeberg.org host to github.com/ConductionNL/stackiq, and replaces the softwarecatalog.app doc link (DNS: no record) with the live softwarecatalog.conduction.nl. The .conduction.nl host itself stays -- stackiq.conduction.nl does not resolve.
Completes the sweep: PHP namespace OCA\SoftwareCatalog -> OCA\Stackiq (the
sub-namespace Service\SoftwareCatalogue -> Service\Stackiq, and the class
SoftwareCatalogueService -> StackiqService, which had been left disagreeing with
its already-renamed file), /apps/softwarecatalog -> /apps/stackiq routes across
code, tests, postman collections, docs and cursor rules.
Postman: the path ARRAY was rewritten alongside the raw URL. Postman builds the
request from the array, so rewriting only raw would leave the collection hitting
a different URL than the diff shows.
FROZEN, each because renaming would fail silently rather than loudly:
- softwarecatalog.conduction.nl (HTTP 200; stackiq.conduction.nl is 000) --
the manifest documentationUrl and footer href would point at nothing.
- softwarecatalogus -- the Dutch VNG catalogue, an external system's name,
not this app's id. Includes the GEMMA fixture XMLs and the register file.
- x-openregister.app in the register descriptor: OpenRegister attributes the
register by this field and may match on it; renaming risks a duplicate or
an orphan. Reported rather than guessed.
- openspec/changes/archive/** -- history; rewriting breaks @SPEC paths.
- openspec/coverage-report.* -- a dated audit snapshot. Rewriting its
observations to say something it never observed is falsification.
- LEGACY_APP_ID in the two Migrate* repair steps, and the old namespace in
MigrateBackgroundJobClasses -- these name what the steps read FROM.
- codeberg.org URLs -- a different host and org, stale independently.
Register slugs are voorzieningen and vng-gemma; neither contains the app id, so
neither moved.
Local: phpcs 0 errors, psalm clean, eslint 0 errors, 120/120 jest.
The register descriptor attributes the register to an owning app through x-openregister.app. It was left on the old app id when the id moved, so the descriptor claimed ownership by an app that no longer answers to that name. Safe to move now: these instances are development-only, so there is no live register whose attribution could be split. The register SLUG is deliberately NOT touched here — that is the key objects are stored against, and it is a separate decision from attribution. Other apps' ids appearing in the same file (e.g. opencatalogi) are cross-app references and stay as they are.
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 | ❌ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 703/703 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-22 17:41 UTC
Download the full PDF report from the workflow artifacts.
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 | ❌ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 703/703 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-22 18:01 UTC
Download the full PDF report from the workflow artifacts.
…rfaced The scripted sweep was fast but blunt. Five distinct failures, each a case of a name moving without the thing that answers to it. 1. TEST CONSTANTS INVERTED THE MIGRATION. The sweep rewrote the tests' LEGACY constant from 'softwarecatalog' to 'stackiq', so they asserted that the migration reads from the namespace it writes TO -- a migration that does nothing, with a green bar. Both now bind to the step's own LEGACY_APP_ID constant, so they cannot drift again. 2. 50 DANGLING @SPEC REFERENCES. The sweep rewrote citation PATHS to openspec/specs/stackiq-* while the directories are still softwarecatalog-*. Capability ids are frozen -- gate-46 dereferences them and archived changes cannot move -- so the citations are reverted, not the directories. gate-46 now resolves every anchor. 3. l10n KEYS ARE THE ENGLISH SOURCE STRING, so renaming a user-visible string renames its key. Two keys drifted out of en.json. Repointed, with the Dutch VALUES carried across (Softwarecatalogus -> Stackiq only where it is the product name, never where it means the VNG catalogue). The .js artifacts were stale too: the l10n check reads JSON, but Nextcloud SERVES the .js, so nl.js/en_US.js would have kept the old keys and Dutch users would have silently fallen back to English past a green check. 4. phpstan: callForSeenUsers() expects Closure(IUser): (bool|null); a void closure does not satisfy it. The IJobList::has()/remove() class-string errors are unsatisfiable BY DESIGN -- this step exists to deregister jobs whose class no longer exists -- so they carry a scoped ignore with that reason, not a baseline entry. 5. gate-16 and prettier: four changed methods tagged with the requirement they implement; 50 files reflowed because 'stackiq' is shorter than 'softwarecatalog' (measured 50 against 2 on development). Local: phpcs 0 errors, phpstan clean, phpmd 0, eslint 0, 120/120 jest, l10n OK, prettier clean, gate-16 0, gate-46 0.
Both CI failures had the same root cause, and it is a subtle one.
eslint-suppressions.json and phpmd.baseline.xml are keyed BY FILE PATH. The
sweep repointed those keys to the new filenames, but the rename of two source
files was a COPY, not a move -- so the old files stayed on disk, now with no
suppression entry pointing at them, and their long-standing findings resurfaced
as new errors. Neither file was reachable any more:
- src/store/plugins/softwarecatalogPlugin.js -- superseded by stackiqPlugin.js,
which orClient.js and store/modules/object.js already import.
- src/views/settings/SoftwareCatalogSettings.vue -- superseded by
StackiqSettings.vue, which registry.js already imports. The registry KEY
stays SoftwareCatalogSettingsPage: that is a manifest identifier, not a
filename.
Deleting them is the fix; repointing the suppressions back would have kept dead
code alive and silenced.
Also removed a genuine new else in MigrateAppConfigKeys::run() (guard plus
continue), rather than adding it to phpmd.baseline.xml -- a baseline records
debt already inherited, and same-day code does not belong in it.
Local: phpcs 0, phpmd 0, phpstan OK, eslint 0 errors, 120/120 jest, l10n OK,
prettier 0, gate-16 0.
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 | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 703/703 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-23 07:29 UTC
Download the full PDF report from the workflow artifacts.
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 | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 703/703 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 07:47 UTC
Download the full PDF report from the workflow artifacts.
The earlier bulk pass built its file list with a case-SENSITIVE grep for
'softwarecatalog'. Every file whose only occurrences were 'SoftwareCatalog' or
'SoftwareCatalogue' -- the PHP namespace and class-name spellings -- was
therefore never in the list, and never rewritten. CI found them as 32 errors:
Class "OCA\SoftwareCatalog\EventListener\SoftwareCatalogEventListener" not
found, because composer's psr-4 now maps only OCA\Stackiq\.
Renamed the missed files and directories with git mv, and removed four stale
DUPLICATES the earlier rename had left behind by copying rather than moving --
tests/Unit/EventListener/SoftwareCatalogEventListener{,Decomposition}Test.php
and tests/Unit/Service/SoftwareCatalogueService{Decomposition,OrganisationMapper}Test.php.
Each had a live counterpart under the new name; the old copies still declared
the old namespace, so they could only ever fail.
lib/Settings/softwarecatalogus_register.json stays: softwarecatalogus is the
Dutch VNG catalogue, not this app, and the file is loaded by an explicit path.
Local: phpcs 0, phpstan OK, phpmd 0, eslint 0, 120/120 jest, l10n OK,
prettier 0, gate-16 0, gate-46 0.
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 | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 703/703 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-23 08:18 UTC
Download the full PDF report from the workflow artifacts.
An earlier flatten of tests/Unit/Service/SoftwareCatalogue left BOTH tests/Unit/Service/Stackiq/ and tests/Unit/Service/Stackiq/Stackiq/ tracked, with byte-identical files. PHP fataled on the second copy: Cannot declare class OCA\Stackiq\Tests\Unit\Service\Stackiq\ ContactPersonHandlerDecompositionTest, because the name is already in use which aborted the whole PHPUnit run (exit 255) rather than failing a test. Local: phpcs 0, phpstan OK, gate-16 0.
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.
Renames the app id
softwarecatalog->stackiq, with the data migration that makes it safe.Why the migration is the point
Nextcloud namespaces
oc_appconfigandoc_preferencesby app id, and there is no in-place app-id upgrade. After the rename every stored row is unreachable — and because every reader supplies a default, nothing errors. Settings just revert, silently.MigrateAppConfigKeysandMigrateUserPreferencesrun first in both<install>and<post-migration>;MigrateBackgroundJobClassesderegisters jobs orphaned by the namespace move.Fixed on the way through
lib/Service/StackiqService.phphad already been renamed on disk but still declaredclass SoftwareCatalogueService, and theService\SoftwareCataloguesub-namespace still pointed at a directory now calledService/Stackiq. Both are corrected, so the class, the namespace and the path finally agree.Postman: the
patharray was rewritten alongside therawURL. Postman builds the request from the array, so rewriting onlyrawwould leave the collection quietly hitting a different URL than the diff shows.FROZEN — and what renaming each would have done
softwarecatalog.conduction.nlstackiq.conduction.nlreturns 000. The manifestdocumentationUrland footer href would point at nothing.softwarecataloguslib/Settings/softwarecatalogus_register.json.x-openregister.appin the register descriptoropenspec/changes/archive/**@specpath pointing into it.openspec/coverage-report.*LEGACY_APP_IDin bothMigrate*steps, and the old namespace insideMigrateBackgroundJobClassescodeberg.org/Conduction/SoftwareCatalogURLsRegister slugs are
voorzieningenandvng-gemma— neither contains the app id, so neither moved.Local verification
phpcs 0 errors · psalm clean · eslint 0 errors · 120/120 jest. PHPUnit cannot run outside a Nextcloud container here (
Class "OC_App" not foundin the bootstrap) — CI's matrix is the check that matters for it.