Skip to content

Release: merge development into beta - #1432

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

Release: merge development into beta#1432
github-actions[bot] wants to merge 16 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 3 commits August 31, 2026 13:30
The 0.2.10-beta.20260831132904 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.
….2.10-beta.20260831132904

chore(release): sync beta back into development
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/shillinq @ 8542a6f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-31 14:53 UTC

Download the full PDF report from the workflow artifacts.

Dependabot cannot update these packages. Its npm updater fails with:

  npm error code EOVERRIDE
  npm error Override for <pkg> conflicts with direct dependency

The package is listed BOTH as a direct dependency and as a literal overrides
entry pinned to the same range. Dependabot bumps the direct dependency and
does not move the override, npm rejects the mismatched pair, and the update
is abandoned -- so these packages can never be updated, security advisories
included.

npm's self-reference is the idiom for exactly this: $<name> tells the
override to follow whatever the direct dependency resolves to, instead of a
range that has to be kept in lockstep by hand. This repo already uses it (see
the vue entry under @vue/test-utils).

Transitive consumers still get pinned to one version -- the direct
dependency's -- which is what the override was there to do. What changes is
that the pin tracks the dependency instead of duplicating it.

Verified in a clean container: bumping the direct dependency with the literal
override reproduces the EOVERRIDE above; with the self-reference the same
bump resolves.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ 28c8b79

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-31 17:06 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/shillinq @ b303418

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-31 20:59 UTC

Download the full PDF report from the workflow artifacts.

