From 7d33384bce83e508f63e6863a224eef700feb51a Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Sat, 22 Aug 2026 18:23:52 +0200 Subject: [PATCH 01/14] =?UTF-8?q?wip(rename):=20app=20id=20softwarecatalog?= =?UTF-8?q?=20->=20stackiq=20=E2=80=94=20appinfo,=20composer,=20package,?= =?UTF-8?q?=20build=20+=20CI=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .forgejo/workflows/app-tests-live.yml | 8 +-- .forgejo/workflows/app-tests.yml | 4 +- .forgejo/workflows/documentation.yml | 7 ++ .forgejo/workflows/release-beta.yml | 2 +- .forgejo/workflows/release-stable.yml | 2 +- .github/docker-compose.ci.yml | 4 +- .github/workflows/code-quality.yml | 6 +- .github/workflows/documentation.yml | 7 ++ .github/workflows/issue-triage.yml | 2 +- .github/workflows/openspec-sync.yml | 2 +- .github/workflows/release.yml | 6 +- appinfo/info.xml | 92 +++++++++++++++++++-------- composer.json | 4 +- css/dashboardWidgets.css | 4 +- package-lock.json | 4 +- package.json | 2 +- phpcs.xml | 4 +- phpmd.xml | 4 +- phpstan.neon | 2 +- playwright.config.ts | 2 +- publiccode.yml | 4 +- templates/index.php | 4 +- templates/settings/admin.php | 4 +- vitest.config.js | 4 +- webpack.config.js | 4 +- 25 files changed, 119 insertions(+), 69 deletions(-) diff --git a/.forgejo/workflows/app-tests-live.yml b/.forgejo/workflows/app-tests-live.yml index 4ef96cc7..282adba7 100644 --- a/.forgejo/workflows/app-tests-live.yml +++ b/.forgejo/workflows/app-tests-live.yml @@ -1,14 +1,14 @@ -# app-tests-live.yml — softwarecatalog caller for the LIVE-NC reusable workflow. +# app-tests-live.yml — stackiq caller for the LIVE-NC reusable workflow. # # Boots a real, seeded Nextcloud (db + NC + openregister deployed/enabled + -# softwarecatalog deployed/enabled), then runs the deep Playwright e2e +# stackiq deployed/enabled), then runs the deep Playwright e2e # (tests/e2e/workflows/) and/or the Newman API-contract suite against it as # HARD gates. Generalised per GAP-2 (arm CI live-gating) from openregister's # reference rig; the reusable tests-live.yml is byte-identical fleet-wide, only # these inputs differ. Additive — does not touch app-tests.yml / release / # pre-merge workflows. # -# Gate status for softwarecatalog (see TESTING-CI-ROLLOUT.md for the evidence table): +# Gate status for stackiq (see TESTING-CI-ROLLOUT.md for the evidence table): # deep-e2e: true — e2e RESOLVES register+schema at runtime from /api/voorzieningen/config — CI-portable # newman: true — ARMED: the collection "0. Setup / Preflight" request resolves the register # numeric id from the stable slug 'voorzieningen' (and addresses the org/contact/ @@ -38,7 +38,7 @@ jobs: live: uses: ./.forgejo/workflows/tests-live.yml with: - app-id: softwarecatalog + app-id: stackiq is-openregister: false run-e2e: true run-newman: true diff --git a/.forgejo/workflows/app-tests.yml b/.forgejo/workflows/app-tests.yml index cc027389..f68d5ac3 100644 --- a/.forgejo/workflows/app-tests.yml +++ b/.forgejo/workflows/app-tests.yml @@ -1,4 +1,4 @@ -# app-tests.yml — softwarecatalog caller for the reusable feature-test workflow. +# app-tests.yml — stackiq caller for the reusable feature-test workflow. # # Runs the PHASE-5 testing layers on every PR to the protected branches. # phpunit-unit + l10n-check HARD-GATE; e2e/newman are scaffolded and opt-in @@ -29,6 +29,6 @@ jobs: tests: uses: ./.forgejo/workflows/tests.yml with: - app-id: softwarecatalog + app-id: stackiq run-e2e: ${{ github.event.inputs.run-e2e == 'true' }} run-newman: ${{ github.event.inputs.run-newman == 'true' }} diff --git a/.forgejo/workflows/documentation.yml b/.forgejo/workflows/documentation.yml index d8e3a7ce..928668f9 100644 --- a/.forgejo/workflows/documentation.yml +++ b/.forgejo/workflows/documentation.yml @@ -21,5 +21,12 @@ jobs: if: github.event_name != 'pull_request' uses: Conduction/.github/.forgejo/workflows/documentation-deploy.yml@main with: + # FROZEN through the softwarecatalog -> stackiq app-id rename. + # This names an EXISTING Cloudflare Pages project. Renaming it here does + # not rename the project — the deploy simply targets a project that does + # not exist, and a Pages deploy against an unknown project reports success + # while reaching nobody (see the two green Cloudflare deploys that shipped + # to nothing during the fleet rename). Rename the Cloudflare project first, + # then this line. cf-project-name: softwarecatalog-docs secrets: inherit diff --git a/.forgejo/workflows/release-beta.yml b/.forgejo/workflows/release-beta.yml index 5ada7134..0d75d0f3 100644 --- a/.forgejo/workflows/release-beta.yml +++ b/.forgejo/workflows/release-beta.yml @@ -9,7 +9,7 @@ jobs: release: uses: Conduction/.github/.forgejo/workflows/release-beta.yml@main with: - app-name: softwarecatalog + app-name: stackiq secrets: CODEBERG_TOKEN: ${{ secrets.CODEBERG_TOKEN }} NEXTCLOUD_SIGNING_KEY: ${{ secrets.NEXTCLOUD_SIGNING_KEY }} diff --git a/.forgejo/workflows/release-stable.yml b/.forgejo/workflows/release-stable.yml index b359397b..6fe5d23c 100644 --- a/.forgejo/workflows/release-stable.yml +++ b/.forgejo/workflows/release-stable.yml @@ -9,5 +9,5 @@ jobs: release: uses: Conduction/.github/.forgejo/workflows/release-semrel.yml@main with: - app-name: softwarecatalog + app-name: stackiq secrets: inherit diff --git a/.github/docker-compose.ci.yml b/.github/docker-compose.ci.yml index 4194657f..b4dedba7 100644 --- a/.github/docker-compose.ci.yml +++ b/.github/docker-compose.ci.yml @@ -20,7 +20,7 @@ volumes: services: db: image: pgvector/pgvector:pg16 - container_name: softwarecatalog-ci-db + container_name: stackiq-ci-db environment: POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud @@ -62,4 +62,4 @@ services: networks: default: - name: softwarecatalog-ci-network + name: stackiq-ci-network diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index 20937988..7fb79c13 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -117,7 +117,7 @@ jobs: quality: uses: ConductionNL/.github/.github/workflows/quality.yml@main with: - app-name: softwarecatalog + app-name: stackiq php-version: "8.3" # THE LIST IS THE WHOLE DECLARED RANGE. appinfo/info.xml declares # , so 32, 33 and 34 each get @@ -171,7 +171,7 @@ jobs: # declares only `smoke` + `chromium`. enable-playwright: true playwright-test-path: tests/e2e - # `occ app:enable softwarecatalog` runs InitializeSettings, but that + # `occ app:enable stackiq` runs InitializeSettings, but that # repair step has no user session (OpenRegister RBAC can deny it), # swallows its own exception as a warning, and imports with # `force: false` — so a fresh install can come up with no `voorzieningen` @@ -179,7 +179,7 @@ jobs: # explicitly over the admin API and fails loudly if the registers, # schemas, or the app's own register→schema mapping still aren't there. # cwd for this step is the Nextcloud server root. - playwright-seed-command: 'bash apps/softwarecatalog/tests/e2e/ci-seed.sh' + playwright-seed-command: 'bash apps/stackiq/tests/e2e/ci-seed.sh' # Integration Tests (Newman) stays OFF here, deliberately. The # `enable-newman: false` further up is not a default nobody chose: it diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 1de66271..347c1078 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -29,4 +29,11 @@ jobs: packages: write uses: ConductionNL/.github/.github/workflows/documentation.yml@main with: + # FROZEN through the softwarecatalog -> stackiq app-id rename. + # `softwarecatalog.conduction.nl` answers 200 today; `stackiq.conduction.nl` + # answers 000 (no DNS record). A CNAME is not a name we own in this repo — + # it is a claim about a record that exists. Publishing docs at a host that + # resolves to nothing takes the documentation site OFFLINE, which is a + # regression, not a rename. Move this only after DNS + the Pages/Cloudflare + # binding for the new host are live, in a change that verifies both. cname: softwarecatalog.conduction.nl diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml index ac9a743c..d188b67f 100644 --- a/.github/workflows/issue-triage.yml +++ b/.github/workflows/issue-triage.yml @@ -23,7 +23,7 @@ jobs: contents: read uses: ConductionNL/.github/.github/workflows/issue-triage.yml@main with: - app-name: softwarecatalog + app-name: stackiq backlog-existing: ${{ github.event_name == 'workflow_dispatch' && inputs.backlog-existing || false }} secrets: PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }} diff --git a/.github/workflows/openspec-sync.yml b/.github/workflows/openspec-sync.yml index 541e3221..96e43482 100644 --- a/.github/workflows/openspec-sync.yml +++ b/.github/workflows/openspec-sync.yml @@ -18,6 +18,6 @@ jobs: contents: read uses: ConductionNL/.github/.github/workflows/openspec-sync.yml@main with: - app-name: softwarecatalog + app-name: stackiq secrets: PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c488856..80bfc8a2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,7 +46,7 @@ jobs: uses: ConductionNL/.github/.github/workflows/release.yml@main with: release-type: unstable - app-name: softwarecatalog + app-name: stackiq secrets: inherit beta: @@ -58,7 +58,7 @@ jobs: uses: ConductionNL/.github/.github/workflows/release.yml@main with: release-type: beta - app-name: softwarecatalog + app-name: stackiq secrets: inherit stable: @@ -70,5 +70,5 @@ jobs: uses: ConductionNL/.github/.github/workflows/release.yml@main with: release-type: stable - app-name: softwarecatalog + app-name: stackiq secrets: inherit diff --git a/appinfo/info.xml b/appinfo/info.xml index 0c68b0f6..317a65ad 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -1,14 +1,14 @@ - softwarecatalog - Software Catalogus - Software Catalogus + stackiq + Stackiq + Stackiq Manage your software portfolio with applications, modules, and connections Beheer je softwareportfolio met applicaties, modules en koppelingen ⚠️ **Active development — not for production use yet.** This app is under active development. Although it may carry a stable release status, **please do not use it in production environments before 17 June 2026.** See the [app page on conduction.nl](https://conduction.nl/apps/softwarecatalog) for release planning and what this app does. -Software Catalogus brings structured software portfolio management to Nextcloud. Keep track of all the applications, modules, and connections in your organization — and share them across a federated open data network. +Stackiq brings structured software portfolio management to Nextcloud. Keep track of all the applications, modules, and connections in your organization — and share them across a federated open data network. **Key Features** @@ -18,7 +18,7 @@ Software Catalogus brings structured software portfolio management to Nextcloud. - **Contract & license administration** — Track contracts with an approval workflow, renewal status, and expiry alerts - **GEMMA/ArchiMate standards & compliance** — Maintain a standards register, record compliance claims with evidence, cross-check modules against standards in a compliance matrix, and import/export ArchiMate models - **Portfolio roadmap** — See applications in use grouped by lifecycle phase, with end-of-support and phase-out warnings -- **Federated synchronization** — Share and sync catalog data with other Software Catalogus instances via OpenCatalogi's directory network (optional; degrades gracefully if OpenCatalogi is not installed) +- **Federated synchronization** — Share and sync catalog data with other Stackiq instances via OpenCatalogi's directory network (optional; degrades gracefully if OpenCatalogi is not installed) - **Automatic user provisioning** — Sync contacts and organizations from your register into Nextcloud accounts and groups - **Open data publishing** — Publish selected catalog entries for transparency and reuse, with anonymous self-registration and moderation for new organizations @@ -30,7 +30,7 @@ Free and open source under the EUPL license. ]]> ⚠️ **In actieve ontwikkeling — nog niet voor productiegebruik.** Deze app is volop in ontwikkeling. Hoewel de app een stabiele release-status kan hebben, **gebruik deze nog niet in productieomgevingen vóór 17 juni 2026.** Zie de [app-pagina op conduction.nl](https://conduction.nl/apps/softwarecatalog) voor release-planning en het doel van deze app. -Software Catalogus brengt gestructureerd softwareportfoliobeheer naar Nextcloud. Houd al je applicaties, modules en koppelingen bij — en deel ze via een gefedereerd open data netwerk. +Stackiq brengt gestructureerd softwareportfoliobeheer naar Nextcloud. Houd al je applicaties, modules en koppelingen bij — en deel ze via een gefedereerd open data netwerk. **Belangrijkste functies** @@ -40,7 +40,7 @@ Software Catalogus brengt gestructureerd softwareportfoliobeheer naar Nextcloud. - **Contract- en licentiebeheer** — Volg contracten met een goedkeuringsworkflow, verlengingsstatus en verloopmeldingen - **GEMMA/ArchiMate-standaarden & compliance** — Beheer een standaardenregister, leg compliance-claims met bewijs vast, toets modules tegen standaarden in een compliance-matrix en importeer/exporteer ArchiMate-modellen - **Portfolioroadmap** — Zie applicaties in gebruik gegroepeerd op levenscyclusfase, met waarschuwingen voor einde ondersteuning en uitfasering -- **Gefedereerde synchronisatie** — Deel en synchroniseer catalogusdata met andere Software Catalogus-instanties via het directorynetwerk van OpenCatalogi (optioneel; werkt zonder OpenCatalogi met beperkte functionaliteit) +- **Gefedereerde synchronisatie** — Deel en synchroniseer catalogusdata met andere Stackiq-instanties via het directorynetwerk van OpenCatalogi (optioneel; werkt zonder OpenCatalogi met beperkte functionaliteit) - **Automatische gebruikersaanmaak** — Synchroniseer contacten en organisaties vanuit je register naar Nextcloud-accounts en -groepen - **Open data publicatie** — Publiceer geselecteerde catalogusitems voor transparantie en hergebruik, met anonieme zelfregistratie en moderatie voor nieuwe organisaties @@ -53,7 +53,7 @@ Vrij en open source onder de EUPL-licentie. 0.1.141-unstable.20260821053703 EUPL-1.2 Conduction - SoftwareCatalog + Stackiq https://github.com/ConductionNL/stackiq https://github.com/ConductionNL/stackiq @@ -73,7 +73,7 @@ Vrij en open source onder de EUPL-licentie. + OCA\Stackiq\Repair\MigrateAppConfigKeys + OCA\Stackiq\Repair\MigrateUserPreferences + + OCA\Stackiq\Repair\MigrateBackgroundJobClasses + - OCA\SoftwareCatalog\Repair\RenameDutchSchemaSlugs - OCA\SoftwareCatalog\Repair\InitializeSettings - OCA\SoftwareCatalog\Repair\MigrateContactsToNc - OCA\SoftwareCatalog\Repair\BackfillContractApprovalState + OCA\Stackiq\Repair\RenameDutchSchemaSlugs + OCA\Stackiq\Repair\InitializeSettings + OCA\Stackiq\Repair\MigrateContactsToNc + OCA\Stackiq\Repair\BackfillContractApprovalState - OCA\SoftwareCatalog\Repair\RenameDutchCatalogColumns + OCA\Stackiq\Repair\RenameDutchCatalogColumns - OCA\SoftwareCatalog\Repair\RenameDutchCatalogValues + OCA\Stackiq\Repair\RenameDutchCatalogValues - OCA\SoftwareCatalog\Repair\InitializeSettings + OCA\Stackiq\Repair\MigrateAppConfigKeys + OCA\Stackiq\Repair\MigrateUserPreferences + OCA\Stackiq\Repair\MigrateBackgroundJobClasses + OCA\Stackiq\Repair\InitializeSettings - OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin - OCA\SoftwareCatalog\Sections\SoftwareCatalogAdmin + OCA\Stackiq\Settings\StackiqAdmin + OCA\Stackiq\Sections\StackiqAdmin - softwarecatalog - Software Catalogs - softwarecatalog.dashboard.page + stackiq + Stackiq + stackiq.dashboard.page app.svg diff --git a/composer.json b/composer.json index 880aa7be..499a657b 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "conductionnl/softwarecatalog", + "name": "conductionnl/stackiq", "description": "Quickly build data registers based on schema.json", "license": "EUPL-1.2", "authors": [ @@ -11,7 +11,7 @@ ], "autoload": { "psr-4": { - "OCA\\SoftwareCatalog\\": "lib/" + "OCA\\Stackiq\\": "lib/" } }, "scripts": { diff --git a/css/dashboardWidgets.css b/css/dashboardWidgets.css index adfbc9bc..0dd5005a 100644 --- a/css/dashboardWidgets.css +++ b/css/dashboardWidgets.css @@ -1,8 +1,8 @@ -.icon-softwarecatalog-widget { +.icon-stackiq-widget { background-image: url('../img/app-dark.svg'); filter: var(--background-invert-if-dark); } -body.theme--dark .icon-softwarecatalog-widget { +body.theme--dark .icon-stackiq-widget { background-image: url('../img/app.svg'); } diff --git a/package-lock.json b/package-lock.json index 5643021d..c8622927 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "softwarecatalog", + "name": "stackiq", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "softwarecatalog", + "name": "stackiq", "version": "1.0.0", "license": "EUPL-1.2", "dependencies": { diff --git a/package.json b/package.json index 612f1355..01a31738 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "softwarecatalog", + "name": "stackiq", "version": "1.0.0", "license": "EUPL-1.2", "sideEffects": true, diff --git a/phpcs.xml b/phpcs.xml index 2f60a71f..38914618 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,7 +1,7 @@ - + - softwarecatalog — SEMANTICS ONLY. Formatting belongs to php-cs-fixer via + stackiq — SEMANTICS ONLY. Formatting belongs to php-cs-fixer via conduction/coding-standard; see .php-cs-fixer.dist.php. diff --git a/phpmd.xml b/phpmd.xml index 29d267a8..42f4f7e0 100644 --- a/phpmd.xml +++ b/phpmd.xml @@ -1,9 +1,9 @@ - - softwarecatalog — Conduction PHPMD ruleset (single source: conduction/hydra-gates). + stackiq — Conduction PHPMD ruleset (single source: conduction/hydra-gates). diff --git a/phpstan.neon b/phpstan.neon index ecc4397b..0cebad81 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,4 @@ -# SoftwareCatalog — Conduction PHPStan config. +# Stackiq — Conduction PHPStan config. # # The shared base is the single source of truth. Everything here is either the # app's own tracked debt or an ignore naming a symbol that exists in no other diff --git a/playwright.config.ts b/playwright.config.ts index 76937456..3922c212 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -6,7 +6,7 @@ import * as path from 'path' import { resolveBaseUrl } from './tests/e2e/base-url' /** - * Playwright configuration for softwarecatalog e2e tests. + * Playwright configuration for stackiq e2e tests. * * Base URL comes from `tests/e2e/base-url.ts` and has NO default — see the * rationale there. Set PLAYWRIGHT_BASE_URL (or CI's BASE_URL) to an isolated diff --git a/publiccode.yml b/publiccode.yml index 0d5e0258..8c3dc1e1 100644 --- a/publiccode.yml +++ b/publiccode.yml @@ -1,7 +1,7 @@ publiccodeYmlVersion: "0.4" -name: Software Catalogs -url: "https://codeberg.org/Conduction/softwarecatalog" +name: Stackiq +url: "https://github.com/ConductionNL/stackiq" softwareVersion: "0.2.2" releaseDate: "2026-05-26" developmentStatus: stable diff --git a/templates/index.php b/templates/index.php index 4b84e2e9..6ee06529 100644 --- a/templates/index.php +++ b/templates/index.php @@ -2,7 +2,7 @@ use OCP\Util; -$appId = OCA\SoftwareCatalog\AppInfo\Application::APP_ID; +$appId = OCA\Stackiq\AppInfo\Application::APP_ID; // The webpack build emits a separate runtime chunk (runtimeChunk: { name: 'runtime' }) // plus shared vendor/nc-vue chunks. All must be loaded in dependency order BEFORE // the entry chunk, otherwise __webpack_require__ is never bootstrapped and Vue never @@ -13,6 +13,6 @@ Util::addScript($appId, $appId . '-main'); Util::addStyle($appId, 'main'); ?> -
+
diff --git a/templates/settings/admin.php b/templates/settings/admin.php index caf8137f..3f845a4d 100644 --- a/templates/settings/admin.php +++ b/templates/settings/admin.php @@ -1,7 +1,7 @@ -
+
diff --git a/vitest.config.js b/vitest.config.js index 09c8be6d..3fe266d6 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -1,8 +1,8 @@ /** - * SPDX-FileCopyrightText: 2026 Conduction / SoftwareCatalog Contributors + * SPDX-FileCopyrightText: 2026 Conduction / Stackiq Contributors * SPDX-License-Identifier: EUPL-1.2 * - * Vitest configuration for SoftwareCatalog frontend unit tests. + * Vitest configuration for Stackiq frontend unit tests. * * This OFFLINE suite (no Nextcloud runtime) targets PURE app-local logic that * the rendered UI exercises end-to-end but never asserts exactly: diff --git a/webpack.config.js b/webpack.config.js index 63efa94f..a7a9872e 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,7 +13,7 @@ webpackConfig.stats = { modules: false, } -const appId = 'softwarecatalog' +const appId = 'stackiq' webpackConfig.entry = { main: { import: path.join(__dirname, 'src', 'main.js'), @@ -89,7 +89,7 @@ if (useLocalLib) { useLocalLib = false // eslint-disable-next-line no-console console.warn( - `[softwarecatalog] IGNORING sibling @conduction/nextcloud-vue@${localVersion} — ` + `[stackiq] IGNORING sibling @conduction/nextcloud-vue@${localVersion} — ` + "it does not satisfy this app's declared range. Building against the npm dist.", ) } From 84900fd287fcd61b8950b60a7b9f8eab452d0860 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 22 Aug 2026 18:24:53 +0200 Subject: [PATCH 02/14] refactor(rename): git mv app-named files and dirs to the stackiq spelling --- ...ogEventListener.php => StackiqEventListener.php} | 0 .../{SoftwareCatalogAdmin.php => StackiqAdmin.php} | 0 .../{SoftwareCatalogue => Stackiq}/ApiClient.php | 0 .../ConflictResolver.php | 0 .../ContactPersonHandler.php | 0 .../{SoftwareCatalogue => Stackiq}/DataMapper.php | 0 .../{SoftwareCatalogue => Stackiq}/GroupHandler.php | 0 .../HierarchyHandler.php | 0 .../OrganizationHandler.php | 0 ...yncService.php => StackiqContactSyncService.php} | 0 ...twareCatalogueService.php => StackiqService.php} | 0 .../{SoftwareCatalogAdmin.php => StackiqAdmin.php} | 0 .../.openspec.yaml | 0 .../design.md | 0 .../proposal.md | 0 .../specs/stackiq-mcp-adoption}/spec.md | 0 .../tasks.md | 0 ...twarecatalogus-tests.json => stackiq-tests.json} | 0 .../{softwarecatalogPlugin.js => stackiqPlugin.js} | 0 ...twareCatalogSettings.vue => StackiqSettings.vue} | 0 ...hp => StackiqEventListenerDecompositionTest.php} | 0 ...istenerTest.php => StackiqEventListenerTest.php} | 0 .../ContactPersonHandlerDecompositionTest.php | 0 .../GroupHandlerDecompositionTest.php | 0 .../HierarchyHandlerDecompositionTest.php | 0 .../OrganizationHandlerDecompositionTest.php | 0 ...Test.php => StackiqServiceDecompositionTest.php} | 0 ...php => StackiqServiceOrganisationMapperTest.php} | 0 ...atalog.visual.spec.ts => stackiq.visual.spec.ts} | 0 .../dashboard-visual-linux.png | Bin .../organisations-visual-linux.png | Bin ...lection.json => stackiq.postman_collection.json} | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename lib/EventListener/{SoftwareCatalogEventListener.php => StackiqEventListener.php} (100%) rename lib/Sections/{SoftwareCatalogAdmin.php => StackiqAdmin.php} (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/ApiClient.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/ConflictResolver.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/ContactPersonHandler.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/DataMapper.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/GroupHandler.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/HierarchyHandler.php (100%) rename lib/Service/{SoftwareCatalogue => Stackiq}/OrganizationHandler.php (100%) rename lib/Service/{SoftwareCatalogContactSyncService.php => StackiqContactSyncService.php} (100%) rename lib/Service/{SoftwareCatalogueService.php => StackiqService.php} (100%) rename lib/Settings/{SoftwareCatalogAdmin.php => StackiqAdmin.php} (100%) rename openspec/changes/{softwarecatalog-mcp-adoption => stackiq-mcp-adoption}/.openspec.yaml (100%) rename openspec/changes/{softwarecatalog-mcp-adoption => stackiq-mcp-adoption}/design.md (100%) rename openspec/changes/{softwarecatalog-mcp-adoption => stackiq-mcp-adoption}/proposal.md (100%) rename openspec/changes/{softwarecatalog-mcp-adoption/specs/softwarecatalog-mcp-adoption => stackiq-mcp-adoption/specs/stackiq-mcp-adoption}/spec.md (100%) rename openspec/changes/{softwarecatalog-mcp-adoption => stackiq-mcp-adoption}/tasks.md (100%) rename postman/{softwarecatalogus-tests.json => stackiq-tests.json} (100%) rename src/store/plugins/{softwarecatalogPlugin.js => stackiqPlugin.js} (100%) rename src/views/settings/{SoftwareCatalogSettings.vue => StackiqSettings.vue} (100%) rename tests/Unit/EventListener/{SoftwareCatalogEventListenerDecompositionTest.php => StackiqEventListenerDecompositionTest.php} (100%) rename tests/Unit/EventListener/{SoftwareCatalogEventListenerTest.php => StackiqEventListenerTest.php} (100%) rename tests/Unit/Service/{SoftwareCatalogue => Stackiq}/ContactPersonHandlerDecompositionTest.php (100%) rename tests/Unit/Service/{SoftwareCatalogue => Stackiq}/GroupHandlerDecompositionTest.php (100%) rename tests/Unit/Service/{SoftwareCatalogue => Stackiq}/HierarchyHandlerDecompositionTest.php (100%) rename tests/Unit/Service/{SoftwareCatalogue => Stackiq}/OrganizationHandlerDecompositionTest.php (100%) rename tests/Unit/Service/{SoftwareCatalogueServiceDecompositionTest.php => StackiqServiceDecompositionTest.php} (100%) rename tests/Unit/Service/{SoftwareCatalogueServiceOrganisationMapperTest.php => StackiqServiceOrganisationMapperTest.php} (100%) rename tests/e2e/visual/{softwarecatalog.visual.spec.ts => stackiq.visual.spec.ts} (100%) rename tests/e2e/visual/{softwarecatalog.visual.spec.ts-snapshots => stackiq.visual.spec.ts-snapshots}/dashboard-visual-linux.png (100%) rename tests/e2e/visual/{softwarecatalog.visual.spec.ts-snapshots => stackiq.visual.spec.ts-snapshots}/organisations-visual-linux.png (100%) rename tests/integration/{softwarecatalog.postman_collection.json => stackiq.postman_collection.json} (100%) diff --git a/lib/EventListener/SoftwareCatalogEventListener.php b/lib/EventListener/StackiqEventListener.php similarity index 100% rename from lib/EventListener/SoftwareCatalogEventListener.php rename to lib/EventListener/StackiqEventListener.php diff --git a/lib/Sections/SoftwareCatalogAdmin.php b/lib/Sections/StackiqAdmin.php similarity index 100% rename from lib/Sections/SoftwareCatalogAdmin.php rename to lib/Sections/StackiqAdmin.php diff --git a/lib/Service/SoftwareCatalogue/ApiClient.php b/lib/Service/Stackiq/ApiClient.php similarity index 100% rename from lib/Service/SoftwareCatalogue/ApiClient.php rename to lib/Service/Stackiq/ApiClient.php diff --git a/lib/Service/SoftwareCatalogue/ConflictResolver.php b/lib/Service/Stackiq/ConflictResolver.php similarity index 100% rename from lib/Service/SoftwareCatalogue/ConflictResolver.php rename to lib/Service/Stackiq/ConflictResolver.php diff --git a/lib/Service/SoftwareCatalogue/ContactPersonHandler.php b/lib/Service/Stackiq/ContactPersonHandler.php similarity index 100% rename from lib/Service/SoftwareCatalogue/ContactPersonHandler.php rename to lib/Service/Stackiq/ContactPersonHandler.php diff --git a/lib/Service/SoftwareCatalogue/DataMapper.php b/lib/Service/Stackiq/DataMapper.php similarity index 100% rename from lib/Service/SoftwareCatalogue/DataMapper.php rename to lib/Service/Stackiq/DataMapper.php diff --git a/lib/Service/SoftwareCatalogue/GroupHandler.php b/lib/Service/Stackiq/GroupHandler.php similarity index 100% rename from lib/Service/SoftwareCatalogue/GroupHandler.php rename to lib/Service/Stackiq/GroupHandler.php diff --git a/lib/Service/SoftwareCatalogue/HierarchyHandler.php b/lib/Service/Stackiq/HierarchyHandler.php similarity index 100% rename from lib/Service/SoftwareCatalogue/HierarchyHandler.php rename to lib/Service/Stackiq/HierarchyHandler.php diff --git a/lib/Service/SoftwareCatalogue/OrganizationHandler.php b/lib/Service/Stackiq/OrganizationHandler.php similarity index 100% rename from lib/Service/SoftwareCatalogue/OrganizationHandler.php rename to lib/Service/Stackiq/OrganizationHandler.php diff --git a/lib/Service/SoftwareCatalogContactSyncService.php b/lib/Service/StackiqContactSyncService.php similarity index 100% rename from lib/Service/SoftwareCatalogContactSyncService.php rename to lib/Service/StackiqContactSyncService.php diff --git a/lib/Service/SoftwareCatalogueService.php b/lib/Service/StackiqService.php similarity index 100% rename from lib/Service/SoftwareCatalogueService.php rename to lib/Service/StackiqService.php diff --git a/lib/Settings/SoftwareCatalogAdmin.php b/lib/Settings/StackiqAdmin.php similarity index 100% rename from lib/Settings/SoftwareCatalogAdmin.php rename to lib/Settings/StackiqAdmin.php diff --git a/openspec/changes/softwarecatalog-mcp-adoption/.openspec.yaml b/openspec/changes/stackiq-mcp-adoption/.openspec.yaml similarity index 100% rename from openspec/changes/softwarecatalog-mcp-adoption/.openspec.yaml rename to openspec/changes/stackiq-mcp-adoption/.openspec.yaml diff --git a/openspec/changes/softwarecatalog-mcp-adoption/design.md b/openspec/changes/stackiq-mcp-adoption/design.md similarity index 100% rename from openspec/changes/softwarecatalog-mcp-adoption/design.md rename to openspec/changes/stackiq-mcp-adoption/design.md diff --git a/openspec/changes/softwarecatalog-mcp-adoption/proposal.md b/openspec/changes/stackiq-mcp-adoption/proposal.md similarity index 100% rename from openspec/changes/softwarecatalog-mcp-adoption/proposal.md rename to openspec/changes/stackiq-mcp-adoption/proposal.md diff --git a/openspec/changes/softwarecatalog-mcp-adoption/specs/softwarecatalog-mcp-adoption/spec.md b/openspec/changes/stackiq-mcp-adoption/specs/stackiq-mcp-adoption/spec.md similarity index 100% rename from openspec/changes/softwarecatalog-mcp-adoption/specs/softwarecatalog-mcp-adoption/spec.md rename to openspec/changes/stackiq-mcp-adoption/specs/stackiq-mcp-adoption/spec.md diff --git a/openspec/changes/softwarecatalog-mcp-adoption/tasks.md b/openspec/changes/stackiq-mcp-adoption/tasks.md similarity index 100% rename from openspec/changes/softwarecatalog-mcp-adoption/tasks.md rename to openspec/changes/stackiq-mcp-adoption/tasks.md diff --git a/postman/softwarecatalogus-tests.json b/postman/stackiq-tests.json similarity index 100% rename from postman/softwarecatalogus-tests.json rename to postman/stackiq-tests.json diff --git a/src/store/plugins/softwarecatalogPlugin.js b/src/store/plugins/stackiqPlugin.js similarity index 100% rename from src/store/plugins/softwarecatalogPlugin.js rename to src/store/plugins/stackiqPlugin.js diff --git a/src/views/settings/SoftwareCatalogSettings.vue b/src/views/settings/StackiqSettings.vue similarity index 100% rename from src/views/settings/SoftwareCatalogSettings.vue rename to src/views/settings/StackiqSettings.vue diff --git a/tests/Unit/EventListener/SoftwareCatalogEventListenerDecompositionTest.php b/tests/Unit/EventListener/StackiqEventListenerDecompositionTest.php similarity index 100% rename from tests/Unit/EventListener/SoftwareCatalogEventListenerDecompositionTest.php rename to tests/Unit/EventListener/StackiqEventListenerDecompositionTest.php diff --git a/tests/Unit/EventListener/SoftwareCatalogEventListenerTest.php b/tests/Unit/EventListener/StackiqEventListenerTest.php similarity index 100% rename from tests/Unit/EventListener/SoftwareCatalogEventListenerTest.php rename to tests/Unit/EventListener/StackiqEventListenerTest.php diff --git a/tests/Unit/Service/SoftwareCatalogue/ContactPersonHandlerDecompositionTest.php b/tests/Unit/Service/Stackiq/ContactPersonHandlerDecompositionTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogue/ContactPersonHandlerDecompositionTest.php rename to tests/Unit/Service/Stackiq/ContactPersonHandlerDecompositionTest.php diff --git a/tests/Unit/Service/SoftwareCatalogue/GroupHandlerDecompositionTest.php b/tests/Unit/Service/Stackiq/GroupHandlerDecompositionTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogue/GroupHandlerDecompositionTest.php rename to tests/Unit/Service/Stackiq/GroupHandlerDecompositionTest.php diff --git a/tests/Unit/Service/SoftwareCatalogue/HierarchyHandlerDecompositionTest.php b/tests/Unit/Service/Stackiq/HierarchyHandlerDecompositionTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogue/HierarchyHandlerDecompositionTest.php rename to tests/Unit/Service/Stackiq/HierarchyHandlerDecompositionTest.php diff --git a/tests/Unit/Service/SoftwareCatalogue/OrganizationHandlerDecompositionTest.php b/tests/Unit/Service/Stackiq/OrganizationHandlerDecompositionTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogue/OrganizationHandlerDecompositionTest.php rename to tests/Unit/Service/Stackiq/OrganizationHandlerDecompositionTest.php diff --git a/tests/Unit/Service/SoftwareCatalogueServiceDecompositionTest.php b/tests/Unit/Service/StackiqServiceDecompositionTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogueServiceDecompositionTest.php rename to tests/Unit/Service/StackiqServiceDecompositionTest.php diff --git a/tests/Unit/Service/SoftwareCatalogueServiceOrganisationMapperTest.php b/tests/Unit/Service/StackiqServiceOrganisationMapperTest.php similarity index 100% rename from tests/Unit/Service/SoftwareCatalogueServiceOrganisationMapperTest.php rename to tests/Unit/Service/StackiqServiceOrganisationMapperTest.php diff --git a/tests/e2e/visual/softwarecatalog.visual.spec.ts b/tests/e2e/visual/stackiq.visual.spec.ts similarity index 100% rename from tests/e2e/visual/softwarecatalog.visual.spec.ts rename to tests/e2e/visual/stackiq.visual.spec.ts diff --git a/tests/e2e/visual/softwarecatalog.visual.spec.ts-snapshots/dashboard-visual-linux.png b/tests/e2e/visual/stackiq.visual.spec.ts-snapshots/dashboard-visual-linux.png similarity index 100% rename from tests/e2e/visual/softwarecatalog.visual.spec.ts-snapshots/dashboard-visual-linux.png rename to tests/e2e/visual/stackiq.visual.spec.ts-snapshots/dashboard-visual-linux.png diff --git a/tests/e2e/visual/softwarecatalog.visual.spec.ts-snapshots/organisations-visual-linux.png b/tests/e2e/visual/stackiq.visual.spec.ts-snapshots/organisations-visual-linux.png similarity index 100% rename from tests/e2e/visual/softwarecatalog.visual.spec.ts-snapshots/organisations-visual-linux.png rename to tests/e2e/visual/stackiq.visual.spec.ts-snapshots/organisations-visual-linux.png diff --git a/tests/integration/softwarecatalog.postman_collection.json b/tests/integration/stackiq.postman_collection.json similarity index 100% rename from tests/integration/softwarecatalog.postman_collection.json rename to tests/integration/stackiq.postman_collection.json From d634288c50154841b05ca718c40ae132b4161bf9 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 22 Aug 2026 18:36:37 +0200 Subject: [PATCH 03/14] feat(rename): repair steps carrying appconfig, user preferences and job 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 and . matters because an app-id rename presents to Nextcloud as a FIRST install of stackiq, and installAppLastSteps() guards with $previousVersion !== '' -- so 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. --- lib/Repair/MigrateAppConfigKeys.php | 229 ++++++++++++++ lib/Repair/MigrateBackgroundJobClasses.php | 137 ++++++++ lib/Repair/MigrateUserPreferences.php | 185 +++++++++++ .../rename-app-id-to-stackiq/hydra.json | 8 + .../rename-app-id-to-stackiq/proposal.md | 71 +++++ .../specs/app-id-rename/spec.md | 153 +++++++++ .../changes/rename-app-id-to-stackiq/tasks.md | 39 +++ .../Unit/Repair/MigrateAppConfigKeysTest.php | 299 ++++++++++++++++++ .../MigrateBackgroundJobClassesTest.php | 148 +++++++++ .../Repair/MigrateUserPreferencesTest.php | 270 ++++++++++++++++ 10 files changed, 1539 insertions(+) create mode 100644 lib/Repair/MigrateAppConfigKeys.php create mode 100644 lib/Repair/MigrateBackgroundJobClasses.php create mode 100644 lib/Repair/MigrateUserPreferences.php create mode 100644 openspec/changes/rename-app-id-to-stackiq/hydra.json create mode 100644 openspec/changes/rename-app-id-to-stackiq/proposal.md create mode 100644 openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md create mode 100644 openspec/changes/rename-app-id-to-stackiq/tasks.md create mode 100644 tests/Unit/Repair/MigrateAppConfigKeysTest.php create mode 100644 tests/Unit/Repair/MigrateBackgroundJobClassesTest.php create mode 100644 tests/Unit/Repair/MigrateUserPreferencesTest.php diff --git a/lib/Repair/MigrateAppConfigKeys.php b/lib/Repair/MigrateAppConfigKeys.php new file mode 100644 index 00000000..dc0420c3 --- /dev/null +++ b/lib/Repair/MigrateAppConfigKeys.php @@ -0,0 +1,229 @@ +` and `` and MUST stay + * there. `InitializeSettings` writes app config itself; if it ran first, every + * key it touched would look "already present" here and the operator's real + * value would stay stranded in the old namespace forever. + * + * All OCP service calls use POSITIONAL arguments (named args are FATAL on + * `occ upgrade`). + * + * @category Repair + * @package OCA\Stackiq\Repair + * @author Conduction b.v. + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * @version GIT: + * @link https://github.com/ConductionNL/stackiq + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-app-config-survives-the-rename + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Repair; + +use OCA\Stackiq\AppInfo\Application; +use OCP\IAppConfig; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; +use Psr\Log\LoggerInterface; +use Throwable; + +/** + * Copies app config from the legacy `softwarecatalog` app id to `stackiq`. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-app-config-survives-the-rename + */ +class MigrateAppConfigKeys implements IRepairStep { + /** + * The app id every stored row was written under before the rename. + */ + public const LEGACY_APP_ID = 'softwarecatalog'; + + /** + * Keys Nextcloud owns in every app's namespace. These MUST NOT be copied. + * + * `enabled` is the dangerous one. `AppManager::enableApp()` writes it as + * type MIXED; copying it with `setValueString()` stores it as STRING, and + * the next `occ app:enable` then fails permanently with + * `AppConfigTypeConflictException` — a conflict that is hit BEFORE the app + * can run anything that would repair it. `installed_version` and `types` + * are Nextcloud's own bookkeeping for the new id and are already correct. + */ + private const RESERVED_KEYS = [ + 'enabled', + 'installed_version', + 'types', + ]; + + /** + * Constructor. + * + * @param IAppConfig $appConfig The typed app config service. + * @param LoggerInterface $logger The logger. + */ + public function __construct( + private readonly IAppConfig $appConfig, + private readonly LoggerInterface $logger, + ) { + }//end __construct() + + /** + * Returns the name of this repair step. + * + * @return string The repair step name. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-app-config-survives-the-rename + */ + public function getName(): string { + return 'Migrate app config from the softwarecatalog app id to stackiq'; + }//end getName() + + /** + * Copy every non-reserved app config key from the legacy app id. + * + * Both the READS and the WRITE sit inside the try. This step runs under + * `` — the only hook that fires on the fresh install an app-id + * rename performs — so an escaping throw aborts the install and the app + * never enables at all. A config key that fails to copy is a reverted + * setting; a failed install is no app. + * + * @param IOutput $output The output interface for progress reporting. + * + * @return void + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-app-config-survives-the-rename + */ + public function run(IOutput $output): void { + try { + // Exhaustive enumeration. getKeys() lists every key stored under the + // old app id regardless of value — the alternative shapes + // (searchValues, getUsersForUserValue) all match on a VALUE, so over + // an open value set they migrate nothing and report success. + $keys = $this->appConfig->getKeys(self::LEGACY_APP_ID); + + // Values come from getAllValues() rather than the typed getters + // because it returns each row in its STORED type without asserting + // one. getValueString() on a key stored as MIXED or INT raises + // AppConfigTypeConflictException, which would abort the whole copy + // on the first typed key it met. + $values = $this->appConfig->getAllValues(self::LEGACY_APP_ID); + + $copied = 0; + $skipped = 0; + + foreach ($keys as $key) { + if (in_array($key, self::RESERVED_KEYS, true) === true) { + $skipped++; + continue; + } + + // Never clobber a value the new namespace already holds — either + // a previous run copied it, or an admin has since changed it. + if ($this->appConfig->hasKey(Application::APP_ID, $key) === true) { + $skipped++; + continue; + } + + if (array_key_exists($key, $values) === false) { + $skipped++; + continue; + } + + if ($this->copyValue($key, $values[$key]) === true) { + $copied++; + } else { + $skipped++; + } + } + + $output->info( + sprintf( + 'Stackiq: migrated %d app config key(s) from "%s" (skipped %d)', + $copied, + self::LEGACY_APP_ID, + $skipped + ) + ); + } catch (Throwable $e) { + // Swallowed deliberately — see the docblock. Logged at error level so + // the reverted-settings symptom has a cause to find. + $this->logger->error( + 'Stackiq: failed to migrate app config from the legacy app id: ' . $e->getMessage(), + [ + 'app' => Application::APP_ID, + 'exception' => $e, + ] + ); + $output->warning('Stackiq: app config migration failed; see the log. Settings may have reverted to defaults.'); + }//end try + }//end run() + + /** + * Write one legacy value into the new namespace in its own type. + * + * Empty strings and empty arrays are treated as "nothing stored" and are + * not copied — an empty value is indistinguishable from the default every + * reader already supplies, so copying it adds a row and changes nothing. + * Scalars are copied as-is: `false` and `0` are real, chosen values. + * + * @param string $key The config key. + * @param mixed $value The value as stored under the legacy app id. + * + * @return bool True when a value was written. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-app-config-survives-the-rename + */ + protected function copyValue(string $key, mixed $value): bool { + if (is_bool($value) === true) { + $this->appConfig->setValueBool(Application::APP_ID, $key, $value); + return true; + } + + if (is_int($value) === true) { + $this->appConfig->setValueInt(Application::APP_ID, $key, $value); + return true; + } + + if (is_float($value) === true) { + $this->appConfig->setValueFloat(Application::APP_ID, $key, $value); + return true; + } + + if (is_array($value) === true) { + if ($value === []) { + return false; + } + + $this->appConfig->setValueArray(Application::APP_ID, $key, $value); + return true; + } + + $string = (string)$value; + if ($string === '') { + return false; + } + + $this->appConfig->setValueString(Application::APP_ID, $key, $string); + return true; + }//end copyValue() +}//end class diff --git a/lib/Repair/MigrateBackgroundJobClasses.php b/lib/Repair/MigrateBackgroundJobClasses.php new file mode 100644 index 00000000..1fd05941 --- /dev/null +++ b/lib/Repair/MigrateBackgroundJobClasses.php @@ -0,0 +1,137 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * @version GIT: + * @link https://github.com/ConductionNL/stackiq + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-background-job-classes-survive-the-rename + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Repair; + +use OCA\Stackiq\AppInfo\Application; +use OCP\BackgroundJob\IJobList; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; +use Psr\Log\LoggerInterface; +use Throwable; + +/** + * Removes background job registrations left behind by the namespace rename. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-background-job-classes-survive-the-rename + */ +class MigrateBackgroundJobClasses implements IRepairStep { + /** + * The exact job class strings written to `oc_jobs` before the rename. + * + * Written out in full rather than derived from the current class names, + * so that a later namespace change cannot silently widen what this step + * deletes. These four are the complete `` list as it stood + * in `appinfo/info.xml` before the rename. + */ + public const LEGACY_JOB_CLASSES = [ + 'OCA\SoftwareCatalog\BackgroundJob\OrganizationContactSyncJob', + 'OCA\SoftwareCatalog\BackgroundJob\ContractStatusJob', + 'OCA\SoftwareCatalog\BackgroundJob\FederationSyncJob', + 'OCA\SoftwareCatalog\BackgroundJob\EolSyncJob', + ]; + + /** + * Constructor. + * + * @param IJobList $jobList The background job list. + * @param LoggerInterface $logger The logger. + */ + public function __construct( + private readonly IJobList $jobList, + private readonly LoggerInterface $logger, + ) { + }//end __construct() + + /** + * Returns the name of this repair step. + * + * @return string The repair step name. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-background-job-classes-survive-the-rename + */ + public function getName(): string { + return 'Deregister background jobs orphaned by the OCA\\SoftwareCatalog namespace rename'; + }//end getName() + + /** + * Remove every legacy job registration. + * + * The whole body sits inside the try. This step runs under `` — + * the only hook that fires on the fresh install an app-id rename performs — + * so an escaping throw aborts the install and the app never enables at all. + * + * @param IOutput $output The output interface for progress reporting. + * + * @return void + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-background-job-classes-survive-the-rename + */ + public function run(IOutput $output): void { + try { + $removed = 0; + + foreach (self::LEGACY_JOB_CLASSES as $legacyClass) { + // remove() is a no-op when the row is absent, so has() is only an + // accounting call — it keeps the reported count honest on a + // re-run rather than claiming work that did not happen. + if ($this->jobList->has($legacyClass, null) === false) { + continue; + } + + $this->jobList->remove($legacyClass, null); + $removed++; + } + + $output->info( + sprintf('Stackiq: deregistered %d orphaned background job(s) from the legacy namespace', $removed) + ); + } catch (Throwable $e) { + // Swallowed deliberately — see the docblock. + $this->logger->error( + 'Stackiq: failed to deregister legacy background jobs: ' . $e->getMessage(), + [ + 'app' => Application::APP_ID, + 'exception' => $e, + ] + ); + $output->warning('Stackiq: legacy background job cleanup failed; see the log.'); + }//end try + }//end run() +}//end class diff --git a/lib/Repair/MigrateUserPreferences.php b/lib/Repair/MigrateUserPreferences.php new file mode 100644 index 00000000..31d32b6d --- /dev/null +++ b/lib/Repair/MigrateUserPreferences.php @@ -0,0 +1,185 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * @version GIT: + * @link https://github.com/ConductionNL/stackiq + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-user-preferences-survive-the-rename + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Repair; + +use Closure; +use OCA\Stackiq\AppInfo\Application; +use OCP\IConfig; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; +use Psr\Log\LoggerInterface; +use Throwable; + +/** + * Copies per-user preferences from the legacy `softwarecatalog` app id to `stackiq`. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-user-preferences-survive-the-rename + */ +class MigrateUserPreferences implements IRepairStep { + /** + * The app id every stored preference was written under before the rename. + */ + public const LEGACY_APP_ID = 'softwarecatalog'; + + /** + * Number of preference values copied during the current run. + */ + private int $copied = 0; + + /** + * Number of users that carried at least one legacy preference. + */ + private int $users = 0; + + /** + * Constructor. + * + * @param IConfig $config The user config service. + * @param IUserManager $userManager The user manager. + * @param LoggerInterface $logger The logger. + */ + public function __construct( + private readonly IConfig $config, + private readonly IUserManager $userManager, + private readonly LoggerInterface $logger, + ) { + }//end __construct() + + /** + * Returns the name of this repair step. + * + * @return string The repair step name. + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-user-preferences-survive-the-rename + */ + public function getName(): string { + return 'Migrate user preferences from the softwarecatalog app id to stackiq'; + }//end getName() + + /** + * Copy every legacy preference for every seen user. + * + * Both the READS and the WRITES sit inside the try. This step runs under + * `` — the only hook that fires on the fresh install an app-id + * rename performs — so an escaping throw aborts the install and the app + * never enables at all. + * + * @param IOutput $output The output interface for progress reporting. + * + * @return void + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-user-preferences-survive-the-rename + */ + public function run(IOutput $output): void { + $this->copied = 0; + $this->users = 0; + + try { + $this->userManager->callForSeenUsers( + Closure::fromCallable([$this, 'migrateUser']) + ); + + $output->info( + sprintf( + 'Stackiq: migrated %d user preference value(s) for %d user(s) from "%s"', + $this->copied, + $this->users, + self::LEGACY_APP_ID + ) + ); + } catch (Throwable $e) { + // Swallowed deliberately — see the docblock. + $this->logger->error( + 'Stackiq: failed to migrate user preferences from the legacy app id: ' . $e->getMessage(), + [ + 'app' => Application::APP_ID, + 'exception' => $e, + ] + ); + $output->warning('Stackiq: user preference migration failed; see the log. Users may see default view settings.'); + }//end try + }//end run() + + /** + * Copy one user's legacy preferences into the new namespace. + * + * @param IUser $user The user to migrate. + * + * @return void + * + * @spec openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md#requirement-stored-user-preferences-survive-the-rename + */ + protected function migrateUser(IUser $user): void { + $userId = $user->getUID(); + + // Exhaustive per-user enumeration. getUserKeys() lists the keys this + // user actually holds under the old app id — it needs no value to match, + // which is exactly why getUsersForUserValue() is unusable here. + $keys = $this->config->getUserKeys($userId, self::LEGACY_APP_ID); + if ($keys === []) { + return; + } + + $touched = false; + + foreach ($keys as $key) { + $legacy = $this->config->getUserValue($userId, self::LEGACY_APP_ID, $key, ''); + if ($legacy === '') { + continue; + } + + // Never clobber a value the new namespace already holds. + $current = $this->config->getUserValue($userId, Application::APP_ID, $key, ''); + if ($current !== '') { + continue; + } + + $this->config->setUserValue($userId, Application::APP_ID, $key, $legacy); + $this->copied++; + $touched = true; + } + + if ($touched === true) { + $this->users++; + } + }//end migrateUser() +}//end class diff --git a/openspec/changes/rename-app-id-to-stackiq/hydra.json b/openspec/changes/rename-app-id-to-stackiq/hydra.json new file mode 100644 index 00000000..db776a48 --- /dev/null +++ b/openspec/changes/rename-app-id-to-stackiq/hydra.json @@ -0,0 +1,8 @@ +{ + "spec_slug": "rename-app-id-to-stackiq", + "title": "Rename the app id from softwarecatalog to stackiq", + "app": "stackiq", + "repo": "https://github.com/ConductionNL/stackiq", + "depends_on": [], + "issue": null +} diff --git a/openspec/changes/rename-app-id-to-stackiq/proposal.md b/openspec/changes/rename-app-id-to-stackiq/proposal.md new file mode 100644 index 00000000..64dc37a4 --- /dev/null +++ b/openspec/changes/rename-app-id-to-stackiq/proposal.md @@ -0,0 +1,71 @@ +--- +kind: code +--- + +# Proposal: Rename the app id from `softwarecatalog` to `stackiq` + +## Problem + +The repository was renamed to `ConductionNL/stackiq` in the 2026-08 fleet +renaming, but the app itself was not: `appinfo/info.xml` still declares +`softwarecatalog` and `SoftwareCatalog`. Until +the id moves, the repo name and the installed app disagree, `occ` commands and +URLs still carry the old name, and every later change has to keep straddling +both spellings. + +Moving an app id is not a search-and-replace, because **Nextcloud has no +in-place app-id upgrade**. `oc_appconfig` and `oc_preferences` are namespaced by +app id; the moment the id changes, every row written under the old one becomes +unreachable. Nothing errors — every reader in this codebase supplies a default — +so admin settings and per-user preferences silently revert and the instance +looks freshly installed. `oc_jobs` has the same shape one level down: it stores +the background job's CLASS NAME as a string, so the namespace rename orphans all +four job rows and they simply stop running. + +The mirror-image risk is renaming too much. Several identifiers in this tree are +**values other systems store and match on**, not names this app owns. Rewriting +one of those does not fail loudly either — it produces a working-looking app that +quietly does less: a group check that matches nobody, a dashboard widget that +vanishes from every dashboard, an OpenRegister import that creates a second +configuration and orphans the first, a documentation deploy to a host with no DNS +record. + +## Proposed Change + +1. **Move the identity.** `` -> `stackiq`, `` -> `Stackiq`, PHP + root namespace `OCA\SoftwareCatalog` -> `OCA\Stackiq`, l10n domain, URL and + route prefixes, webpack bundle prefix, DOM mount ids, composer/npm package + names, and the display name -> "Stackiq". App-named classes and files move + with it (`SoftwareCatalogueService` -> `StackiqService`, + `lib/Service/SoftwareCatalogue/` -> `lib/Service/Stackiq/`, + `SoftwareCatalogAdmin` -> `StackiqAdmin`, and their tests). + +2. **Carry the stored data across.** Three new `IRepairStep`s — + `MigrateAppConfigKeys`, `MigrateUserPreferences`, + `MigrateBackgroundJobClasses` — registered FIRST in both `` and + ``. Ordering is load-bearing: `InitializeSettings` writes app + config itself, so if it ran first the copy step would see the key as already + present and strand the operator's real value. `` matters because an + app-id rename presents to Nextcloud as a FIRST install of `stackiq`, and + `Installer::installAppLastSteps()` guards `` with + `if ($previousVersion !== '')` — so `` is the only hook that fires on + the very upgrade these steps exist for. + +3. **Freeze what this app does not own**, each with a comment naming the + consequence so a later tidy-up does not undo it. The full inventory is in the + spec's "Externally Owned Identifiers Stay Frozen" requirement. + +## Non-goals + +- Registering `stackiq` with the Nextcloud App Store, or issuing the signing + certificate for the new id. `.nextcloud/certificates/softwarecatalog.csr` is + left as-is; a maintainer action is required before a stable release publishes + under the new id. +- Moving `softwarecatalog.conduction.nl` / `www.conduction.nl/apps/softwarecatalog` + or the `softwarecatalog-docs` Cloudflare Pages project. Those move when DNS and + the Pages binding move, in a change that verifies both. +- Renaming `openspec/specs/*` capability directories. They are referenced from + `openspec/changes/archive/**`, which is frozen history. +- Renaming PHP/JS method, property and local-variable names that contain the + product name. Several are named after the frozen group ids, and renaming a + method declaration drags it into gate-16's diff scope for no functional gain. diff --git a/openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md b/openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md new file mode 100644 index 00000000..7bf7a3fa --- /dev/null +++ b/openspec/changes/rename-app-id-to-stackiq/specs/app-id-rename/spec.md @@ -0,0 +1,153 @@ +--- +status: proposed +--- + +# App-Id Rename: softwarecatalog to stackiq + +## Purpose + +The app's Nextcloud id moves from `softwarecatalog` to `stackiq`, and its PHP +namespace from `OCA\SoftwareCatalog` to `OCA\Stackiq`, without losing a single +stored value and without rewriting any identifier another system owns. + +The reason this needs a spec at all is that **the failure mode of getting it +wrong is silence.** Nextcloud namespaces `oc_appconfig` and `oc_preferences` by +app id and offers no in-place app-id upgrade. Every reader in this codebase +supplies a default, so a row that becomes unreachable does not raise — the +setting simply reverts to its default and the instance looks freshly installed. +The same shape applies to every identifier stored outside this app's own +namespace: a group id, a dashboard widget id, an OpenRegister configuration +appId, a DNS name. Renaming any of those produces a working-looking app that +quietly does less. + +--- + +## Requirements + +### Requirement: The App Identity Is stackiq + +The app SHALL declare `stackiq` as its Nextcloud app id in `appinfo/info.xml` +and `Stackiq` as its ``, and SHALL use `stackiq` consistently as its +l10n domain, its URL prefix (`/apps/stackiq/...`), its route-name prefix, its +webpack bundle prefix, its DOM mount-point id, and its composer/npm package +name. The PHP root namespace SHALL be `OCA\Stackiq`. + +#### Scenario: The app enables and serves its SPA under the new id + +- **GIVEN** a Nextcloud instance with OpenRegister installed +- **WHEN** `occ app:enable stackiq` runs and a user opens `/apps/stackiq/` +- **THEN** the navigation entry MUST resolve via route `stackiq.dashboard.page`, the SPA MUST mount on `#stackiq`, and its scripts MUST load from `/apps/stackiq/js/stackiq-main.js` +- @e2e exclude Covered by the existing e2e suite, which navigates the app by its `/apps//` base URL; the rename retargets that suite rather than adding a scenario to it. + +#### Scenario: Translations resolve under the new domain + +- **GIVEN** a browser with the Dutch locale +- **WHEN** the SPA calls `t('stackiq', 'Applications')` +- **THEN** the string MUST resolve from `l10n/nl.js`, whose `OC.L10N.register` domain is `stackiq` +- @e2e exclude Assertable offline; `tests/l10n/check-l10n.js` enforces domain/msgid parity across all 38 locales. + +### Requirement: Stored App Config Survives The Rename + +On both fresh install and upgrade, the app SHALL copy every `oc_appconfig` key +stored under the app id `softwarecatalog` into the `stackiq` namespace before +any other repair step writes app config. + +The enumeration SHALL be exhaustive (`IAppConfig::getKeys()` over the old app +id), the copy SHALL be non-destructive (the old rows are never deleted) and +idempotent (a key already present under the new id is left alone), and the +Nextcloud-reserved keys `enabled`, `installed_version` and `types` SHALL be +skipped. + +#### Scenario: An operator's admin settings survive the rename + +- **GIVEN** an instance where `softwarecatalog` has `federation_enabled = true` and `federation_directory_url` set +- **WHEN** the renamed app is installed and the repair step runs +- **THEN** both keys MUST be readable under app id `stackiq` with their original values, and the original `softwarecatalog` rows MUST still exist +- @e2e exclude Repair-step behaviour with no UI surface; covered by `tests/Unit/Repair/MigrateAppConfigKeysTest.php`. + +#### Scenario: The reserved `enabled` key is never copied + +- **GIVEN** an instance where `AppManager::enableApp()` has written `enabled` as a MIXED-typed value +- **WHEN** the repair step runs +- **THEN** it MUST skip `enabled`, `installed_version` and `types`, because copying `enabled` with `setValueString()` stores it as STRING and the next `occ app:enable` then fails permanently with `AppConfigTypeConflictException` — a conflict hit before the app can run anything that would repair it +- @e2e exclude Repair-step behaviour with no UI surface; covered by `tests/Unit/Repair/MigrateAppConfigKeysTest.php`. + +#### Scenario: The step runs before any step that writes config + +- **GIVEN** `InitializeSettings` also writes app config +- **WHEN** the repair steps are ordered in `appinfo/info.xml` +- **THEN** the migration step MUST be declared FIRST in both `` and ``, because a step that writes first makes the key look "already present" and strands the operator's real value in the old namespace forever +- @e2e exclude Declaration ordering in `appinfo/info.xml`; verified by reading the manifest, not by a browser. + +### Requirement: Stored User Preferences Survive The Rename + +On both fresh install and upgrade, the app SHALL copy every `oc_preferences` +value stored under the app id `softwarecatalog`, for every seen user, into the +`stackiq` namespace. + +The user enumeration SHALL use `IUserManager::callForSeenUsers()` combined with +`IConfig::getUserKeys()`. It SHALL NOT use `getUsersForUserValue()`: that method +matches on a VALUE, so over the open value set this app stores (`pref_*` holds +arbitrary user-chosen view state) it migrates nothing and reports success. + +#### Scenario: A user's saved view preference survives the rename + +- **GIVEN** a user who has stored `pref_applications-view = table` under app id `softwarecatalog` +- **WHEN** the renamed app is installed and the repair step runs +- **THEN** `getUserValue($uid, 'stackiq', 'pref_applications-view')` MUST return `table` +- @e2e exclude Repair-step behaviour with no UI surface; covered by `tests/Unit/Repair/MigrateUserPreferencesTest.php`. + +#### Scenario: A failure in one user does not abort the install + +- **GIVEN** the step runs under ``, the only hook that fires on the fresh install an app-id rename performs +- **WHEN** any read or write throws +- **THEN** the exception MUST be caught and logged rather than escaping, because an escaping throw aborts the install and the app never enables at all +- @e2e exclude Repair-step behaviour with no UI surface; covered by `tests/Unit/Repair/MigrateUserPreferencesTest.php`. + +### Requirement: Stored Background Job Classes Survive The Rename + +The app SHALL deregister the four `oc_jobs` rows whose stored `class` string +carries the old `OCA\SoftwareCatalog\BackgroundJob\` prefix, so that Nextcloud's +own `` registration of the `OCA\Stackiq\BackgroundJob\` +classes is the only surviving registration. + +#### Scenario: The orphaned job rows are removed + +- **GIVEN** an instance whose `oc_jobs` table holds `OCA\SoftwareCatalog\BackgroundJob\ContractStatusJob` +- **WHEN** the repair step runs +- **THEN** that row MUST be removed, because the class no longer exists: the job silently never runs again and nothing reports it +- @e2e exclude Repair-step behaviour with no UI surface; covered by `tests/Unit/Repair/MigrateBackgroundJobClassesTest.php`. + +### Requirement: Externally Owned Identifiers Stay Frozen + +The rename SHALL NOT change any identifier whose authority lives outside this +app. Specifically it SHALL leave unchanged: the Nextcloud group ids +`software-catalog-users` and `software-catalog-admins`; the dashboard widget id +`softwarecatalog_concept_organisaties_widget`; the appId this app passes to +OpenRegister's configuration importer and the `sourceUrl` / +`lib/Settings/softwarecatalogus_register.json` filename that accompanies it; the +live hosts `softwarecatalog.conduction.nl` and +`www.conduction.nl/apps/softwarecatalog`; the Cloudflare Pages project +`softwarecatalog-docs`; VNG's own `softwarecatalogus.nl` identifiers; and every +other Conduction app's id and namespace. + +#### Scenario: Group membership still resolves after the rename + +- **GIVEN** users who are members of the Nextcloud group `software-catalog-admins` +- **WHEN** an authorization check runs after the rename +- **THEN** it MUST still test membership of `software-catalog-admins`, because Nextcloud stores membership by group id in `oc_group_user` and a renamed literal makes every check miss — silently dropping everyone's permissions rather than erroring +- @e2e exclude Asserted at the unit level against the frozen literals; no UI path exercises a group rename. + +#### Scenario: OpenRegister still recognises its own configuration row + +- **GIVEN** OpenRegister holds a Configuration row created with `appId = "softwarecatalog"` +- **WHEN** this app calls `getConfiguredAppVersion()` and `importFromApp()` +- **THEN** it MUST keep passing the literal `softwarecatalog`, because OpenRegister looks the row up by that string in ITS OWN namespace: a new appId makes it see an app it has never configured, import a SECOND configuration, and orphan the existing registers and schemas without an error +- @e2e exclude Cross-app persistence behaviour; asserted at the unit level against the frozen constant. + +#### Scenario: Documentation still publishes to a host that resolves + +- **GIVEN** `softwarecatalog.conduction.nl` answers HTTP 200 and `stackiq.conduction.nl` does not resolve +- **WHEN** the documentation workflow deploys +- **THEN** the `cname` input MUST remain `softwarecatalog.conduction.nl`, because publishing at a host with no DNS record takes the documentation site offline — a regression, not a rename +- @e2e exclude CI workflow input; verified by probing both hosts, not by a browser test. diff --git a/openspec/changes/rename-app-id-to-stackiq/tasks.md b/openspec/changes/rename-app-id-to-stackiq/tasks.md new file mode 100644 index 00000000..a8b14350 --- /dev/null +++ b/openspec/changes/rename-app-id-to-stackiq/tasks.md @@ -0,0 +1,39 @@ +# Tasks: Rename the app id from `softwarecatalog` to `stackiq` + +## 1. App identity + +- [x] `appinfo/info.xml`: `` -> `stackiq`, `` -> `Stackiq`, display names -> "Stackiq", navigation id/name/route. +- [x] `composer.json` psr-4 `OCA\Stackiq\` + package name `conductionnl/stackiq`. +- [x] `package.json` / `package-lock.json` name -> `stackiq` (both `name` fields; `npm ci` fails if they disagree). +- [x] `webpack.config.js` `appId`, bundle names, log prefix. +- [x] `templates/index.php` + `templates/settings/admin.php` mount ids -> `#stackiq` / `#stackiq-settings`. +- [x] PHP root namespace `OCA\SoftwareCatalog` -> `OCA\Stackiq` across `lib/` and `tests/`. +- [x] `git mv` app-named classes/files and update their contents. +- [x] Frontend l10n domain, `/apps/stackiq/` URLs, route names. +- [x] `l10n/*.js` `OC.L10N.register` domain; product-name msgids and their translations. +- [x] CI callers: `app-name` / `app-id` inputs, seed command path, docker-compose CI names. + +## 2. Data migration (the point of the PR) + +- [x] `lib/Repair/MigrateAppConfigKeys.php` — `IAppConfig::getKeys('softwarecatalog')`, skip `enabled` / `installed_version` / `types`, copy-only-if-absent, non-destructive, whole body in try. +- [x] `lib/Repair/MigrateUserPreferences.php` — `callForSeenUsers()` + `getUserKeys()`; NOT `getUsersForUserValue()`. +- [x] `lib/Repair/MigrateBackgroundJobClasses.php` — deregister the four orphaned `oc_jobs` rows. +- [x] All three registered FIRST in BOTH `` and ``. +- [x] Unit tests for all three, in the same commit as the steps. +- [x] Confirm the classes are TRACKED (`git check-ignore -v lib/Repair/*.php`, `git ls-files lib/Repair/`). + +## 3. Freezes + +- [x] Group ids `software-catalog-users` / `software-catalog-admins` — left, commented. +- [x] Dashboard widget id `softwarecatalog_concept_organisaties_widget` — left, commented. +- [x] OpenRegister importer appId + `lib/Settings/softwarecatalogus_register.json` — left, commented. +- [x] Live hosts + Cloudflare Pages project — left, commented, both names probed. +- [x] VNG `softwarecatalogus.nl` identifiers, `issues/`, `reacties/` — left. +- [x] `openspec/changes/archive/**` and `openspec/specs/*` directory names — left. + +## 4. Verification + +- [x] `composer cs:fix` before pushing (`OCA\Stackiq` sorts differently against `OCA\OpenRegister`). +- [x] `composer check:strict`, `npm run lint`, `npm run test`. +- [x] gate-16 spec-coverage and gate-46 spec-anchors run locally, not round-tripped through CI. +- [x] Full-tree sweep: every remaining `softwarecatalog` hit classified as renamed or frozen-with-reason. diff --git a/tests/Unit/Repair/MigrateAppConfigKeysTest.php b/tests/Unit/Repair/MigrateAppConfigKeysTest.php new file mode 100644 index 00000000..22df8959 --- /dev/null +++ b/tests/Unit/Repair/MigrateAppConfigKeysTest.php @@ -0,0 +1,299 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * @version GIT: + * + * @link https://github.com/ConductionNL/stackiq + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Tests\Unit\Repair; + +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Repair\MigrateAppConfigKeys; +use OCP\IAppConfig; +use OCP\Migration\IOutput; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use RuntimeException; + +/** + * @covers \OCA\Stackiq\Repair\MigrateAppConfigKeys + */ +class MigrateAppConfigKeysTest extends TestCase { + /** + * The legacy app id every stored row was written under. + * + * Spelled out literally rather than read from the class under test: if the + * constant ever moved, reading it here would make the test agree with the + * change instead of catching it. + * + * @var string + */ + private const LEGACY = 'softwarecatalog'; + + /** + * The step reports a name that says what it does. + * + * @return void + */ + public function testGetNameDescribesTheMigration(): void { + $appConfig = $this->createMock(IAppConfig::class); + $step = new MigrateAppConfigKeys($appConfig, new NullLogger()); + + $this->assertStringContainsString('softwarecatalog', $step->getName()); + $this->assertStringContainsString('stackiq', $step->getName()); + }//end testGetNameDescribesTheMigration() + + /** + * The legacy app id is exactly the pre-rename app id. + * + * @return void + */ + public function testLegacyAppIdIsTheOldAppId(): void { + $this->assertSame(self::LEGACY, MigrateAppConfigKeys::LEGACY_APP_ID); + $this->assertNotSame(Application::APP_ID, MigrateAppConfigKeys::LEGACY_APP_ID); + }//end testLegacyAppIdIsTheOldAppId() + + /** + * A plain string value is copied into the new namespace. + * + * @return void + */ + public function testCopiesStringValueToTheNewAppId(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->with(self::LEGACY)->willReturn(['federation_directory_url']); + $appConfig->method('getAllValues')->with(self::LEGACY)->willReturn( + ['federation_directory_url' => 'https://directory.example.org'] + ); + $appConfig->method('hasKey')->willReturn(false); + + $appConfig->expects($this->once()) + ->method('setValueString') + ->with(Application::APP_ID, 'federation_directory_url', 'https://directory.example.org') + ->willReturn(true); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testCopiesStringValueToTheNewAppId() + + /** + * The stored TYPE survives the copy. + * + * A bool written back as the string "1" reads as a different value through + * `getValueBool()` on some drivers and raises a type conflict on others, so + * the type is not cosmetic. + * + * @return void + */ + public function testPreservesTheStoredValueType(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['federation_enabled', 'page_size', 'ratio']); + $appConfig->method('getAllValues')->willReturn( + [ + 'federation_enabled' => true, + 'page_size' => 250, + 'ratio' => 1.5, + ] + ); + $appConfig->method('hasKey')->willReturn(false); + + $appConfig->expects($this->once())->method('setValueBool') + ->with(Application::APP_ID, 'federation_enabled', true)->willReturn(true); + $appConfig->expects($this->once())->method('setValueInt') + ->with(Application::APP_ID, 'page_size', 250)->willReturn(true); + $appConfig->expects($this->once())->method('setValueFloat') + ->with(Application::APP_ID, 'ratio', 1.5)->willReturn(true); + $appConfig->expects($this->never())->method('setValueString'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testPreservesTheStoredValueType() + + /** + * `false` and `0` are copied — they are chosen values, not absences. + * + * @return void + */ + public function testCopiesFalseAndZeroBecauseTheyAreRealValues(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['federation_enabled', 'retry_count']); + $appConfig->method('getAllValues')->willReturn( + [ + 'federation_enabled' => false, + 'retry_count' => 0, + ] + ); + $appConfig->method('hasKey')->willReturn(false); + + $appConfig->expects($this->once())->method('setValueBool') + ->with(Application::APP_ID, 'federation_enabled', false)->willReturn(true); + $appConfig->expects($this->once())->method('setValueInt') + ->with(Application::APP_ID, 'retry_count', 0)->willReturn(true); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testCopiesFalseAndZeroBecauseTheyAreRealValues() + + /** + * The Nextcloud-reserved keys are never copied. + * + * This is the arm that matters most. `AppManager::enableApp()` writes + * `enabled` as type MIXED; copying it with `setValueString()` stores STRING, + * and the next `occ app:enable` then fails permanently with + * `AppConfigTypeConflictException` — hit before the app can run anything + * that would repair it. + * + * @return void + */ + public function testNeverCopiesTheNextcloudReservedKeys(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['enabled', 'installed_version', 'types']); + $appConfig->method('getAllValues')->willReturn( + [ + 'enabled' => 'yes', + 'installed_version' => '0.1.141', + 'types' => 'filesystem', + ] + ); + $appConfig->method('hasKey')->willReturn(false); + + $appConfig->expects($this->never())->method('setValueString'); + $appConfig->expects($this->never())->method('setValueBool'); + $appConfig->expects($this->never())->method('setValueInt'); + $appConfig->expects($this->never())->method('setValueArray'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testNeverCopiesTheNextcloudReservedKeys() + + /** + * A key already present under the new app id is left alone. + * + * @return void + */ + public function testDoesNotClobberAValueTheNewNamespaceAlreadyHolds(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['federation_directory_url']); + $appConfig->method('getAllValues')->willReturn(['federation_directory_url' => 'https://old.example.org']); + $appConfig->method('hasKey') + ->with(Application::APP_ID, 'federation_directory_url') + ->willReturn(true); + + $appConfig->expects($this->never())->method('setValueString'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testDoesNotClobberAValueTheNewNamespaceAlreadyHolds() + + /** + * The legacy rows are never deleted. + * + * @return void + */ + public function testIsNonDestructive(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['federation_peers']); + $appConfig->method('getAllValues')->willReturn(['federation_peers' => ['a', 'b']]); + $appConfig->method('hasKey')->willReturn(false); + $appConfig->method('setValueArray')->willReturn(true); + + $appConfig->expects($this->never())->method('deleteKey'); + $appConfig->expects($this->never())->method('deleteApp'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testIsNonDestructive() + + /** + * An empty string is not copied — it is indistinguishable from the default. + * + * @return void + */ + public function testSkipsEmptyValues(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['blank', 'empty_list']); + $appConfig->method('getAllValues')->willReturn( + [ + 'blank' => '', + 'empty_list' => [], + ] + ); + $appConfig->method('hasKey')->willReturn(false); + + $appConfig->expects($this->never())->method('setValueString'); + $appConfig->expects($this->never())->method('setValueArray'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testSkipsEmptyValues() + + /** + * A throw NEVER escapes into the installer. + * + * This step runs under `` — the only hook that fires on the fresh + * install an app-id rename performs — so an escaping throw aborts the + * install and the app never enables at all. A reverted setting is + * recoverable; a failed install is not. + * + * @return void + */ + public function testAThrowNeverEscapesTheInstaller(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willThrowException(new RuntimeException('database gone')); + + $output = $this->createMock(IOutput::class); + $output->expects($this->once())->method('warning'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($output); + }//end testAThrowNeverEscapesTheInstaller() + + /** + * A throw during the WRITE is caught too, not only during the reads. + * + * @return void + */ + public function testAThrowDuringTheWriteIsAlsoCaught(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['federation_directory_url']); + $appConfig->method('getAllValues')->willReturn(['federation_directory_url' => 'https://x']); + $appConfig->method('hasKey')->willReturn(false); + $appConfig->method('setValueString')->willThrowException(new RuntimeException('write failed')); + + $output = $this->createMock(IOutput::class); + $output->expects($this->once())->method('warning'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($output); + }//end testAThrowDuringTheWriteIsAlsoCaught() + + /** + * Re-running after a completed migration writes nothing. + * + * @return void + */ + public function testIsIdempotentOnASecondRun(): void { + $appConfig = $this->createMock(IAppConfig::class); + $appConfig->method('getKeys')->willReturn(['a', 'b', 'c']); + $appConfig->method('getAllValues')->willReturn(['a' => 'x', 'b' => 2, 'c' => true]); + $appConfig->method('hasKey')->willReturn(true); + + $appConfig->expects($this->never())->method('setValueString'); + $appConfig->expects($this->never())->method('setValueInt'); + $appConfig->expects($this->never())->method('setValueBool'); + + (new MigrateAppConfigKeys($appConfig, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testIsIdempotentOnASecondRun() +}//end class diff --git a/tests/Unit/Repair/MigrateBackgroundJobClassesTest.php b/tests/Unit/Repair/MigrateBackgroundJobClassesTest.php new file mode 100644 index 00000000..69eb7ec5 --- /dev/null +++ b/tests/Unit/Repair/MigrateBackgroundJobClassesTest.php @@ -0,0 +1,148 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * @version GIT: + * + * @link https://github.com/ConductionNL/stackiq + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Tests\Unit\Repair; + +use OCA\Stackiq\Repair\MigrateBackgroundJobClasses; +use OCP\BackgroundJob\IJobList; +use OCP\Migration\IOutput; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use RuntimeException; + +/** + * @covers \OCA\Stackiq\Repair\MigrateBackgroundJobClasses + */ +class MigrateBackgroundJobClassesTest extends TestCase { + /** + * The step reports a name that says what it does. + * + * @return void + */ + public function testGetNameDescribesTheCleanup(): void { + $step = new MigrateBackgroundJobClasses($this->createMock(IJobList::class), new NullLogger()); + + $this->assertStringContainsString('SoftwareCatalog', $step->getName()); + }//end testGetNameDescribesTheCleanup() + + /** + * The list is exactly the four pre-rename `` entries. + * + * @return void + */ + public function testLegacyListIsTheFourPreRenameJobs(): void { + $this->assertSame( + [ + 'OCA\SoftwareCatalog\BackgroundJob\OrganizationContactSyncJob', + 'OCA\SoftwareCatalog\BackgroundJob\ContractStatusJob', + 'OCA\SoftwareCatalog\BackgroundJob\FederationSyncJob', + 'OCA\SoftwareCatalog\BackgroundJob\EolSyncJob', + ], + MigrateBackgroundJobClasses::LEGACY_JOB_CLASSES + ); + }//end testLegacyListIsTheFourPreRenameJobs() + + /** + * No entry in the legacy list names a class that still exists. + * + * If one did, the step would deregister a live job. + * + * @return void + */ + public function testNoLegacyEntryNamesALiveClass(): void { + foreach (MigrateBackgroundJobClasses::LEGACY_JOB_CLASSES as $legacyClass) { + $this->assertStringStartsWith('OCA\SoftwareCatalog\\', $legacyClass); + $this->assertStringNotContainsString('OCA\Stackiq\\', $legacyClass); + } + }//end testNoLegacyEntryNamesALiveClass() + + /** + * Every registered legacy job is removed. + * + * @return void + */ + public function testRemovesEveryRegisteredLegacyJob(): void { + $jobList = $this->createMock(IJobList::class); + $jobList->method('has')->willReturn(true); + + $removed = []; + $jobList->method('remove')->willReturnCallback( + static function (mixed $job, mixed $argument) use (&$removed): void { + $removed[] = $job; + } + ); + + (new MigrateBackgroundJobClasses($jobList, new NullLogger()))->run($this->createMock(IOutput::class)); + + $this->assertSame(MigrateBackgroundJobClasses::LEGACY_JOB_CLASSES, $removed); + }//end testRemovesEveryRegisteredLegacyJob() + + /** + * A job that is not registered is not removed. + * + * @return void + */ + public function testRemovesNothingWhenNoLegacyJobIsRegistered(): void { + $jobList = $this->createMock(IJobList::class); + $jobList->method('has')->willReturn(false); + + $jobList->expects($this->never())->method('remove'); + + (new MigrateBackgroundJobClasses($jobList, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testRemovesNothingWhenNoLegacyJobIsRegistered() + + /** + * The step never ADDS a job — registration stays Nextcloud's job. + * + * @return void + */ + public function testNeverRegistersAJobItself(): void { + $jobList = $this->createMock(IJobList::class); + $jobList->method('has')->willReturn(true); + + $jobList->expects($this->never())->method('add'); + + (new MigrateBackgroundJobClasses($jobList, new NullLogger()))->run($this->createMock(IOutput::class)); + }//end testNeverRegistersAJobItself() + + /** + * A throw NEVER escapes into the installer. + * + * @return void + */ + public function testAThrowNeverEscapesTheInstaller(): void { + $jobList = $this->createMock(IJobList::class); + $jobList->method('has')->willThrowException(new RuntimeException('database gone')); + + $output = $this->createMock(IOutput::class); + $output->expects($this->once())->method('warning'); + + (new MigrateBackgroundJobClasses($jobList, new NullLogger()))->run($output); + }//end testAThrowNeverEscapesTheInstaller() +}//end class diff --git a/tests/Unit/Repair/MigrateUserPreferencesTest.php b/tests/Unit/Repair/MigrateUserPreferencesTest.php new file mode 100644 index 00000000..07151b51 --- /dev/null +++ b/tests/Unit/Repair/MigrateUserPreferencesTest.php @@ -0,0 +1,270 @@ + + * @copyright 2026 Conduction B.V. + * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * @version GIT: + * + * @link https://github.com/ConductionNL/stackiq + * + * SPDX-FileCopyrightText: 2026 Conduction B.V. + * SPDX-License-Identifier: EUPL-1.2 + */ + +declare(strict_types=1); + +namespace OCA\Stackiq\Tests\Unit\Repair; + +use Closure; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Repair\MigrateUserPreferences; +use OCP\IConfig; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Migration\IOutput; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use RuntimeException; + +/** + * @covers \OCA\Stackiq\Repair\MigrateUserPreferences + */ +class MigrateUserPreferencesTest extends TestCase { + /** + * The legacy app id every stored preference was written under. + * + * @var string + */ + private const LEGACY = 'softwarecatalog'; + + /** + * Build a user manager whose callForSeenUsers yields the given user ids. + * + * @param list $userIds The user ids to yield. + * + * @return IUserManager The stubbed user manager. + */ + private function userManagerYielding(array $userIds): IUserManager { + $users = []; + foreach ($userIds as $uid) { + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn($uid); + $users[] = $user; + } + + $userManager = $this->createMock(IUserManager::class); + $userManager->method('callForSeenUsers')->willReturnCallback( + static function (Closure $callback) use ($users): void { + foreach ($users as $user) { + $callback($user); + } + } + ); + + return $userManager; + }//end userManagerYielding() + + /** + * The step reports a name that says what it does. + * + * @return void + */ + public function testGetNameDescribesTheMigration(): void { + $step = new MigrateUserPreferences( + $this->createMock(IConfig::class), + $this->createMock(IUserManager::class), + new NullLogger() + ); + + $this->assertStringContainsString('softwarecatalog', $step->getName()); + $this->assertStringContainsString('stackiq', $step->getName()); + }//end testGetNameDescribesTheMigration() + + /** + * The legacy app id is exactly the pre-rename app id. + * + * @return void + */ + public function testLegacyAppIdIsTheOldAppId(): void { + $this->assertSame(self::LEGACY, MigrateUserPreferences::LEGACY_APP_ID); + $this->assertNotSame(Application::APP_ID, MigrateUserPreferences::LEGACY_APP_ID); + }//end testLegacyAppIdIsTheOldAppId() + + /** + * Every seen user's legacy preferences land under the new app id. + * + * @return void + */ + public function testCopiesEveryLegacyPreferenceForEverySeenUser(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturnMap( + [ + ['alice', self::LEGACY, ['pref_applications-view', 'pref_theme']], + ['bob', self::LEGACY, ['pref_applications-view']], + ] + ); + $config->method('getUserValue')->willReturnCallback( + static function (string $uid, string $app, string $key, string $default = ''): string { + if ($app !== self::LEGACY) { + // Nothing under the new app id yet. + return ''; + } + + return match ("$uid/$key") { + 'alice/pref_applications-view' => 'table', + 'alice/pref_theme' => 'dark', + 'bob/pref_applications-view' => 'cards', + default => '', + }; + } + ); + + $written = []; + $config->method('setUserValue')->willReturnCallback( + static function (string $uid, string $app, string $key, string $value) use (&$written): void { + $written[] = "$uid/$app/$key=$value"; + } + ); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice', 'bob']), new NullLogger()); + $step->run($this->createMock(IOutput::class)); + + $this->assertSame( + [ + 'alice/' . Application::APP_ID . '/pref_applications-view=table', + 'alice/' . Application::APP_ID . '/pref_theme=dark', + 'bob/' . Application::APP_ID . '/pref_applications-view=cards', + ], + $written + ); + }//end testCopiesEveryLegacyPreferenceForEverySeenUser() + + /** + * `getUsersForUserValue()` is NEVER used to enumerate. + * + * It needs a VALUE to match, so over the open value set `pref_*` holds it + * migrates nothing and still reports success — the exact shape of failure + * this whole step exists to avoid. + * + * @return void + */ + public function testDoesNotEnumerateByValue(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturn(['pref_applications-view']); + $config->method('getUserValue')->willReturn(''); + + $config->expects($this->never())->method('getUsersForUserValue'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice']), new NullLogger()); + $step->run($this->createMock(IOutput::class)); + }//end testDoesNotEnumerateByValue() + + /** + * A value already present under the new app id is left alone. + * + * @return void + */ + public function testDoesNotClobberAValueTheNewNamespaceAlreadyHolds(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturn(['pref_applications-view']); + $config->method('getUserValue')->willReturnCallback( + static fn (string $uid, string $app, string $key, string $default = ''): string + => $app === self::LEGACY ? 'table' : 'cards' + ); + + $config->expects($this->never())->method('setUserValue'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice']), new NullLogger()); + $step->run($this->createMock(IOutput::class)); + }//end testDoesNotClobberAValueTheNewNamespaceAlreadyHolds() + + /** + * The legacy rows are never deleted. + * + * @return void + */ + public function testIsNonDestructive(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturn(['pref_applications-view']); + $config->method('getUserValue')->willReturnCallback( + static fn (string $uid, string $app, string $key, string $default = ''): string + => $app === self::LEGACY ? 'table' : '' + ); + + $config->expects($this->never())->method('deleteUserValue'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice']), new NullLogger()); + $step->run($this->createMock(IOutput::class)); + }//end testIsNonDestructive() + + /** + * A user with no legacy preferences is skipped without writes. + * + * @return void + */ + public function testSkipsUsersWithNoLegacyPreferences(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturn([]); + + $config->expects($this->never())->method('setUserValue'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice', 'bob']), new NullLogger()); + $step->run($this->createMock(IOutput::class)); + }//end testSkipsUsersWithNoLegacyPreferences() + + /** + * A throw NEVER escapes into the installer. + * + * The step runs under `` — the only hook that fires on the fresh + * install an app-id rename performs — so an escaping throw aborts the + * install and the app never enables at all. + * + * @return void + */ + public function testAThrowNeverEscapesTheInstaller(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willThrowException(new RuntimeException('database gone')); + + $output = $this->createMock(IOutput::class); + $output->expects($this->once())->method('warning'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice']), new NullLogger()); + $step->run($output); + }//end testAThrowNeverEscapesTheInstaller() + + /** + * A throw during the WRITE is caught too, not only during the reads. + * + * @return void + */ + public function testAThrowDuringTheWriteIsAlsoCaught(): void { + $config = $this->createMock(IConfig::class); + $config->method('getUserKeys')->willReturn(['pref_applications-view']); + $config->method('getUserValue')->willReturnCallback( + static fn (string $uid, string $app, string $key, string $default = ''): string + => $app === self::LEGACY ? 'table' : '' + ); + $config->method('setUserValue')->willThrowException(new RuntimeException('write failed')); + + $output = $this->createMock(IOutput::class); + $output->expects($this->once())->method('warning'); + + $step = new MigrateUserPreferences($config, $this->userManagerYielding(['alice']), new NullLogger()); + $step->run($output); + }//end testAThrowDuringTheWriteIsAlsoCaught() +}//end class From debcb4b2b2df9cf29879a1b79b06ae4460df1429 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 22 Aug 2026 18:38:52 +0200 Subject: [PATCH 04/14] docs(rename): README, SECURITY, openapi title, eslint suppressions and 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. --- README.md | 48 +++++++++++++++++++-------------------- SECURITY.md | 6 ++--- eslint-suppressions.json | 4 ++-- openapi.json | 4 ++-- run_integration_tests.sh | 14 ++++++------ scripts/check-vue-demi.js | 4 ++-- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index ce2146c3..025da88d 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@

- Software Catalogus logo + Stackiq logo

-

Software Catalogus

+

Stackiq

GEMMA-compliant software catalog for Nextcloud — applications, modules, and integration management

- Latest release - License - Code quality - Documentation + Latest release + License + Code quality + Documentation

--- -Software Catalogus brings structured software portfolio management to Nextcloud. Register the applications, modules, and connections (koppelingen) that make up your organization's IT landscape, manage contacts and organizations, and synchronize catalog data across a federated open data network — all aligned with Dutch GEMMA standards. +Stackiq brings structured software portfolio management to Nextcloud. Register the applications, modules, and connections (koppelingen) that make up your organization's IT landscape, manage contacts and organizations, and synchronize catalog data across a federated open data network — all aligned with Dutch GEMMA standards. It integrates with [OpenRegister](https://codeberg.org/Conduction/openregister) for data storage and automatic user provisioning, turning register contacts into Nextcloud accounts with role-based group membership. @@ -92,7 +92,7 @@ graph TD ### Directory Structure ``` -softwarecatalog/ +stackiq/ ├── appinfo/ # Nextcloud app manifest, routes, navigation ├── lib/ # PHP backend — controllers, services, event listeners │ ├── Controller/ # API and page controllers @@ -104,7 +104,7 @@ softwarecatalog/ ├── docs/ # Technical documentation ├── img/ # App icons and screenshots ├── l10n/ # Translations (en, nl) -└── docusaurus/ # Product documentation site (softwarecatalog.app) +└── docusaurus/ # Product documentation site (softwarecatalog.conduction.nl) ``` ## Requirements @@ -120,7 +120,7 @@ softwarecatalog/ ### From the Nextcloud App Store 1. Go to **Apps** in your Nextcloud instance -2. Search for **Software Catalogus** +2. Search for **Stackiq** 3. Click **Download and enable** > OpenRegister must be installed first. [Install OpenRegister -->](https://apps.nextcloud.com/apps/openregister) @@ -129,11 +129,11 @@ softwarecatalog/ ```bash cd /var/www/html/custom_apps -git clone https://codeberg.org/Conduction/softwarecatalog.git -cd softwarecatalog +git clone https://github.com/ConductionNL/stackiq.git +cd stackiq npm install npm run build -php occ app:enable softwarecatalog +php occ app:enable stackiq ``` ## Development @@ -147,7 +147,7 @@ docker compose -f openregister/docker-compose.yml up -d ### Frontend development ```bash -cd softwarecatalog +cd stackiq npm install npm run dev # Watch mode npm run build # Production build @@ -180,7 +180,7 @@ npm run stylelint # CSS linting ## Documentation -Full documentation is available at **[softwarecatalog.app](https://softwarecatalog.app)** +Full documentation is available at **[softwarecatalog.conduction.nl](https://softwarecatalog.conduction.nl)** | Page | Description | |------|-------------| @@ -191,11 +191,11 @@ Full documentation is available at **[softwarecatalog.app](https://softwarecatal ## Testing -Software Catalogus is tested through three complementary layers that together provide comprehensive quality assurance. +Stackiq is tested through three complementary layers that together provide comprehensive quality assurance. ### Code Quality (Conduction Quality Workflow) -Every commit runs through the [Conduction quality workflow](https://codeberg.org/Conduction/softwarecatalog/actions) — a strict CI/CD pipeline that enforces: +Every commit runs through the [Conduction quality workflow](https://github.com/ConductionNL/stackiq/actions) — a strict CI/CD pipeline that enforces: - **PHP Lint** — syntax validation - **PHPCS** — coding standards (PEAR + PSR-12 + custom Conduction rules, including forbidden functions and named parameter enforcement) @@ -263,7 +263,7 @@ The master file `issues.md` tracks all 137 IGS (In Review/Scoped) issues with th ## Required Repositories -The Softwarecatalogus is not a standalone application — it runs as a Nextcloud app backed by several other apps, with a separate React-based public frontend. +Stackiq is not a standalone application — it runs as a Nextcloud app backed by several other apps, with a separate React-based public frontend. | Repository | Role | Required | |-----------|------|----------| @@ -305,8 +305,8 @@ docker exec -u www-data nextcloud php occ app:enable opencatalogi # 3. NL Design — theming (no hard dependencies, but should be early) docker exec -u www-data nextcloud php occ app:enable nldesign -# 4. Software Catalogus — depends on OpenRegister and OpenCatalogi -docker exec -u www-data nextcloud php occ app:enable softwarecatalog +# 4. Stackiq — depends on OpenRegister and OpenCatalogi +docker exec -u www-data nextcloud php occ app:enable stackiq # 5. LaunchPad — optional, for dashboard widgets docker exec -u www-data nextcloud php occ app:enable launchpad @@ -314,7 +314,7 @@ docker exec -u www-data nextcloud php occ app:enable launchpad ### 3. Import data -The Softwarecatalogus requires register schemas and seed data to function. Import the configurations via the OpenRegister Magic Mapper: +Stackiq requires register schemas and seed data to function. Import the configurations via the OpenRegister Magic Mapper: ```bash # Import the softwarecatalogus register configuration @@ -323,13 +323,13 @@ The Softwarecatalogus requires register schemas and seed data to function. Impor curl -X POST "http://localhost:8080/index.php/apps/openregister/api/configurations?force=true" \ -u admin:admin \ -H "Content-Type: application/json" \ - -d @softwarecatalog/configurations/softwarecatalogus_register.json + -d @stackiq/lib/Settings/softwarecatalogus_register.json ``` For a complete test environment with users, organizations, and sample data: ```bash -bash softwarecatalog/test-setup.sh +bash stackiq/test-setup.sh ``` This creates 7 test users across 4 organizations (leverancier, gemeente, samenwerking, admin), seeds contact persons and sample applications, and verifies RBAC scoping. @@ -338,7 +338,7 @@ This creates 7 test users across 4 organizations (leverancier, gemeente, samenwe ```bash # Nextcloud app frontend (Vue 2) -cd softwarecatalog && npm install && npm run build +cd stackiq && npm install && npm run build # Public frontend (React) — only needed if not using Docker cd tilburg-woo-ui && yarn install && yarn build diff --git a/SECURITY.md b/SECURITY.md index 040d94c4..0c0df29b 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -46,16 +46,16 @@ For every app `` under [ConductionNL](https://github.com/ConductionNL), two | **Always-latest released SBOM** (auto-redirects to newest release) | `https://github.com/ConductionNL//releases/latest/download/sbom.cdx.json` | | **Specific release SBOM** (pinned, for compliance archives) | `https://github.com/ConductionNL//releases/download//sbom.cdx.json` | -Example — fetch the latest softwarecatalog SBOM: +Example — fetch the latest stackiq SBOM: ```bash -curl -sL https://github.com/ConductionNL/softwarecatalog/releases/latest/download/sbom.cdx.json | jq . +curl -sL https://github.com/ConductionNL/stackiq/releases/latest/download/sbom.cdx.json | jq . ``` Example — fetch the SBOM for a specific historical release: ```bash -curl -sL https://github.com/ConductionNL/softwarecatalog/releases/download/v1.0.0/sbom.cdx.json | jq . +curl -sL https://github.com/ConductionNL/stackiq/releases/download/v1.0.0/sbom.cdx.json | jq . ``` ### Update cadence diff --git a/eslint-suppressions.json b/eslint-suppressions.json index d8594712..855f5d7d 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -394,7 +394,7 @@ "count": 2 } }, - "src/store/plugins/softwarecatalogPlugin.js": { + "src/store/plugins/stackiqPlugin.js": { "no-console": { "count": 5 }, @@ -474,7 +474,7 @@ "count": 1 } }, - "src/views/settings/SoftwareCatalogSettings.vue": { + "src/views/settings/StackiqSettings.vue": { "jsdoc/require-param-type": { "count": 3 }, diff --git a/openapi.json b/openapi.json index 32f1ef47..bd45fa77 100644 --- a/openapi.json +++ b/openapi.json @@ -1,9 +1,9 @@ { "openapi": "3.0.3", "info": { - "title": "softwarecatalog", + "title": "stackiq", "version": "0.1.141-unstable.20260821053703", - "description": "Software Catalog", + "description": "Stackiq", "license": { "name": "agpl" } diff --git a/run_integration_tests.sh b/run_integration_tests.sh index 8539f8b2..cf887412 100644 --- a/run_integration_tests.sh +++ b/run_integration_tests.sh @@ -12,7 +12,7 @@ echo "" echo "[TEST 1] GET /api/koppelingen-gebruik (basic response)" RESPONSE=$(docker exec -u 33 master-nextcloud-1 curl -s -u 'admin:admin' \ -H "Content-Type: application/json" \ - "http://localhost/index.php/apps/softwarecatalog/api/koppelingen-gebruik?_limit=1") + "http://localhost/index.php/apps/stackiq/api/koppelingen-gebruik?_limit=1") TOTAL=$(echo "$RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('total', 0))" 2>/dev/null) RESULTS_COUNT=$(echo "$RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin).get('results', [])))" 2>/dev/null) @@ -29,7 +29,7 @@ echo "" echo "[TEST 2] GET /api/koppelingen-gebruik (pagination with _limit=5)" RESPONSE=$(docker exec -u 33 master-nextcloud-1 curl -s -u 'admin:admin' \ -H "Content-Type: application/json" \ - "http://localhost/index.php/apps/softwarecatalog/api/koppelingen-gebruik?_limit=5") + "http://localhost/index.php/apps/stackiq/api/koppelingen-gebruik?_limit=5") RESULTS_COUNT=$(echo "$RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin).get('results', [])))" 2>/dev/null) LIMIT=$(echo "$RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('limit', 0))" 2>/dev/null) @@ -47,13 +47,13 @@ echo "" echo "[TEST 3] GET /api/koppelingen-gebruik/{uuid} (filter by UUID)" # Get a module UUID from the first result TEST_UUID=$(docker exec -u 33 master-nextcloud-1 curl -s -u 'admin:admin' \ - "http://localhost/index.php/apps/softwarecatalog/api/koppelingen-gebruik?_limit=1" | \ + "http://localhost/index.php/apps/stackiq/api/koppelingen-gebruik?_limit=1" | \ python3 -c "import sys, json; d=json.load(sys.stdin); print(d['results'][0]['module'] if d.get('results') else '')" 2>/dev/null) if [ -n "$TEST_UUID" ]; then echo " Using UUID: $TEST_UUID" RESPONSE=$(docker exec -u 33 master-nextcloud-1 curl -s -u 'admin:admin' \ - "http://localhost/index.php/apps/softwarecatalog/api/koppelingen-gebruik/${TEST_UUID}") + "http://localhost/index.php/apps/stackiq/api/koppelingen-gebruik/${TEST_UUID}") TOTAL=$(echo "$RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('total', 0))" 2>/dev/null) RESULTS_COUNT=$(echo "$RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin).get('results', [])))" 2>/dev/null) @@ -69,7 +69,7 @@ echo "" # Test 4: Response structure validation echo "[TEST 4] Response structure validation" RESPONSE=$(docker exec -u 33 master-nextcloud-1 curl -s -u 'admin:admin' \ - "http://localhost/index.php/apps/softwarecatalog/api/koppelingen-gebruik?_limit=1") + "http://localhost/index.php/apps/stackiq/api/koppelingen-gebruik?_limit=1") HAS_RESULTS=$(echo "$RESPONSE" | python3 -c "import sys, json; print('results' in json.load(sys.stdin))" 2>/dev/null) HAS_TOTAL=$(echo "$RESPONSE" | python3 -c "import sys, json; print('total' in json.load(sys.stdin))" 2>/dev/null) @@ -98,6 +98,6 @@ echo "Manual Tests Complete" echo "================================================" echo "" echo "To run PHPUnit integration tests:" -echo " cd softwarecatalog" -echo " docker exec -u 33 master-nextcloud-1 bash -c \"cd /var/www/html/apps-extra/softwarecatalog && vendor/bin/phpunit --testsuite 'Integration Tests'\"" +echo " cd stackiq" +echo " docker exec -u 33 master-nextcloud-1 bash -c \"cd /var/www/html/apps-extra/stackiq && vendor/bin/phpunit --testsuite 'Integration Tests'\"" diff --git a/scripts/check-vue-demi.js b/scripts/check-vue-demi.js index ce127ab8..34da9a90 100644 --- a/scripts/check-vue-demi.js +++ b/scripts/check-vue-demi.js @@ -66,7 +66,7 @@ if (before.isVue3) { } process.stderr.write( - '[softwarecatalog] vue-demi is on the Vue 2 shim — switching to Vue 3\n', + '[stackiq] vue-demi is on the Vue 2 shim — switching to Vue 3\n', ) const bin = path.resolve( @@ -85,7 +85,7 @@ const after = inspectShim() if (!after.isVue3) { process.stderr.write( - '[softwarecatalog] FATAL: vue-demi is still on the Vue 2 shim.\n' + '[stackiq] FATAL: vue-demi is still on the Vue 2 shim.\n' + ' This app is Vue 3. Building now would produce a bundle whose pinia /\n' + ' vue-codemirror6 imports resolve against a Vue 2 compatibility layer.\n' + ' Fix with a clean install (postinstall hooks always re-run under `npm ci`):\n' From b62189b32b4c9f56a34c0f3102c4970499258723 Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Sat, 22 Aug 2026 19:30:34 +0200 Subject: [PATCH 05/14] wip(stackiq): checkpoint in-flight rename work before session limit --- ARCHIMATE_IMPORT_FIX.md | 10 +- appinfo/routes.php | 12 +- l10n/be.js | 2 +- l10n/bg.js | 2 +- l10n/bs.js | 2 +- l10n/ca.js | 2 +- l10n/cs.js | 2 +- l10n/da.js | 2 +- l10n/de.js | 2 +- l10n/el.js | 2 +- l10n/en.js | 2 +- l10n/en_US.js | 2 +- l10n/es.js | 2 +- l10n/et.js | 2 +- l10n/fi.js | 2 +- l10n/fr.js | 2 +- l10n/ga.js | 2 +- l10n/hr.js | 2 +- l10n/hu.js | 2 +- l10n/is.js | 2 +- l10n/it.js | 2 +- l10n/lb.js | 2 +- l10n/lt.js | 2 +- l10n/lv.js | 2 +- l10n/mk.js | 2 +- l10n/mt.js | 2 +- l10n/nb.js | 2 +- l10n/nl.js | 2 +- l10n/pl.js | 2 +- l10n/pt.js | 2 +- l10n/rm.js | 2 +- l10n/ro.js | 2 +- l10n/ru.js | 2 +- l10n/sk.js | 2 +- l10n/sl.js | 2 +- l10n/sq.js | 2 +- l10n/sr.js | 2 +- l10n/sv.js | 2 +- l10n/tr.js | 2 +- l10n/uk.js | 2 +- lib/AppInfo/Application.php | 144 +++++++-------- lib/BackgroundJob/ContractStatusJob.php | 8 +- lib/BackgroundJob/EolSyncJob.php | 10 +- lib/BackgroundJob/FederationSyncJob.php | 10 +- .../OrganizationContactSyncJob.php | 28 +-- lib/Controller/AanbodController.php | 14 +- .../AangebodenGebruikController.php | 16 +- lib/Controller/ContactpersonenController.php | 18 +- lib/Controller/ContractApprovalController.php | 12 +- lib/Controller/DashboardController.php | 8 +- lib/Controller/FacetController.php | 12 +- lib/Controller/FederationController.php | 30 ++-- lib/Controller/GebruikController.php | 14 +- lib/Controller/IntakeController.php | 10 +- lib/Controller/MergeController.php | 12 +- lib/Controller/ModerationController.php | 26 +-- .../OrganisationMembersController.php | 12 +- lib/Controller/PortfolioReportController.php | 10 +- lib/Controller/PreferencesController.php | 10 +- lib/Controller/PublicationController.php | 12 +- lib/Controller/ReviewController.php | 12 +- lib/Controller/SbomController.php | 20 ++- .../Settings/ModuleRegistrationHandler.php | 8 +- lib/Controller/Settings/SyncHandler.php | 8 +- lib/Controller/SettingsController.php | 34 ++-- lib/Controller/ViewController.php | 16 +- lib/Dashboard/ConceptOrganisatiesWidget.php | 16 +- .../DecisionConcludedListener.php | 16 +- .../ModuleComplianceSubscriber.php | 18 +- .../ModuleRegistrationSubscriber.php | 12 +- .../OpenRegisterEventsDebugListener.php | 24 +-- lib/EventListener/StackiqEventListener.php | 112 ++++++------ lib/EventListener/TestEventListener.php | 20 +-- .../UserProfileUpdatedEventListener.php | 6 +- lib/Examples/ContactpersoonServiceExample.php | 12 +- .../UnsupportedSbomFormatException.php | 8 +- lib/Portal/PortalContributionProvider.php | 18 +- lib/Repair/BackfillContractApprovalState.php | 10 +- lib/Repair/InitializeSettings.php | 26 +-- lib/Repair/MigrateContactsToNc.php | 24 +-- lib/Repair/RenameDutchCatalogColumns.php | 8 +- lib/Repair/RenameDutchCatalogDecisions.php | 8 +- lib/Repair/RenameDutchCatalogValues.php | 8 +- lib/Repair/RenameDutchSchemaSlugDecisions.php | 4 +- lib/Repair/RenameDutchSchemaSlugs.php | 8 +- lib/Sections/StackiqAdmin.php | 18 +- lib/Service/AanbodService.php | 12 +- .../AangebodenGebruik/GebruikBulkHandler.php | 8 +- lib/Service/AangebodenGebruikService.php | 14 +- lib/Service/ArchiMate/ArchiMateContext.php | 12 +- lib/Service/ArchiMateExportService.php | 28 +-- lib/Service/ArchiMateImportService.php | 28 +-- lib/Service/ArchiMateService.php | 28 +-- .../Contactpersoon/ContactValidator.php | 8 +- lib/Service/ContactpersoonService.php | 22 +-- lib/Service/ContractApprovalService.php | 21 ++- lib/Service/ContractStatusService.php | 6 +- lib/Service/EolMatcherService.php | 6 +- lib/Service/EolSyncService.php | 8 +- lib/Service/FacetService.php | 12 +- lib/Service/Federation/FederationConfig.php | 10 +- lib/Service/Federation/FederationMerger.php | 6 +- lib/Service/Federation/FederationService.php | 12 +- lib/Service/GebruikService.php | 6 +- lib/Service/GebruikSyncService.php | 36 ++-- lib/Service/IntakeService.php | 8 +- lib/Service/MergeOrganisatieService.php | 14 +- lib/Service/ModerationService.php | 8 +- lib/Service/ModuleComplianceService.php | 12 +- lib/Service/ModuleEventProcessor.php | 30 ++-- lib/Service/ModuleRegistrationService.php | 8 +- lib/Service/ModuleVersionService.php | 8 +- lib/Service/OrganisatieService.php | 22 +-- lib/Service/OrganizationSyncService.php | 80 ++++----- lib/Service/PortfolioReportDerivation.php | 6 +- lib/Service/PortfolioReportService.php | 6 +- lib/Service/ProfileFieldMapper.php | 10 +- lib/Service/ProgressTracker.php | 10 +- lib/Service/PublicationService.php | 6 +- lib/Service/ReviewAggregateService.php | 8 +- lib/Service/ReviewService.php | 10 +- lib/Service/SbomImportService.php | 10 +- lib/Service/SbomParserService.php | 8 +- .../Settings/ModuleSettingsHandler.php | 10 +- .../Settings/OrganizationSettingsHandler.php | 10 +- lib/Service/ViewQueryBuilder.php | 8 +- lib/Service/ViewService.php | 14 +- lib/Settings/StackiqAdmin.php | 20 +-- .../register.d/contracts-to-decidesk.json | 4 +- phpmd.baseline.xml | 6 +- phpstan-baseline.neon | 164 +++++++++--------- src/App.vue | 14 +- src/assets/app.css | 2 +- src/components/ContactpersonenList.vue | 50 +++--- src/components/PaginationComponent.vue | 14 +- src/components/cards/OrganisatieCard.vue | 6 +- .../contracts/ContractApprovalPanel.vue | 32 ++-- .../organisations/OrganisationMergePanel.vue | 30 ++-- .../organisations/OrganisationSwitcher.vue | 6 +- src/components/reviews/ReviewsPanel.vue | 16 +- src/components/sbom/SbomComponentsPanel.vue | 48 ++--- .../VulnerabilityExposurePanel.vue | 26 +-- src/composables/orClient.js | 6 +- src/customComponents.js | 8 +- src/dialogs/ChangePasswordDialog.vue | 38 ++-- src/dialogs/ManageUserGroupsDialog.vue | 12 +- src/dialogs/SuiteWizard/Step1Details.vue | 16 +- src/dialogs/SuiteWizard/Step2Applications.vue | 8 +- src/dialogs/SuiteWizard/Step3Confirm.vue | 10 +- src/dialogs/SuiteWizardDialog.vue | 24 +-- src/icons.js | 2 +- src/main.js | 12 +- src/manifest.json | 4 +- src/modals/AddContactpersoonModal.vue | 30 ++-- src/modals/BulkSyncDialog.vue | 2 +- src/modals/GrantOrganisationAccessModal.vue | 14 +- src/modals/OrganisationModal.vue | 56 +++--- src/modals/SaveFacetViewModal.vue | 12 +- src/modals/SubmitReviewModal.vue | 24 +-- .../object/ChangeOrganisatieStatusDialog.vue | 30 ++-- src/modals/object/DeleteObject.vue | 18 +- src/modals/object/DownloadObject.vue | 14 +- src/modals/object/LockObject.vue | 22 +-- src/modals/object/MassDeleteObject.vue | 28 +-- src/modals/object/MassDepublishObjects.vue | 24 +-- src/modals/object/MassLockObjects.vue | 28 +-- src/modals/object/MassPublishObjects.vue | 24 +-- src/modals/object/MassUnlockObjects.vue | 24 +-- src/modals/object/MassValidateObjects.vue | 34 ++-- src/modals/object/MergeObject.vue | 2 +- .../object/MergeOrganisationConfirmDialog.vue | 24 +-- src/modals/object/MigrationObject.vue | 6 +- src/modals/object/ObjectModal.vue | 6 +- src/registry.js | 2 +- src/router.js | 2 +- src/services/facets.js | 2 +- src/services/facets.spec.js | 8 +- src/settings.js | 4 +- src/sidebars/dashboard/DashboardSideBar.vue | 4 +- src/store/modules/facets.js | 11 +- src/store/modules/object.js | 10 +- src/store/modules/organisatie.js | 34 ++-- src/store/modules/settings.js | 64 +++---- src/store/modules/view.js | 4 +- src/store/plugins/stackiqPlugin.js | 16 +- src/utils/adminApi.js | 6 +- src/utils/heartbeat.js | 2 +- src/utils/suiteWizard.js | 4 +- src/utils/translationBadge.js | 4 +- src/utils/translationBadge.spec.js | 2 +- src/views/ComplianceMatrixView.vue | 74 ++++---- src/views/Dashboard.vue | 2 +- src/views/FacetedCatalogIndexView.vue | 28 +-- src/views/KwetsbaarhedenView.vue | 48 ++--- src/views/LicensePostureView.vue | 50 +++--- src/views/LifecycleRoadmapView.vue | 46 ++--- src/views/organisaties/PortfolioReport.vue | 80 ++++----- src/views/settings/Settings.vue | 16 +- src/views/settings/StackiqSettings.vue | 26 +-- .../sections/ArchiMateImportExport.vue | 8 +- .../sections/CronjobConfiguration.vue | 10 +- .../settings/sections/EmailConfiguration.vue | 2 +- .../settings/sections/EolSyncSettings.vue | 66 +++---- .../settings/sections/FederationSettings.vue | 58 +++---- .../settings/sections/ModerationQueue.vue | 26 +-- .../sections/OpenRegisterIntegration.vue | 2 +- .../sections/OrganizationSynchronization.vue | 8 +- .../sections/UserGroupsConfiguration.vue | 4 +- .../settings/sections/VersionInformation.vue | 8 +- src/views/suites/SuitesIndexView.vue | 6 +- .../widgets/ConceptOrganisatiesWidget.vue | 8 +- .../KoppelingenGebruikIntegrationTest.php | 34 ++-- tests/OrganizationSyncTest.php | 32 ++-- tests/Stubs/Db/ObjectEntity.php | 8 +- tests/Stubs/Db/Organisation.php | 4 +- tests/Stubs/Db/OrganisationMapper.php | 4 +- tests/Stubs/Db/SchemaMapper.php | 8 +- tests/Stubs/Service/ConfigurationService.php | 6 +- tests/Stubs/Service/ObjectService.php | 6 +- tests/Stubs/Service/OrganisationService.php | 6 +- .../Stubs/Service/RegisterResolverService.php | 8 +- .../AppInfo/CompositionRootArgumentsTest.php | 12 +- .../AppInfo/ManifestRegisterSentinelTest.php | 6 +- ...AanbodControllerAcceptDenyContractTest.php | 12 +- .../Unit/Controller/AanbodControllerTest.php | 12 +- ...nGebruikControllerEndpointContractTest.php | 12 +- ...gebodenGebruikControllerStatusCodeTest.php | 12 +- .../AangebodenGebruikControllerTest.php | 12 +- .../Unit/Controller/AdminAuthPostureTest.php | 4 +- ...actpersonenControllerDecompositionTest.php | 4 +- ...ersonenControllerOrganisationScopeTest.php | 20 +-- ...personenControllerUpdateUserGroupsTest.php | 20 +-- ...ersonenControllerUserAdminContractTest.php | 16 +- .../ContractApprovalControllerTest.php | 10 +- .../DashboardControllerContractTest.php | 12 +- tests/Unit/Controller/FacetControllerTest.php | 20 +-- .../GebruikControllerContractTest.php | 12 +- .../GebruikControllerDecompositionTest.php | 12 +- tests/Unit/Controller/MergeControllerTest.php | 10 +- .../OrganisationMembersControllerTest.php | 8 +- .../PortfolioReportControllerTest.php | 12 +- .../PreferencesControllerContractTest.php | 14 +- .../Controller/PublicationControllerTest.php | 10 +- .../ReviewControllerContractTest.php | 16 +- tests/Unit/Controller/SbomControllerTest.php | 12 +- .../SettingsControllerCanonicalWriteTest.php | 8 +- .../SettingsControllerDecompositionTest.php | 4 +- ...gsControllerEmailArchiMateContractTest.php | 20 +-- .../SettingsControllerStatusContractTest.php | 20 +-- ...ingsControllerUserGroupsConfigAuthTest.php | 20 +-- ...ttingsControllerUserGroupsContractTest.php | 20 +-- .../Controller/ViewControllerContractTest.php | 12 +- .../ViewControllerDecompositionTest.php | 10 +- ...eComplianceSubscriberDecompositionTest.php | 10 +- ...erEventsDebugListenerDecompositionTest.php | 10 +- .../StackiqEventListenerDecompositionTest.php | 18 +- .../StackiqEventListenerTest.php | 40 ++--- ...eUpdatedEventListenerDecompositionTest.php | 10 +- tests/Unit/NoEmptyControlFlowBlockTest.php | 6 +- tests/Unit/OrganisationUserWorkflowTest.php | 20 +-- .../Portal/PortalContributionProviderTest.php | 14 +- .../Repair/RenameDutchCatalogColumnsTest.php | 16 +- .../Repair/RenameDutchCatalogValuesTest.php | 12 +- .../RenameDutchSchemaSlugDecisionsTest.php | 10 +- tests/Unit/SbomImportServiceTest.php | 16 +- tests/Unit/SbomParserServiceTest.php | 10 +- .../AanbodServiceDecompositionTest.php | 10 +- ...gebodenGebruikServiceDecompositionTest.php | 6 +- .../Service/AangebodenGebruikServiceTest.php | 10 +- .../Service/ArchiMateConfigFailModeTest.php | 12 +- ...rchiMateExportServiceDecompositionTest.php | 4 +- ...rchiMateImportServiceDecompositionTest.php | 4 +- .../ArchiMateServiceDecompositionTest.php | 6 +- .../BioComplianceRegisterShapeTest.php | 6 +- .../Unit/Service/ContactPersonHandlerTest.php | 14 +- ...ContactpersoonServiceDecompositionTest.php | 4 +- .../Service/ContractApprovalServiceTest.php | 10 +- .../Service/ContractStatusServiceTest.php | 10 +- .../Service/DeepMergeAuthorizationTest.php | 10 +- tests/Unit/Service/EolMatcherServiceTest.php | 8 +- tests/Unit/Service/EolRegisterShapeTest.php | 6 +- tests/Unit/Service/EolSyncServiceTest.php | 14 +- tests/Unit/Service/FacetServiceTest.php | 16 +- tests/Unit/Service/FederationMergerTest.php | 8 +- tests/Unit/Service/FederationServiceTest.php | 36 ++-- .../GebruikServiceGetApplicationIdsTest.php | 14 +- .../GebruikSyncServiceDecompositionTest.php | 12 +- tests/Unit/Service/IntakeModerationTest.php | 18 +- .../Service/LifecycleRegisterShapeTest.php | 6 +- .../Service/MergeOrganisatieServiceTest.php | 20 +-- ...duleComplianceServiceDecompositionTest.php | 10 +- .../Service/ModuleComplianceServiceTest.php | 10 +- ...leRegistrationServiceDecompositionTest.php | 12 +- .../ModuleVersionServiceDecompositionTest.php | 12 +- .../Service/OpenDataRegisterShapeTest.php | 6 +- .../OrganisatieServiceMapStatusMergeTest.php | 8 +- .../OrganisatieServiceParentHierarchyTest.php | 8 +- ...ganizationSyncServiceDecompositionTest.php | 10 +- .../Service/PortfolioReportServiceTest.php | 12 +- .../PortfolioTimeRegisterShapeTest.php | 6 +- tests/Unit/Service/PublicationServiceTest.php | 10 +- tests/Unit/Service/PublishGateRbacTest.php | 6 +- tests/Unit/Service/QueryLimitBoundingTest.php | 18 +- .../Service/RegisterFragmentMergeTest.php | 6 +- .../Service/ReviewAggregateServiceTest.php | 12 +- tests/Unit/Service/ReviewServiceTest.php | 14 +- tests/Unit/Service/SbomRegisterShapeTest.php | 6 +- ...ingsServiceArchiMateStatusFallbackTest.php | 8 +- ...ttingsServiceCatalogTypeResolutionTest.php | 8 +- .../SettingsServiceConfigVersionTest.php | 8 +- .../SettingsServiceDecompositionTest.php | 10 +- .../Service/SettingsServiceEolConfigTest.php | 8 +- ...ettingsServiceRegisterVerificationTest.php | 8 +- .../SettingsServiceResolveImportForceTest.php | 8 +- .../SettingsServiceResolverWiringTest.php | 18 +- .../ContactPersonHandlerDecompositionTest.php | 4 +- .../Stackiq/GroupHandlerDecompositionTest.php | 10 +- .../HierarchyHandlerDecompositionTest.php | 14 +- .../OrganizationHandlerDecompositionTest.php | 4 +- .../StackiqServiceDecompositionTest.php | 32 ++-- .../StackiqServiceOrganisationMapperTest.php | 26 +-- .../SymfonyEmailServiceDecompositionTest.php | 12 +- tests/Unit/Service/ViewServiceTest.php | 10 +- tests/Unit/Settings/ContractRbacTest.php | 10 +- .../RegisterConfigFieldResolutionTest.php | 6 +- tests/Unit/Settings/SchemaRbacTest.php | 6 +- tests/Unit/SettingsRouteTableTest.php | 4 +- tests/analysis-stubs/decidesk-events.stub.php | 4 +- tests/bootstrap-unit.php | 2 +- tests/bootstrap.php | 4 +- 330 files changed, 2366 insertions(+), 2332 deletions(-) diff --git a/ARCHIMATE_IMPORT_FIX.md b/ARCHIMATE_IMPORT_FIX.md index 6f4749ff..8f3addff 100644 --- a/ARCHIMATE_IMPORT_FIX.md +++ b/ARCHIMATE_IMPORT_FIX.md @@ -61,12 +61,12 @@ Before testing, ensure AMEF configuration is properly set: ```bash # Check AMEF configuration -docker-compose exec -u 33 nextcloud php occ config:app:get softwarecatalog amef_config +docker-compose exec -u 33 nextcloud php occ config:app:get stackiq amef_config # Check via API curl -u 'admin:admin' \ -H 'OCS-APIREQUEST: true' \ - 'http://localhost/index.php/apps/softwarecatalog/api/settings/debug' + 'http://localhost/index.php/apps/stackiq/api/settings/debug' ``` ### 2. Test Import via UI @@ -81,7 +81,7 @@ curl -u 'admin:admin' \ curl -u 'admin:admin' \ -H 'OCS-APIREQUEST: true' \ -F 'archiMateFile=@/path/to/GEMMA_release.xml' \ - 'http://localhost/index.php/apps/softwarecatalog/api/archimate/import' + 'http://localhost/index.php/apps/stackiq/api/archimate/import' ``` ### 4. Monitor Logs @@ -130,7 +130,7 @@ docker logs master-nextcloud-1 | grep -E 'Object creation completed|Object updat ### 1. Check Object Creation ```bash # Check if objects were created in the database -docker-compose exec -u 33 nextcloud php occ config:app:get softwarecatalog amef_config +docker-compose exec -u 33 nextcloud php occ config:app:get stackiq amef_config ``` ### 2. Verify Schema Mapping @@ -150,7 +150,7 @@ The fix ensures that: 1. **Check AMEF Configuration**: ```bash - docker-compose exec -u 33 nextcloud php occ config:app:get softwarecatalog amef_config + docker-compose exec -u 33 nextcloud php occ config:app:get stackiq amef_config ``` Ensure all schema IDs are properly set. diff --git a/appinfo/routes.php b/appinfo/routes.php index cabad721..f523000c 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -3,16 +3,16 @@ declare(strict_types=1); /** - * SoftwareCatalog Routes Configuration + * Stackiq Routes Configuration * - * This file defines the API routes for the SoftwareCatalog application. + * This file defines the API routes for the Stackiq application. * * @category Configuration - * @package OCA\SoftwareCatalog + * @package OCA\Stackiq * @version 1.0.0 * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ return [ @@ -212,7 +212,7 @@ ['name' => 'moderation#approve', 'url' => '/api/moderation/{uuid}/approve', 'verb' => 'POST'], ['name' => 'moderation#reject', 'url' => '/api/moderation/{uuid}/reject', 'verb' => 'POST'], - // CATALOG RATINGS (softwarecatalog#375) — authenticated review + // CATALOG RATINGS (stackiq#375) — authenticated review // submission (author/status always server-stamped, never from the // client) + public approved-only aggregate for module/dienst detail. ['name' => 'review#submit', 'url' => '/api/reviews', 'verb' => 'POST'], @@ -298,7 +298,7 @@ // `dashboard#page` route above: both entries target the same // controller#method, so without a postfix they generate the same // internal route name and the later one silently displaces the first — - // which 404'd the app's own entry point (`/apps/softwarecatalog/`) for + // which 404'd the app's own entry point (`/apps/stackiq/`) for // every user, because this route's `path` requirement ('.+') can never // match an empty path. ['name' => 'dashboard#page', 'url' => '/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.+'], 'defaults' => ['path' => ''], 'postfix' => 'spa'], diff --git a/l10n/be.js b/l10n/be.js index 06f6fe51..18cdffbf 100644 --- a/l10n/be.js +++ b/l10n/be.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/bg.js b/l10n/bg.js index fd8a5bfa..d93693a1 100644 --- a/l10n/bg.js +++ b/l10n/bg.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/bs.js b/l10n/bs.js index 6d165269..9ca1053a 100644 --- a/l10n/bs.js +++ b/l10n/bs.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/ca.js b/l10n/ca.js index 9c4c9cc5..a3e7bc15 100644 --- a/l10n/ca.js +++ b/l10n/ca.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/cs.js b/l10n/cs.js index cb456d33..16de9025 100644 --- a/l10n/cs.js +++ b/l10n/cs.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/da.js b/l10n/da.js index d55f3f96..3f96efc2 100644 --- a/l10n/da.js +++ b/l10n/da.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/de.js b/l10n/de.js index 98910613..d8b6c5ae 100644 --- a/l10n/de.js +++ b/l10n/de.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/el.js b/l10n/el.js index 3722bee0..2b107591 100644 --- a/l10n/el.js +++ b/l10n/el.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/en.js b/l10n/en.js index 2295bce9..2e40fbc7 100644 --- a/l10n/en.js +++ b/l10n/en.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "AMEF elements" : "AMEF elements", "AMEF standards" : "AMEF standards", diff --git a/l10n/en_US.js b/l10n/en_US.js index e160e615..479f247d 100644 --- a/l10n/en_US.js +++ b/l10n/en_US.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/es.js b/l10n/es.js index ff91aaf6..8eb29407 100644 --- a/l10n/es.js +++ b/l10n/es.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/et.js b/l10n/et.js index d7e932b3..21daf809 100644 --- a/l10n/et.js +++ b/l10n/et.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/fi.js b/l10n/fi.js index 522b806d..59474e4e 100644 --- a/l10n/fi.js +++ b/l10n/fi.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/fr.js b/l10n/fr.js index da58d6b8..bef79b41 100644 --- a/l10n/fr.js +++ b/l10n/fr.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/ga.js b/l10n/ga.js index 5336188a..9eccb9db 100644 --- a/l10n/ga.js +++ b/l10n/ga.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/hr.js b/l10n/hr.js index 7b5ab0dc..cd772827 100644 --- a/l10n/hr.js +++ b/l10n/hr.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/hu.js b/l10n/hu.js index 68d25d84..621d9d3e 100644 --- a/l10n/hu.js +++ b/l10n/hu.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/is.js b/l10n/is.js index e9d7d694..34fbd291 100644 --- a/l10n/is.js +++ b/l10n/is.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/it.js b/l10n/it.js index 81281724..868e5787 100644 --- a/l10n/it.js +++ b/l10n/it.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/lb.js b/l10n/lb.js index 29c443a6..1327853c 100644 --- a/l10n/lb.js +++ b/l10n/lb.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/lt.js b/l10n/lt.js index 9f916475..0e00640d 100644 --- a/l10n/lt.js +++ b/l10n/lt.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/lv.js b/l10n/lv.js index d257f7b4..125c8a72 100644 --- a/l10n/lv.js +++ b/l10n/lv.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/mk.js b/l10n/mk.js index 9b7c4304..585e9c48 100644 --- a/l10n/mk.js +++ b/l10n/mk.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/mt.js b/l10n/mt.js index a6dacbe0..a18df4e6 100644 --- a/l10n/mt.js +++ b/l10n/mt.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/nb.js b/l10n/nb.js index a79ec9b9..44ca59ed 100644 --- a/l10n/nb.js +++ b/l10n/nb.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/nl.js b/l10n/nl.js index 25a15fe2..712d992e 100644 --- a/l10n/nl.js +++ b/l10n/nl.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "AMEF elements" : "Amef elementen", "AMEF standards" : "Standaarden AMEF", diff --git a/l10n/pl.js b/l10n/pl.js index 6f2b1fde..e795c225 100644 --- a/l10n/pl.js +++ b/l10n/pl.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/pt.js b/l10n/pt.js index 9fe86cef..76bc51eb 100644 --- a/l10n/pt.js +++ b/l10n/pt.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/rm.js b/l10n/rm.js index daf44b83..5373610d 100644 --- a/l10n/rm.js +++ b/l10n/rm.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/ro.js b/l10n/ro.js index bf2dad4d..a6d4cae0 100644 --- a/l10n/ro.js +++ b/l10n/ro.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/ru.js b/l10n/ru.js index 0110c294..199b74fb 100644 --- a/l10n/ru.js +++ b/l10n/ru.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/sk.js b/l10n/sk.js index 2d9de754..e36ccfe4 100644 --- a/l10n/sk.js +++ b/l10n/sk.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/sl.js b/l10n/sl.js index 7a2df0d4..db606bea 100644 --- a/l10n/sl.js +++ b/l10n/sl.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/sq.js b/l10n/sq.js index cc5e15b5..9f596431 100644 --- a/l10n/sq.js +++ b/l10n/sq.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/sr.js b/l10n/sr.js index 264246e4..8c0808d8 100644 --- a/l10n/sr.js +++ b/l10n/sr.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/sv.js b/l10n/sv.js index 97866bb0..ccf03735 100644 --- a/l10n/sv.js +++ b/l10n/sv.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/tr.js b/l10n/tr.js index 50a64146..d6e9d555 100644 --- a/l10n/tr.js +++ b/l10n/tr.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/l10n/uk.js b/l10n/uk.js index 6d1a9913..27bcd4e1 100644 --- a/l10n/uk.js +++ b/l10n/uk.js @@ -1,5 +1,5 @@ OC.L10N.register( - "softwarecatalog", + "stackiq", { "Acquisition" : "Acquisition", "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement)." : "Applications in use for an organisation, grouped by lifecycle phase and ordered by nearest urgency (end-of-support, phase-out or planned replacement).", diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index e41a15d5..e71b14f4 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -1,24 +1,24 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\AppInfo; +namespace OCA\Stackiq\AppInfo; use OCA\Decidesk\Event\DecisionConcludedEvent; use OCA\OpenRegister\Contract\ObjectServiceInterface; @@ -26,53 +26,53 @@ use OCA\OpenRegister\Event\ObjectUpdatedEvent; use OCA\OpenRegister\Event\UserProfileUpdatedEvent; use OCA\OpenRegister\Service\OrganisationService as OpenRegisterOrganisationService; -use OCA\SoftwareCatalog\BackgroundJob\ContractStatusJob; -use OCA\SoftwareCatalog\BackgroundJob\EolSyncJob; -use OCA\SoftwareCatalog\BackgroundJob\FederationSyncJob; -use OCA\SoftwareCatalog\BackgroundJob\OrganizationContactSyncJob; -use OCA\SoftwareCatalog\Controller\ContactpersonenController; -use OCA\SoftwareCatalog\Dashboard\ConceptOrganisatiesWidget; -use OCA\SoftwareCatalog\EventListener\DecisionConcludedListener; -use OCA\SoftwareCatalog\EventListener\ModuleComplianceSubscriber; -use OCA\SoftwareCatalog\EventListener\ModuleRegistrationSubscriber; -use OCA\SoftwareCatalog\EventListener\TestEventListener; -use OCA\SoftwareCatalog\EventListener\UserProfileUpdatedEventListener; -use OCA\SoftwareCatalog\Service\ArchiMateExportService; -use OCA\SoftwareCatalog\Service\ArchiMateImportService; -use OCA\SoftwareCatalog\Service\ArchiMateService; -use OCA\SoftwareCatalog\Service\ContactpersoonService; -use OCA\SoftwareCatalog\Service\ContractApprovalService; -use OCA\SoftwareCatalog\Service\ContractStatusService; -use OCA\SoftwareCatalog\Service\EolMatcherService; -use OCA\SoftwareCatalog\Service\EolSyncService; -use OCA\SoftwareCatalog\Service\FacetService; -use OCA\SoftwareCatalog\Service\Federation\FederationConfig; -use OCA\SoftwareCatalog\Service\Federation\FederationMerger; -use OCA\SoftwareCatalog\Service\Federation\FederationService; -use OCA\SoftwareCatalog\Service\GebruikSyncService; -use OCA\SoftwareCatalog\Service\IntakeService; -use OCA\SoftwareCatalog\Service\MergeOrganisatieService; -use OCA\SoftwareCatalog\Service\ModerationService; -use OCA\SoftwareCatalog\Service\ModuleComplianceService; -use OCA\SoftwareCatalog\Service\ModuleRegistrationService; -use OCA\SoftwareCatalog\Service\ModuleVersionService; -use OCA\SoftwareCatalog\Service\OrganisatieService; -use OCA\SoftwareCatalog\Service\OrganizationSyncService; -use OCA\SoftwareCatalog\Service\ProgressTracker; -use OCA\SoftwareCatalog\Service\PublicationService; -use OCA\SoftwareCatalog\Service\ReviewAggregateService; -use OCA\SoftwareCatalog\Service\ReviewService; -use OCA\SoftwareCatalog\Service\SbomImportService; -use OCA\SoftwareCatalog\Service\SbomParserService; -use OCA\SoftwareCatalog\Service\SettingsService; -use OCA\SoftwareCatalog\Service\SoftwareCatalogContactSyncService; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\GroupHandler; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\HierarchyHandler; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\OrganizationHandler; -use OCA\SoftwareCatalog\Service\SymfonyEmailService; -use OCA\SoftwareCatalog\Service\ViewQueryBuilder; -use OCA\SoftwareCatalog\Service\ViewService; +use OCA\Stackiq\BackgroundJob\ContractStatusJob; +use OCA\Stackiq\BackgroundJob\EolSyncJob; +use OCA\Stackiq\BackgroundJob\FederationSyncJob; +use OCA\Stackiq\BackgroundJob\OrganizationContactSyncJob; +use OCA\Stackiq\Controller\ContactpersonenController; +use OCA\Stackiq\Dashboard\ConceptOrganisatiesWidget; +use OCA\Stackiq\EventListener\DecisionConcludedListener; +use OCA\Stackiq\EventListener\ModuleComplianceSubscriber; +use OCA\Stackiq\EventListener\ModuleRegistrationSubscriber; +use OCA\Stackiq\EventListener\TestEventListener; +use OCA\Stackiq\EventListener\UserProfileUpdatedEventListener; +use OCA\Stackiq\Service\ArchiMateExportService; +use OCA\Stackiq\Service\ArchiMateImportService; +use OCA\Stackiq\Service\ArchiMateService; +use OCA\Stackiq\Service\ContactpersoonService; +use OCA\Stackiq\Service\ContractApprovalService; +use OCA\Stackiq\Service\ContractStatusService; +use OCA\Stackiq\Service\EolMatcherService; +use OCA\Stackiq\Service\EolSyncService; +use OCA\Stackiq\Service\FacetService; +use OCA\Stackiq\Service\Federation\FederationConfig; +use OCA\Stackiq\Service\Federation\FederationMerger; +use OCA\Stackiq\Service\Federation\FederationService; +use OCA\Stackiq\Service\GebruikSyncService; +use OCA\Stackiq\Service\IntakeService; +use OCA\Stackiq\Service\MergeOrganisatieService; +use OCA\Stackiq\Service\ModerationService; +use OCA\Stackiq\Service\ModuleComplianceService; +use OCA\Stackiq\Service\ModuleRegistrationService; +use OCA\Stackiq\Service\ModuleVersionService; +use OCA\Stackiq\Service\OrganisatieService; +use OCA\Stackiq\Service\OrganizationSyncService; +use OCA\Stackiq\Service\ProgressTracker; +use OCA\Stackiq\Service\PublicationService; +use OCA\Stackiq\Service\ReviewAggregateService; +use OCA\Stackiq\Service\ReviewService; +use OCA\Stackiq\Service\SbomImportService; +use OCA\Stackiq\Service\SbomParserService; +use OCA\Stackiq\Service\SettingsService; +use OCA\Stackiq\Service\StackiqContactSyncService; +use OCA\Stackiq\Service\Stackiq\ContactPersonHandler; +use OCA\Stackiq\Service\Stackiq\GroupHandler; +use OCA\Stackiq\Service\Stackiq\HierarchyHandler; +use OCA\Stackiq\Service\Stackiq\OrganizationHandler; +use OCA\Stackiq\Service\SymfonyEmailService; +use OCA\Stackiq\Service\ViewQueryBuilder; +use OCA\Stackiq\Service\ViewService; use OCP\App\IAppManager; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; @@ -92,14 +92,14 @@ use Psr\Log\LoggerInterface; /** - * Main Application class for SoftwareCatalog + * Main Application class for Stackiq * * @category Application - * @package OCA\SoftwareCatalog\AppInfo + * @package OCA\Stackiq\AppInfo * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @@ -109,7 +109,7 @@ class Application extends App implements IBootstrap { /** * The application ID */ - public const APP_ID = 'softwarecatalog'; + public const APP_ID = 'stackiq'; /** * Application constructor @@ -157,7 +157,7 @@ public function register(IRegistrationContext $context): void { }//end register() /** - * Wire the four SoftwareCatalogue handler services as DI bindings. + * Wire the four Stackiq handler services as DI bindings. * * Single-responsibility helper extracted from `register()` per * `openspec/changes/method-decomposition/tasks.md` task 9.1. @@ -170,7 +170,7 @@ public function register(IRegistrationContext $context): void { */ private function registerHandlerServices(IRegistrationContext $context): void { $context->registerService( - 'OCA\SoftwareCatalog\Service\SoftwareCatalogue\OrganizationHandler', + 'OCA\Stackiq\Service\Stackiq\OrganizationHandler', function (ContainerInterface $c) { return new OrganizationHandler( _groupManager: $c->get(IGroupManager::class), @@ -183,7 +183,7 @@ function (ContainerInterface $c) { ); $context->registerService( - 'OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler', + 'OCA\Stackiq\Service\Stackiq\ContactPersonHandler', function (ContainerInterface $c) { return new ContactPersonHandler( _userManager: $c->get(IUserManager::class), @@ -200,7 +200,7 @@ function (ContainerInterface $c) { ); $context->registerService( - 'OCA\SoftwareCatalog\Service\SoftwareCatalogue\GroupHandler', + 'OCA\Stackiq\Service\Stackiq\GroupHandler', function (ContainerInterface $c) { return new GroupHandler( _groupManager: $c->get(IGroupManager::class), @@ -214,11 +214,11 @@ function (ContainerInterface $c) { ); $context->registerService( - 'OCA\SoftwareCatalog\Service\SoftwareCatalogue\HierarchyHandler', + 'OCA\Stackiq\Service\Stackiq\HierarchyHandler', function (ContainerInterface $c) { return new HierarchyHandler( - _organizationHandler: $c->get('OCA\SoftwareCatalog\Service\SoftwareCatalogue\OrganizationHandler'), - _contactPersonHandler: $c->get('OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler'), + _organizationHandler: $c->get('OCA\Stackiq\Service\Stackiq\OrganizationHandler'), + _contactPersonHandler: $c->get('OCA\Stackiq\Service\Stackiq\ContactPersonHandler'), _logger: $c->get(LoggerInterface::class), _userManager: $c->get(IUserManager::class), _groupManager: $c->get(IGroupManager::class) @@ -361,9 +361,9 @@ function ($container) { // Register the Nextcloud-Contacts bridge (identity → NC addressbook, // relationship records keyed by contactsUid; ADR-019/ADR-022). $context->registerService( - SoftwareCatalogContactSyncService::class, + StackiqContactSyncService::class, function ($container) { - return new SoftwareCatalogContactSyncService( + return new StackiqContactSyncService( contactsManager: $container->get('OCP\Contacts\IManager'), logger: $container->get('Psr\Log\LoggerInterface') ); @@ -434,7 +434,7 @@ function ($container) { ); // Register the registration/review moderation/approval-queue service - // (generalised to also moderate beoordeeling — softwarecatalog#375). + // (generalised to also moderate beoordeeling — stackiq#375). $context->registerService( ModerationService::class, function ($container) { @@ -447,7 +447,7 @@ function ($container) { ); // Register the authenticated review-submission service (catalog-ratings, - // softwarecatalog#375). Author identity comes from IUserSession, never + // stackiq#375). Author identity comes from IUserSession, never // from client input. $context->registerService( ReviewService::class, @@ -462,7 +462,7 @@ function ($container) { ); // Register the public approved-only review aggregate/read service - // (catalog-ratings, softwarecatalog#375) — split from ReviewService + // (catalog-ratings, stackiq#375) — split from ReviewService // to keep each class under the complexity budget. $context->registerService( ReviewAggregateService::class, @@ -607,7 +607,7 @@ function ($container) { return new OrganizationContactSyncJob( timeFactory: $container->get('OCP\AppFramework\Utility\ITimeFactory'), orgSyncService: $container->get(OrganizationSyncService::class), - contactSync: $container->get(SoftwareCatalogContactSyncService::class), + contactSync: $container->get(StackiqContactSyncService::class), settingsService: $container->get(SettingsService::class), appManager: $container->get(IAppManager::class), logger: $container->get(LoggerInterface::class) @@ -731,7 +731,7 @@ function ($container) { request: $container->get('OCP\IRequest'), settingsService: $container->get(SettingsService::class), contactPersonHandler: $container->get( - 'OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler' + 'OCA\Stackiq\Service\Stackiq\ContactPersonHandler' ), contactSvc: $container->get(ContactpersoonService::class), userManager: $container->get('OCP\IUserManager'), @@ -773,7 +773,7 @@ private function registerEventListeners(IRegistrationContext $context): void { $context->registerEventListener(UserLoggedInEvent::class, TestEventListener::class); // OpenRegister object lifecycle events are NO LONGER broadcast to - // SoftwareCatalogEventListener. + // StackiqEventListener. // // That listener's own docblock has said "DISABLED: All processing is now // handled by cron-based OrganizationSyncService to avoid race conditions" @@ -784,7 +784,7 @@ private function registerEventListeners(IRegistrationContext $context): void { // then discarded the result. // // The cost was not theoretical. Importing OpenCatalogi's configuration — - // twelve seeded objects — produced 657 SoftwareCatalog event handlings. + // twelve seeded objects — produced 657 Stackiq event handlings. // Each one resolved three services from the container and wrote six log // lines BEFORE reaching the schema check that decides the event is not // ours. `occ maintenance:repair` reached 119 of 120 steps and then sat in diff --git a/lib/BackgroundJob/ContractStatusJob.php b/lib/BackgroundJob/ContractStatusJob.php index 171d3ca9..45a8e1c9 100644 --- a/lib/BackgroundJob/ContractStatusJob.php +++ b/lib/BackgroundJob/ContractStatusJob.php @@ -12,11 +12,11 @@ * correct mechanism (tasks.md 2.1 → 2.2). * * @category BackgroundJob - * @package OCA\SoftwareCatalog\BackgroundJob + * @package OCA\Stackiq\BackgroundJob * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-administration/spec.md * @@ -26,9 +26,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\BackgroundJob; +namespace OCA\Stackiq\BackgroundJob; -use OCA\SoftwareCatalog\Service\ContractStatusService; +use OCA\Stackiq\Service\ContractStatusService; use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; diff --git a/lib/BackgroundJob/EolSyncJob.php b/lib/BackgroundJob/EolSyncJob.php index 38ee9ec8..83d510c7 100644 --- a/lib/BackgroundJob/EolSyncJob.php +++ b/lib/BackgroundJob/EolSyncJob.php @@ -14,11 +14,11 @@ * sharing it. * * @category BackgroundJob - * @package OCA\SoftwareCatalog\BackgroundJob + * @package OCA\Stackiq\BackgroundJob * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/eol-feed-integration/spec.md#requirement-eol-sync-runs-on-a-schedule-with-a-manual-trigger * @@ -28,9 +28,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\BackgroundJob; +namespace OCA\Stackiq\BackgroundJob; -use OCA\SoftwareCatalog\Service\EolSyncService; +use OCA\Stackiq\Service\EolSyncService; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use Psr\Log\LoggerInterface; @@ -58,7 +58,7 @@ public function __construct( ) { parent::__construct(time: $timeFactory); - // Floor at 300s (the shortest interval any existing SoftwareCatalog + // Floor at 300s (the shortest interval any existing Stackiq // background job runs at — OrganizationContactSyncJob) so a // mistyped admin value can never schedule a tighter loop than the // rest of the app's cron surface. diff --git a/lib/BackgroundJob/FederationSyncJob.php b/lib/BackgroundJob/FederationSyncJob.php index 265c21de..b3a701a1 100644 --- a/lib/BackgroundJob/FederationSyncJob.php +++ b/lib/BackgroundJob/FederationSyncJob.php @@ -9,11 +9,11 @@ * federation is disabled — so the job is always safe to run. * * @category BackgroundJob - * @package OCA\SoftwareCatalog\BackgroundJob + * @package OCA\Stackiq\BackgroundJob * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/federated-catalog-sync/spec.md * @@ -23,10 +23,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\BackgroundJob; +namespace OCA\Stackiq\BackgroundJob; -use OCA\SoftwareCatalog\Service\Federation\FederationConfig; -use OCA\SoftwareCatalog\Service\Federation\FederationService; +use OCA\Stackiq\Service\Federation\FederationConfig; +use OCA\Stackiq\Service\Federation\FederationService; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use Psr\Log\LoggerInterface; diff --git a/lib/BackgroundJob/OrganizationContactSyncJob.php b/lib/BackgroundJob/OrganizationContactSyncJob.php index d2e14e10..575107af 100644 --- a/lib/BackgroundJob/OrganizationContactSyncJob.php +++ b/lib/BackgroundJob/OrganizationContactSyncJob.php @@ -4,24 +4,24 @@ * Organization Contact Synchronization Background Job * * This file contains the background job class for synchronizing organizations and contact persons - * between SoftwareCatalog objects and OpenRegister entities. + * between Stackiq objects and OpenRegister entities. * * @category BackgroundJob - * @package OCA\SoftwareCatalog\BackgroundJob + * @package OCA\Stackiq\BackgroundJob * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: 1.0.0 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\BackgroundJob; +namespace OCA\Stackiq\BackgroundJob; -use OCA\SoftwareCatalog\Service\OrganizationSyncService; -use OCA\SoftwareCatalog\Service\SettingsService; -use OCA\SoftwareCatalog\Service\SoftwareCatalogContactSyncService; +use OCA\Stackiq\Service\OrganizationSyncService; +use OCA\Stackiq\Service\SettingsService; +use OCA\Stackiq\Service\StackiqContactSyncService; use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; @@ -30,7 +30,7 @@ /** * Background job for comprehensive organization and contact person synchronization * - * This job runs every 5 minutes to ensure data consistency between SoftwareCatalog objects + * This job runs every 5 minutes to ensure data consistency between Stackiq objects * and OpenRegister entities using full sync (all organizations). All business logic is * delegated to the OrganizationSyncService. * @@ -38,11 +38,11 @@ * system-level background job that needs unrestricted access to all objects. * * @category BackgroundJob - * @package OCA\SoftwareCatalog\BackgroundJob + * @package OCA\Stackiq\BackgroundJob * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: 1.0.0 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ class OrganizationContactSyncJob extends TimedJob { @@ -58,7 +58,7 @@ class OrganizationContactSyncJob extends TimedJob { * * @param ITimeFactory $timeFactory The time factory for job scheduling * @param OrganizationSyncService $orgSyncService The sync service - * @param SoftwareCatalogContactSyncService $contactSync The Nextcloud-Contacts bridge + * @param StackiqContactSyncService $contactSync The Nextcloud-Contacts bridge * @param SettingsService $settingsService The settings service (register/schema id resolution) * @param IAppManager $appManager The Nextcloud app manager * @param LoggerInterface $logger The logger @@ -66,7 +66,7 @@ class OrganizationContactSyncJob extends TimedJob { public function __construct( ITimeFactory $timeFactory, OrganizationSyncService $orgSyncService, - private readonly SoftwareCatalogContactSyncService $contactSync, + private readonly StackiqContactSyncService $contactSync, private readonly SettingsService $settingsService, private readonly IAppManager $appManager, private readonly LoggerInterface $logger, @@ -83,7 +83,7 @@ public function __construct( * Delegates organisation/contact synchronisation to the * OrganizationSyncService, then keeps every catalog relationship record's * `contactsUid` link to the Nextcloud addressbook fresh via - * SoftwareCatalogContactSyncService. Per cross-app interface contract #2, + * StackiqContactSyncService. Per cross-app interface contract #2, * identity lives in Nextcloud Contacts — this job refreshes the link, it * does NOT mirror identity into OpenRegister. * @@ -135,7 +135,7 @@ protected function run($argument): void { * Refresh the `contactsUid` link on every contactpersoon/organisatie record. * * For each record this (re)resolves its Nextcloud Contact through - * SoftwareCatalogContactSyncService and writes back the UID only when it is + * StackiqContactSyncService and writes back the UID only when it is * missing or has changed. Never mirrors identity into OpenRegister and * never deletes a source object — a record that cannot be resolved is left * intact for a later pass. diff --git a/lib/Controller/AanbodController.php b/lib/Controller/AanbodController.php index f26a6501..9d1d8ed1 100644 --- a/lib/Controller/AanbodController.php +++ b/lib/Controller/AanbodController.php @@ -1,25 +1,25 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\Service\AanbodService; +use OCA\Stackiq\Service\AanbodService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -35,12 +35,12 @@ * (provider), and for accepting or denying these offers. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ class AanbodController extends Controller { /** diff --git a/lib/Controller/AangebodenGebruikController.php b/lib/Controller/AangebodenGebruikController.php index 521b0ffc..a62f8abe 100644 --- a/lib/Controller/AangebodenGebruikController.php +++ b/lib/Controller/AangebodenGebruikController.php @@ -1,26 +1,26 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\Service\AangebodenGebruikService; +use OCA\Stackiq\Service\AangebodenGebruikService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AnonRateLimit; @@ -38,12 +38,12 @@ * (participants), and for updating the @self property of gebruiks objects. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @@ -866,7 +866,7 @@ function ($key) { public function getApiDocumentation(): JSONResponse { $documentation = [ 'api_version' => '2.0.0', - 'description' => 'SoftwareCatalog AangebodenGebruik API', + 'description' => 'Stackiq AangebodenGebruik API', 'base_url' => '/api/aangeboden-gebruik', 'endpoints' => [ [ diff --git a/lib/Controller/ContactpersonenController.php b/lib/Controller/ContactpersonenController.php index 14c7e159..e123e455 100644 --- a/lib/Controller/ContactpersonenController.php +++ b/lib/Controller/ContactpersonenController.php @@ -1,18 +1,18 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * SPDX-FileCopyrightText: 2026 Conduction B.V. * SPDX-License-Identifier: EUPL-1.2 @@ -20,11 +20,11 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\Service\ContactpersoonService; -use OCA\SoftwareCatalog\Service\SettingsService; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler; +use OCA\Stackiq\Service\ContactpersoonService; +use OCA\Stackiq\Service\SettingsService; +use OCA\Stackiq\Service\Stackiq\ContactPersonHandler; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -46,12 +46,12 @@ * - Managing user group memberships * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) diff --git a/lib/Controller/ContractApprovalController.php b/lib/Controller/ContractApprovalController.php index ed1075e4..972ba8c7 100644 --- a/lib/Controller/ContractApprovalController.php +++ b/lib/Controller/ContractApprovalController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. @@ -32,7 +32,7 @@ * * @version GIT: * - * @link https://codeberg.org/Conduction/softwarecatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-decision-delegation/spec.md * @@ -42,10 +42,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\ContractApprovalService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\ContractApprovalService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; diff --git a/lib/Controller/DashboardController.php b/lib/Controller/DashboardController.php index 8890ba43..cebdb5c2 100644 --- a/lib/Controller/DashboardController.php +++ b/lib/Controller/DashboardController.php @@ -1,18 +1,18 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; diff --git a/lib/Controller/FacetController.php b/lib/Controller/FacetController.php index 16475333..c453a6d6 100644 --- a/lib/Controller/FacetController.php +++ b/lib/Controller/FacetController.php @@ -1,16 +1,16 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * SPDX-FileCopyrightText: 2026 Conduction B.V. * SPDX-License-Identifier: EUPL-1.2 @@ -20,9 +20,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\Service\FacetService; +use OCA\Stackiq\Service\FacetService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; @@ -32,7 +32,7 @@ * Controller for the GEMMA-dimension facet aggregation endpoint. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * * @spec openspec/specs/gemma-faceted-search/spec.md#requirement-facet-aggregation-endpoint-returns-gemma-dimension-counts */ diff --git a/lib/Controller/FederationController.php b/lib/Controller/FederationController.php index d59aff77..e57f5b38 100644 --- a/lib/Controller/FederationController.php +++ b/lib/Controller/FederationController.php @@ -9,7 +9,7 @@ * of all configured peers. All write/read paths delegate to FederationService; * no bespoke federation logic lives here. * - * AUTH (ADR-005): every method is `#[AuthorizedAdminSetting(SoftwareCatalogAdmin::class)]` + * AUTH (ADR-005): every method is `#[AuthorizedAdminSetting(StackiqAdmin::class)]` * — Nextcloud's admin-settings middleware rejects any non-admin caller before * the controller body runs (matching the moderation controller's posture and the * service's admin-only intent), so an authenticated non-admin can never reach @@ -17,11 +17,11 @@ * OWASP A01:2021). * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/federated-catalog-sync/spec.md * @@ -31,11 +31,11 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\Federation\FederationService; -use OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\Federation\FederationService; +use OCA\Stackiq\Settings\StackiqAdmin; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting; @@ -64,10 +64,10 @@ public function __construct( * * @return JSONResponse `{available, enabled, directoryUrl, peers, staleAfter, message}`. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/federated-catalog-sync/spec.md */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function status(): JSONResponse { return new JSONResponse(data: $this->federation->getStatus()); }//end status() @@ -79,10 +79,10 @@ public function status(): JSONResponse { * * @return JSONResponse `{ok, reason}` or a 400 when the peer is rejected. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/federated-catalog-sync/spec.md */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function addPeer(string $peerUrl = ''): JSONResponse { $result = $this->federation->addPeer($peerUrl); if ($result['ok'] === false) { @@ -99,10 +99,10 @@ public function addPeer(string $peerUrl = ''): JSONResponse { * * @return JSONResponse `{ok, reason}` or a 400 when the peer is unknown. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/federated-catalog-sync/spec.md */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function removePeer(string $peerUrl = ''): JSONResponse { $result = $this->federation->removePeer($peerUrl); if ($result['ok'] === false) { @@ -117,10 +117,10 @@ public function removePeer(string $peerUrl = ''): JSONResponse { * * @return JSONResponse `{ok, reason, peers}` or a 400 when federation is off/unavailable. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/federated-catalog-sync/spec.md */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function pull(): JSONResponse { $result = $this->federation->pullAllPeers(); if ($result['ok'] === false) { diff --git a/lib/Controller/GebruikController.php b/lib/Controller/GebruikController.php index 0ae801b1..7f07267c 100644 --- a/lib/Controller/GebruikController.php +++ b/lib/Controller/GebruikController.php @@ -1,26 +1,26 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://github.com/nextcloud/softwarecatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; use Exception; -use OCA\SoftwareCatalog\Service\GebruikService; +use OCA\Stackiq\Service\GebruikService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AnonRateLimit; @@ -38,12 +38,12 @@ * with role-based access for gebruik-beheerder and aanbod-beheerder users. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://github.com/nextcloud/softwarecatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/vendor-visibility-rbac/tasks.md#task-2 */ diff --git a/lib/Controller/IntakeController.php b/lib/Controller/IntakeController.php index f66b6815..7fbae2cf 100644 --- a/lib/Controller/IntakeController.php +++ b/lib/Controller/IntakeController.php @@ -17,11 +17,11 @@ * anonymous client has no CSRF token. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @@ -31,10 +31,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\IntakeService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\IntakeService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AnonRateLimit; diff --git a/lib/Controller/MergeController.php b/lib/Controller/MergeController.php index 2cb7ef15..63a20766 100644 --- a/lib/Controller/MergeController.php +++ b/lib/Controller/MergeController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/organisation-merge/spec.md#requirement-both-merge-endpoints-must-be-admin-only-with-an-explicit-per-object-authorization-guard * @@ -29,10 +29,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\MergeOrganisatieService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\MergeOrganisatieService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; diff --git a/lib/Controller/ModerationController.php b/lib/Controller/ModerationController.php index d233f474..368bce09 100644 --- a/lib/Controller/ModerationController.php +++ b/lib/Controller/ModerationController.php @@ -13,7 +13,7 @@ * to `approved`/`rejected` — the schema's own `status`-conditioned public * RBAC rule does the visibility job `publicatiedatum` does for organisatie. * - * AUTH (ADR-005): every method is `#[AuthorizedAdminSetting(SoftwareCatalogAdmin::class)]` + * AUTH (ADR-005): every method is `#[AuthorizedAdminSetting(StackiqAdmin::class)]` * — Nextcloud's admin-settings middleware rejects any non-admin caller before * the controller body runs, so an authenticated non-admin can never reach the * approve/publish path (no privilege escalation / IDOR — OWASP A01:2021). The @@ -21,11 +21,11 @@ * currently `pending` and on peer-sourced (federated) mirrors. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @spec openspec/specs/catalog-ratings/spec.md#requirement-review-moderation-must-reuse-the-existing-moderation-queue-mechanism-not-a-second-one @@ -36,11 +36,11 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\ModerationService; -use OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\ModerationService; +use OCA\Stackiq\Settings\StackiqAdmin; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting; @@ -74,11 +74,11 @@ public function __construct( * * @return JSONResponse `{ok, items}` or a 400. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/open-data-publishing/spec.md * @spec openspec/specs/catalog-ratings/spec.md#requirement-review-moderation-must-reuse-the-existing-moderation-queue-mechanism-not-a-second-one */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function pending(string $type = ModerationService::MODERATED_TYPE): JSONResponse { $result = $this->moderation->listPending(type: $type); if ($result['ok'] === false) { @@ -96,11 +96,11 @@ public function pending(string $type = ModerationService::MODERATED_TYPE): JSONR * * @return JSONResponse `{ok, status}` or a 400. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/open-data-publishing/spec.md * @spec openspec/specs/catalog-ratings/spec.md#requirement-a-newly-submitted-review-must-require-moderation-approval-before-becoming-public */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function approve(string $uuid, string $type = ModerationService::MODERATED_TYPE): JSONResponse { $result = $this->moderation->approve($uuid, type: $type); if ($result['ok'] === false) { @@ -118,11 +118,11 @@ public function approve(string $uuid, string $type = ModerationService::MODERATE * * @return JSONResponse `{ok, status}` or a 400. * - * @AuthorizedAdminSetting(settings=OCA\SoftwareCatalog\Settings\SoftwareCatalogAdmin) + * @AuthorizedAdminSetting(settings=OCA\Stackiq\Settings\StackiqAdmin) * @spec openspec/specs/open-data-publishing/spec.md * @spec openspec/specs/catalog-ratings/spec.md#requirement-a-newly-submitted-review-must-require-moderation-approval-before-becoming-public */ - #[AuthorizedAdminSetting(settings: SoftwareCatalogAdmin::class)] + #[AuthorizedAdminSetting(settings: StackiqAdmin::class)] public function reject(string $uuid, string $type = ModerationService::MODERATED_TYPE): JSONResponse { $result = $this->moderation->reject($uuid, type: $type); if ($result['ok'] === false) { diff --git a/lib/Controller/OrganisationMembersController.php b/lib/Controller/OrganisationMembersController.php index cc752432..9ac6a6d8 100644 --- a/lib/Controller/OrganisationMembersController.php +++ b/lib/Controller/OrganisationMembersController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/multi-org-membership/spec.md#requirement-granting-or-revoking-organisation-access-must-be-restricted-to-a-beheerder-of-that-organisation-req-004 * @@ -40,9 +40,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; +use OCA\Stackiq\AppInfo\Application; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; diff --git a/lib/Controller/PortfolioReportController.php b/lib/Controller/PortfolioReportController.php index fbde6b7f..bde7ad93 100644 --- a/lib/Controller/PortfolioReportController.php +++ b/lib/Controller/PortfolioReportController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/portfolio-rationalization-time/specs/portfolio-rationalization-time/spec.md#requirement-report-and-csv-export-are-scoped-to-the-requesters-authorised-organisations * @@ -23,10 +23,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; use Exception; -use OCA\SoftwareCatalog\Service\PortfolioReportService; +use OCA\Stackiq\Service\PortfolioReportService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataDownloadResponse; diff --git a/lib/Controller/PreferencesController.php b/lib/Controller/PreferencesController.php index b813742b..f5672a18 100644 --- a/lib/Controller/PreferencesController.php +++ b/lib/Controller/PreferencesController.php @@ -1,7 +1,7 @@ * @copyright 2024 Conduction B.V. @@ -17,14 +17,14 @@ * * @version GIT: * - * @link https://codeberg.org/Conduction/softwarecatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; +use OCA\Stackiq\AppInfo\Application; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; diff --git a/lib/Controller/PublicationController.php b/lib/Controller/PublicationController.php index dc908a7b..b6e4fe30 100644 --- a/lib/Controller/PublicationController.php +++ b/lib/Controller/PublicationController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @@ -31,10 +31,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\PublicationService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\PublicationService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; diff --git a/lib/Controller/ReviewController.php b/lib/Controller/ReviewController.php index f9312948..3971b11a 100644 --- a/lib/Controller/ReviewController.php +++ b/lib/Controller/ReviewController.php @@ -14,11 +14,11 @@ * anonymous module/dienst detail page view, mirroring `FacetController`. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/catalog-ratings/spec.md * @@ -28,11 +28,11 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\ReviewAggregateService; -use OCA\SoftwareCatalog\Service\ReviewService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\ReviewAggregateService; +use OCA\Stackiq\Service\ReviewService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\NoAdminRequired; diff --git a/lib/Controller/SbomController.php b/lib/Controller/SbomController.php index 2bebb47c..e753a1c3 100644 --- a/lib/Controller/SbomController.php +++ b/lib/Controller/SbomController.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/sbom-import/spec.md * @@ -36,11 +36,11 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Exception\UnsupportedSbomFormatException; -use OCA\SoftwareCatalog\Service\SbomImportService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Exception\UnsupportedSbomFormatException; +use OCA\Stackiq\Service\SbomImportService; use OCP\AppFramework\Controller; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http; @@ -69,6 +69,12 @@ class SbomController extends Controller { * group membership OR manage-ACL on the target moduleVersie's parent * module"). * + * `software-catalog-admins` is FROZEN across the softwarecatalog -> stackiq + * rename: it is a Nextcloud group id, and membership is stored against that + * literal in `oc_group_user`. Renaming it makes every membership check miss + * without raising anything, so the app would silently drop the permissions + * of everyone currently in the group. + * * @var array */ private const MANAGE_GROUPS = ['software-catalog-admins', 'aanbod-beheerder', 'functioneel-beheerder']; diff --git a/lib/Controller/Settings/ModuleRegistrationHandler.php b/lib/Controller/Settings/ModuleRegistrationHandler.php index 0c13d806..31eec685 100644 --- a/lib/Controller/Settings/ModuleRegistrationHandler.php +++ b/lib/Controller/Settings/ModuleRegistrationHandler.php @@ -7,11 +7,11 @@ * and CouplingBetweenObjects on that controller. * * @category Handler - * @package OCA\SoftwareCatalog\Controller\Settings + * @package OCA\Stackiq\Controller\Settings * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-3 * @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller\Settings; +namespace OCA\Stackiq\Controller\Settings; -use OCA\SoftwareCatalog\Service\ModuleRegistrationService; +use OCA\Stackiq\Service\ModuleRegistrationService; use Psr\Log\LoggerInterface; /** diff --git a/lib/Controller/Settings/SyncHandler.php b/lib/Controller/Settings/SyncHandler.php index 77971911..e96ffe0c 100644 --- a/lib/Controller/Settings/SyncHandler.php +++ b/lib/Controller/Settings/SyncHandler.php @@ -7,11 +7,11 @@ * and CouplingBetweenObjects on that controller. * * @category Handler - * @package OCA\SoftwareCatalog\Controller\Settings + * @package OCA\Stackiq\Controller\Settings * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-3 * @@ -21,9 +21,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Controller\Settings; +namespace OCA\Stackiq\Controller\Settings; -use OCA\SoftwareCatalog\Service\OrganizationSyncService; +use OCA\Stackiq\Service\OrganizationSyncService; use Psr\Log\LoggerInterface; /** diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 5bc0f6af..4f4da286 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -22,15 +22,15 @@ * SPDX-License-Identifier: EUPL-1.2 */ -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; use OCA\OpenRegister\Service\ConfigurationService; use OCA\OpenRegister\Contract\ObjectServiceInterface; -use OCA\SoftwareCatalog\Service\ArchiMateService; -use OCA\SoftwareCatalog\Service\EolSyncService; -use OCA\SoftwareCatalog\Service\OrganizationSyncService; -use OCA\SoftwareCatalog\Service\ProgressTracker; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\ArchiMateService; +use OCA\Stackiq\Service\EolSyncService; +use OCA\Stackiq\Service\OrganizationSyncService; +use OCA\Stackiq\Service\ProgressTracker; +use OCA\Stackiq\Service\SettingsService; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -578,7 +578,7 @@ public function load(): JSONResponse { }//end load() /** - * Initialize the SoftwareCatalog settings + * Initialize the Stackiq settings * * @return JSONResponse JSON response containing the initialization results * @@ -629,7 +629,7 @@ public function status(): JSONResponse { 'versionInfo' => $versionInfo, 'timestamp' => time(), 'autoConfigCompleted' => $this->config->getValueString( - 'softwarecatalog', + 'stackiq', 'auto_config_completed', 'false' ) === 'true', @@ -801,7 +801,7 @@ public function sendTestEmail(): JSONResponse { ); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: Failed to send test email in controller', + 'Stackiq: Failed to send test email in controller', [ 'exception_class' => get_class($e), 'exception_message' => $e->getMessage(), @@ -1915,14 +1915,14 @@ public function testEmailConnection(): JSONResponse { return new JSONResponse(['message' => 'Not authenticated'], Http::STATUS_UNAUTHORIZED); } - $this->logger->info('SoftwareCatalog: Email connection test endpoint called'); + $this->logger->info('Stackiq: Email connection test endpoint called'); try { $data = $this->request->getParams(); $emailSettings = $data['emailSettings'] ?? $data ?? []; $this->logger->info( - 'SoftwareCatalog: Email connection test request data', + 'Stackiq: Email connection test request data', [ 'has_email_settings' => empty($emailSettings) === false, 'transport_type' => $emailSettings['transportType'] ?? 'not specified', @@ -1933,7 +1933,7 @@ public function testEmailConnection(): JSONResponse { $result = $this->settingsService->testEmailConnection($emailSettings); $this->logger->info( - 'SoftwareCatalog: Email connection test result from service', + 'Stackiq: Email connection test result from service', [ 'success' => $result['success'], 'message' => $result['message'] ?? 'no message', @@ -1949,7 +1949,7 @@ public function testEmailConnection(): JSONResponse { ); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: Failed to test email connection', + 'Stackiq: Failed to test email connection', [ 'exception_class' => get_class($e), 'exception_message' => $e->getMessage(), @@ -2876,13 +2876,13 @@ public function testArchiMateRoundTrip(): JSONResponse { } try { - $this->logger->info('SoftwareCatalog: ArchiMate round-trip test started'); + $this->logger->info('Stackiq: ArchiMate round-trip test started'); // Call the ArchiMate service to perform round-trip test. $result = $this->archiMateService->testRoundTrip(); $this->logger->info( - 'SoftwareCatalog: ArchiMate round-trip test completed', + 'Stackiq: ArchiMate round-trip test completed', [ 'success' => $result['success'], 'message' => $result['message'] ?? 'no message', @@ -2899,7 +2899,7 @@ public function testArchiMateRoundTrip(): JSONResponse { ); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: ArchiMate round-trip test failed', + 'Stackiq: ArchiMate round-trip test failed', [ 'exception_class' => get_class($e), 'exception_message' => $e->getMessage(), @@ -3596,7 +3596,7 @@ public function bulkSyncStandards(): JSONResponse { $this->logger->info('SettingsController: Starting bulk sync of module standards.'); // Get the ModuleComplianceService from the container. - $moduleComplianceService = $this->container->get(\OCA\SoftwareCatalog\Service\ModuleComplianceService::class); + $moduleComplianceService = $this->container->get(\OCA\Stackiq\Service\ModuleComplianceService::class); // Perform the bulk sync. $results = $moduleComplianceService->bulkSyncModuleStandards(); diff --git a/lib/Controller/ViewController.php b/lib/Controller/ViewController.php index f39199ce..1b84d49e 100644 --- a/lib/Controller/ViewController.php +++ b/lib/Controller/ViewController.php @@ -1,25 +1,25 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://github.com/nextcloud/softwarecatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ -namespace OCA\SoftwareCatalog\Controller; +namespace OCA\Stackiq\Controller; -use OCA\SoftwareCatalog\Service\ViewService; +use OCA\Stackiq\Service\ViewService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\JSONResponse; @@ -34,12 +34,12 @@ * with optional enrichment capabilities for products, usage data (gebruik), and related information. * * @category Controller - * @package OCA\SoftwareCatalog\Controller + * @package OCA\Stackiq\Controller * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://github.com/nextcloud/softwarecatalog + * @link https://github.com/ConductionNL/stackiq */ class ViewController extends Controller { /** @@ -377,7 +377,7 @@ public function getApiDocumentation(): JSONResponse { $documentation = [ 'api_version' => '1.0.0', - 'description' => 'SoftwareCatalog View API - Query and enrich ArchiMate views', + 'description' => 'Stackiq View API - Query and enrich ArchiMate views', 'base_url' => '/api/views', 'endpoints' => [ [ diff --git a/lib/Dashboard/ConceptOrganisatiesWidget.php b/lib/Dashboard/ConceptOrganisatiesWidget.php index d2f8f1d7..a2258130 100644 --- a/lib/Dashboard/ConceptOrganisatiesWidget.php +++ b/lib/Dashboard/ConceptOrganisatiesWidget.php @@ -4,17 +4,17 @@ * Concept Organisaties Dashboard Widget. * * @category Dashboard - * @package OCA\SoftwareCatalog\Dashboard + * @package OCA\Stackiq\Dashboard * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ -namespace OCA\SoftwareCatalog\Dashboard; +namespace OCA\Stackiq\Dashboard; -use OCA\SoftwareCatalog\AppInfo\Application; +use OCA\Stackiq\AppInfo\Application; use OCP\Dashboard\IWidget; use OCP\IL10N; use OCP\IURLGenerator; @@ -39,6 +39,12 @@ public function __construct( * @return string The widget ID */ public function getId(): string { + // FROZEN across the softwarecatalog -> stackiq rename. The Dashboard app + // stores each user's chosen widgets BY WIDGET ID, in its own `dashboard` + // appid namespace in `oc_preferences` — data this app's repair steps + // cannot reach. Renaming this id therefore does not error: the widget + // simply stops matching the stored selection and silently vanishes from + // every dashboard that had it. return 'softwarecatalog_concept_organisaties_widget'; }//end getId() @@ -66,7 +72,7 @@ public function getOrder(): int { * @return string The icon CSS class name */ public function getIconClass(): string { - return 'icon-softwarecatalog-widget'; + return 'icon-stackiq-widget'; }//end getIconClass() /** diff --git a/lib/EventListener/DecisionConcludedListener.php b/lib/EventListener/DecisionConcludedListener.php index c9fa995b..682747be 100644 --- a/lib/EventListener/DecisionConcludedListener.php +++ b/lib/EventListener/DecisionConcludedListener.php @@ -1,24 +1,24 @@ Actief` transition is reached ONLY here, as * a projection of an `approved` decidesk outcome — never on local authority. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-decision-delegation/spec.md * @@ -28,10 +28,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\Decidesk\Event\DecisionConcludedEvent; -use OCA\SoftwareCatalog\Service\ContractApprovalService; +use OCA\Stackiq\Service\ContractApprovalService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use Psr\Log\LoggerInterface; @@ -59,7 +59,7 @@ public function __construct( /** * Handle a concluded decidesk Decision. * - * Only `DecisionConcludedEvent`s whose `sourceApp` is softwarecatalog are + * Only `DecisionConcludedEvent`s whose `sourceApp` is stackiq are * acted on; everything else is ignored. The carried `decisionId` is * IDOR-checked against the contract's stored `approvalDecisionId` inside * `resolveContractForOutcome()` before any projection is written. diff --git a/lib/EventListener/ModuleComplianceSubscriber.php b/lib/EventListener/ModuleComplianceSubscriber.php index 478beb70..d751ad60 100644 --- a/lib/EventListener/ModuleComplianceSubscriber.php +++ b/lib/EventListener/ModuleComplianceSubscriber.php @@ -4,26 +4,26 @@ * Module Compliance Subscriber. * * This file contains the subscriber class for handling module compliance updates - * in the SoftwareCatalog application. + * in the Stackiq application. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\OpenRegister\Event\ObjectCreatedEvent; use OCA\OpenRegister\Event\ObjectUpdatedEvent; -use OCA\SoftwareCatalog\Service\ModuleComplianceService; -use OCA\SoftwareCatalog\Service\ModuleVersionService; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\ModuleComplianceService; +use OCA\Stackiq\Service\ModuleVersionService; +use OCA\Stackiq\Service\SettingsService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use Psr\Container\ContainerInterface; @@ -36,11 +36,11 @@ * synchronizes the 'standards' property based on linked compliance objects. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ class ModuleComplianceSubscriber implements IEventListener { /** diff --git a/lib/EventListener/ModuleRegistrationSubscriber.php b/lib/EventListener/ModuleRegistrationSubscriber.php index 267ed084..ec8612ae 100644 --- a/lib/EventListener/ModuleRegistrationSubscriber.php +++ b/lib/EventListener/ModuleRegistrationSubscriber.php @@ -7,22 +7,22 @@ * based on the owning organisation's type. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\OpenRegister\Event\ObjectCreatedEvent; use OCA\OpenRegister\Event\ObjectUpdatedEvent; -use OCA\SoftwareCatalog\Service\ModuleRegistrationService; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\ModuleRegistrationService; +use OCA\Stackiq\Service\SettingsService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use Psr\Container\ContainerInterface; @@ -33,7 +33,7 @@ * based on the owning organisation's type. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener */ class ModuleRegistrationSubscriber implements IEventListener { /** diff --git a/lib/EventListener/OpenRegisterEventsDebugListener.php b/lib/EventListener/OpenRegisterEventsDebugListener.php index 87118c31..4416542e 100644 --- a/lib/EventListener/OpenRegisterEventsDebugListener.php +++ b/lib/EventListener/OpenRegisterEventsDebugListener.php @@ -1,14 +1,14 @@ * @copyright 2024 Conduction B.V. @@ -16,14 +16,14 @@ * * @version GIT: * - * @link https://SoftwareCatalog.app + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\OpenRegister\Event\ObjectCreatedEvent; use OCA\OpenRegister\Event\ObjectDeletedEvent; @@ -43,10 +43,10 @@ use Psr\Log\LoggerInterface; /** - * Debug event listener for all OpenRegister events in SoftwareCatalog + * Debug event listener for all OpenRegister events in Stackiq * * This listener provides comprehensive debugging information for all OpenRegister events - * received by the SoftwareCatalog app. It logs event details at info level and can be + * received by the Stackiq app. It logs event details at info level and can be * easily enabled/disabled. * * @template T of Event @@ -111,7 +111,7 @@ public function handle(Event $event): void { $this->logger->debug( 'OpenRegister debug listener triggered', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'eventType' => $eventType, 'eventClass' => $eventClass, 'debugEnabled' => $this->debugEnabled, @@ -119,7 +119,7 @@ public function handle(Event $event): void { ); if ($this->debugEnabled === false) { - $this->logger->warning('SoftwareCatalog OpenRegister Debug: Debug disabled, skipping detailed logging.'); + $this->logger->warning('Stackiq OpenRegister Debug: Debug disabled, skipping detailed logging.'); return; } @@ -128,9 +128,9 @@ public function handle(Event $event): void { // Log comprehensive debug information. $this->logger->info( - '[SoftwareCatalog] OPENREGISTER EVENT: {eventType} received from OpenRegister', + '[Stackiq] OPENREGISTER EVENT: {eventType} received from OpenRegister', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'eventType' => $eventType, 'eventClass' => $eventClass, 'listenerClass' => self::class, @@ -192,7 +192,7 @@ private function extractEventData(Event $event): array { } $data['eventType'] = 'Unknown'; - $data['note'] = 'Event type not specifically handled by SoftwareCatalog debug listener'; + $data['note'] = 'Event type not specifically handled by Stackiq debug listener'; return $data; }//end extractEventData() diff --git a/lib/EventListener/StackiqEventListener.php b/lib/EventListener/StackiqEventListener.php index 73d18ea2..5f2cf672 100644 --- a/lib/EventListener/StackiqEventListener.php +++ b/lib/EventListener/StackiqEventListener.php @@ -1,13 +1,13 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -19,7 +19,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\OpenRegister\Event\ObjectCreatedEvent; use OCA\OpenRegister\Event\ObjectDeletedEvent; @@ -27,9 +27,9 @@ use OCA\OpenRegister\Event\ObjectRevertedEvent; use OCA\OpenRegister\Event\ObjectUnlockedEvent; use OCA\OpenRegister\Event\ObjectUpdatedEvent; -use OCA\SoftwareCatalog\Service\ContactpersoonService; -use OCA\SoftwareCatalog\Service\GebruikSyncService; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\ContactpersoonService; +use OCA\Stackiq\Service\GebruikSyncService; +use OCA\Stackiq\Service\SettingsService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use Psr\Container\ContainerInterface; @@ -43,7 +43,7 @@ * user blocking/unblocking functionality. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: @@ -53,9 +53,9 @@ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ -class SoftwareCatalogEventListener implements IEventListener { +class StackiqEventListener implements IEventListener { /** - * Constructor for SoftwareCatalogEventListener + * Constructor for StackiqEventListener * * @param ContainerInterface $container DI container for lazy service resolution. */ @@ -83,7 +83,7 @@ public function handle(Event $event): void { $settingsService = $this->container->get(SettingsService::class); $logger->info( - 'SoftwareCatalog: Processing event', + 'Stackiq: Processing event', [ 'eventType' => get_class($event), 'timestamp' => date('Y-m-d H:i:s'), @@ -100,7 +100,7 @@ public function handle(Event $event): void { try { $logger = $this->container->get(LoggerInterface::class); $logger->error( - 'SoftwareCatalog: Error in event handler', + 'Stackiq: Error in event handler', [ 'eventType' => get_class($event), 'exception' => $e->getMessage(), @@ -171,7 +171,7 @@ private function dispatchEvent( || $event instanceof ObjectRevertedEvent ) { $logger->debug( - 'SoftwareCatalog: Ignoring object lifecycle event', + 'Stackiq: Ignoring object lifecycle event', [ 'eventType' => get_class($event), ] @@ -261,10 +261,10 @@ private function runOrganizationSync( ): void { $objectId = $object->getUuid(); try { - $orgSyncService = $this->container->get('OCA\SoftwareCatalog\Service\OrganizationSyncService'); + $orgSyncService = $this->container->get('OCA\Stackiq\Service\OrganizationSyncService'); $result = $orgSyncService->processSpecificOrganization($object); $logger->info( - 'SoftwareCatalog: Successfully processed organization ' . $phase, + 'Stackiq: Successfully processed organization ' . $phase, [ 'objectId' => $objectId, 'processResult' => $result, @@ -272,7 +272,7 @@ private function runOrganizationSync( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process organization ' . $phase, + 'Stackiq: Failed to process organization ' . $phase, [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -309,7 +309,7 @@ private function runGebruikSync( $gebruikSyncService = $this->container->get(GebruikSyncService::class); $result = $gebruikSyncService->processSpecificGebruik($object); $logger->info( - 'SoftwareCatalog: Successfully processed gebruik ' . $phase, + 'Stackiq: Successfully processed gebruik ' . $phase, [ 'objectId' => $objectId, 'processResult' => $result, @@ -317,7 +317,7 @@ private function runGebruikSync( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process gebruik ' . $phase, + 'Stackiq: Failed to process gebruik ' . $phase, [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -366,7 +366,7 @@ private function refetchOrganizationWithContactpersonen( ); $logger->info( - 'SoftwareCatalog: Refetched organization with contactpersonen', + 'Stackiq: Refetched organization with contactpersonen', [ 'objectId' => $objectId, 'contactpersonenCount' => count( @@ -378,7 +378,7 @@ private function refetchOrganizationWithContactpersonen( return $orgWithContacts; } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to refetch organization with contactpersonen', + 'Stackiq: Failed to refetch organization with contactpersonen', [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -414,7 +414,7 @@ private function handleObjectCreated( ): void { $object = $event->getObject(); if ($object === null) { - $logger->warning('SoftwareCatalog: ObjectCreatedEvent received with null object'); + $logger->warning('Stackiq: ObjectCreatedEvent received with null object'); return; } @@ -426,7 +426,7 @@ private function handleObjectCreated( $objectSchemaIdInt = (int)$objectSchemaId; $logger->info( - 'SoftwareCatalog: Processing object creation', + 'Stackiq: Processing object creation', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -444,7 +444,7 @@ private function handleObjectCreated( $gebruikSchemaId = $catalogSchemaIds['usage']; $logger->debug( - 'SoftwareCatalog: Configuration lookup results', + 'Stackiq: Configuration lookup results', [ 'organisatieSchemaId' => $organisationSchemaId, 'contactpersoonSchemaId' => $contactSchemaId, @@ -462,7 +462,7 @@ private function handleObjectCreated( // Only process active organizations. if ($this->isActiveStatus(status: $status) === false) { $logger->debug( - 'SoftwareCatalog: Skipping non-active organization creation', + 'Stackiq: Skipping non-active organization creation', [ 'objectId' => $objectId, 'status' => $status, @@ -472,7 +472,7 @@ private function handleObjectCreated( } $logger->info( - 'SoftwareCatalog: Processing active organization creation', + 'Stackiq: Processing active organization creation', [ 'objectId' => $objectId, 'status' => $status, @@ -485,28 +485,28 @@ private function handleObjectCreated( // Check if this is a contactpersoon object. if ($this->matchesSchema(objectSchemaIdInt: $objectSchemaIdInt, configured: $contactSchemaId) === true) { - $logger->info('SoftwareCatalog: Processing contactpersoon creation', ['objectId' => $objectId]); + $logger->info('Stackiq: Processing contactpersoon creation', ['objectId' => $objectId]); $contactSvc->processContactpersoon($object); return; } // Check if this is a contactgegevens object (deprecated - use contactpersoon instead). if ($this->matchesSchema(objectSchemaIdInt: $objectSchemaIdInt, configured: $contactInfoSchemaId) === true) { - $logger->info('SoftwareCatalog: Processing contactgegevens creation (deprecated)', ['objectId' => $objectId]); + $logger->info('Stackiq: Processing contactgegevens creation (deprecated)', ['objectId' => $objectId]); // Contactgegevens is deprecated, use contactpersoon instead. return; } // Check if this is a gebruik object. if ($this->matchesSchema(objectSchemaIdInt: $objectSchemaIdInt, configured: $gebruikSchemaId) === true) { - $logger->info('SoftwareCatalog: Processing gebruik creation', ['objectId' => $objectId]); + $logger->info('Stackiq: Processing gebruik creation', ['objectId' => $objectId]); $this->runGebruikSync(object: $object, phase: 'creation', logger: $logger); return; }//end if // Log unhandled object types. $logger->debug( - 'SoftwareCatalog: Object creation not handled - not a supported object type', + 'Stackiq: Object creation not handled - not a supported object type', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaIdInt, @@ -547,7 +547,7 @@ private function handleObjectUpdated( $oldObject = $event->getOldObject(); if ($object === null) { - $logger->warning('SoftwareCatalog: ObjectUpdatedEvent received with null object'); + $logger->warning('Stackiq: ObjectUpdatedEvent received with null object'); return; } @@ -559,7 +559,7 @@ private function handleObjectUpdated( $objectSchemaIdInt = (int)$objectSchemaId; $logger->info( - 'SoftwareCatalog: Processing object update', + 'Stackiq: Processing object update', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -576,7 +576,7 @@ private function handleObjectUpdated( $logger->debug( 'Got organisation schema ID', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieSchemaId' => $organisationSchemaId, 'organisatieSchemaIdInt' => $orgSchemaIdInt, ] @@ -585,7 +585,7 @@ private function handleObjectUpdated( $logger->debug( 'Organization schema check', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'objectSchemaId' => $objectSchemaId, 'objectSchemaIdInt' => $objectSchemaIdInt, 'organisatieSchemaId' => $organisationSchemaId, @@ -607,7 +607,7 @@ private function handleObjectUpdated( $logger->debug( 'Organization status check', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'objectId' => $objectId, 'status' => $status, 'oldStatus' => $oldStatus, @@ -621,7 +621,7 @@ private function handleObjectUpdated( // Only process active organizations. if ($this->isActiveStatus(status: $status) === true && $status !== $oldStatus) { $logger->info( - 'SoftwareCatalog: Processing active organization update', + 'Stackiq: Processing active organization update', [ 'objectId' => $objectId, 'status' => $status, @@ -641,7 +641,7 @@ private function handleObjectUpdated( if ($this->isActiveStatus(status: $status) === false || $status === $oldStatus) { $logger->debug( - 'SoftwareCatalog: Skipping non-active organization update', + 'Stackiq: Skipping non-active organization update', [ 'objectId' => $objectId, 'status' => $status, @@ -659,7 +659,7 @@ private function handleObjectUpdated( if ($contactSchemaId !== null && $objectSchemaIdInt === $cntSchemaIdInt) { $logger->info( - 'SoftwareCatalog: Matched contactpersoon schema - processing update', + 'Stackiq: Matched contactpersoon schema - processing update', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -674,7 +674,7 @@ private function handleObjectUpdated( ); $logger->info( - 'SoftwareCatalog: Successfully processed contactpersoon update', + 'Stackiq: Successfully processed contactpersoon update', [ 'objectId' => $objectId, 'timestamp' => date('Y-m-d H:i:s'), @@ -682,7 +682,7 @@ private function handleObjectUpdated( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process contactpersoon update', + 'Stackiq: Failed to process contactpersoon update', [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -702,7 +702,7 @@ private function handleObjectUpdated( if ($contactInfoSchemaId !== null && $objectSchemaIdInt === $infoSchemaIdInt) { $logger->info( - 'SoftwareCatalog: Matched contactgegevens schema - processing update (backward compatibility)', + 'Stackiq: Matched contactgegevens schema - processing update (backward compatibility)', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -718,7 +718,7 @@ private function handleObjectUpdated( ); $logger->info( - 'SoftwareCatalog: Successfully processed contactgegevens update (as contactpersoon)', + 'Stackiq: Successfully processed contactgegevens update (as contactpersoon)', [ 'objectId' => $objectId, 'timestamp' => date('Y-m-d H:i:s'), @@ -726,7 +726,7 @@ private function handleObjectUpdated( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process contactgegevens update', + 'Stackiq: Failed to process contactgegevens update', [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -746,7 +746,7 @@ private function handleObjectUpdated( if ($gebruikSchemaId !== null && $objectSchemaIdInt === $gebruikSchemaIdInt) { $logger->info( - 'SoftwareCatalog: Matched gebruik schema - processing update', + 'Stackiq: Matched gebruik schema - processing update', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -760,7 +760,7 @@ private function handleObjectUpdated( // Log if we don't handle this schema type. $logger->debug( - 'SoftwareCatalog: Object update not handled - focusing only on organisatie, contactpersonen, and gebruik', + 'Stackiq: Object update not handled - focusing only on organisatie, contactpersonen, and gebruik', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -801,7 +801,7 @@ private function handleObjectDeleted( ): void { $object = $event->getObject(); if ($object === null) { - $logger->warning('SoftwareCatalog: ObjectDeletedEvent received with null object'); + $logger->warning('Stackiq: ObjectDeletedEvent received with null object'); return; } @@ -810,7 +810,7 @@ private function handleObjectDeleted( $objectRegisterId = $object->getRegister(); $logger->info( - 'SoftwareCatalog: Processing object deletion', + 'Stackiq: Processing object deletion', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -825,7 +825,7 @@ private function handleObjectDeleted( $objectSchemaIdInt = (int)$objectSchemaId; if ($organisationSchemaId !== null && $objectSchemaIdInt === $orgSchemaIdInt) { - $logger->info('SoftwareCatalog: Processing organization deletion', ['objectId' => $objectId]); + $logger->info('Stackiq: Processing organization deletion', ['objectId' => $objectId]); $this->runOrganizationSync(object: $object, phase: 'deletion', logger: $logger); return; }//end if @@ -836,7 +836,7 @@ private function handleObjectDeleted( if ($contactSchemaId !== null && $objectSchemaIdInt === $cntSchemaIdInt) { $logger->info( - 'SoftwareCatalog: Matched contactpersoon schema - processing deletion', + 'Stackiq: Matched contactpersoon schema - processing deletion', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -848,7 +848,7 @@ private function handleObjectDeleted( $contactSvc->handleContactDeletion($object); $logger->info( - 'SoftwareCatalog: Successfully processed contactpersoon deletion', + 'Stackiq: Successfully processed contactpersoon deletion', [ 'objectId' => $objectId, 'timestamp' => date('Y-m-d H:i:s'), @@ -856,7 +856,7 @@ private function handleObjectDeleted( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process contactpersoon deletion', + 'Stackiq: Failed to process contactpersoon deletion', [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -876,7 +876,7 @@ private function handleObjectDeleted( if ($contactInfoSchemaId !== null && $objectSchemaIdInt === $infoSchemaIdInt) { $logger->info( - 'SoftwareCatalog: Matched contactgegevens schema - processing deletion (backward compatibility)', + 'Stackiq: Matched contactgegevens schema - processing deletion (backward compatibility)', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -888,7 +888,7 @@ private function handleObjectDeleted( $contactSvc->handleContactDeletion($object); $logger->info( - 'SoftwareCatalog: Successfully processed contactgegevens deletion', + 'Stackiq: Successfully processed contactgegevens deletion', [ 'objectId' => $objectId, 'timestamp' => date('Y-m-d H:i:s'), @@ -896,7 +896,7 @@ private function handleObjectDeleted( ); } catch (\Exception $e) { $logger->error( - 'SoftwareCatalog: Failed to process contactgegevens deletion', + 'Stackiq: Failed to process contactgegevens deletion', [ 'objectId' => $objectId, 'exception' => $e->getMessage(), @@ -918,7 +918,7 @@ private function handleObjectDeleted( $objectData = $object->getObject(); $logger->info( - 'SoftwareCatalog: Matched gebruik schema - processing deletion', + 'Stackiq: Matched gebruik schema - processing deletion', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, @@ -931,7 +931,7 @@ private function handleObjectDeleted( // For deletions, we mainly log the event since the object is being removed. // No specific cleanup needed for gebruik objects currently. $logger->info( - 'SoftwareCatalog: Gebruik object deleted - no specific cleanup required', + 'Stackiq: Gebruik object deleted - no specific cleanup required', [ 'objectId' => $objectId, 'timestamp' => date('Y-m-d H:i:s'), @@ -942,7 +942,7 @@ private function handleObjectDeleted( // Log if we don't handle this schema type. $logger->debug( - 'SoftwareCatalog: Object deletion not handled - focusing only on organisatie, contactpersonen, and gebruik', + 'Stackiq: Object deletion not handled - focusing only on organisatie, contactpersonen, and gebruik', [ 'objectId' => $objectId, 'schemaId' => $objectSchemaId, diff --git a/lib/EventListener/TestEventListener.php b/lib/EventListener/TestEventListener.php index 83ed303e..c55d0250 100644 --- a/lib/EventListener/TestEventListener.php +++ b/lib/EventListener/TestEventListener.php @@ -1,13 +1,13 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -17,7 +17,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; @@ -32,7 +32,7 @@ * triggered for testing purposes. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: @@ -63,7 +63,7 @@ public function __construct( public function handle(Event $event): void { // Log that we received ANY event first. $this->logger->info( - 'SoftwareCatalog TestEventListener: Event received!', + 'Stackiq TestEventListener: Event received!', [ 'eventClass' => get_class($event), 'timestamp' => date('Y-m-d H:i:s'), @@ -75,7 +75,7 @@ public function handle(Event $event): void { if (($event instanceof UserLoggedInEvent) === false) { // Log other events we might receive. $this->logger->debug( - 'SoftwareCatalog TestEventListener: Received unhandled event', + 'Stackiq TestEventListener: Received unhandled event', [ 'eventClass' => get_class($event), 'timestamp' => date('Y-m-d H:i:s'), @@ -87,7 +87,7 @@ public function handle(Event $event): void { $user = $event->getUser(); $this->logger->info( - 'SoftwareCatalog TestEventListener: User logged in successfully!', + 'Stackiq TestEventListener: User logged in successfully!', [ 'userId' => $user->getUID(), 'userDisplayName' => $user->getDisplayName(), @@ -100,7 +100,7 @@ public function handle(Event $event): void { // Test that we can access Nextcloud services. try { $this->logger->debug( - 'SoftwareCatalog TestEventListener: Event listener is working correctly!', + 'Stackiq TestEventListener: Event listener is working correctly!', [ 'message' => 'This confirms that event listeners are properly registered and triggered', 'userId' => $user->getUID(), @@ -109,7 +109,7 @@ public function handle(Event $event): void { ); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog TestEventListener: Error in event processing', + 'Stackiq TestEventListener: Error in event processing', [ 'exception' => $e->getMessage(), 'trace' => $e->getTraceAsString(), diff --git a/lib/EventListener/UserProfileUpdatedEventListener.php b/lib/EventListener/UserProfileUpdatedEventListener.php index 6bbb4c42..a52251b3 100644 --- a/lib/EventListener/UserProfileUpdatedEventListener.php +++ b/lib/EventListener/UserProfileUpdatedEventListener.php @@ -7,7 +7,7 @@ * the changed fields back to the corresponding contactpersoon object. * * @category EventListener - * @package OCA\SoftwareCatalog\EventListener + * @package OCA\Stackiq\EventListener * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -17,10 +17,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\EventListener; +namespace OCA\Stackiq\EventListener; use OCA\OpenRegister\Event\UserProfileUpdatedEvent; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\SettingsService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use Psr\Container\ContainerInterface; diff --git a/lib/Examples/ContactpersoonServiceExample.php b/lib/Examples/ContactpersoonServiceExample.php index 5c82ddc0..ce3b5420 100644 --- a/lib/Examples/ContactpersoonServiceExample.php +++ b/lib/Examples/ContactpersoonServiceExample.php @@ -7,30 +7,30 @@ * method to retrieve contact persons for an organization with their user details spliced in. * * @category Example - * @package OCA\SoftwareCatalog\Examples + * @package OCA\Stackiq\Examples * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Examples; +namespace OCA\Stackiq\Examples; -use OCA\SoftwareCatalog\Service\ContactpersoonService; +use OCA\Stackiq\Service\ContactpersoonService; use Psr\Log\LoggerInterface; /** * Example class demonstrating ContactpersoonService usage. * * @category Example - * @package OCA\SoftwareCatalog\Examples + * @package OCA\Stackiq\Examples * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ class ContactpersoonServiceExample { /** diff --git a/lib/Exception/UnsupportedSbomFormatException.php b/lib/Exception/UnsupportedSbomFormatException.php index dac44031..9ae16c17 100644 --- a/lib/Exception/UnsupportedSbomFormatException.php +++ b/lib/Exception/UnsupportedSbomFormatException.php @@ -3,7 +3,7 @@ /** * UnsupportedSbomFormatException. * - * Thrown by {@see \OCA\SoftwareCatalog\Service\SbomParserService} when an + * Thrown by {@see \OCA\Stackiq\Service\SbomParserService} when an * uploaded document's `bomFormat`/`specVersion` (CycloneDX) or `spdxVersion` * (SPDX) is not one this app supports. Carries the offending format/version * in its message so the controller can surface a precise 422 rather than a @@ -11,11 +11,11 @@ * this is thrown (fail-fast, not a silent partial parse). * * @category Exception - * @package OCA\SoftwareCatalog\Exception + * @package OCA\Stackiq\Exception * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/sbom-import/spec.md#requirement-cyclonedx-sbom-files-are-parsed-into-a-normalized-component-list * @@ -25,7 +25,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Exception; +namespace OCA\Stackiq\Exception; /** * Thrown when an uploaded SBOM document's format/spec-version is not supported. diff --git a/lib/Portal/PortalContributionProvider.php b/lib/Portal/PortalContributionProvider.php index d3e68dfb..eb68b033 100644 --- a/lib/Portal/PortalContributionProvider.php +++ b/lib/Portal/PortalContributionProvider.php @@ -1,9 +1,9 @@ * @copyright 2026 Conduction B.V. @@ -42,10 +42,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Portal; +namespace OCA\Stackiq\Portal; /** - * Declares what an external portal subject may see in the Software Catalog. + * Declares what an external portal subject may see in Stackiq. * * The contribution is a declarative manifest (pure data — no I/O, no * callbacks). All subject identity (subjectRef, audience, organisation, trust) @@ -82,7 +82,7 @@ class PortalContributionProvider { /** * The audiences this provider contributes to (contract v2, preferred). * - * The registry probes for this method first. Software Catalog serves + * The registry probes for this method first. Stackiq serves * software suppliers (`vendor-org`, organisatie.type "Supplier") and the * municipalities/collaborations that consume that software (`participant-org`, * organisatie.type "Municipality" / "Collaboration" / "Community"). The two @@ -116,7 +116,7 @@ public function getAudience(): string { * * The subject array is server-derived by portaliq (subjectRef UUID, * audience, organisation, trust level low|substantial|high). Returns null - * for any audience Software Catalog does not serve (fail-closed; the registry + * for any audience Stackiq does not serve (fail-closed; the registry * already filters by audience, but a provider must not rely on that). This * wave declares READ collections only — no create-actions and no endpoint * actions (see design.md for the deferral rationale). @@ -159,7 +159,7 @@ public function getContribution(array $subject): ?array { */ private function vendorContribution(): array { return [ - 'label' => 'Software Catalog', + 'label' => 'Stackiq', 'collections' => [ [ 'id' => 'vendorDiensten', @@ -262,7 +262,7 @@ private function vendorContribution(): array { */ private function participantContribution(): array { return [ - 'label' => 'Software Catalog', + 'label' => 'Stackiq', 'collections' => [ [ 'id' => 'participantGebruik', diff --git a/lib/Repair/BackfillContractApprovalState.php b/lib/Repair/BackfillContractApprovalState.php index 8f85020e..73d4b36e 100644 --- a/lib/Repair/BackfillContractApprovalState.php +++ b/lib/Repair/BackfillContractApprovalState.php @@ -18,12 +18,12 @@ * named-argument convention as in MigrateContactsToNc. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-decision-delegation/spec.md * @@ -33,10 +33,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; -use OCA\SoftwareCatalog\Service\ContractApprovalService; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\ContractApprovalService; +use OCA\Stackiq\Service\SettingsService; use OCP\App\IAppManager; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; diff --git a/lib/Repair/InitializeSettings.php b/lib/Repair/InitializeSettings.php index ac4914de..9dad2e9a 100644 --- a/lib/Repair/InitializeSettings.php +++ b/lib/Repair/InitializeSettings.php @@ -1,23 +1,23 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\SettingsService; use OCP\App\IAppManager; use OCP\IAppConfig; use OCP\Migration\IOutput; @@ -26,12 +26,12 @@ use Psr\Log\LoggerInterface; /** - * Repair step that initializes SoftwareCatalog settings on install/upgrade. + * Repair step that initializes Stackiq settings on install/upgrade. * * This runs only during app install or upgrade, not on every request. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * * @spec openspec/specs/repair-init/spec.md */ @@ -60,7 +60,7 @@ public function __construct( * @spec openspec/specs/repair-init/spec.md */ public function getName(): string { - return 'Initialize SoftwareCatalog settings'; + return 'Initialize Stackiq settings'; }//end getName() /** @@ -95,7 +95,7 @@ public function run(IOutput $output): void { } $output->info('Initializing settings for version ' . $currentAppVersion); - $this->logger->info('SoftwareCatalog repair: Starting initialization for version ' . $currentAppVersion); + $this->logger->info('Stackiq repair: Starting initialization for version ' . $currentAppVersion); // @spec openspec/specs/contract-administration/spec.md // Seed window defaults only when the admin has not set them, so @@ -145,18 +145,18 @@ public function run(IOutput $output): void { if (empty($result['errors']) === false) { foreach ($result['errors'] as $error) { $output->warning('Initialization warning: ' . $error); - $this->logger->warning('SoftwareCatalog repair: ' . $error); + $this->logger->warning('Stackiq repair: ' . $error); } } $output->info('Settings initialization completed'); - $this->logger->info('SoftwareCatalog repair: Initialization completed', ['result' => $result]); + $this->logger->info('Stackiq repair: Initialization completed', ['result' => $result]); } catch (\Exception $e) { // Still mark as initialized to prevent repeated failures. $currentAppVersion = $this->appManager->getAppVersion(Application::APP_ID); $this->config->setValueString(Application::APP_ID, 'last_initialized_version', $currentAppVersion); $output->warning('Settings initialization failed: ' . $e->getMessage()); - $this->logger->error('SoftwareCatalog repair: Initialization failed', ['exception' => $e->getMessage()]); + $this->logger->error('Stackiq repair: Initialization failed', ['exception' => $e->getMessage()]); }//end try $output->advance(1); diff --git a/lib/Repair/MigrateContactsToNc.php b/lib/Repair/MigrateContactsToNc.php index 3821e522..663accdc 100644 --- a/lib/Repair/MigrateContactsToNc.php +++ b/lib/Repair/MigrateContactsToNc.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/softwarecatalog-contacts-to-nc/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; -use OCA\SoftwareCatalog\AppInfo\Application; -use OCA\SoftwareCatalog\Service\SettingsService; -use OCA\SoftwareCatalog\Service\SoftwareCatalogContactSyncService; +use OCA\Stackiq\AppInfo\Application; +use OCA\Stackiq\Service\SettingsService; +use OCA\Stackiq\Service\StackiqContactSyncService; use OCP\App\IAppManager; use OCP\IAppConfig; use OCP\Migration\IOutput; @@ -44,11 +44,11 @@ * Idempotent, fail-safe migration of identity to Nextcloud Contacts. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/softwarecatalog-contacts-to-nc/spec.md */ @@ -69,7 +69,7 @@ class MigrateContactsToNc implements IRepairStep { * * @param IAppManager $appManager The app manager. * @param SettingsService $settingsService The settings service (register/schema id resolution). - * @param SoftwareCatalogContactSyncService $contactSync The contacts bridge. + * @param StackiqContactSyncService $contactSync The contacts bridge. * @param IAppConfig $appConfig The app config (convergence marker). * @param LoggerInterface $logger The logger. * @@ -78,7 +78,7 @@ class MigrateContactsToNc implements IRepairStep { public function __construct( private readonly IAppManager $appManager, private readonly SettingsService $settingsService, - private readonly SoftwareCatalogContactSyncService $contactSync, + private readonly StackiqContactSyncService $contactSync, private readonly IAppConfig $appConfig, private readonly LoggerInterface $logger, ) { @@ -92,7 +92,7 @@ public function __construct( * @spec openspec/specs/softwarecatalog-contacts-to-nc/spec.md */ public function getName(): string { - return 'Migrate SoftwareCatalog contacts/organisations to the Nextcloud addressbook'; + return 'Migrate Stackiq contacts/organisations to the Nextcloud addressbook'; }//end getName() /** diff --git a/lib/Repair/RenameDutchCatalogColumns.php b/lib/Repair/RenameDutchCatalogColumns.php index 42cd013b..5df7803c 100644 --- a/lib/Repair/RenameDutchCatalogColumns.php +++ b/lib/Repair/RenameDutchCatalogColumns.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. @@ -103,7 +103,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; use OCP\DB\Exception; use OCP\IDBConnection; diff --git a/lib/Repair/RenameDutchCatalogDecisions.php b/lib/Repair/RenameDutchCatalogDecisions.php index 5ad22487..2387da3b 100644 --- a/lib/Repair/RenameDutchCatalogDecisions.php +++ b/lib/Repair/RenameDutchCatalogDecisions.php @@ -12,7 +12,7 @@ * was already sitting on before the candidate-target support was added. * * @category Repair - * @package OCA\\SoftwareCatalog\\Repair + * @package OCA\\Stackiq\\Repair * @author Conduction B.V. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -24,13 +24,13 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; /** * Pure predicates for the Dutch-to-English column migration. * * @category Repair - * @package OCA\\SoftwareCatalog\\Repair + * @package OCA\\Stackiq\\Repair * @author Conduction B.V. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -70,7 +70,7 @@ public function sanitizeColumnName(string $name): string { /** * Whether moving `$old` to `$new` is safe for a schema declaring `$declared`. * - * This is the softwarecatalog#492 guard, and it is deliberately BOTH halves: + * This is the stackiq#492 guard, and it is deliberately BOTH halves: * * - the destination MUST be declared — otherwise the data lands in a * column nothing reads, and MagicMapper will re-add the Dutch one empty; diff --git a/lib/Repair/RenameDutchCatalogValues.php b/lib/Repair/RenameDutchCatalogValues.php index 03e41d44..36f60276 100644 --- a/lib/Repair/RenameDutchCatalogValues.php +++ b/lib/Repair/RenameDutchCatalogValues.php @@ -18,7 +18,7 @@ * Idempotent: an already-migrated row simply matches no WHERE clause. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * @author Conduction B.V. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -30,7 +30,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; use OCP\DB\Exception; use OCP\IDBConnection; @@ -155,7 +155,7 @@ public function __construct( * @return string */ public function getName(): string { - return 'Translate stored Dutch SoftwareCatalog enum values'; + return 'Translate stored Dutch Stackiq enum values'; }//end getName() /** @@ -168,7 +168,7 @@ public function getName(): string { public function run(IOutput $output): void { $tables = $this->shardTables(); if ($tables === []) { - $output->info('RenameDutchCatalogValues: no SoftwareCatalog shard tables on this install; nothing to do.'); + $output->info('RenameDutchCatalogValues: no Stackiq shard tables on this install; nothing to do.'); return; } diff --git a/lib/Repair/RenameDutchSchemaSlugDecisions.php b/lib/Repair/RenameDutchSchemaSlugDecisions.php index 9fadb66a..0ba9572e 100644 --- a/lib/Repair/RenameDutchSchemaSlugDecisions.php +++ b/lib/Repair/RenameDutchSchemaSlugDecisions.php @@ -13,7 +13,7 @@ * can be decided before touching it is decided here. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * @author Conduction B.V. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -25,7 +25,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; /** * Pure predicates for the Dutch-to-English schema slug migration. diff --git a/lib/Repair/RenameDutchSchemaSlugs.php b/lib/Repair/RenameDutchSchemaSlugs.php index 3882b377..12fa2522 100644 --- a/lib/Repair/RenameDutchSchemaSlugs.php +++ b/lib/Repair/RenameDutchSchemaSlugs.php @@ -28,7 +28,7 @@ * Dutch keys, so resolution is unaffected by this step. * * @category Repair - * @package OCA\SoftwareCatalog\Repair + * @package OCA\Stackiq\Repair * @author Conduction B.V. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -40,7 +40,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Repair; +namespace OCA\Stackiq\Repair; use OCP\DB\Exception; use OCP\IDBConnection; @@ -118,7 +118,7 @@ public function __construct( * @return string */ public function getName(): string { - return 'Rename Dutch SoftwareCatalog schema slugs'; + return 'Rename Dutch Stackiq schema slugs'; }//end getName() /** @@ -131,7 +131,7 @@ public function getName(): string { public function run(IOutput $output): void { $schemaIds = $this->inScopeSchemaIds(); if ($schemaIds === []) { - $output->info('RenameDutchSchemaSlugs: no SoftwareCatalog registers on this install; nothing to do.'); + $output->info('RenameDutchSchemaSlugs: no Stackiq registers on this install; nothing to do.'); return; } diff --git a/lib/Sections/StackiqAdmin.php b/lib/Sections/StackiqAdmin.php index 5e65a48f..def9678d 100644 --- a/lib/Sections/StackiqAdmin.php +++ b/lib/Sections/StackiqAdmin.php @@ -1,24 +1,24 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ -namespace OCA\SoftwareCatalog\Sections; +namespace OCA\Stackiq\Sections; use OCP\IL10N; use OCP\IURLGenerator; use OCP\Settings\IIconSection; -class SoftwareCatalogAdmin implements IIconSection { +class StackiqAdmin implements IIconSection { /** * The localization service. @@ -35,7 +35,7 @@ class SoftwareCatalogAdmin implements IIconSection { private IURLGenerator $urlGenerator; /** - * Constructor for SoftwareCatalogAdmin section. + * Constructor for StackiqAdmin section. * * @param IL10N $l10n The localization service * @param IURLGenerator $urlGenerator The URL generator service @@ -52,7 +52,7 @@ public function __construct(IL10N $l10n, IURLGenerator $urlGenerator) { */ public function getIcon(): string { // phpcs:ignore -- named parameters unsafe for Nextcloud core methods (param names vary by NC version) - return $this->urlGenerator->imagePath('softwarecatalog', 'app-dark.svg'); + return $this->urlGenerator->imagePath('stackiq', 'app-dark.svg'); }//end getIcon() /** @@ -61,7 +61,7 @@ public function getIcon(): string { * @return string The section ID */ public function getID(): string { - return 'softwarecatalog'; + return 'stackiq'; }//end getID() /** @@ -70,7 +70,7 @@ public function getID(): string { * @return string The translated section name */ public function getName(): string { - return $this->l10n->t('Software Catalog'); + return $this->l10n->t('Stackiq'); }//end getName() /** diff --git a/lib/Service/AanbodService.php b/lib/Service/AanbodService.php index 68bddf92..1842300b 100644 --- a/lib/Service/AanbodService.php +++ b/lib/Service/AanbodService.php @@ -1,26 +1,26 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Exception; use OCA\OpenRegister\Contract\ObjectServiceInterface; @@ -38,12 +38,12 @@ * afnemer (consumer) or aanbieder (provider), and for accepting or denying these offers. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) diff --git a/lib/Service/AangebodenGebruik/GebruikBulkHandler.php b/lib/Service/AangebodenGebruik/GebruikBulkHandler.php index 76dcf196..9661df92 100644 --- a/lib/Service/AangebodenGebruik/GebruikBulkHandler.php +++ b/lib/Service/AangebodenGebruik/GebruikBulkHandler.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-7 * @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\AangebodenGebruik; +namespace OCA\Stackiq\Service\AangebodenGebruik; use OCA\OpenRegister\Contract\ObjectServiceInterface; use Psr\Log\LoggerInterface; diff --git a/lib/Service/AangebodenGebruikService.php b/lib/Service/AangebodenGebruikService.php index ac760da7..b3006f95 100644 --- a/lib/Service/AangebodenGebruikService.php +++ b/lib/Service/AangebodenGebruikService.php @@ -1,24 +1,24 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Exception; use OCA\OpenRegister\Contract\ObjectServiceInterface; @@ -36,12 +36,12 @@ * (participants) array, and for updating the @self property of gebruiks objects. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @@ -241,7 +241,7 @@ public function getGebruiksWhereAfnemer(array $options = []): array { // Build next/previous links. $nextLink = null; $prevLink = null; - $consumerPath = '/index.php/apps/softwarecatalog/api/aangeboden-gebruik/afnemer'; + $consumerPath = '/index.php/apps/stackiq/api/aangeboden-gebruik/afnemer'; if ($currentPage < $totalPages) { $nextPage = $currentPage + 1; $nextLink = "{$consumerPath}?_limit={$requestedLimit}&_source=database&page={$nextPage}"; diff --git a/lib/Service/ArchiMate/ArchiMateContext.php b/lib/Service/ArchiMate/ArchiMateContext.php index e31edf57..ea5b435b 100644 --- a/lib/Service/ArchiMate/ArchiMateContext.php +++ b/lib/Service/ArchiMate/ArchiMateContext.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-4 * @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\ArchiMate; +namespace OCA\Stackiq\Service\ArchiMate; use OCA\OpenRegister\Contract\ObjectServiceInterface; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\SettingsService; use Psr\Log\LoggerInterface; /** @@ -41,7 +41,7 @@ class ArchiMateContext { * Constructor. * * @param ObjectServiceInterface $objectService The OpenRegister object service. - * @param SettingsService $settingsService The SoftwareCatalog settings service. + * @param SettingsService $settingsService The Stackiq settings service. * @param LoggerInterface $logger The application logger. * * @spec openspec/changes/method-decomposition/tasks.md#task-4 diff --git a/lib/Service/ArchiMateExportService.php b/lib/Service/ArchiMateExportService.php index 38d2be00..ac365400 100644 --- a/lib/Service/ArchiMateExportService.php +++ b/lib/Service/ArchiMateExportService.php @@ -4,7 +4,7 @@ * ArchiMate Export Service. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -14,19 +14,19 @@ */ /** - * ArchiMate Export Service for the SoftwareCatalog app + * ArchiMate Export Service for the Stackiq app * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Psr\Log\LoggerInterface; @@ -2878,7 +2878,7 @@ private function getViewName(array $viewData): string { }//end getViewName() /** - * Add Bron=Softwarecatalogus property to an XML data array. + * Add Bron=Stackiq property to an XML data array. * * @param array $data The data array. * @param string $sourcePropDefId The Bron property definition ID. @@ -2888,7 +2888,7 @@ private function getViewName(array $viewData): string { private function addSourceProperty(array $data, string $sourcePropDefId): array { $sourceProp = [ '_propertyDefinitionRef' => $sourcePropDefId, - 'value' => ['_value' => 'Softwarecatalogus'], + 'value' => ['_value' => 'Stackiq'], ]; if (isset($data['properties']) === false) { @@ -3071,7 +3071,7 @@ private function buildSwcOrganizationFolders( } $folders[] = [ - 'label' => ['_value' => 'Gebruikt (Softwarecatalogus)'], + 'label' => ['_value' => 'Gebruikt (Stackiq)'], 'items' => $items, ]; } @@ -3083,7 +3083,7 @@ private function buildSwcOrganizationFolders( } $folders[] = [ - 'label' => ['_value' => 'Deelnames (Softwarecatalogus)'], + 'label' => ['_value' => 'Deelnames (Stackiq)'], 'items' => $items, ]; } @@ -3096,7 +3096,7 @@ private function buildSwcOrganizationFolders( } $folders[] = [ - 'label' => ['_value' => 'Relaties (Softwarecatalogus)'], + 'label' => ['_value' => 'Relaties (Stackiq)'], 'items' => $relItems, ]; } @@ -3108,7 +3108,7 @@ private function buildSwcOrganizationFolders( } $folders[] = [ - 'label' => ['_value' => 'Views (Softwarecatalogus)'], + 'label' => ['_value' => 'Views (Stackiq)'], 'items' => $viewItems, ]; } @@ -3146,7 +3146,7 @@ private function assembleOrganizationXml( $xml = $this->createCleanArchiMateXml(modelMetadata: $modelMetadata); // Override model name. - $modelName = 'Softwarecatalogus ' . $orgName; + $modelName = 'Stackiq ' . $orgName; // Remove existing name children and add new one. foreach ($xml->children() as $child) { if ($child->getName() === 'name') { @@ -3203,7 +3203,7 @@ private function assembleOrganizationXml( $propsEl = $elNode->addChild('properties'); $propEl = $propsEl->addChild('property'); $propEl->addAttribute('propertyDefinitionRef', $appEl['bronPropDefId']); - $propEl->addChild('value', 'Softwarecatalogus'); + $propEl->addChild('value', 'Stackiq'); } // --- Relationships section ---. @@ -3235,7 +3235,7 @@ private function assembleOrganizationXml( $propsEl = $relNode->addChild('properties'); $propEl = $propsEl->addChild('property'); $propEl->addAttribute('propertyDefinitionRef', $rel['bronPropDefId']); - $propEl->addChild('value', 'Softwarecatalogus'); + $propEl->addChild('value', 'Stackiq'); } // --- Property Definitions section ---. diff --git a/lib/Service/ArchiMateImportService.php b/lib/Service/ArchiMateImportService.php index d5e41407..da0ae49b 100644 --- a/lib/Service/ArchiMateImportService.php +++ b/lib/Service/ArchiMateImportService.php @@ -1,14 +1,14 @@ + * @package OCA\Stackiq\Service + * @author Stackiq Team * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @link https://github.com/nextcloud/softwarecatalog @@ -18,7 +18,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use OCA\OpenRegister\Service\ObjectService; @@ -43,8 +43,8 @@ * 5. Save objects using ObjectService::saveObjects * * @category Service - * @package OCA\SoftwareCatalog\Service - * @author SoftwareCatalog Team + * @package OCA\Stackiq\Service + * @author Stackiq Team * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @link https://github.com/nextcloud/softwarecatalog @@ -1960,7 +1960,7 @@ private function getCurrentOrganisation(): string { * @spec openspec/specs/archimate-import/spec.md */ private function resolveConfiguredId(string $key): ?string { - $value = $this->config->getValueString('softwarecatalog', $key, ''); + $value = $this->config->getValueString('stackiq', $key, ''); if (trim($value) === '') { $this->logger->warning( 'ArchiMate configuration is incomplete — this id is not configured, so it is omitted rather than passed on as an empty string', @@ -1984,7 +1984,7 @@ public function getAmefConfig(): array { try { // Get configuration from app config using the correct method. - $config = $this->config->getValueString('softwarecatalog', 'amef_config', '{}'); + $config = $this->config->getValueString('stackiq', 'amef_config', '{}'); $decoded = json_decode($config, true); if (is_array($decoded) === false) { @@ -2041,9 +2041,9 @@ private function getAmefRegisterId(): ?int { // Fallback to legacy individual app config keys if not present in JSON. if ($rawRegisterId === null || $rawRegisterId === '') { - $rawRegisterId = $this->config->getValueString('softwarecatalog', 'amef_register_id', ''); - if ($this->config->getValueString('softwarecatalog', 'amef_register', '') !== '') { - $rawRegisterId = $this->config->getValueString('softwarecatalog', 'amef_register', ''); + $rawRegisterId = $this->config->getValueString('stackiq', 'amef_register_id', ''); + if ($this->config->getValueString('stackiq', 'amef_register', '') !== '') { + $rawRegisterId = $this->config->getValueString('stackiq', 'amef_register', ''); } } @@ -2113,9 +2113,9 @@ private function getAmefSchemaIdForType(string $archiMateType): ?int { // Fallback to legacy individual app config keys if not present in JSON. foreach ($candidates as $key) { - $raw = $this->config->getValueString('softwarecatalog', $key, ''); - if ($this->config->getValueString('softwarecatalog', 'amef_' . $key, '') !== '') { - $raw = $this->config->getValueString('softwarecatalog', 'amef_' . $key, ''); + $raw = $this->config->getValueString('stackiq', $key, ''); + if ($this->config->getValueString('stackiq', 'amef_' . $key, '') !== '') { + $raw = $this->config->getValueString('stackiq', 'amef_' . $key, ''); } if ($raw !== '' && is_numeric((string)$raw) === true) { diff --git a/lib/Service/ArchiMateService.php b/lib/Service/ArchiMateService.php index d9376a5d..96ee9280 100644 --- a/lib/Service/ArchiMateService.php +++ b/lib/Service/ArchiMateService.php @@ -1,15 +1,15 @@ + * @package OCA\Stackiq\Service + * @author Stackiq Team * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @link https://github.com/nextcloud/softwarecatalog @@ -19,7 +19,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use OCA\OpenRegister\Service\ObjectService; @@ -39,8 +39,8 @@ * 3. Export: Reconstruct exact XML from stored JSON blobs * * @category Service - * @package OCA\SoftwareCatalog\Service - * @author SoftwareCatalog Team + * @package OCA\Stackiq\Service + * @author Stackiq Team * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @link https://github.com/nextcloud/softwarecatalog @@ -475,8 +475,8 @@ public function exportOrgArchiMate(string $organizationUuid, array $options = [] $options ); - // Generate file name: DD-MM-YYYY_Softwarecatalogus_AMEFF_export_OrgName.xml. - $fileName = date('d-m-Y') . '_Softwarecatalogus_AMEFF_export_' . str_replace(' ', '_', $orgName) . '.xml'; + // Generate file name: DD-MM-YYYY_Stackiq_AMEFF_export_OrgName.xml. + $fileName = date('d-m-Y') . '_Stackiq_AMEFF_export_' . str_replace(' ', '_', $orgName) . '.xml'; return [ 'success' => true, @@ -1392,7 +1392,7 @@ private function validateRequiredConfiguration(): void { $errorMessage .= "- {$item}\n"; } - $settingsHint = 'in the SoftwareCatalog settings before importing.'; + $settingsHint = 'in the Stackiq settings before importing.'; $errorMessage .= "\nPlease configure the AMEF register and all required schema IDs $settingsHint"; $manualHint = 'or set them manually via the admin interface.'; $errorMessage .= "\nYou can use the auto-configuration feature $manualHint"; @@ -1615,7 +1615,7 @@ private function createTempFile(string $content): string { * @spec openspec/specs/archimate-import/spec.md */ private function resolveConfiguredId(string $key): ?string { - $value = $this->config->getValueString('softwarecatalog', $key, ''); + $value = $this->config->getValueString('stackiq', $key, ''); if (trim($value) === '') { $this->logger->warning( 'ArchiMate configuration is incomplete — this id is not configured, so it is omitted rather than passed on as an empty string', @@ -1639,7 +1639,7 @@ public function getAmefConfig(): array { try { // Get configuration from app config using the correct method. - $config = $this->config->getValueString('softwarecatalog', 'amef_config', '{}'); + $config = $this->config->getValueString('stackiq', 'amef_config', '{}'); $decoded = json_decode($config, true); if (is_array($decoded) === false) { @@ -1757,10 +1757,10 @@ private function getAmefRegisterId(): ?int { // Fallback to legacy individual app config keys if not present in JSON. if ($rawRegisterId === null || $rawRegisterId === '') { - $rawRegisterId = $this->config->getValueString('softwarecatalog', 'amef_register_id', ''); - if ($this->config->getValueString('softwarecatalog', 'amef_register', '') !== '') { + $rawRegisterId = $this->config->getValueString('stackiq', 'amef_register_id', ''); + if ($this->config->getValueString('stackiq', 'amef_register', '') !== '') { // If only the plain register key is configured, use it as the ID. - $rawRegisterId = $this->config->getValueString('softwarecatalog', 'amef_register', ''); + $rawRegisterId = $this->config->getValueString('stackiq', 'amef_register', ''); } } diff --git a/lib/Service/Contactpersoon/ContactValidator.php b/lib/Service/Contactpersoon/ContactValidator.php index fe909c68..eb8e7e66 100644 --- a/lib/Service/Contactpersoon/ContactValidator.php +++ b/lib/Service/Contactpersoon/ContactValidator.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-7 * @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Contactpersoon; +namespace OCA\Stackiq\Service\Contactpersoon; use InvalidArgumentException; diff --git a/lib/Service/ContactpersoonService.php b/lib/Service/ContactpersoonService.php index 44b1f9ba..6df8a9a2 100644 --- a/lib/Service/ContactpersoonService.php +++ b/lib/Service/ContactpersoonService.php @@ -4,26 +4,26 @@ * Contactpersoon Service * * This file contains the service class for handling contact person-specific operations - * in the SoftwareCatalog application. + * in the Stackiq application. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\GroupHandler; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\HierarchyHandler; +use OCA\Stackiq\Service\Stackiq\ContactPersonHandler; +use OCA\Stackiq\Service\Stackiq\GroupHandler; +use OCA\Stackiq\Service\Stackiq\HierarchyHandler; use OCP\App\IAppManager; use OCP\AppFramework\Db\DoesNotExistException; use OCP\IAppConfig; @@ -37,11 +37,11 @@ * user account creation, and group management. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @@ -173,7 +173,7 @@ public function processContactpersoon(object $contactPersonObject, bool $isUpdat ); try { $objectService = $this->container->get('OCA\OpenRegister\Service\ObjectService'); - $settingsService = $this->container->get('OCA\SoftwareCatalog\Service\SettingsService'); + $settingsService = $this->container->get('OCA\Stackiq\Service\SettingsService'); $voorzieningenConfig = $settingsService->getVoorzieningenConfig(); $orgObject = $objectService->find( id: $organizationUuid, @@ -186,7 +186,7 @@ public function processContactpersoon(object $contactPersonObject, bool $isUpdat $orgData = $orgObject->getObject(); $orgStatus = strtolower(($orgData['status'] ?? '')); if (in_array(needle: $orgStatus, haystack: ['actief', 'active']) === true) { - $syncServiceClass = 'OCA\SoftwareCatalog\Service\OrganizationSyncService'; + $syncServiceClass = 'OCA\Stackiq\Service\OrganizationSyncService'; $organizationSyncService = $this->container->get($syncServiceClass); $backupStats = [ 'entitiesCreated' => 0, diff --git a/lib/Service/ContractApprovalService.php b/lib/Service/ContractApprovalService.php index 231240df..792d52e3 100644 --- a/lib/Service/ContractApprovalService.php +++ b/lib/Service/ContractApprovalService.php @@ -8,7 +8,7 @@ * expiring/`Verlopen` contract) to decidesk — the canonical fleet decision * authority (cross-app interface contract #1) — through the in-process * `IEventDispatcher` event contract (`OCA\Decidesk\Event\DecisionRequestedEvent` - * / `DecisionConcludedEvent`). softwarecatalog keeps the contract RECORD locally + * / `DecisionConcludedEvent`). stackiq keeps the contract RECORD locally * and PROJECTS the decidesk outcome onto two catalog-local fields * (`approvalDecisionId`, `approvalState`). * @@ -21,11 +21,11 @@ * never set to `Actief` on local authority. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-decision-delegation/spec.md * @@ -35,7 +35,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use OCP\EventDispatcher\IEventDispatcher; @@ -65,6 +65,19 @@ class ContractApprovalService { /** * This consumer app id, stamped on the request event as `sourceApp` and * used by the conclusion listener to filter inbound events. + * + * FROZEN at `softwarecatalog` through the app-id rename. This value is not + * a name we own at read time — it is PERSISTED on decidesk's Decision rows + * when the approval is raised, and `DecisionConcludedListener` matches + * inbound conclusions against it. Every decision already open was stamped + * `softwarecatalog`; moving the constant makes the filter miss them, so + * their outcomes are dropped on the floor and the contract never leaves + * `In onderhandeling`. Nothing errors — a filtered-out event looks exactly + * like an event that was never sent. + * + * It can only move in a coordinated change that also rewrites the stored + * `sourceApp` on decidesk's existing rows, or that accepts both spellings + * on the read side first. */ public const SOURCE_APP = 'softwarecatalog'; diff --git a/lib/Service/ContractStatusService.php b/lib/Service/ContractStatusService.php index 3e1f67d4..0e511ad7 100644 --- a/lib/Service/ContractStatusService.php +++ b/lib/Service/ContractStatusService.php @@ -10,11 +10,11 @@ * without an end date, or any manually-set status in another direction. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/contract-administration/spec.md * @@ -24,7 +24,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use DateTimeImmutable; use OCA\OpenRegister\Contract\ObjectServiceInterface; diff --git a/lib/Service/EolMatcherService.php b/lib/Service/EolMatcherService.php index c55b78fe..112b4128 100644 --- a/lib/Service/EolMatcherService.php +++ b/lib/Service/EolMatcherService.php @@ -15,11 +15,11 @@ * nulled), plus the two provenance fields. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/eol-feed-integration/spec.md#requirement-version-matching-is-conservative-and-unambiguous-only * @spec openspec/specs/eol-feed-integration/spec.md#requirement-stamping-preserves-every-other-field-and-records-provenance @@ -30,7 +30,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; /** * Conservative version-prefix matcher between `moduleVersie.versie` and diff --git a/lib/Service/EolSyncService.php b/lib/Service/EolSyncService.php index 2d21cb63..ae919b91 100644 --- a/lib/Service/EolSyncService.php +++ b/lib/Service/EolSyncService.php @@ -15,11 +15,11 @@ * "sync now" admin endpoint, so the two trigger paths can never drift. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/eol-feed-integration/spec.md#requirement-eol-sync-runs-on-a-schedule-with-a-manual-trigger * @spec openspec/specs/eol-feed-integration/spec.md#requirement-the-feature-degrades-gracefully-when-the-feed-is-unavailable @@ -31,7 +31,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use OCP\AppFramework\Utility\ITimeFactory; @@ -352,7 +352,7 @@ private function fetchCycles(ObjectServiceInterface $objectService, array $confi * Fetch the `moduleVersie` rows belonging to one module. * * @param ObjectServiceInterface $objectService The OpenRegister object service. - * @param int $moduleRegisterId The (softwarecatalog) module register id. + * @param int $moduleRegisterId The (stackiq) module register id. * @param int $versionSchemaId The moduleVersie schema id. * @param string $moduleUuid The owning module's uuid. * diff --git a/lib/Service/FacetService.php b/lib/Service/FacetService.php index a3748455..48bb6b1e 100644 --- a/lib/Service/FacetService.php +++ b/lib/Service/FacetService.php @@ -1,7 +1,7 @@ * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * SPDX-FileCopyrightText: 2026 Conduction B.V. * SPDX-License-Identifier: EUPL-1.2 @@ -23,7 +23,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use InvalidArgumentException; use OCA\OpenRegister\Contract\ObjectServiceInterface; @@ -46,7 +46,7 @@ * by its own selection") facet counts over that map. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * * @spec openspec/specs/gemma-faceted-search/spec.md#requirement-facet-aggregation-endpoint-returns-gemma-dimension-counts * @@ -130,7 +130,7 @@ public function __construct( private readonly LoggerInterface $logger, ICacheFactory $cacheFactory, ) { - $this->facetsCache = $cacheFactory->createDistributed(prefix: 'softwarecatalog_facets'); + $this->facetsCache = $cacheFactory->createDistributed(prefix: 'stackiq_facets'); }//end __construct() diff --git a/lib/Service/Federation/FederationConfig.php b/lib/Service/Federation/FederationConfig.php index 6125fbc5..fc31c52d 100644 --- a/lib/Service/Federation/FederationConfig.php +++ b/lib/Service/Federation/FederationConfig.php @@ -3,17 +3,17 @@ /** * Federation configuration value object. * - * Reads the softwarecatalog federation app-config keys via IAppConfig and + * Reads the stackiq federation app-config keys via IAppConfig and * exposes them as a small immutable value object so callers never touch raw * config keys. Defaults match the spec (directory.opencatalogi.nl, federation * disabled, no peers, hourly sync). * * @category Service - * @package OCA\SoftwareCatalog\Service\Federation + * @package OCA\Stackiq\Service\Federation * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/federated-catalog-sync/spec.md * @@ -23,9 +23,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Federation; +namespace OCA\Stackiq\Service\Federation; -use OCA\SoftwareCatalog\AppInfo\Application; +use OCA\Stackiq\AppInfo\Application; use OCP\IAppConfig; /** diff --git a/lib/Service/Federation/FederationMerger.php b/lib/Service/Federation/FederationMerger.php index 8850261d..470fc7b5 100644 --- a/lib/Service/Federation/FederationMerger.php +++ b/lib/Service/Federation/FederationMerger.php @@ -16,11 +16,11 @@ * therefore treated as read-only by every local write path (isPeerSourced()). * * @category Service - * @package OCA\SoftwareCatalog\Service\Federation + * @package OCA\Stackiq\Service\Federation * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/federated-catalog-sync/spec.md * @@ -30,7 +30,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Federation; +namespace OCA\Stackiq\Service\Federation; /** * Reconciles a peer's published entries with the locally-stored peer mirrors. diff --git a/lib/Service/Federation/FederationService.php b/lib/Service/Federation/FederationService.php index c63acc95..2bd60c10 100644 --- a/lib/Service/Federation/FederationService.php +++ b/lib/Service/Federation/FederationService.php @@ -5,17 +5,17 @@ * * Cross-instance catalog federation by DELEGATING to OpenCatalogi's proven * federation stack (DirectoryService / BroadcastService) — never a bespoke - * wire protocol (design constraint). softwarecatalog contributes only its + * wire protocol (design constraint). stackiq contributes only its * schema mapping, the merge/provenance semantics, the sync schedule, and the * admin controls. When OpenCatalogi is not installed, every entry point * degrades to a clean disabled state with a clear message — it never errors. * * @category Service - * @package OCA\SoftwareCatalog\Service\Federation + * @package OCA\Stackiq\Service\Federation * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/federated-catalog-sync/spec.md * @@ -25,9 +25,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Federation; +namespace OCA\Stackiq\Service\Federation; -use OCA\SoftwareCatalog\Service\SettingsService; +use OCA\Stackiq\Service\SettingsService; use OCP\App\IAppManager; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; @@ -384,7 +384,7 @@ public function pullPeer(string $peerUrl): array { /** * Fetch a peer's published catalog entries via OpenCatalogi's DirectoryService. * - * Delegates the wire to OpenCatalogi — softwarecatalog never speaks a bespoke + * Delegates the wire to OpenCatalogi — stackiq never speaks a bespoke * federation protocol. Only published entries are returned (the peer's own * `publicatiedatum<=$now` public RBAC gate governs that surface). * diff --git a/lib/Service/GebruikService.php b/lib/Service/GebruikService.php index 24cb777b..ba7aeb4c 100644 --- a/lib/Service/GebruikService.php +++ b/lib/Service/GebruikService.php @@ -6,15 +6,15 @@ * Service for retrieving and managing Gebruik (usage) objects. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Exception; use OCA\OpenRegister\Contract\ObjectServiceInterface; diff --git a/lib/Service/GebruikSyncService.php b/lib/Service/GebruikSyncService.php index f581203f..532a0533 100644 --- a/lib/Service/GebruikSyncService.php +++ b/lib/Service/GebruikSyncService.php @@ -10,7 +10,7 @@ * - Auto-updating status based on date fields * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Ruben van der Linde * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl @@ -22,7 +22,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use DateTime; use Exception; @@ -34,7 +34,7 @@ * Service for synchronizing and processing Gebruik (Usage) objects. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Ruben van der Linde * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl * @version GIT: @@ -113,7 +113,7 @@ public function processSpecificGebruik(ObjectEntity $gebruikObject): array { $this->logger->debug( 'Processing gebruik object', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'currentStatus' => $gebruikData['status'] ?? 'Unknown', ] @@ -135,7 +135,7 @@ public function processSpecificGebruik(ObjectEntity $gebruikObject): array { $this->logger->critical( 'GEBRUIK PROCESSING COMPLETED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'stats' => $stats, 'processingTime' => $stats['duration'] . 's', @@ -150,7 +150,7 @@ public function processSpecificGebruik(ObjectEntity $gebruikObject): array { $this->logger->error( 'GEBRUIK PROCESSING ERROR', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikObject->getUuid(), 'exception' => $e->getMessage(), 'file' => $e->getFile(), @@ -199,7 +199,7 @@ private function processAmefElements(ObjectEntity $gebruikObject): array { $this->logger->debug( 'Processing referentiecomponenten', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'referentieComponentenCount' => count($referenceComponents), ] @@ -233,7 +233,7 @@ private function processAmefElements(ObjectEntity $gebruikObject): array { $this->logger->error( 'AMEF configuration missing', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'amefRegister' => $amefRegister, 'elementSchema' => $elementSchema, ] @@ -278,7 +278,7 @@ private function processAmefElements(ObjectEntity $gebruikObject): array { $this->logger->critical( 'AMEF ELEMENTS UPDATED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'amefSlugs' => $amefSlugs, 'amefElementsCount' => count($amefSlugs), @@ -292,7 +292,7 @@ private function processAmefElements(ObjectEntity $gebruikObject): array { $this->logger->error( 'AMEF PROCESSING ERROR', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikObject->getUuid(), 'exception' => $e->getMessage(), ] @@ -337,7 +337,7 @@ private function searchAmefElementsByIds(array $ids, string $register, string $s $this->logger->warning( 'Failed to search for AMEF element', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'id' => $id, 'error' => $e->getMessage(), ] @@ -348,7 +348,7 @@ private function searchAmefElementsByIds(array $ids, string $register, string $s $this->logger->info( 'AMEF elements search completed', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'searchedIds' => $ids, 'foundElementsCount' => count($foundElements), ] @@ -382,7 +382,7 @@ private function updateStatusBasedOnDates(ObjectEntity $gebruikObject): array { $this->logger->info( 'CHECKING STATUS DATES', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'currentStatus' => $currentStatus, 'statusDates' => $statusDates, @@ -402,7 +402,7 @@ private function updateStatusBasedOnDates(ObjectEntity $gebruikObject): array { $this->logger->critical( 'STATUS AUTO-UPDATED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'oldStatus' => $currentStatus, 'newStatus' => $targetStatus, @@ -417,7 +417,7 @@ private function updateStatusBasedOnDates(ObjectEntity $gebruikObject): array { $this->logger->error( 'STATUS UPDATE ERROR', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikObject->getUuid(), 'exception' => $e->getMessage(), ] @@ -471,7 +471,7 @@ private function resolveLatestEligibleStatus(array $statusDates, string $gebruik $this->logger->warning( 'Invalid date format', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikUuid, 'status' => $status, 'dateString' => $dateString, @@ -526,7 +526,7 @@ private function updateGebruikObject(ObjectEntity $gebruikObject, array $updated $this->logger->info( 'Gebruik object updated successfully', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikObject->getUuid(), ] ); @@ -534,7 +534,7 @@ private function updateGebruikObject(ObjectEntity $gebruikObject, array $updated $this->logger->error( 'Failed to update gebruik object', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'gebruikId' => $gebruikObject->getUuid(), 'error' => $e->getMessage(), ] diff --git a/lib/Service/IntakeService.php b/lib/Service/IntakeService.php index b0792ee8..83adf120 100644 --- a/lib/Service/IntakeService.php +++ b/lib/Service/IntakeService.php @@ -17,11 +17,11 @@ * admin-gated step (ModerationService). * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @@ -31,7 +31,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; @@ -270,7 +270,7 @@ private function resolveTarget(): ?array { * FALSE, and because an object is not an array the array arm below cannot * rescue it — so this method used to return `null` for EVERY real save, * putting `uuid: null` in the submit response and the audit log - * (softwarecatalog#490). `property_exists()` is the instrument + * (stackiq#490). `property_exists()` is the instrument * `Entity::getter()` itself decides on; `method_exists()` is kept as the * second arm for genuinely concrete accessors, and the call is wrapped * because neither probe guarantees the other object's shape. diff --git a/lib/Service/MergeOrganisatieService.php b/lib/Service/MergeOrganisatieService.php index b9200008..9bf9ad06 100644 --- a/lib/Service/MergeOrganisatieService.php +++ b/lib/Service/MergeOrganisatieService.php @@ -46,11 +46,11 @@ * - compliancy: `@self.organisation` (system-level owning organisation). * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/organisation-merge/spec.md * @@ -60,10 +60,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\OrganizationHandler; +use OCA\Stackiq\Service\Stackiq\OrganizationHandler; use OCP\App\IAppManager; use OCP\EventDispatcher\IEventDispatcher; use OCP\IGroupManager; @@ -75,10 +75,10 @@ * Service orchestrating organisation-merge dry-run and execute. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/organisation-merge/spec.md * @@ -472,7 +472,7 @@ private function repointBySelfOrganisation(string $objectType, string $source, s * wrong here, and both fail silently: * * - `method_exists()` is **false** for every such accessor. That was - * softwarecatalog#490: the caller's re-point branch never ran, so a merge + * stackiq#490: the caller's re-point branch never ran, so a merge * re-pointed nothing for `contract`/`compliancy` while still tombstoning * the source organisation. * - `is_callable()` is **true** for ANY name on a class with `__call()`, so diff --git a/lib/Service/ModerationService.php b/lib/Service/ModerationService.php index 48565f88..62dfac8a 100644 --- a/lib/Service/ModerationService.php +++ b/lib/Service/ModerationService.php @@ -5,7 +5,7 @@ * * The admin-only counterpart to IntakeService (organisatie) and * ReviewService (beoordeeling) — a single generalised mechanism, not two - * parallel ones (catalog-ratings, softwarecatalog#375: "reuse the + * parallel ones (catalog-ratings, stackiq#375: "reuse the * ModerationQueue.vue pattern... do not invent a second moderation * mechanism"). Every method takes an explicit `$type` selecting which * moderated type/field/values to operate on; it defaults to the original @@ -28,11 +28,11 @@ * ModerationController. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @spec openspec/specs/catalog-ratings/spec.md#requirement-review-moderation-must-reuse-the-existing-moderation-queue-mechanism-not-a-second-one @@ -43,7 +43,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; diff --git a/lib/Service/ModuleComplianceService.php b/lib/Service/ModuleComplianceService.php index dfb181c8..5b18c436 100644 --- a/lib/Service/ModuleComplianceService.php +++ b/lib/Service/ModuleComplianceService.php @@ -4,22 +4,22 @@ * Module Compliance Service * * This file contains the service class for handling module compliance logic - * in the SoftwareCatalog application. + * in the Stackiq application. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use Psr\Container\ContainerInterface; @@ -32,11 +32,11 @@ * property based on linked compliance objects and their standaardversie references. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) diff --git a/lib/Service/ModuleEventProcessor.php b/lib/Service/ModuleEventProcessor.php index dc943e4d..e90af878 100644 --- a/lib/Service/ModuleEventProcessor.php +++ b/lib/Service/ModuleEventProcessor.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-6 * @@ -21,13 +21,13 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; /** - * Handles shared module-event processing logic extracted from SoftwareCatalogEventListener. + * Handles shared module-event processing logic extracted from StackiqEventListener. * * This processor centralises the schema-ID lookup, early-guard, and delegation * steps that were duplicated across handleObjectCreated / handleObjectUpdated / @@ -93,18 +93,18 @@ public function processOrganisatieCreated(object $object, array $schemaIds): voi if (in_array(needle: $status, haystack: ['actief', 'active']) !== true) { $this->logger->debug( - 'SoftwareCatalog: Skipping non-active organization creation', + 'Stackiq: Skipping non-active organization creation', ['objectId' => $object->getUuid(), 'status' => $status] ); return; } try { - $orgSyncService = $this->container->get('OCA\SoftwareCatalog\Service\OrganizationSyncService'); + $orgSyncService = $this->container->get('OCA\Stackiq\Service\OrganizationSyncService'); $orgSyncService->processSpecificOrganization($object); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: Failed to process organization creation', + 'Stackiq: Failed to process organization creation', ['objectId' => $object->getUuid(), 'exception' => $e->getMessage()] ); } @@ -164,16 +164,16 @@ public function processOrganisatieDeleted(object $object, array $schemaIds): boo } $this->logger->info( - 'SoftwareCatalog: Processing organization deletion', + 'Stackiq: Processing organization deletion', ['objectId' => $object->getUuid()] ); try { - $orgSyncService = $this->container->get('OCA\SoftwareCatalog\Service\OrganizationSyncService'); + $orgSyncService = $this->container->get('OCA\Stackiq\Service\OrganizationSyncService'); $orgSyncService->processSpecificOrganization($object); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: Failed to process organization deletion', + 'Stackiq: Failed to process organization deletion', ['objectId' => $object->getUuid(), 'exception' => $e->getMessage()] ); } @@ -193,7 +193,7 @@ private function processActiveOrganisationUpdate(object $object, string $status) $objectId = $object->getUuid(); $this->logger->info( - 'SoftwareCatalog: Processing active organization update', + 'Stackiq: Processing active organization update', ['objectId' => $objectId, 'status' => $status] ); @@ -212,11 +212,11 @@ private function processActiveOrganisationUpdate(object $object, string $status) _multitenancy: false ); - $orgSyncService = $this->container->get('OCA\SoftwareCatalog\Service\OrganizationSyncService'); + $orgSyncService = $this->container->get('OCA\Stackiq\Service\OrganizationSyncService'); $orgSyncService->processSpecificOrganization($orgWithContacts); } catch (\Exception $e) { $this->logger->error( - 'SoftwareCatalog: Failed to process organization update', + 'Stackiq: Failed to process organization update', ['objectId' => $objectId, 'exception' => $e->getMessage()] ); }//end try diff --git a/lib/Service/ModuleRegistrationService.php b/lib/Service/ModuleRegistrationService.php index 43606e83..5fede71c 100644 --- a/lib/Service/ModuleRegistrationService.php +++ b/lib/Service/ModuleRegistrationService.php @@ -7,19 +7,19 @@ * based on the owning organisation's type. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use Psr\Container\ContainerInterface; @@ -30,7 +30,7 @@ * based on the owning organisation's type. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service */ class ModuleRegistrationService { /** diff --git a/lib/Service/ModuleVersionService.php b/lib/Service/ModuleVersionService.php index 4efb3d02..d00ed17c 100644 --- a/lib/Service/ModuleVersionService.php +++ b/lib/Service/ModuleVersionService.php @@ -8,19 +8,19 @@ * the module's name and description. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: 1.0.0 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use Psr\Container\ContainerInterface; @@ -35,7 +35,7 @@ * (`fetchVersionData()`, `compareVersions()`, `updateVersionRecord()`). * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * * @spec openspec/changes/method-decomposition/tasks.md#task-9-5 */ diff --git a/lib/Service/OrganisatieService.php b/lib/Service/OrganisatieService.php index 9a1029ac..7c77a9a2 100644 --- a/lib/Service/OrganisatieService.php +++ b/lib/Service/OrganisatieService.php @@ -4,22 +4,22 @@ * Organisatie Service. * * This file contains the service class for handling organization-specific operations - * in the SoftwareCatalog application. + * in the Stackiq application. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\OrganizationHandler; +use OCA\Stackiq\Service\Stackiq\OrganizationHandler; use OCP\App\IAppManager; use OCP\IAppConfig; use OCP\IUserManager; @@ -33,11 +33,11 @@ * status management, and integration with OpenRegister. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ @@ -153,7 +153,7 @@ public function updateOrganizationStatus(string $organizationUuid, array $object $organisationMapper = $this->container->get('OCA\OpenRegister\Db\OrganisationMapper'); $organisationEntity = $organisationMapper->findByUuid($organizationUuid); - // Map status from SoftwareCatalog to OpenRegister. + // Map status from Stackiq to OpenRegister. $active = $this->mapStatus(status: $objectData['beoordeling'] ?? 'actief'); // Update the entity. @@ -200,7 +200,7 @@ private function getOrganisationService(): ?\OCA\OpenRegister\Service\Organisati }//end getOrganisationService() /** - * Maps organization data from Software Catalog object to OpenRegister format. + * Maps organization data from Stackiq object to OpenRegister format. * * @param array $objectData The organization object data. * @@ -229,9 +229,9 @@ private function mapOrganizationDataForOpenRegister(array $objectData): array { }//end mapOrganizationDataForOpenRegister() /** - * Maps status from Software Catalog to OpenRegister format. + * Maps status from Stackiq to OpenRegister format. * - * @param string $status The status from Software Catalog + * @param string $status The status from Stackiq * * @return bool The mapped active status for OpenRegister * diff --git a/lib/Service/OrganizationSyncService.php b/lib/Service/OrganizationSyncService.php index d598cf2b..d757ce67 100644 --- a/lib/Service/OrganizationSyncService.php +++ b/lib/Service/OrganizationSyncService.php @@ -4,24 +4,24 @@ * Organization Synchronization Service * * This file contains the service class for synchronizing organizations and contact persons - * between SoftwareCatalog objects and OpenRegister entities. + * between Stackiq objects and OpenRegister entities. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; -use OCA\SoftwareCatalog\Service\SoftwareCatalogue\ContactPersonHandler; +use OCA\Stackiq\Service\Stackiq\ContactPersonHandler; use OCP\IAppConfig; use OCP\IDBConnection; use Psr\Container\ContainerInterface; @@ -31,14 +31,14 @@ /** * Service for synchronizing organizations and contact persons. * - * This service provides comprehensive synchronization between SoftwareCatalog objects + * This service provides comprehensive synchronization between Stackiq objects * and OpenRegister entities, ensuring data consistency and proper user management. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @@ -995,7 +995,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->debug( 'Ensuring organisation entity', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'name' => ($objectData['name'] ?? 'Unknown'), 'status' => ($objectData['status'] ?? 'Unknown'), @@ -1019,7 +1019,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->debug( 'Existing entity found', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'entityId' => $organisationEntity->getId(), 'shouldBeActive' => $shouldBeActive, @@ -1031,7 +1031,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->debug( 'Updating entity status', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'oldActive' => $organisationEntity->getActive(), 'newActive' => $shouldBeActive, @@ -1087,7 +1087,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->info( 'OrganizationSyncService: Found existing entity by slug, updating UUID to match object', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'oldEntityUuid' => $organisationEntity->getUuid(), 'slug' => $slug, @@ -1116,7 +1116,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->debug( 'Creating new organisation entity', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'name' => ($objectData['name'] ?? 'Unknown'), ] @@ -1128,7 +1128,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->debug( 'New organisation entity created', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, 'entityId' => $organisationEntity->getId(), 'active' => $organisationEntity->getActive(), @@ -1171,7 +1171,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->error( '❌ ORGANISATION ENTITY CREATION FAILED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationId, ] ); @@ -1183,7 +1183,7 @@ private function ensureOrganisationEntity(object $organisationObject, array &$st $this->logger->error( '💥 ENSURE ORGANISATION ENTITY EXCEPTION', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organisatieId' => $organisationObject->getId(), 'exception' => $e->getMessage(), 'file' => $e->getFile(), @@ -1606,7 +1606,7 @@ public function getSyncStatus(int $minutesBack = 10): array { // Configuration. 'contactSchemaConfigured' => empty($contactSchema) === false, - 'lastSyncTime' => $this->config->getValueString('softwarecatalog', 'last_sync_time', 'Never'), + 'lastSyncTime' => $this->config->getValueString('stackiq', 'last_sync_time', 'Never'), // Email configuration status. 'emailStatus' => $this->getEmailConfigurationStatus(), @@ -1671,7 +1671,7 @@ private function formatNumber(int $number): string { * @spec openspec/specs/organization-sync/spec.md */ public function recordSyncTime(): void { - $this->config->setValueString('softwarecatalog', 'last_sync_time', date('Y-m-d H:i:s')); + $this->config->setValueString('stackiq', 'last_sync_time', date('Y-m-d H:i:s')); }//end recordSyncTime() @@ -1705,7 +1705,7 @@ public function processSpecificOrganization($organizationObject): array { $this->logger->info( '🏢 ORGANIZATION PROCESSING STARTED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'trigger' => 'ObjectCreatedEvent', 'organizationId' => $organizationUuid, 'organizationName' => ($objectData['name'] ?? 'Unknown'), @@ -1732,7 +1732,7 @@ public function processSpecificOrganization($organizationObject): array { $this->logger->info( '✅ ORGANISATION ENTITY CREATED/UPDATED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationUuid' => $organizationUuid, 'entityId' => $organisationEntity->getId(), 'entityActive' => $organisationEntity->getActive(), @@ -1772,7 +1772,7 @@ public function processSpecificOrganization($organizationObject): array { $this->logger->error( '❌ ORGANISATION ENTITY FAILED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationUuid' => $organizationUuid, 'error' => 'Failed to create/update organisation entity', ] @@ -1786,7 +1786,7 @@ public function processSpecificOrganization($organizationObject): array { $this->logger->info( '🏁 ORGANIZATION PROCESSING COMPLETED', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'stats' => $stats, 'processingTime' => $stats['duration'] . 's', @@ -1799,7 +1799,7 @@ public function processSpecificOrganization($organizationObject): array { $this->logger->error( '💥 ORGANIZATION PROCESSING EXCEPTION', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationObject->getUuid(), 'exception' => $e->getMessage(), 'file' => $e->getFile(), @@ -1840,7 +1840,7 @@ private function processNestedContactPersons($organizationObject, array &$stats) $this->logger->info( '👥 PROCESSING NESTED CONTACT PERSONS', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'contactCount' => count($contactPersons), ] @@ -1968,7 +1968,7 @@ private function processRelatedContactPersons(string $organizationUuid, $organiz $this->logger->debug( 'Finding related contact persons', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, ] ); @@ -2121,7 +2121,7 @@ private function processRelatedContactPersons(string $organizationUuid, $organiz $this->logger->info( '👥 PROCESSING RELATED CONTACT PERSONS', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'contactCount' => count($relatedContacts), ] @@ -2284,7 +2284,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( '📧 FETCHING EXISTING CONTACT PERSON', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'contactId' => $existingContactId, 'email' => $email, @@ -2316,7 +2316,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( '📧 CREATING NEW CONTACT PERSON OBJECT', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'email' => $email, 'name' => ($contactData['voornaam'] ?? '') . ' ' . ($contactData['achternaam'] ?? ''), @@ -2398,7 +2398,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( '✅ CONTACT PERSON OBJECT READY', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'contactId' => $contactObject->getUuid(), 'email' => $email, @@ -2417,7 +2417,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( 'Organisation entity missing for ' . $organizationUuid . ', creating backup entity', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), ] ); @@ -2442,7 +2442,7 @@ private function createOrUpdateContactPersonObject( $this->logger->error( 'Backup org entity creation failed', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'error' => $backupEx->getMessage(), ] @@ -2461,7 +2461,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( 'Creating user account for contact person (org is active)', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'organizationId' => $organizationUuid, 'email' => $email, @@ -2496,7 +2496,7 @@ private function createOrUpdateContactPersonObject( $this->logger->debug( 'Saving contact with username via direct mapper update', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'username' => $user->getUID(), 'hasOrganisatie' => isset($contactObjectData['organization']) === true, @@ -2519,7 +2519,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( 'Contact saved with username', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'username' => $user->getUID(), ] @@ -2528,7 +2528,7 @@ private function createOrUpdateContactPersonObject( $this->logger->warning( 'Failed to save username to contact object (user was created)', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'username' => $user->getUID(), 'error' => $saveEx->getMessage(), @@ -2555,7 +2555,7 @@ private function createOrUpdateContactPersonObject( $this->logger->info( 'User account created', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'username' => $user->getUID(), ] @@ -2566,7 +2566,7 @@ private function createOrUpdateContactPersonObject( $this->logger->error( 'User account creation failed', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), 'email' => $email, ] @@ -2684,7 +2684,7 @@ public function processSpecificContactPerson($contactObject): array { $this->logger->info( '[EVENT] Organisation entity missing for ' . $organizationUuid . ', creating backup entity', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), ] ); @@ -2709,7 +2709,7 @@ public function processSpecificContactPerson($contactObject): array { $this->logger->error( 'Backup org entity creation failed', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'organizationId' => $organizationUuid, 'error' => $backupEx->getMessage(), ] @@ -2798,7 +2798,7 @@ public function processSpecificContactPerson($contactObject): array { $this->logger->debug( '[EVENT] Skipping contact - user account creation failed (likely no email)', [ - 'app' => 'softwarecatalog', + 'app' => 'stackiq', 'contactId' => $contactObject->getUuid(), ] ); diff --git a/lib/Service/PortfolioReportDerivation.php b/lib/Service/PortfolioReportDerivation.php index 00e7c1a5..324079fe 100644 --- a/lib/Service/PortfolioReportDerivation.php +++ b/lib/Service/PortfolioReportDerivation.php @@ -13,11 +13,11 @@ * (design.md Decision 3). * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/portfolio-rationalization-time/specs/portfolio-rationalization-time/spec.md * @@ -27,7 +27,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use DateTimeImmutable; diff --git a/lib/Service/PortfolioReportService.php b/lib/Service/PortfolioReportService.php index 2972a813..21612b3a 100644 --- a/lib/Service/PortfolioReportService.php +++ b/lib/Service/PortfolioReportService.php @@ -16,7 +16,7 @@ * {@see PortfolioReportDerivation}. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 @@ -30,12 +30,12 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use DateTimeImmutable; use Exception; use OCA\OpenRegister\Contract\ObjectServiceInterface; -use OCA\SoftwareCatalog\AppInfo\Application; +use OCA\Stackiq\AppInfo\Application; use OCP\App\IAppManager; use OCP\IAppConfig; use Psr\Container\ContainerInterface; diff --git a/lib/Service/ProfileFieldMapper.php b/lib/Service/ProfileFieldMapper.php index 3e106f07..26928b40 100644 --- a/lib/Service/ProfileFieldMapper.php +++ b/lib/Service/ProfileFieldMapper.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-8 * @@ -21,10 +21,10 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; /** - * Maps Nextcloud user profile field keys to SoftwareCatalog contactpersoon field names. + * Maps Nextcloud user profile field keys to Stackiq contactpersoon field names. * * Used by UserProfileUpdatedEventListener to delegate field-name resolution * without bloating the event-handler method. diff --git a/lib/Service/ProgressTracker.php b/lib/Service/ProgressTracker.php index 066546d2..3e90f642 100644 --- a/lib/Service/ProgressTracker.php +++ b/lib/Service/ProgressTracker.php @@ -7,17 +7,17 @@ * Supports real-time streaming via Server-Sent Events. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: 1.0.0 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCP\ISession; use Psr\Log\LoggerInterface; @@ -26,12 +26,12 @@ * Service for tracking and reporting progress of long-running operations * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: 1.0.0 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ class ProgressTracker { /** diff --git a/lib/Service/PublicationService.php b/lib/Service/PublicationService.php index 73829b55..046a1384 100644 --- a/lib/Service/PublicationService.php +++ b/lib/Service/PublicationService.php @@ -18,11 +18,11 @@ * (public + federation) read surface. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/open-data-publishing/spec.md * @@ -32,7 +32,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use Psr\Container\ContainerInterface; diff --git a/lib/Service/ReviewAggregateService.php b/lib/Service/ReviewAggregateService.php index 60ec30de..8e13a1d7 100644 --- a/lib/Service/ReviewAggregateService.php +++ b/lib/Service/ReviewAggregateService.php @@ -2,7 +2,7 @@ /** * Public approved-only review aggregate/read path (catalog-ratings, - * softwarecatalog#375) — split out of ReviewService (which owns the + * stackiq#375) — split out of ReviewService (which owns the * authenticated write path) to keep each class under the * ExcessiveClassComplexity budget. * @@ -15,11 +15,11 @@ * matching — computing it here is fully unit-testable regardless of that. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/catalog-ratings/spec.md#requirement-module-and-dienst-detail-pages-must-display-an-aggregate-rating-computed-only-from-approved-reviews * @@ -29,7 +29,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; diff --git a/lib/Service/ReviewService.php b/lib/Service/ReviewService.php index d3183d46..3bc2e1c8 100644 --- a/lib/Service/ReviewService.php +++ b/lib/Service/ReviewService.php @@ -5,7 +5,7 @@ * ReviewAggregateService for the approved-only read/aggregate path; split * to keep each class under the ExcessiveClassComplexity budget). * - * The write path for the `catalog-ratings` feature (softwarecatalog#375). + * The write path for the `catalog-ratings` feature (stackiq#375). * Unlike `IntakeService` (anonymous organisation registration), a review * submission REQUIRES an authenticated Nextcloud session — anonymous public * review submission is explicitly out of scope. The author identity is never @@ -17,11 +17,11 @@ * organisatie moderation pattern) may change that. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/catalog-ratings/spec.md * @@ -31,7 +31,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCP\IUser; use OCP\IUserSession; @@ -359,7 +359,7 @@ private function resolveTarget(): ?array { * FALSE, and because an object is not an array the array arm below cannot * rescue it — so this method used to return `null` for EVERY real save, * putting `uuid: null` in the submit response and the audit log - * (softwarecatalog#490). `property_exists()` is the instrument + * (stackiq#490). `property_exists()` is the instrument * `Entity::getter()` itself decides on; `method_exists()` is kept as the * second arm for genuinely concrete accessors, and the call is wrapped * because neither probe guarantees the other object's shape. diff --git a/lib/Service/SbomImportService.php b/lib/Service/SbomImportService.php index 727f75be..48e290b3 100644 --- a/lib/Service/SbomImportService.php +++ b/lib/Service/SbomImportService.php @@ -22,11 +22,11 @@ * set rather than a mixed old/new set; re-running the import starts clean. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/sbom-import/spec.md#requirement-re-import-replaces-the-previous-component-set-and-is-soft-delete-aware * @@ -36,7 +36,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use DateTime; use OCA\OpenRegister\Contract\ObjectServiceInterface; @@ -101,7 +101,7 @@ public function __construct( * * @return array Import result summary. * - * @throws \OCA\SoftwareCatalog\Exception\UnsupportedSbomFormatException When the + * @throws \OCA\Stackiq\Exception\UnsupportedSbomFormatException When the * document's format/version is not supported. * No component is written in that case. * @throws RuntimeException When the target `moduleVersie` cannot be @@ -215,7 +215,7 @@ public function importForModuleVersie( * * @return array{components: array>, vulnerabilities: array} * - * @throws \OCA\SoftwareCatalog\Exception\UnsupportedSbomFormatException When + * @throws \OCA\Stackiq\Exception\UnsupportedSbomFormatException When * the document's format/version is not supported. * * @spec openspec/specs/sbom-import/spec.md#requirement-cyclonedx-sbom-files-are-parsed-into-a-normalized-component-list diff --git a/lib/Service/SbomParserService.php b/lib/Service/SbomParserService.php index 5b39319a..6dc19b69 100644 --- a/lib/Service/SbomParserService.php +++ b/lib/Service/SbomParserService.php @@ -20,11 +20,11 @@ * "Alternative considered"). * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2026 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/sbom-import/spec.md#requirement-cyclonedx-sbom-files-are-parsed-into-a-normalized-component-list * @@ -34,9 +34,9 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; -use OCA\SoftwareCatalog\Exception\UnsupportedSbomFormatException; +use OCA\Stackiq\Exception\UnsupportedSbomFormatException; /** * Pure CycloneDX 1.5/1.6 (+ optional SPDX 2.x) SBOM parser. diff --git a/lib/Service/Settings/ModuleSettingsHandler.php b/lib/Service/Settings/ModuleSettingsHandler.php index 336bd31a..cb6323ab 100644 --- a/lib/Service/Settings/ModuleSettingsHandler.php +++ b/lib/Service/Settings/ModuleSettingsHandler.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-1 * @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Settings; +namespace OCA\Stackiq\Service\Settings; use InvalidArgumentException; use OCP\IAppConfig; @@ -42,7 +42,7 @@ class ModuleSettingsHandler { * * @var string */ - private const APP_NAME = 'softwarecatalog'; + private const APP_NAME = 'stackiq'; /** * Constructor. diff --git a/lib/Service/Settings/OrganizationSettingsHandler.php b/lib/Service/Settings/OrganizationSettingsHandler.php index b36a0603..90520263 100644 --- a/lib/Service/Settings/OrganizationSettingsHandler.php +++ b/lib/Service/Settings/OrganizationSettingsHandler.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-1 * @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service\Settings; +namespace OCA\Stackiq\Service\Settings; use InvalidArgumentException; use OCP\IAppConfig; @@ -42,7 +42,7 @@ class OrganizationSettingsHandler { * * @var string */ - private const APP_NAME = 'softwarecatalog'; + private const APP_NAME = 'stackiq'; /** * Constructor. diff --git a/lib/Service/ViewQueryBuilder.php b/lib/Service/ViewQueryBuilder.php index ef349e55..705f520e 100644 --- a/lib/Service/ViewQueryBuilder.php +++ b/lib/Service/ViewQueryBuilder.php @@ -1,17 +1,17 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/changes/method-decomposition/tasks.md#task-6 * @@ -21,7 +21,7 @@ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; /** * Builds and applies filters and sorting to view query option arrays. diff --git a/lib/Service/ViewService.php b/lib/Service/ViewService.php index 5104f1b1..21c0db91 100644 --- a/lib/Service/ViewService.php +++ b/lib/Service/ViewService.php @@ -1,25 +1,25 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @spec openspec/specs/method-decomposition/spec.md */ declare(strict_types=1); -namespace OCA\SoftwareCatalog\Service; +namespace OCA\Stackiq\Service; use OCA\OpenRegister\Contract\ObjectServiceInterface; use OCP\App\IAppManager; @@ -37,12 +37,12 @@ * data such as products, usage information (gebruik), and related data. * * @category Service - * @package OCA\SoftwareCatalog\Service + * @package OCA\Stackiq\Service * @author Conduction b.v. * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq * * @SuppressWarnings(PHPMD.ExcessiveClassLength) * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) @@ -93,7 +93,7 @@ public function __construct( private readonly IUserSession $userSession, ICacheFactory $cacheFactory, ) { - $this->viewsCache = $cacheFactory->createDistributed(prefix: 'softwarecatalog_views'); + $this->viewsCache = $cacheFactory->createDistributed(prefix: 'stackiq_views'); }//end __construct() /** diff --git a/lib/Settings/StackiqAdmin.php b/lib/Settings/StackiqAdmin.php index bfb06895..c21e8db0 100644 --- a/lib/Settings/StackiqAdmin.php +++ b/lib/Settings/StackiqAdmin.php @@ -1,18 +1,18 @@ * @copyright 2024 Conduction B.V. * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version GIT: - * @link https://codeberg.org/Conduction/SoftwareCatalog + * @link https://github.com/ConductionNL/stackiq */ -namespace OCA\SoftwareCatalog\Settings; +namespace OCA\Stackiq\Settings; use OCP\App\IAppManager; use OCP\AppFramework\Http\TemplateResponse; @@ -21,7 +21,7 @@ use OCP\IL10N; use OCP\Settings\IDelegatedSettings; -class SoftwareCatalogAdmin implements IDelegatedSettings { +class StackiqAdmin implements IDelegatedSettings { /** * The localization service. @@ -52,7 +52,7 @@ class SoftwareCatalogAdmin implements IDelegatedSettings { private IInitialState $initialState; /** - * Constructor for SoftwareCatalogAdmin settings. + * Constructor for StackiqAdmin settings. * * @param IAppConfig $config The application configuration service * @param IL10N $l10n The localization service @@ -72,9 +72,9 @@ public function __construct(IAppConfig $config, IL10N $l10n, IAppManager $appMan * @return TemplateResponse The template response for the settings form */ public function getForm(): TemplateResponse { - $this->initialState->provideInitialState('version', $this->appManager->getAppVersion('softwarecatalog')); + $this->initialState->provideInitialState('version', $this->appManager->getAppVersion('stackiq')); - return new TemplateResponse('softwarecatalog', 'settings/admin', []); + return new TemplateResponse('stackiq', 'settings/admin', []); }//end getForm() /** @@ -84,7 +84,7 @@ public function getForm(): TemplateResponse { */ public function getSection(): string { // Name of the previously created section. - $sectionName = 'softwarecatalog'; + $sectionName = 'stackiq'; return $sectionName; }//end getSection() @@ -117,7 +117,7 @@ public function getName(): ?string { /** * App config keys an authorized (delegated) admin may manage. * - * Returned as a map of appId => list of allowed config keys. SoftwareCatalog + * Returned as a map of appId => list of allowed config keys. Stackiq * exposes no delegatable sub-keys, so this is intentionally empty; the * `#[AuthorizedAdminSetting]` attribute still scopes the endpoints to full * admins (fail-closed). Required by IDelegatedSettings — its absence is a diff --git a/lib/Settings/register.d/contracts-to-decidesk.json b/lib/Settings/register.d/contracts-to-decidesk.json index c70c8e48..2097a43f 100644 --- a/lib/Settings/register.d/contracts-to-decidesk.json +++ b/lib/Settings/register.d/contracts-to-decidesk.json @@ -5,7 +5,7 @@ "properties": { "approvalDecisionId": { "type": "string", - "description": "PROJECTION FIELD. The id of the decidesk Decision (decisionType contract / contract-renewal) raised for this contract's approval/sign-off, resolved via the ADR-019 integration registry. Empty until the contract is submitted for approval. softwarecatalog never authors an approval decision locally; it raises it in decidesk and stores the returned id here for outcome reconciliation.", + "description": "PROJECTION FIELD. The id of the decidesk Decision (decisionType contract / contract-renewal) raised for this contract's approval/sign-off, resolved via the ADR-019 integration registry. Empty until the contract is submitted for approval. stackiq never authors an approval decision locally; it raises it in decidesk and stores the returned id here for outcome reconciliation.", "facetable": false, "title": "Approval decision id", "order": 20, @@ -20,7 +20,7 @@ "rejected" ], "default": "none", - "description": "PROJECTION of the decidesk outcome for the approval/renewal decision — distinct from the catalog lifecycle field `status`. `none` = no decision raised; `pending` = a decidesk Decision is open; `approved` = decidesk reported an adopting outcome (this is the ONLY thing that drives the `In onderhandeling -> Actief` transition on `status`); `rejected` = decidesk rejected/withdrew (status stays `In onderhandeling`). softwarecatalog NEVER sets `status = Actief` on its own authority — it is always a projection of an `approved` decidesk outcome. The date-driven `Actief -> Verlopen` expiry transition is catalog-local and is NOT a decision delegated to decidesk.", + "description": "PROJECTION of the decidesk outcome for the approval/renewal decision — distinct from the catalog lifecycle field `status`. `none` = no decision raised; `pending` = a decidesk Decision is open; `approved` = decidesk reported an adopting outcome (this is the ONLY thing that drives the `In onderhandeling -> Actief` transition on `status`); `rejected` = decidesk rejected/withdrew (status stays `In onderhandeling`). stackiq NEVER sets `status = Actief` on its own authority — it is always a projection of an `approved` decidesk outcome. The date-driven `Actief -> Verlopen` expiry transition is catalog-local and is NOT a decision delegated to decidesk.", "facetable": false, "title": "Approval state", "order": 21, diff --git a/phpmd.baseline.xml b/phpmd.baseline.xml index d5560e6d..0ad78b14 100644 --- a/phpmd.baseline.xml +++ b/phpmd.baseline.xml @@ -5,7 +5,7 @@ - - - + + + diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4e7093b5..a0f1beca 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,7 +1,7 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#2 \\$listener of method OCP\\\\AppFramework\\\\Bootstrap\\\\IRegistrationContext\\:\\:registerEventListener\\(\\) expects class\\-string\\\\>, 'OCA\\\\\\\\SoftwareCatalog\\\\\\\\EventListener\\\\\\\\UserProfileUpdatedEventListener' given\\.$#" + message: "#^Parameter \\#2 \\$listener of method OCP\\\\AppFramework\\\\Bootstrap\\\\IRegistrationContext\\:\\:registerEventListener\\(\\) expects class\\-string\\\\>, 'OCA\\\\\\\\Stackiq\\\\\\\\EventListener\\\\\\\\UserProfileUpdatedEventListener' given\\.$#" count: 1 path: lib/AppInfo/Application.php @@ -26,12 +26,12 @@ parameters: path: lib/Controller/AangebodenGebruikController.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Controller\\\\ContactpersonenController\\:\\:\\$secureRandom is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Controller\\\\ContactpersonenController\\:\\:\\$secureRandom is never read, only written\\.$#" count: 1 path: lib/Controller/ContactpersonenController.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Controller\\\\ContactpersonenController\\:\\:\\$settingsService is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Controller\\\\ContactpersonenController\\:\\:\\$settingsService is never read, only written\\.$#" count: 1 path: lib/Controller/ContactpersonenController.php @@ -46,7 +46,7 @@ parameters: path: lib/Controller/SettingsController.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Dashboard\\\\ConceptOrganisatiesWidget\\:\\:\\$url is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Dashboard\\\\ConceptOrganisatiesWidget\\:\\:\\$url is never read, only written\\.$#" count: 1 path: lib/Dashboard/ConceptOrganisatiesWidget.php @@ -66,7 +66,7 @@ parameters: path: lib/EventListener/UserProfileUpdatedEventListener.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\AanbodService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\AanbodService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/AanbodService.php @@ -76,32 +76,32 @@ parameters: path: lib/Service/AangebodenGebruikService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:checkOrganisationOwnership\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:checkOrganisationOwnership\\(\\) is unused\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:getAllObjectsForSchema\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:getAllObjectsForSchema\\(\\) is unused\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:getApplicationsOwnedByOrganisation\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:getApplicationsOwnedByOrganisation\\(\\) is unused\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:getKoppelingenConfiguration\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:getKoppelingenConfiguration\\(\\) is unused\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:getObjectsRelatedToUuid\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:getObjectsRelatedToUuid\\(\\) is unused\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\AangebodenGebruikService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\AangebodenGebruikService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/AangebodenGebruikService.php @@ -121,7 +121,7 @@ parameters: path: lib/Service/ArchiMateExportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateExportService\\:\\:addDataToXmlNode\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateExportService\\:\\:addDataToXmlNode\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateExportService.php @@ -156,57 +156,57 @@ parameters: path: lib/Service/ArchiMateImportService.php - - message: "#^Constant OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:CONFIG_KEYS is unused\\.$#" + message: "#^Constant OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:CONFIG_KEYS is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:calculateOptimizedStatistics\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:calculateOptimizedStatistics\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:debugViewNodeHierarchy\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:debugViewNodeHierarchy\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:extractNodesRecursively\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:extractNodesRecursively\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:isAssoc\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:isAssoc\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:logMemoryUsage\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:logMemoryUsage\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsDirectToService\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsDirectToService\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsInParallelBatches\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsInParallelBatches\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsInSingleBatch\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:saveObjectsInSingleBatch\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:transformSectionObjectsBatch\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:transformSectionObjectsBatch\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:transformViewsOptimized\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:transformViewsOptimized\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php @@ -256,7 +256,7 @@ parameters: path: lib/Service/ArchiMateImportService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateImportService\\:\\:\\$rootFolder is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ArchiMateImportService\\:\\:\\$rootFolder is never read, only written\\.$#" count: 1 path: lib/Service/ArchiMateImportService.php @@ -291,62 +291,62 @@ parameters: path: lib/Service/ArchiMateImportService.php - - message: "#^Constant OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:CONFIG_KEYS is unused\\.$#" + message: "#^Constant OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:CONFIG_KEYS is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:calculateObjectStatistics\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:calculateObjectStatistics\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:calculateOptimizedStatistics\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:calculateOptimizedStatistics\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:convertToOpenRegisterObjects\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:convertToOpenRegisterObjects\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:findItemsInSection\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:findItemsInSection\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:getAmefSchemaIdForType\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:getAmefSchemaIdForType\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:getVoorzieningenConfig\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:getVoorzieningenConfig\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:initializeCache\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:initializeCache\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:isOperationInProgress\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:isOperationInProgress\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:logMemoryUsage\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:logMemoryUsage\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:saveObjectsToDatabase\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:saveObjectsToDatabase\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:transformArchiMateXmlToObjectsBatch\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:transformArchiMateXmlToObjectsBatch\\(\\) is unused\\.$#" count: 1 path: lib/Service/ArchiMateService.php @@ -361,17 +361,17 @@ parameters: path: lib/Service/ArchiMateService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:\\$lastSaveTimingBreakdown is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:\\$lastSaveTimingBreakdown is never read, only written\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:\\$rootFolder is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:\\$rootFolder is never read, only written\\.$#" count: 1 path: lib/Service/ArchiMateService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ArchiMateService\\:\\:\\$userSession is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ArchiMateService\\:\\:\\$userSession is never read, only written\\.$#" count: 1 path: lib/Service/ArchiMateService.php @@ -401,12 +401,12 @@ parameters: path: lib/Service/ArchiMateService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ContactpersoonService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ContactpersoonService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/ContactpersoonService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ContactpersoonService\\:\\:\\$groupHandler is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ContactpersoonService\\:\\:\\$groupHandler is never read, only written\\.$#" count: 1 path: lib/Service/ContactpersoonService.php @@ -431,17 +431,17 @@ parameters: path: lib/Service/ModuleComplianceService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\OrganisatieService\\:\\:getActiveOrganisationUuid\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\OrganisatieService\\:\\:getActiveOrganisationUuid\\(\\) is unused\\.$#" count: 1 path: lib/Service/OrganisatieService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\OrganisatieService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\OrganisatieService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/OrganisatieService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\OrganisatieService\\:\\:\\$organizationHandler is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\OrganisatieService\\:\\:\\$organizationHandler is never read, only written\\.$#" count: 1 path: lib/Service/OrganisatieService.php @@ -451,12 +451,12 @@ parameters: path: lib/Service/OrganizationSyncService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\OrganizationSyncService\\:\\:jsonContains\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\OrganizationSyncService\\:\\:jsonContains\\(\\) is unused\\.$#" count: 1 path: lib/Service/OrganizationSyncService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\OrganizationSyncService\\:\\:jsonExtract\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\OrganizationSyncService\\:\\:jsonExtract\\(\\) is unused\\.$#" count: 1 path: lib/Service/OrganizationSyncService.php @@ -491,7 +491,7 @@ parameters: path: lib/Service/SettingsService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\SettingsService\\:\\:\\$request is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\SettingsService\\:\\:\\$request is never read, only written\\.$#" count: 1 path: lib/Service/SettingsService.php @@ -516,119 +516,119 @@ parameters: path: lib/Service/SettingsService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogue\\\\ContactPersonHandler\\:\\:addUserToGroup\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\Stackiq\\\\ContactPersonHandler\\:\\:addUserToGroup\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogue\\\\ContactPersonHandler\\:\\:ensureUniqueUsername\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\Stackiq\\\\ContactPersonHandler\\:\\:ensureUniqueUsername\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogue\\\\ContactPersonHandler\\:\\:getAllowedRoleGroups\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\Stackiq\\\\ContactPersonHandler\\:\\:getAllowedRoleGroups\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogue\\\\ContactPersonHandler\\:\\:getOrganizationGroup\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\Stackiq\\\\ContactPersonHandler\\:\\:getOrganizationGroup\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Offset 'organization' on array\\{username\\: string\\} on left side of \\?\\? does not exist\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Offset 'organisation' on array\\{username\\: string\\} on left side of \\?\\? does not exist\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Offset 'rollen' on array\\{username\\: mixed\\} on left side of \\?\\? does not exist\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogue\\\\ContactPersonHandler\\:\\:\\$_config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\Stackiq\\\\ContactPersonHandler\\:\\:\\$_config is never read, only written\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Result of \\|\\| is always true\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Strict comparison using \\=\\=\\= between OCP\\\\IUser\\|null and false will always evaluate to false\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Strict comparison using \\=\\=\\= between true and false will always evaluate to false\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Variable \\$currentRollen in empty\\(\\) always exists and is always falsy\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Variable \\$username on left side of \\?\\? always exists and is not nullable\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/ContactPersonHandler.php + path: lib/Service/Stackiq/ContactPersonHandler.php - message: "#^Strict comparison using \\=\\=\\= between 0\\|1\\|false and true will always evaluate to false\\.$#" count: 1 - path: lib/Service/SoftwareCatalogue/GroupHandler.php + path: lib/Service/Stackiq/GroupHandler.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogueService\\:\\:activateContactpersonenForOrganization\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\StackiqService\\:\\:activateContactpersonenForOrganization\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogueService.php + path: lib/Service/StackiqService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogueService\\:\\:activateUsersForOrganization\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\StackiqService\\:\\:activateUsersForOrganization\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogueService.php + path: lib/Service/StackiqService.php - - message: "#^Method OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogueService\\:\\:ensureContactPersonInOrganization\\(\\) is unused\\.$#" + message: "#^Method OCA\\\\Stackiq\\\\Service\\\\StackiqService\\:\\:ensureContactPersonInOrganization\\(\\) is unused\\.$#" count: 1 - path: lib/Service/SoftwareCatalogueService.php + path: lib/Service/StackiqService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogueService\\:\\:\\$_organizationHandler is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\StackiqService\\:\\:\\$_organizationHandler is never read, only written\\.$#" count: 1 - path: lib/Service/SoftwareCatalogueService.php + path: lib/Service/StackiqService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\SoftwareCatalogueService\\:\\:\\$appName is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\StackiqService\\:\\:\\$appName is never read, only written\\.$#" count: 1 - path: lib/Service/SoftwareCatalogueService.php + path: lib/Service/StackiqService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\SymfonyEmailService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\SymfonyEmailService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/SymfonyEmailService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Service\\\\ViewService\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Service\\\\ViewService\\:\\:\\$config is never read, only written\\.$#" count: 1 path: lib/Service/ViewService.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Settings\\\\SoftwareCatalogAdmin\\:\\:\\$config is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Settings\\\\StackiqAdmin\\:\\:\\$config is never read, only written\\.$#" count: 1 - path: lib/Settings/SoftwareCatalogAdmin.php + path: lib/Settings/StackiqAdmin.php - - message: "#^Property OCA\\\\SoftwareCatalog\\\\Settings\\\\SoftwareCatalogAdmin\\:\\:\\$l10n is never read, only written\\.$#" + message: "#^Property OCA\\\\Stackiq\\\\Settings\\\\StackiqAdmin\\:\\:\\$l10n is never read, only written\\.$#" count: 1 - path: lib/Settings/SoftwareCatalogAdmin.php + path: lib/Settings/StackiqAdmin.php - message: "#^Dead catch \\- Exception is never thrown in the try block\\.$#" diff --git a/src/App.vue b/src/App.vue index 0ac53357..c57079ee 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,7 +2,7 @@ @@ -127,7 +127,7 @@ - {{ t('softwarecatalog', 'Manage Groups') }} + {{ t('stackiq', 'Manage Groups') }} @@ -141,7 +141,7 @@ - {{ t('softwarecatalog', 'Disable User') }} + {{ t('stackiq', 'Disable User') }} @@ -155,7 +155,7 @@ - {{ t('softwarecatalog', 'Enable User') }} + {{ t('stackiq', 'Enable User') }} @@ -599,7 +599,7 @@ export default { if (contactIndex === -1) { showError( this.t( - 'softwarecatalog', + 'stackiq', 'Contactpersoon not found in organisation data', ), ) @@ -614,7 +614,7 @@ export default { console.error('Contactpersoon is not an object:', contactObject) showError( this.t( - 'softwarecatalog', + 'stackiq', 'Invalid contact person data structure', ), ) @@ -673,13 +673,13 @@ export default { await this.refreshUserData() showSuccess( - this.t('softwarecatalog', 'User account created successfully'), + this.t('stackiq', 'User account created successfully'), ) } catch (error) { console.error('Error in convertToUser:', error) showError( this.t( - 'softwarecatalog', + 'stackiq', 'Failed to create user account: {error}', { error: error.message, @@ -777,13 +777,13 @@ export default { async disableUser(contactpersoon) { try { await this.organisatieStore.disableUser(contactpersoon.id) - showSuccess(this.t('softwarecatalog', 'User disabled successfully')) + showSuccess(this.t('stackiq', 'User disabled successfully')) // Update the local contactpersoon data to reflect disabled status this.updateContactpersoonStatus(contactpersoon.id, true) } catch (error) { showError( - this.t('softwarecatalog', 'Failed to disable user: {error}', { + this.t('stackiq', 'Failed to disable user: {error}', { error: error.message, }), ) @@ -799,13 +799,13 @@ export default { async enableUser(contactpersoon) { try { await this.organisatieStore.enableUser(contactpersoon.id) - showSuccess(this.t('softwarecatalog', 'User enabled successfully')) + showSuccess(this.t('stackiq', 'User enabled successfully')) // Update the local contactpersoon data to reflect enabled status this.updateContactpersoonStatus(contactpersoon.id, false) } catch (error) { showError( - this.t('softwarecatalog', 'Failed to enable user: {error}', { + this.t('stackiq', 'Failed to enable user: {error}', { error: error.message, }), ) diff --git a/src/components/PaginationComponent.vue b/src/components/PaginationComponent.vue index a63bc924..7bc20e5c 100644 --- a/src/components/PaginationComponent.vue +++ b/src/components/PaginationComponent.vue @@ -4,7 +4,7 @@
{{ - t('softwarecatalog', 'Page {current} of {total}', { + t('stackiq', 'Page {current} of {total}', { current: currentPage, total: totalPages, }) @@ -16,14 +16,14 @@
- {{ t('softwarecatalog', 'First') }} + {{ t('stackiq', 'First') }} - {{ t('softwarecatalog', 'Previous') }} + {{ t('stackiq', 'Previous') }} @@ -50,21 +50,21 @@ - {{ t('softwarecatalog', 'Next') }} + {{ t('stackiq', 'Next') }} - {{ t('softwarecatalog', 'Last') }} + {{ t('stackiq', 'Last') }}
diff --git a/src/components/cards/OrganisatieCard.vue b/src/components/cards/OrganisatieCard.vue index 9dd9a61a..842c9255 100644 --- a/src/components/cards/OrganisatieCard.vue +++ b/src/components/cards/OrganisatieCard.vue @@ -1,8 +1,8 @@ /** * OrganisatieCard.vue * Custom card component for displaying organisatie objects -* @category Components * @package softwarecatalog * @author Ruben Linde * @copyright +* @category Components * @package stackiq * @author Ruben Linde * @copyright 2024 * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version 1.0.0 * -@link https://github.com/opencatalogi/softwarecatalog */ +@link https://github.com/ConductionNL/stackiq */ @@ -256,13 +256,13 @@ export default { this.sourceName = obj.name || obj.name - || t('softwarecatalog', 'Unknown organisation') + || t('stackiq', 'Unknown organisation') this.status = obj.status || '' this.mergedInto = obj.mergedInto || '' } catch (e) { // Non-fatal — the panel still renders merge controls with an // empty source name rather than failing the whole detail page. - this.sourceName = t('softwarecatalog', 'Unknown organisation') + this.sourceName = t('stackiq', 'Unknown organisation') } finally { this.loading = false } @@ -311,7 +311,7 @@ export default { })) } catch (e) { this.error = t( - 'softwarecatalog', + 'stackiq', 'Could not load target organisations.', ) } finally { @@ -347,7 +347,7 @@ export default { this.showConfirm = true } catch (e) { this.error = - e.message || t('softwarecatalog', 'Could not preview the merge.') + e.message || t('stackiq', 'Could not preview the merge.') } finally { this.previewing = false } @@ -375,12 +375,12 @@ export default { this.status = 'merged' this.mergedInto = String(this.selectedTarget.value) showSuccess( - t('softwarecatalog', 'Organisation successfully merged.'), + t('stackiq', 'Organisation successfully merged.'), ) } catch (e) { this.confirmError = e.message - || t('softwarecatalog', 'Could not merge the organisations.') + || t('stackiq', 'Could not merge the organisations.') } finally { this.busy = false } diff --git a/src/components/organisations/OrganisationSwitcher.vue b/src/components/organisations/OrganisationSwitcher.vue index 2e8cd988..1c3a21ea 100644 --- a/src/components/organisations/OrganisationSwitcher.vue +++ b/src/components/organisations/OrganisationSwitcher.vue @@ -51,7 +51,7 @@ - {{ t('softwarecatalog', 'Manage members') }} + {{ t('stackiq', 'Manage members') }} @@ -28,7 +28,7 @@ + :name="t('stackiq', 'Loading reviews')" /> - {{ t('softwarecatalog', 'Revoke access') }} + {{ t('stackiq', 'Revoke access') }}
  • - {{ t('softwarecatalog', 'No members yet.') }} + {{ t('stackiq', 'No members yet.') }}
  • diff --git a/src/modals/OrganisationModal.vue b/src/modals/OrganisationModal.vue index 9f9d9b65..5ad4d680 100644 --- a/src/modals/OrganisationModal.vue +++ b/src/modals/OrganisationModal.vue @@ -14,17 +14,17 @@
    @@ -32,9 +32,9 @@ @@ -57,9 +57,9 @@
    @@ -67,17 +67,17 @@
    + :label="t('stackiq', 'Phone')" + :placeholder="t('stackiq', '+31 20 123 4567')" />
    @@ -86,8 +86,8 @@
    + :label="t('stackiq', 'CBS')" + :placeholder="t('stackiq', 'CBS number')" />
    @@ -98,7 +98,7 @@

    {{ t( - 'softwarecatalog', + 'stackiq', 'This dialog will close automatically in {seconds} seconds...', { seconds: countdown }, ) @@ -108,7 +108,7 @@

    - {{ t('softwarecatalog', 'Cancel') }} + {{ t('stackiq', 'Cancel') }} {{ isEditMode - ? t('softwarecatalog', 'Update Organisation') - : t('softwarecatalog', 'Create Organisation') + ? t('stackiq', 'Update Organisation') + : t('stackiq', 'Create Organisation') }}
    @@ -215,11 +215,11 @@ export default { */ modalTitle() { if (this.isEditMode) { - return this.t('softwarecatalog', 'Edit Organisation') + return this.t('stackiq', 'Edit Organisation') } else if (this.isCopyMode) { - return this.t('softwarecatalog', 'Copy Organisation') + return this.t('stackiq', 'Copy Organisation') } - return this.t('softwarecatalog', 'Create Organisation') + return this.t('stackiq', 'Create Organisation') }, isFormValid() { @@ -385,7 +385,7 @@ export default { async saveOrganisation() { if (!this.isFormValid) { showError( - this.t('softwarecatalog', 'Please fill in all required fields'), + this.t('stackiq', 'Please fill in all required fields'), ) return } @@ -404,7 +404,7 @@ export default { if (Object.keys(changes).length === 0) { // No changes detected this.successMessage = this.t( - 'softwarecatalog', + 'stackiq', 'No changes to save', ) this.success = true @@ -421,7 +421,7 @@ export default { changes, ) this.successMessage = this.t( - 'softwarecatalog', + 'stackiq', 'Organisation updated successfully', ) @@ -437,7 +437,7 @@ export default { schema: schemaConfig.schema, }) this.successMessage = this.t( - 'softwarecatalog', + 'stackiq', 'Organisation created successfully', ) @@ -466,7 +466,7 @@ export default { console.error('Error saving organisation:', error) showError( this.t( - 'softwarecatalog', + 'stackiq', 'Failed to save organisation: {error}', { error: error.message }, ), diff --git a/src/modals/SaveFacetViewModal.vue b/src/modals/SaveFacetViewModal.vue index 1b1fcb32..a4fff72d 100644 --- a/src/modals/SaveFacetViewModal.vue +++ b/src/modals/SaveFacetViewModal.vue @@ -13,14 +13,14 @@ free-text search, if any) on the module/dienst index pages, then emits - {{ t('softwarecatalog', 'Save view') }} + {{ t('stackiq', 'Save view') }} diff --git a/src/modals/SubmitReviewModal.vue b/src/modals/SubmitReviewModal.vue index 3f99b702..12150981 100644 --- a/src/modals/SubmitReviewModal.vue +++ b/src/modals/SubmitReviewModal.vue @@ -15,14 +15,14 @@ - {{ t('softwarecatalog', 'Submit review') }} + {{ t('stackiq', 'Submit review') }} @@ -229,7 +229,7 @@ export default { await apiRequest('reviews', { method: 'POST', body }) showSuccess( t( - 'softwarecatalog', + 'stackiq', 'Thank you — your review was submitted for moderation', ), ) @@ -238,7 +238,7 @@ export default { } catch (submitError) { this.error = submitError.message showError( - t('softwarecatalog', 'Could not submit your review') + t('stackiq', 'Could not submit your review') + ': ' + submitError.message, ) diff --git a/src/modals/object/ChangeOrganisatieStatusDialog.vue b/src/modals/object/ChangeOrganisatieStatusDialog.vue index 56c546d5..9fb4020a 100644 --- a/src/modals/object/ChangeOrganisatieStatusDialog.vue +++ b/src/modals/object/ChangeOrganisatieStatusDialog.vue @@ -1,8 +1,8 @@ /** * ChangeOrganisatieStatusDialog.vue * Dialog for changing organisatie status with -confirmation * @category Components * @package softwarecatalog * @author Ruben Linde +confirmation * @category Components * @package stackiq * @author Ruben Linde * @copyright 2024 * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * @version 1.0.0 * -@link https://github.com/opencatalogi/softwarecatalog */ +@link https://github.com/ConductionNL/stackiq */