Release: merge development into beta#63
Conversation
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
PHPUnit Tests
Integration Tests (Newman)
E2E Tests (Playwright)
Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (215 total)
PHPUnit TestsPHPUnit tests were not enabled for this run. Integration Tests (Newman)Newman integration tests were not enabled for this run. E2E Tests (Playwright)Playwright E2E tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (215 total)
PHPUnit TestsPHPUnit tests were not enabled for this run. Integration Tests (Newman)Newman integration tests were not enabled for this run. E2E Tests (Playwright)Playwright E2E tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (215 total)
PHPUnit TestsPHPUnit tests were not enabled for this run. Integration Tests (Newman)Newman integration tests were not enabled for this run. E2E Tests (Playwright)Playwright E2E tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 215/215 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-04-25 15:11 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 215/215 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-01 11:53 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-12 07:46 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-12 12:37 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-12 21:20 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-12 21:26 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-12 22:17 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-12 22:41 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-13 05:56 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-13 07:56 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-13 09:25 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-13 09:28 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-17 07:45 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 08:56 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 12:34 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ |
Quality workflow — 2026-05-18 15:10 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 15:13 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 18:11 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 18:55 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 19:17 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 20:46 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 21:00 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-18 21:16 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 02:57 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 03:05 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/shillinq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 428/428 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 03:10 UTC
Download the full PDF report from the workflow artifacts.
…ording-notification' (#515) from wip/archive-restore-overdue into development
| uses: Conduction/.github/.github/workflows/documentation.yml@main | ||
| with: | ||
| cname: shillinq.app | ||
| cname: shillinq.conduction.nl |
docs(openspec): add portal-payment-initiation ff change
…itiation) Adds the write leg to the customer portal's "Pay my invoices" surface: - PaymentProviderInterface port + MolliePaymentProvider binding (REQ-SPPI-001), delegating to the existing MolliePaymentAdapterInterface with method=ideal. - PortalAssertionVerifier (adapted from the fleet A6 reference receiver) + PortalPaymentInitiationController + PortalPaymentSessionService (REQ-SPPI-002/003/004): a fail-closed, ownership-scoped initiation endpoint that resolves the subject's customerMasterId claim from portaliq's own portalAccount register, verifies the target ARInvoice belongs to that CustomerMaster and is payable, mints/reuses a PaymentRequest with the server-side invoice amount, and mints an iDEAL checkout session. - PaymentReconciliationService now writes a subject-safe confirmationSummary on capture (REQ-SPPI-005); PaymentRequest schema gains that scalar (register version 0.1.0 -> 0.1.1). - PortalContributionProvider gains a `pay` endpoint-forward action + rowAction on salesInvoices/paymentRequests (REQ-SPPI-006); supplier/accountant stay read-only. All existing PSP/webhook/reconciliation plumbing is consumed, not rebuilt. Full unit suite (3963 tests), PHPCS/PHPMD/PHPStan/Psalm all green in the nextcloud:34 container; openspec validate --strict passes; change archived.
…itiation feat(portal): subject-initiated payment initiation (portal-payment-initiation)
…not unlimited readRows() passed `'limit' => 0` intending "unlimited". OpenRegister forwards it as a literal SQL LIMIT 0, so findAll() returned ZERO rows and the migration was a silent no-op that still reported "0 migrated, 0 skipped, 0 failed" — green, and dead, on every real instance. Live-verified on a running instance (shillinq register, schema Account, 155 rows): findAll(['limit' => 0]) => 0 rows (both rbac on and off) findAll([]) => 155 rows (no implicit page cap) offset paging => pages disjoint, works as expected Fix: read source rows in explicit limit/offset batches (READ_BATCH_SIZE = 200), so the fold never depends on implicit "unlimited" semantics and never loads an unbounded result set at once. The unit suite missed this because the test double's findAll() ignored `limit` and `offset` entirely — the mock was more permissive than the real service. It now mirrors OpenRegister's real paging semantics, which is what turns this into a real regression guard: reintroducing `limit => 0` fails 5 tests instead of 0. Adds testFoldsEverySourceRowAcrossReadBatches (seeds READ_BATCH_SIZE + 5 rows) to prove paging advances to the final page rather than re-reading page one. Refs #503
…rmat, idempotency
Live-running the held migration on a real instance surfaced four further defects,
none of which the unit suite could see because the test double was more permissive
than OpenRegister actually is. Each is fixed and now guarded by a test that fails
without the fix.
1. ObjectEntity rows were unreadable. foldRows() did `(array) $row`, but
findAll() returns ObjectEntity objects whose payload lives in getObject();
casting one yields mangled "\0*\0prop" keys, so every field — including the id
— vanished and every row was rejected as "row without a stable id".
normaliseRow() now resolves the payload. Note Nextcloud's Entity base serves
getters via __call(), so method_exists() reports FALSE for getObject()/getUuid()
— it probes by calling, never by reflection.
2. Explicit nulls failed validation. The builders emit null for every absent
optional field, and OpenRegister validates a present null against the declared
type ("Property 'subsidie.regelingArtikel' should be type 'string' but is
'null'"), failing the whole row. pruneNulls() drops null keys before saving —
lossless, since an absent optional property is valid and null carries no data.
3. Date-typed fields got timestamps. toDateTime() emits ATOM, but 11 target
properties declare `format: date` and reject
'2026-01-15T00:00:00+00:00'. Adds toDate() (Y-m-d) and routes exactly those 11
through it; orderDate/endDate/peppolSentAt stay date-time as declared.
4. The step was NOT idempotent — the most dangerous one. orderExists() filtered on
`migratedFrom.key`, and OpenRegister does not support dot-path filters on nested
properties, so it always answered "no existing Order": every run re-folded every
source row, meaning each `occ upgrade` would add a duplicate set of financial
records. Filtering on top-level `orderNumber` instead still duplicated
DBAOpdracht, whose orderNumber is prefixed "DBA-" and so never equals its
migration key. The markers are now read once per run into a set (also updated
after each save, so a single run cannot double-fold either).
Live-verified end to end on a running instance, per source type:
Subsidie 1 migrated -> re-run 0 migrated / 1 skipped, exactly 1 Order
DBAOpdracht 1 migrated -> re-run 0 migrated / 1 skipped, exactly 1 Order
source rows untouched; decidesk's `order` schema (1585) untouched throughout
The PurchaseOrder path remains UNPROVEN: no PurchaseOrder row can be created on a
live instance at all, because schema 1115 carries `all_of: ["1585"]` — it composes
decidesk's Order schema and therefore demands decidesk's required properties. That
is a separate data-level defect, filed separately; the migration stays HELD until
it is resolved.
Refs #503
phpcs: missing doc comment + missing blank line before function.
fix(repair): FoldIntoOrder was a silent no-op, then non-idempotent — 5 live-only defects
Re-authored 254 Dutch schema-property `title` values in
lib/Settings/shillinq_register.json to English so manifest-driven UI
labels (grid columns, form field labels) are English-authored per the
fleet-wide i18n rule. Property/schema KEYS are unchanged — verified the
set of property keys per schema is byte-identical to origin/development.
Added 191 new l10n keys to both l10n/en.json (identity) and l10n/nl.json
(the original Dutch title text) so Dutch users keep seeing Dutch via the
app's l10n layer; 20 of the 211 unique new titles already had l10n
entries and were left untouched. Two English titles ("Description",
"Valid From") were reachable from two slightly different Dutch originals
("Beschrijving"/"Omschrijving", "Geldig Van"/"Geldig Vanaf") — resolved
to the more standard spelling for the nl.json value.
Version bumps: register info.version 0.6.2 -> 0.6.3 (with changelog note
in info.description), appinfo/info.xml <version> 0.9.15 -> 0.9.16.
No build needed — register titles are imported by OpenRegister at
runtime and l10n/*.json is served directly.
i18n(schema): author shillinq property titles in English + NL l10n
The abstract-order-primitive fold migration was held pending a real live run. It is now live-verified on 8080 against real created rows for ALL THREE source types: Subsidie -> OrderPrimitive(subsidie), idempotent re-run skips PurchaseOrder-> OrderPrimitive(purchase), cent->EUR confirmed (121000 -> 1210.00) DBAOpdracht -> OrderPrimitive(engagement), idempotent re-run skips Each produces exactly one correctly-mapped OrderPrimitive; a second run folds nothing again (no duplicates); source rows and decidesk's `order` schema (1585) are untouched. Live-running it also surfaced + fixed five defects the mocked suite could not see (PR #381). Non destructive, idempotent, fail soft. RetireSubsidieSchema stays HELD: it DELETES folded Subsidie rows (must lag the fold by a release for a rollback window) and still carries the limit=>0 dead-read bug (#382). Refs #503
…abled (#503) Mark the live-verify task done and the FoldIntoOrder hold lifted; RetireSubsidieSchema stays held (destructive + #382 limit=>0). Change remains OPEN for Phase 3 (type-aware UI/nav) and Phase 4 (compliance re-point) — not archivable yet. Refs #503
feat(repair): re-enable FoldIntoOrder — #503 fold live-verified end to end
…atches trait Phase C foundation for #382. Factors the correct paginated read pattern (the fix that FoldIntoOrder proved live) into a shared trait so the eleven sibling repair steps still carrying `findAll(['limit' => 0])` can adopt one audited helper rather than each re-implementing pagination. `readAllRows()` reads every row in explicit limit/offset batches, unscoped (_rbac/_multitenancy false — a migration must see all tenants' rows), and lets exceptions propagate so each step keeps its own missing-schema handling. FoldIntoOrder is refactored onto the trait as the first consumer; its eleven unit tests (which now faithfully model OpenRegister's limit/offset semantics) pass unchanged, proving the extraction is behaviour-preserving. Refs #382
…-trait refactor(repair): shared ReadsSourceRowsInBatches trait (#382 foundation)
…h filter (#382) `shillinq:orders:audit` is the tool the FoldIntoOrder hold notes cite to validate the fold, but it was green-but-dead. countRows() used `findAll(['limit' => 0])` (literal SQL LIMIT 0 => zero rows), and countMigrated() used BOTH `limit => 0` and a `['migratedFrom.schema' => ...]` dot-path filter (OpenRegister does not support nested filters => matches nothing). Every schema reported source=0 migrated=0, so the `migrated >= source` check was 0>=0 => "OK / PASS" for everything, always — even when nothing had been folded. Fix: adopt ReadsSourceRowsInBatches for the counts, and match the nested migratedFrom marker in PHP (reading the ObjectEntity payload via getObject()) instead of via an unsupported dot-path filter. The test double was unfaithful in exactly the two masking ways (it ignored `limit` and it DID support the dot-path filter), so it passed with broken code. It now mirrors OpenRegister's real semantics (limit literal, offset applied, dot-path filters match nothing), which is what makes the three existing assertions real. Refs #382
…ounts fix(command): orders:audit reported a false PASS — limit=>0 + dot-path filter (#382)
…r steps (#382) The eleven remaining repair steps each carried TWO latent bugs, both masked because the first made the second unreachable: 1. `findAll(['limit' => 0])` — literal SQL LIMIT 0 => ZERO rows. Every step read nothing and reported a clean no-op summary (green, and dead) on any real instance. 2. `(array) $row` — OpenRegister returns ObjectEntity objects whose payload lives in getObject(); casting one yields mangled "\0*\0prop" keys, so once the read is fixed the step would process all-null fields. Same defect that bit FoldIntoOrder. Both are now routed through the shared ReadsSourceRowsInBatches trait: - readAllRows() — batched limit/offset read (never limit=0). - rowPayload() — resolves the ObjectEntity payload via getObject() (never a blind cast). Also fixes RetireSubsidieSchema::orderExists(), whose delete gate filtered on a dot-path `migratedFrom.schema`/`.key` (OpenRegister does not support nested filters => matched nothing => it never deleted a Subsidie). It now reads Orders once and matches the marker in PHP. RetireSubsidieSchema remains HELD (unregistered) regardless. Test doubles for the affected steps now mirror OpenRegister's real findAll semantics (limit literal, offset applied, dot-path filters match nothing). Full suite: 3966 green. Steps whose source schemas exist on the shared instance are additionally live-verified in follow-up; MigrateProductVendorMaster's source schemas are absent there so it is trait/unit-proven only. Refs #382
CustomSniffs.Functions.NamedParameters requires named args for internal calls. Also wraps one DunningRun call that exceeded the 150-char line limit. No behaviour change; full suite 3966 green, phpcs 0 errors on all changed files. Refs #382
…payload fix(repair): dead-read + ObjectEntity-cast across all repair steps (#382)
…ma-hold-note docs(repair): RetireSubsidieSchema held only for release-lag now (#503/#382)
…ema-label translation
chore(deps): bump @conduction/nextcloud-vue to ^1.0.0-beta.221
Adds tests/e2e/order-primitive.spec.ts — live, API-driven Playwright e2e for the
five browser/API-observable order-primitive scenarios:
1-3. an Order of type subsidie / purchase / engagement can be created (and the
distinct shapes prove it resolves to shillinq's OrderPrimitive, not
decidesk's `order`).
4. subsidie keeps its statutory lifecycle (verleen: aanvraag -> verleend).
5. a transition never crosses orderType boundaries (a purchase `approve` is
REFUSED on a subsidie) — the orderType gate, REQ-ORD-002.
Adds an OrFixtures.transition() helper (POST /api/objects/{id}/transition) so the
lifecycle scenarios can be driven end-to-end through OpenRegister's real HTTP +
auth + storage stack.
The remaining three scenarios are backend occ behaviour a browser cannot drive
and are marked `@e2e exclude` with their proof references:
- migration is lossless -> FoldIntoOrder live run (#503/#381) + FoldIntoOrderTest
- money units normalised -> FoldIntoOrder cent->EUR live (#503) + FoldIntoOrderTest
- audit detects unmigrated rows-> `occ shillinq:orders:audit` live (#388) + OrdersAuditCommandTest
Every seeded object carries a run-unique prefix and is deleted in afterAll.
All five tests pass in isolation (the cross-type gate 3/3 on repeat); the spec is
serial with a generous timeout + config retries to absorb the loaded shared dev
instance (single object-creates observed at 18-24s there).
Refs #503
…ance lag (#503) Behaviour is deterministic in isolation; the extra retries only cover the shared dev instance's transient object-API slowness (18-24s creates under a concurrent session). No product flakiness. Refs #503
test(e2e): Playwright coverage for order-primitive scenarios (#503)
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.