Skip to content

Release: merge development into beta - #887

Open
github-actions[bot] wants to merge 27 commits into
betafrom
development
Open

Release: merge development into beta#887
github-actions[bot] wants to merge 27 commits into
betafrom
development

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

github-actions Bot and others added 4 commits August 31, 2026 10:27
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.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ a9568c6

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 314e19e

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>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 4272731

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.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 0e78ad0

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.

rubenvdlinde and others added 3 commits September 1, 2026 07:33
* 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.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 763bc3f

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.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 11e391b

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.

rubenvdlinde and others added 2 commits September 1, 2026 08:58
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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ cc7502d

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.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 8fc2890

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.

rubenvdlinde and others added 2 commits September 1, 2026 10:13
…#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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ b9cf05a

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.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 2591d0f

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.

rubenvdlinde and others added 2 commits September 1, 2026 11:28
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.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ fc61c75

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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 604dd77

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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ eae4001

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.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 8fd7064

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.

github-actions Bot and others added 7 commits September 1, 2026 21:57
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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 3672dfa

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.

dependabot Bot added 2 commits September 1, 2026 22:17
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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 8dae3ef

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.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 4d763b3

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>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/stackiq @ 92c32b8

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant