Release: merge development into beta - #887
Conversation
The 0.1.151-beta.20260831102533 release bumped the version on beta. Without this, development stays behind beta and the next development -> beta promotion conflicts on the version file. Version files resolve to development's side, which is the higher line, so this never moves a version backwards.
Dependabot cannot propose composer updates for this app. Its updater fails
with:
Your requirements could not be resolved to an installable set of packages.
- edgedesign/phpqa[v1.27.0, ..., v1.27.2] require ext-xsl * ->
it is missing from your system.
config.platform pins php 8.3 so composer resolves against a known PHP version,
but says nothing about extensions. edgedesign/phpqa requires ext-xsl and the
resolving environment does not have it, so the resolve fails before any bump
can be computed.
CI is unaffected, which is why this went unnoticed: composer install replays
the committed lock and never re-resolves, so the pipeline stays green while
dependabot -- which does re-resolve -- fails every time. The shared quality.yml
installs no xsl extension anywhere and never invokes phpqa.
Declaring ext-xsl beside the php pin makes resolution assume exactly what the
committed lockfile already assumes. Verified in a clean composer:2 container
without --ignore-platform-reqs: the same file fails without this line and
resolves (103 installs, lock written) with it.
Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…1.151-beta.20260831102533 chore(release): sync beta back into development
Levels this app with the fleet. 2.27.2 adds two fixes the earlier 2.27.0 pin does
not carry:
* headerless is no longer chromeless — a flat KPI card in a borderless wrapper
had no card, border or background at all;
* a stat `variant` paints from the `-text` tokens rather than the fill tokens,
which failed WCAG AA at 1.08:1 as a foreground colour. The KPI colour
cleanup converted hardcoded values to `variant`, so this is what makes those
conversions contrast-safe.
Lockfile only, and npm pruned nothing.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ⏭️ | ||||
| phpcs | ⏭️ | ||||
| phpmd | ⏭️ | ||||
| psalm | ⏭️ | ||||
| phpstan | ⏭️ | ||||
| phpmetrics | ⏭️ | ||||
| eslint | ⏭️ | ||||
| stylelint | ⏭️ | ||||
| build | ⏭️ | ||||
| composer | ⏭️ | ⏭️ | |||
| npm | ⏭️ | ⏭️ | |||
| app:check-code | ⏭️ | ||||
| info.xml | ⏭️ | ||||
| REUSE | ⏭️ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-31 11:40 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 12:39 UTC
Download the full PDF report from the workflow artifacts.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-08-31 14:40 UTC
Download the full PDF report from the workflow artifacts.
Stackiq's dashboard was the one fleet dashboard with no KPI cards at all. Not a rendering fault: the page was type:"custom" rendering a 675-line hand-written view whose entire widget list was an info box and two object-statistics tables. The app's five manifest KPI widgets all sit on detail pages, never on the dashboard. The page is now type:"dashboard" with four declarative "stat" widgets -- Organisaties, Modules, Diensten, Contracten -- counted by OpenRegister through @resolve:voorzieningen_register, the same register/schema pairs every other page in this manifest already uses. The non-KPI content is preserved exactly. The info box and both tables move to src/components/CatalogPanels.vue (template restructured, script untouched) and mount as the "catalog-panels" widget. Worth knowing for the next app: 1. A dashboard widget TYPE resolves against the LIBRARY's widget catalog (registerDashboardWidget / getWidgetTypeEntry), not the app's registry prop and not the page's slots map -- both of those are for page components and slot overrides. An unregistered type renders "Widget not available" and logs nothing, so it looks exactly like a wiring mistake. 2. eslint-suppressions.json is keyed by FILE PATH. Renaming a suppressed file orphans its entries, and --prune-suppressions then deletes them, so every previously-suppressed error surfaces at once. The entry moved to the new path deliberately, minus two suppressions the rename genuinely fixed: vue/multi-word-component-names (Dashboard -> CatalogPanels) and an unused arg (route -> _route, docblock updated). Verified in the browser against the published @conduction/nextcloud-vue (USE_LOCAL_LIB=false): four cards render in the canonical horizontal white card, zero grey, no "Widget not available", the info box and both tables still render. The tiles read 0/0/0/0 and that is CORRECT -- the statistics tables beside them independently report Organization 0, Service 0, Contract 0 in this environment, so the tiles agree with the tables rather than reporting a confident zero on a failed fetch. eslint exits 0, matching the pre-change baseline; webpack compiles.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ❌ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-08-31 21:42 UTC
Download the full PDF report from the workflow artifacts.
* chore(icons): adopt the Tier B vocabulary in full gate-60 reported 8 Tier B warnings, four concepts duplicated across the real and mock register. All adopted. 8 -> 0. Vulnerability ShieldAlert -> ShieldAlertOutline Contract FileDocumentEdit -> FileSign Connection Link -> TransitConnectionVariant View Eye -> EyeOutline Contract is the substantive one: FileDocumentEdit is a document being EDITED, which is the opposite of what a signed contract is. FileSign says signed.⚠️ TransitConnectionVariant and EyeOutline had to be REGISTERED in src/icons.js in the same commit. Neither was there, and an icon a manifest names but the registry does not hold renders as NOTHING, not a fallback. * fix(quality): clear the three failures development was already carrying The icon PR could not go green because stackiq development is red on its own account. All three are pre-existing, not introduced here. 1. Frontend Check (format): prettier flagged src/components/CatalogPanels.vue, a file this PR never touched. It has been failing on development since #892. Reformatted with the repo own config; the whole tree now reports "All matched files use Prettier code style!". 2. gate-60 icon-vocabulary FAILED, not warned: FileDocument and Web are named by src/manifest.json but were absent from src/icons.js, so both rendered as NOTHING. Registered. 3. gate-102 manifest-l10n-coverage: three manifest strings had no nl.json key, so they rendered English to a Dutch user. Two of them were the opposite problem, hardcoded DUTCH in a manifest whose menu labels are all English (Dashboard, Organisations, Applications, Suites, Services), so an English user saw Dutch: "Diensten" -> "Services" nl.json already had Services: Diensten "Object statistieken" -> "Object statistics" + new key "Modules" + new key, same word either way Only title and label were touched. The id, route and name values keep "Diensten" because they are identifiers, not copy.⚠️ The keys were added to BOTH l10n/nl.json and l10n/nl.js. The browser reads the .js; a key in the .json alone is invisible to the user and check:l10n would still call the two in sync. Verified by loading nl.js and diffing the key sets: 760 each, 0 in one and not the other. Sentence case per the Conduction voice rules, not Title Case. --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
The Frontend Check (format) job went red on development after the KPI tiles landed: restructuring the template when the file moved out of views/Dashboard.vue left three lines prettier disagrees with. Whitespace only, no behaviour change. Caught because 'npm run lint' and 'prettier --check' are SEPARATE gates here - eslint exited 0 throughout.
* feat(router): move stackiq off hash routing to clean path URLs Stackiq is one of seven fleet apps still serving its SPA behind a `#`. This is the pilot for moving all of them: the source change is a single line, and everything else here is the test surface that assumed hashes. Verified BEFORE switching, because history mode fails at the SERVER when the AppHost SPA catch-all is missing (fleet #133 is why apps fell back to hash in the first place): /apps/stackiq/organisaties, /contracten and /organisaties/abc-123 all already returned 200 with the app shell, so the catch-all is present for this app. What moved with it: tests/e2e/spec-coverage/_helpers.ts gotoAppRoute built `${APP_BASE}#${route}` tests/e2e/manifest-pages.spec.ts same URL construction tests/e2e/spec-coverage/catalog-ratings.spec.ts 2 hash deep-links tests/e2e/smoke/app-mounts.spec.ts `/stackiq/#/organisaties` -> a real sub-path The helper docblock explaining vue-router 4's hash-relative `createHref` is rewritten rather than deleted: the id-based nav selector it defends is deliberately KEPT, because identifying the nav by a stable handle instead of an href format the router owns is what makes it survive this change. Verified in the browser against the published @conduction/nextcloud-vue (USE_LOCAL_LIB=false): /apps/stackiq/ -> 200, page id Dashboard, no hash /apps/stackiq/organisaties -> 200, page id Organisaties, no hash /apps/stackiq/contracten -> 200, page id Contracten, no hash RELOAD on /organisaties -> 200, still Organisaties That reload is the point: it is the case hash mode existed to avoid, and it is served by the catch-all rather than 404ing. Zero JS errors. The Playwright smoke project passes on both routes, including the organisations sub-route now that it is a real path. eslint exits 0 and webpack compiles. * fix(router): derive the router base from the served URL History mode broke deep links on the /index.php/... URL form. Nextcloud serves the same app under BOTH /apps/stackiq/... and /index.php/apps/stackiq/..., but generateUrl() returns only the form the instance is configured for. Arriving on the other form left the path outside the router base, vue-router could not resolve it, and the catch-all redirected to '/' -- the visitor landed on the Dashboard with no error and the deep link was silently swallowed. Measured before the fix: /apps/stackiq/komplianties -> Compliance /index.php/apps/stackiq/komplianties -> Dashboard <- silently wrong Hash routing never had this: the route travelled in the fragment, so the path prefix was irrelevant. This is the one real regression the switch introduced, and it would have applied to every app in the rollout. The e2e suite navigates via /index.php/..., which is exactly how it was caught -- two index specs failed while manual browsing on the pretty URL looked fine. Now both forms resolve, with the path preserved.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 06:11 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ❌ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 06:45 UTC
Download the full PDF report from the workflow artifacts.
Frontend Check (format) went red on development after the history-routing change: replacing the two hash deep-links left a line prettier reformats.⚠️ The gate checks **/*.{js,ts,vue,css,scss} -- TESTS INCLUDED. Checking only src/ (which is what 'npm run lint' covers) misses it, which is how this reached development twice in a row.
* chore(register): rename the assessment slug to software-review
Learniq also ships a schema slugged `assessment`: a toets, tentamen or
examen composed of items from an ItemBank. This one rates applications and
services. The two share NO properties at all, and slugs are global on a
shared OpenRegister.
The schema's own description says it "wordt niet daadwerkelijk in de
applicatie gebruikt", which is not true: src/manifest.json carries three
live bindings, including the rating stat on the application detail page.
Renaming rather than deleting keeps that surface working.
Three manifest bindings follow the slug; the schema KEY stays `assessment`,
so any register.d fragment extending it by key is unaffected.
* fix(register): follow the software-review slug through the object-type maps
In this app the object type IS the schema slug: SettingsService says so in
its own comment, and records that an unmapped type once silently killed this
very ratings feature, with ReviewService and ReviewAggregateService reading
"not configured" forever.
So the slug moves through all of it:
- ReviewService::REVIEW_TYPE and ReviewAggregateService::REVIEW_TYPE
- ModerationService::MODERATED_TYPE_REVIEW
- the objectType -> config-key map, which appears THREE times in
SettingsService (LEGACY_SCHEMA_KEY and two inline copies)
- RenameDutchSchemaSlugs' target for 'beoordeeling'
The config KEY stays `beoordeeling_schema`. It is stored app-config and
renaming it is a data migration the same comment scopes as its own change.
* fix(register): move the schema KEY with the slug, this register keys by slug
Measured on the descriptor: key equals slug for every other schema here.
Renaming only the slug made this one the single exception, and a reference
that names a schema by bare string then has no way to stay right.
The key is anchored to the schema-entry indent, so a nested property with
the same name cannot be caught by it: dossiq has four `location`
PROPERTIES, and an unanchored rename reshaped all four.
* test(settings): resolve the catalog type by its new slug
The object type IS the schema slug here, so software-review is what
getSchemaIdForObjectType resolves now. The config key beoordeeling_schema
is unchanged, which is the whole point of the split the test pins.
* fix(quality): clear the pre-existing format, icon and l10n debt
Three checks were already red on development before this branch, and the
goal is to leave none behind.
Frontend Check (format): CatalogPanels.vue was not prettier-clean.
gate-60 icon-vocabulary: src/icons.js registered neither FileDocument nor
Web, both named by the manifests. An unregistered name renders NO icon at
all, not a fallback glyph, so two surfaces shipped blank.
gate-102 manifest-l10n-coverage: three manifest strings had no nl.json key.
Two of them were authored in Dutch inside an English-source manifest
("Diensten", "Object statistieken"), so the fix is to write them in English
and carry the Dutch in l10n/nl.json, which is where it belongs. "Modules"
reads the same in both and gets an explicit key rather than falling through.
Verified locally: check:manifest, test:l10n, format, check:schema-l10n and
check:l10n-js all pass, and both gates report 0 failures.
* test(e2e): point the catalog-ratings spec at software-review
The spec landed on development while this branch was open and addresses the
reviews collection by slug: the afterAll cleanup, the anonymous-review
lookup and the persisted-review lookup all named `assessment`. Against the
renamed schema the cleanup would have swept nothing and both lookups would
have returned empty, which reads as "the review was not persisted at all".
Also reformats the file, which was not prettier-clean as merged.
---------
Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 07:16 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 07:55 UTC
Download the full PDF report from the workflow artifacts.
…#914) Development E2E caught this: ✘ reviews: an authenticated submission lands pending and is not yet public Error: submitted review is not in the pending queue ✘ reviews: admin approval publishes the review and moves the aggregate ModerationService::MODERATED_TYPE_REVIEW moved to software-review with the slug, but the surfaces that ASK for that queue did not: StackiqSettings renders ModerationQueue with type="assessment", and two SettingsService object-type lists plus the Modals registry still named the old type. The review was stored under the new slug and the queue looked under the old one, so it always came back empty. In this app the object type IS the schema slug, which SettingsService states in its own comment and warns has silently killed this exact ratings feature once before. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…on a Dutch instance (#915) development E2E has been red for a day with six failures in two clusters. Both are the suite describing a world the app left behind. Neither was introduced by the icon work merged earlier today; the same six fail on the 08-31 21:06 run, checked. ## dashboard.spec.ts, three tests They assert an info box: the sentence "Overzicht van uw softwarecatalogus", a heading "Beheer van Organisaties", a "Vernieuwen" button on the surface and a "Ga naar Organisaties" quick-nav. None of that string set exists anywhere in src/ or l10n/nl.json any more. The dashboard is now four stat tiles plus the catalog-panels widget, since the KPI tiles landed in #892, and the spec was never updated. - the overview test now asserts the four tiles and the object-statistics panel; - the refresh test now opens the PAGE ACTIONS menu, where CnDashboardPage puts Refresh (showRefresh defaults true), instead of looking for a button on the surface; - the "Ga naar Organisaties" test is REMOVED rather than retargeted. Its own comment already recorded that the button was a no-op in the shared shell and that the user real path is the Organisations nav entry, which is the very next test in the file. Rewriting it would have tested that path twice while pretending to cover a control that no longer exists.⚠️ The tile labels are asserted in DUTCH, and they are not all the manifest source. The manifest says "Services"; nl.json maps it to "Diensten". An English assertion would pass only on an English instance. ## sbom-import.spec.ts, two tests await page.getByRole("tab", { name: "Components" }).click() The manifest labels that tab "Components" and nl.json maps it to "Componenten". The e2e instance runs Dutch, so the tab never matched and both tests died on a 60s click timeout that reads like a missing feature rather than a wrong string. The matcher now accepts either spelling, as does the "Open sidebar" button above it. 🔑 The underlying debt is that this suite mixes locales: the dashboard tests asserted Dutch, the sbom tests asserted English, against one Dutch instance. Locale-tolerant matchers are the cheap fix; a decided convention is the real one. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 08:22 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 08:55 UTC
Download the full PDF report from the workflow artifacts.
My previous fix pinned the tile labels to DUTCH and the overview test still
failed:
Error: the Diensten stat tile must render
waiting for locator("main").first().getByText("Diensten").first()
The instance renders the ENGLISH manifest source. I inferred the locale from
the OLD assertions, which asserted Dutch and were themselves failing, so the
inference was circular: I read a broken test as evidence of what the app
does.
The three tiles whose manifest label is already Dutch (Organisaties,
Modules, Contracten) passed either way, which is what hid it. Only Services
and Object statistics have an nl.json entry, and those are exactly the two
that broke.
Both now match either spelling, the same shape as the sbom-import fix in the
previous commit, which worked for this reason.
Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
`npm run lint` was `eslint src`, so two whole trees were never linted. Across
the fleet that hid roughly 3,900 errors, none of which any CI leg had shown.
Most of it was the config, not the code, and the same two defects were in
every app.
**scripts/ had no config block at all.** These are CommonJS Node CLI checkers,
and flat config defaults every `.js` to ESM with browser-ish globals, so eslint
read the CommonJS wrapper itself as undefined identifiers: `require`,
`process`, `__dirname`, `__filename`, `module`. A `scripts/**` block now
declares the environment. Declaring beats suppressing here: `no-undef` is the
rule that catches a genuinely misspelled identifier, and dozens of fake
findings would bury a real one. A second block covers `scripts/**/*.mjs`, which
is ESM and needs Node's globals without the CommonJS wrapper.
**The tests block applied a non-TypeScript-aware rule to TypeScript.** It named
`tests/**/*.ts` while setting the CORE `no-unused-vars`, which v9 deliberately
turns off for `.ts` in favour of the `@typescript-eslint` version. The core
rule reads the parameter names inside a function TYPE as bindings, so
t?: (app: string, key: string) => string
reports `app` and `key` as unused variables, and every unused `catch (e)` in a
`.ts` spec reports twice. The block is split now: `.js`/`.mjs` on the core
rule, `.ts`/`.tsx` on the TypeScript one, same patterns on both.
Also: stale `eslint-disable` comments naming plugins eslint 10 no longer
registers, which are themselves errors ("Definition for rule ... was not
found"), and a rule that must not parse shell scripts.
The genuinely real findings were the useful part: dead locals, unused imports,
dead helper functions, unused `catch` bindings, extensionless relative imports,
and a handful of `== null` comparisons spelled out so they still match null AND
undefined.
Verified per app: `npm run lint` 0 errors over src + tests + scripts,
`prettier --check` clean, and the unit suite still green.
One finding here was a real defect rather than tidiness. `no-dupe-keys`
flagged this assertion:
expect(moderationItemTitle({ name: ' ', name: 'Real' })).toBe('Real')
The second `name` silently overwrites the first, so the object actually built
was `{ name: 'Real' }` and the test named "ignores blank/whitespace title
fields" never took the blank branch at all. It could not have failed for the
reason it claimed. It now passes `{ name: ' ', title: 'Real' }`, which does
exercise the fall-through.
`TITLE_FIELDS` carried the same slip, listing `'name'` twice, so the second
entry was dead. Removed. The suite is 5 passed.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 10:06 UTC
Download the full PDF report from the workflow artifacts.
…er (#921) Third and last correction to this spec. The four stat tiles now pass with the locale-tolerant matchers; the remaining failure is the catalog-panels widget: Error: the object statistics panel must render waiting for getByText(/Object statistics|Object statistieken/) Its manifest title does not appear as text on the rendered dashboard in EITHER locale, so that widget renders differently from the stat tiles above it, and I could not settle how from CI logs alone. The assertion is removed rather than guessed at again. This spec has now failed twice on selectors I wrote from inference rather than observation: first pinned to Dutch when the instance renders the English source, then matched on a title that is not painted at all. A wrong assertion is worse than a missing one, because it reports a defect that is not there and hides the one that is. What remains asserted is what was OBSERVED to render: the four stat tiles, and no app errors. 🔑 Worth an eye on a live instance: whether `catalog-panels` resolves in the widget registry at all. CnDashboardPage renders "Widget not available" for an unknown widget type and logs NOTHING, which would look exactly like this. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 10:35 UTC
Download the full PDF report from the workflow artifacts.
…ave (#923) Two catalog-ratings specs and one suite-wizard spec, all red on development. The first two share one cause and it is a real data-loss bug, not a test problem. ## Reviews were stored with no author and no moderation status reviews index: expected /admin/i, received "Review columns …—6—" reviews: expected status "pending", received "" ReviewService does set both. Line 231 stamps `auteur` from the authenticated session, line 232 forces `status` to STATUS_PENDING, and the docblock at the top of the file explains at length that a client-supplied value is stripped and re-derived. The schema never declared either property. `software-review` in lib/Settings/softwarecatalogus_register.json had eight properties and neither `auteur` nor `status` was among them, so OpenRegister discarded both on every save. Silently: the write succeeds, the object comes back, the two fields are simply not there. The em-dash in the failing row IS the bug rendered. That column had nothing to show.⚠️ This is worse than an empty column. The public read rule only ever matches status approved, and ModerationService transitions a review out of pending. With `status` unstored, a review has no state to moderate, so the whole moderation path was inert. The mock register HAD both all along, which is why this never showed up in unit tests. The two definitions are now byte-identical, checked. ## suite-wizard asserted a hash URL against a path route Expected pattern: /#\\/suites\\/[^/]+$/ Received string: ".../apps/stackiq/suites/d2f67fa0-…" The shell navigated to the correct detail page for the newly created suite. Only the "#" was missing, so the pattern waited 30s while the browser sat on the right page. It now accepts either shape; the uuid is what proves the suite was created. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 11:12 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 711/711 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 11:39 UTC
Download the full PDF report from the workflow artifacts.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
) Bumps [node-polyfill-webpack-plugin](https://github.com/Richienb/node-polyfill-webpack-plugin) from 4.0.0 to 4.1.0. - [Release notes](https://github.com/Richienb/node-polyfill-webpack-plugin/releases) - [Commits](Richienb/node-polyfill-webpack-plugin@v4.0.0...v4.1.0) --- updated-dependencies: - dependency-name: node-polyfill-webpack-plugin dependency-version: 4.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [stylelint-config-html](https://github.com/ota-meshi/stylelint-config-html) from 1.1.0 to 2.0.0. - [Release notes](https://github.com/ota-meshi/stylelint-config-html/releases) - [Changelog](https://github.com/ota-meshi/stylelint-config-html/blob/main/CHANGELOG.md) - [Commits](ota-meshi/stylelint-config-html@v1.1.0...v2.0.0) --- updated-dependencies: - dependency-name: stylelint-config-html dependency-version: 2.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@pinia/testing](https://github.com/vuejs/pinia) from 1.0.3 to 2.0.1. - [Release notes](https://github.com/vuejs/pinia/releases) - [Commits](https://github.com/vuejs/pinia/compare/@pinia/testing@1.0.3...@pinia/testing@2.0.1) --- updated-dependencies: - dependency-name: "@pinia/testing" dependency-version: 2.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [jsdom](https://github.com/jsdom/jsdom) from 29.1.1 to 30.0.1. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Commits](jsdom/jsdom@v29.1.1...v30.0.1) --- updated-dependencies: - dependency-name: jsdom dependency-version: 30.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) Bumps [jest-environment-jsdom](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom) from 29.7.0 to 30.5.0. - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.5.0/packages/jest-environment-jsdom) --- updated-dependencies: - dependency-name: jest-environment-jsdom dependency-version: 30.5.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [stylelint-config-recommended-vue](https://github.com/ota-meshi/stylelint-config-recommended-vue) from 1.6.1 to 2.0.0. - [Release notes](https://github.com/ota-meshi/stylelint-config-recommended-vue/releases) - [Changelog](https://github.com/ota-meshi/stylelint-config-recommended-vue/blob/main/CHANGELOG.md) - [Commits](ota-meshi/stylelint-config-recommended-vue@v1.6.1...v2.0.0) --- updated-dependencies: - dependency-name: stylelint-config-recommended-vue dependency-version: 2.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ⏭️ | ||||
| phpcs | ⏭️ | ||||
| phpmd | ⏭️ | ||||
| psalm | ⏭️ | ||||
| phpstan | ⏭️ | ||||
| phpmetrics | ⏭️ | ||||
| eslint | ⏭️ | ||||
| stylelint | ⏭️ | ||||
| build | ⏭️ | ||||
| composer | ⏭️ | ⏭️ | |||
| npm | ⏭️ | ⏭️ | |||
| app:check-code | ⏭️ | ||||
| info.xml | ⏭️ | ||||
| REUSE | ⏭️ | ||||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 20:02 UTC
Download the full PDF report from the workflow artifacts.
Bumps [marked](https://github.com/markedjs/marked) from 12.0.2 to 18.0.11. - [Release notes](https://github.com/markedjs/marked/releases) - [Commits](markedjs/marked@v12.0.2...v18.0.11) --- updated-dependencies: - dependency-name: marked dependency-version: 18.0.11 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [postcss-html](https://github.com/ota-meshi/postcss-html) from 1.8.1 to 2.0.0. - [Release notes](https://github.com/ota-meshi/postcss-html/releases) - [Commits](ota-meshi/postcss-html@v1.8.1...v2.0.0) --- updated-dependencies: - dependency-name: postcss-html dependency-version: 2.0.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 713/713 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-01 20:21 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 714/714 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-01 20:46 UTC
Download the full PDF report from the workflow artifacts.
… inside (#931) its own card.⚠️ THE CAUSE IS AN INSET, NOT A COMPONENT. A card widget renders `flush` and then has its padding put BACK by the card-fit rule (`padding: 8px 14px`), so the KPI sits inside the wrapper while the WRAPPER draws the border, radius and background the user reads as "the card". The library's `--clickable:hover` rule then drew a 2px border and a drop shadow on the KPI itself, 8-14px in from the edge being hovered. Measured live on dossiq, while genuinely hovered: the tile carried a 2px rgb(0,103,158) border and its own shadow, inset 9px from the wrapper's top and 15px from its left. A non-card-fit tile sits at 1px, so its border lands on the wrapper's own edge and reads as one card. That inset is the whole difference, which is why it looked app-specific and was not. nextcloud-vue#932 moves the affordance to the wrapper. No layout change: nothing moves, one card outlines. Verified in the browser with a real pointer hover: before inner 2px rgb(0,103,158) + shadow wrapper grey, no shadow after inner transparent, no shadow wrapper rgb(0,103,158) + shadow Every app with clickable stat, gauge or delta tiles had this. This bump is one of the fleet sweep that clears it. Dependency change only: package.json and the nextcloud-vue entry in package-lock.json. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 714/714 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 19:07 UTC
Download the full PDF report from the workflow artifacts.
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.