… otherwise (#1436)

gate-60 reported 19 Tier B warnings. Eighteen adopted, one refused. 19 -> 1.

Adopted:
  11x Documents tab   FileDocumentOutline -> FileDocumentMultipleOutline
      cancel action   Cancel              -> CloseCircleOutline
      Document (file) FileCertificateOutline -> FileDocumentOutline
      Subsidy         CashMultiple        -> HandHeartOutline
      Invoice         FileDocumentOutline -> ReceiptTextOutline
      Employee        AccountTie          -> AccountTieOutline
      Payroll         CashMultiple        -> CashSync
      Order           FileDocumentMultipleOutline -> ClipboardListOutline

REFUSED: Location, which the gate wants on MapMarkerOutline. Its own
description settles it:

  "Physical or virtual storage location in the warehouse hierarchy
   (warehouse -> zone -> bin -> in-transit)."

These are warehouse bins, not map pins. Warehouse is the more truthful
glyph and it stays, as a non-blocking WARN.

Two near-misses worth naming, because both would have been silent:
  - 40-eu-fondsen.json has TWO FileCertificateOutline entries. Only the one
    labelled "Document" was flagged; the other is "Supporting documents",
    where a certificate icon is right. Changed by line, not by value.
  - shillinq_register.json has TWO CashMultiple entries. The schema KEY is
    Subsidie and only its title is "Subsidy", so a match on value or on the
    English name would have hit the wrong schema. Located via the schema
    block instead.

Every icon introduced here is already registered in src/icons.js, checked
explicitly: an icon a manifest names but the registry does not hold renders
as NOTHING, not a fallback.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ 9cfcbad

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-31 21:58 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 3 commits September 1, 2026 06:56
…ent (#1438)

* chore(register): retire the example schema, rename Project to engagement

Two slug collisions in one register.

`example` was the untouched scaffold placeholder, still carrying
"replace with your app's actual schemas" inside a 114 schema register.
Keepiq shipped the same placeholder. Measured on the dev instance: id 432
(shillinq) and id 1112 (keepiq), byte-identical.

`Project` collided with planninq's `project`, a container for tasks and
kanban columns. This one is a consultancy engagement with RJ 270
percentage-of-completion revenue recognition: a different entity wearing
the same word. Slugs are global on a shared OpenRegister, and pipelinq holds
a third `project` row, so this was a three-way collision.

The schema KEY stays `Project`, so the five register.d fragments that extend
it by key keep working untouched. Only the slug moves, across:

- the register's slug field and two `schema` bindings
- the 499-entry register declaration in register.d/000-register-declaration.json
- register.d/bookkeeping-cost-centers-dimensions.json, two bindings
- src/manifest.json, two bindings
- three mock seed objects
- FoldExpensesAndHoursIntoProject, three slug uses, and
  RematerialiseConvertedCalculations' schema list

Those two repair steps matter: a repair step's mandatory catch(\Throwable)
turns a slug that no longer resolves into a silent no-op, so leaving them
behind would have quietly stopped the expense fold and the calculation
rematerialisation without failing anything.

* fix(register): move the Project KEY too, this register keys by slug

Measured on the descriptor: key equals slug for 112 of the 113 schemas.
Renaming only the slug made Project the single exception, and the references
that name a schema by bare string had no way to stay right. Three tests
caught it, and one of them, CostCentersDimensionsFragmentTest, was reading a
seed object that no longer matched.

So the key moves with the slug, and everything that names it follows:
- the schema entry key in shillinq_register.json
- the three register.d fragments that EXTEND it by key
  (zzz-mcp-tool-surface, abstract-project-cost-lines, add-shillinq-audit-trail)
- the aggregation join `"through": "Project"`
- the cloudevents rollover target list
- six test sites

Also tags FoldExpensesAndHoursIntoProject::run with its @SPEC, which gate-16
named.

---------

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
* fix(bbv): drop the second Refresh, and wire the one that stays

The BBV compliance dashboard shipped two Refresh controls. CnActionsMenu
renders one as the first item of the page-level Actions menu, and the
component wrote another into its #header-actions slot right beside it.

The two were not even equivalent. The hand-written button called
loadProgrammes, while the menu item broadcasts on cn:page:refresh and this
component subscribed to nothing. So one Refresh worked and the other did
nothing at all, which is why the button alone could not simply be deleted:
@refresh on CnDashboardPage now routes the menu item to loadProgrammes, and
:refreshing drives its spinner.

The e2e assertion that proves it is unchanged in substance. It still arms a
waitForResponse on the dashboard endpoint before clicking and fails if the
click stops re-querying, so a broken rewire fails the spec.

* test(e2e): target the Refresh menu item by its real role

Run against the dev instance the first version failed: it opened the Actions
menu, then looked for role=button. NcActionButton renders the item as
role=menuitem inside the popover, and the popover mounts outside the page
content, so the scoped button query matched nothing.

The aria snapshot from that failure is also the evidence the fix works. The
page header reads New Publication, Edit with Buildiq, Actions, with no second
Refresh beside the menu, and the menu carries exactly one Refresh.

* style(bbv): use logical margins on the dashboard header chips

stylelint reported both as csstools/use-logical warnings on the file this
branch already touches. Pre-existing, and cheap to clear while here.

margin-inline-end also does the right thing under a right-to-left locale,
where margin-right would push the chip the wrong way.
…ries (#1437)

* feat(reports): finish the move, and retire the six duplicate menu entries

ADR-112. This app invented the pattern and then stopped halfway.

ReportingComplianceOverview already holds every report as a card with a
category filter, and reportViews.js says why it exists: the cards were sourced
from the menu-IA audit "so the whole report surface lives on one cards page".
The component's own merge comment says it again, that the views are merged in
"instead of leaving them as scattered menu items".

They were left as scattered menu items. Six report entries — EMU reporting,
Variance Report, Consolidated Report, Destruction report, IV3 reports, SiSa
reports — were still in the navigation, five of them ALREADY declared as cards
on the page they were supposed to have moved to. Reachable twice, and the menu
copy is the one that never shrinks.

The sixth, BookkeepingDestructionReport, was never added as a card. So it is
added here, in the same change that retires its entry: retiring an entry whose
card does not exist removes the report from the product rather than moving it.

The pages stay routable. Deep links, e2e specs and the cards all address them
by route name; only the menu entries go, declared in menu-layout.json under
`removals` with `removalsReplacedBy` naming the overview.

The "Available reports" KPI is `reports.length` over the merged
`[...apiTypes, ...views]`, so the extra card raises the KPI and the rendered
card count together and the e2e's KPI-equals-cards assertion still holds. 97
view cards now.

Verified: manifest validation passes, gate-53 passes, and the six are gone from
the assembled menu while the overview entry stays.

* fix(nav): baseline the ten pages the retired report entries left orphaned

check:nav-reachability failed on the previous commit, and it was right to: it
reads the manifest menu, and the six report pages no longer have an entry
there. Four detail pages fell with them, orphaned solely because their index
was.

They are not unreachable. Each is a CARD on ReportingComplianceOverview, which
is a live menu entry, and a card navigates by route name — so the page is one
click from the navigation, and the detail pages keep the card -> index ->
detail chain. What the checker cannot see is that shillinq's cards are declared
in src/components/reporting/reportViews.js, a JS module, rather than in the
manifest it reads.

So this is the baseline's documented case ("reachable some other, non-menu
way"), and each entry says which way rather than just asserting it is fine.

Worth naming the limit: for an app whose cards live in the MANIFEST — as
ADR-112's type:"reports" page declares them — a checker could follow
config.cards[].route and confer reachability directly, with no baseline at all.
shillinq keeps its custom overview for the dynamic /api/reporting/types
catalogue, so it does not get that for free.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ d9625f6

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 05:03 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

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ abd5c1f

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 05:36 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/shillinq @ c6c0ee6

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 06:22 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 2 commits September 1, 2026 09:27
ADR-107 decision 6 puts hours logged on a case in humaniq, not here. Shillinq
ships the opposite in uren-domain-subject-link.json, which adds subjectApp and
subjectId to UrenRegistratie so a domain app can book against a case in this
app. Both cite ADR-081, a number two documents claimed until the 2026-08-26
renumbering, so the citation resolved to whichever the reader assumed.

Neither arrangement has ever carried a record. A fleet-wide grep finds
subjectApp in three places: the overlay that declares it, a test asserting the
declaration, and dossiq's case-kpis-hours tile. Nothing writes it, so that tile
reports 0 hours on every case in every install. Humaniq's domainObjectRef is
equally unwired.

So there is nothing to migrate, and the work is to pick where the ledger and
WBSO fields live once the hour moves. The proposal states both shapes and
leaves the choice to design.md. Tasks order the consumers by blast radius and
put the two statutory readers last, behind a side-by-side proof: a wrong
1225-hour urencriterium count costs a real person a real deduction.
…chema (#1444)

The real register stopped declaring `example` when the scaffold placeholder
was retired, but the mock register still shipped three seed objects whose
@self.schema named it. A seed bound to a schema no register declares cannot
import; it is dropped with a warning, which is the quiet kind of failure
this whole consolidation is trying to remove.

The mock has no components.schemas of its own, so nothing else referenced
the slug.

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/shillinq @ b1309a6

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 08:34 UTC

Download the full PDF report from the workflow artifacts.

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

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ 1e47447

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 11:29 UTC

Download the full PDF report from the workflow artifacts.

docs(openspec): deprecate booked hours in shillinq, lean on humaniq
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ a94a4ba

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 12:58 UTC

Download the full PDF report from the workflow artifacts.

Nextcloud serves an app under both /apps/shillinq/... and
/index.php/apps/shillinq/..., but generateUrl() returns only the form the
instance is configured for. Used as the vue-router base, that means a visitor
arriving on the other form has a pathname the router cannot strip its base
from. No route matches, the catch-all takes over, and they land on the
dashboard with no error at all.

Measured live on learniq, which had the identical base, across all 282 of its
routes: /apps/learniq/courses resolved to Courses, and
/index.php/apps/learniq/courses resolved to the dashboard. Not one broken page,
every deep link in that URL form.

routerBase() derives the base from the pathname, so it always matches the URL
the visitor actually arrived on. openregister, opencatalogi, stackiq, larpinq,
zaakafhandelapp, pipelinq and keepiq already do exactly this.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/shillinq @ 3be4a49

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-01 19:37 UTC

Download the full PDF report from the workflow artifacts.

… inside (#1463)

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/shillinq @ 1a12bef

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-manifest-shell
format
check-l10n-js
check-schema-l10n
check-manifest-budget
check-markers
check-registers
check-seeds
check-fragment-required
check-nav-reachability
check-job-registration
test-l10n
composer ✅ 106/106
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-02 19:45 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