Release: merge development into beta - #13
Conversation
#14) Completes the journeydoc (ADR-030) rollout for deskdesk: - 6 user-track tutorials covering the booking flow (first-launch, browse-desks, book-a-slot, recurring-booking, calendar-sync, desk-knowledge) — promoted from skeletons to real prose with numbered steps + verification + common-issues - 3 admin-track tutorials (floors-zones, knowledge-source, admin-settings) - Adds globalSetup + storageState wiring to playwright.config.ts (the bootstrap config left auth as a TODO) - docs-screenshots.spec.ts upgraded from skeleton to real Playwright flows — 37 PNGs under docs/static/screenshots/tutorials/{user,admin}/ - Captures show real DeskDesk content (4 seeded desks across floors, admin settings card); flow-detail shots refresh once more seed data or stable testids land. Build: `npm run build` in docs/ -> [SUCCESS].
Quality Report — ConductionNL/deskdesk @
|
| 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-13 06:06 UTC
Download the full PDF report from the workflow artifacts.
…ate from code CI/CD) (#16)
Quality Report — ConductionNL/deskdesk @
|
| 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-13 09:24 UTC
Download the full PDF report from the workflow artifacts.
Defense against supply-chain attacks (e.g. shai-hulud, nx-style compromised publishes) by blocking install of any package version published less than 24h ago. - .npmrc: `min-release-age=1` (npm 11.5+ native; older npm ignores it) - .github/dependabot.yml: `cooldown.default-days: 1`, with @conduction/* excluded so first-party releases reach our apps immediately For release-day consumption of fresh @conduction/* deps, use `npm install --min-release-age=0 @conduction/pkg@x.y.z`.
Quality Report — ConductionNL/deskdesk @
|
| 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-17 07:44 UTC
Download the full PDF report from the workflow artifacts.
* fix(quality): clean development to 0 failing CI checks
Brings development from 6 failing required CI jobs (lint-check,
phpcs, Vue eslint, Vue stylelint, npm Security, npm License) to 0
failures, so the open PRs that rebase onto development can also
clear quality gates.
## Root causes
1. **package-lock.json out of sync** with peer-dep requirements.
vue-apexcharts@1.7.0 requires apexcharts@>=4 while the app pins
apexcharts@^3.54.1 for Vue 2. npm ci hit ERESOLVE on every PR,
breaking 5 jobs that need node_modules.
2. **Missing transitive devDeps** — @nextcloud/eslint-config and
@nextcloud/stylelint-config declare these as peerDeps, but
legacy-peer-deps mode means they were never installed:
eslint-plugin-import, eslint-plugin-n, eslint-plugin-jsdoc,
eslint-plugin-promise, eslint-config-standard, postcss-html,
stylelint-config-recommended-{scss,vue}, typescript, @babel/core,
@babel/eslint-parser, @vue/eslint-config-typescript,
eslint-import-resolver-exports, @nextcloud/eslint-plugin.
3. **eslint import/named** trips on exports-map subpaths inside
@conduction/nextcloud-vue's nested @nextcloud/vue install.
Disabled to match the other import/* rules already off.
4. **phpcs**: 7 violations in lib/Service/SettingsService.php
(equals-align + one inline IF). 6 auto-fixed via phpcbf; the
inline IF was expanded into a 4-line if/else.
5. **Auto-fixable lint**: 12 key-spacing + 1 max-attributes-per-line
errors across DetailPageWrapper/IndexPageWrapper/KnowledgeTab,
fixed via eslint --fix.
## What changed
- .npmrc: legacy-peer-deps=true with rationale comment
- package.json: 14 added devDeps
- package-lock.json: regenerated on Node 20 / npm 11
- eslint.config.js: import/named off
- lib/Service/SettingsService.php: phpcbf fixes + inline IF expansion
- 3 src/views/*.vue: eslint --fix
## Verification
- npm ci --dry-run: up to date in 3s
- npm run lint: 0 errors (0 warnings)
- npm run stylelint: 0 errors (2 deprecation warnings)
- vendor/bin/phpcs --standard=phpcs.xml: 12/12 files clean
* chore(dependabot): target development branch
Per ConductionNL convention: main is the protected production branch,
all feature/build work goes through development. Open dependabot PRs
that targeted main (e.g. #11) will need manual retarget; future PRs
will be raised against development.
* fix(quality): allow pako + sha.js compound AND licenses
pako (MIT AND Zlib) and sha.js (MIT AND BSD-3-Clause) are
transitive deps via webpack/babel toolchain — both component
licenses are on the default allowlist but the compound 'AND'
expression isn't parsed by the license-checker. Same pattern as
pipelinq and zaakafhandelapp.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-19 04:12 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-19 06:08 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 07:36 UTC
Download the full PDF report from the workflow artifacts.
Replace bare-brand Layout title with descriptive form that includes the keyword payload. Docusaurus auto-appends the site title as suffix, so SERPs no longer show duplicate brand titles.
fix(docs): descriptive homepage title (#80)
Replace auto-generated meta descriptions on the highest-traffic pages with hand-written, CTR-tuned variants. Part of the SEO epic ConductionNL/.github#75.
fix(docs): hand-written meta descriptions (#81)
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 08:16 UTC
Download the full PDF report from the workflow artifacts.
…nical #21468B (#28) * fix(brand): use canonical cobalt #21468B in custom.css * fix(brand): use canonical cobalt #21468B in logo.svg
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ⏭️ | ||||
| phpcs | ⏭️ | ||||
| phpmd | ⏭️ | ||||
| psalm | ⏭️ | ||||
| phpstan | ⏭️ | ||||
| phpmetrics | ⏭️ | ||||
| eslint | ⏭️ | ||||
| stylelint | ⏭️ | ||||
| composer | ⏭️ | ⏭️ | |||
| npm | ⏭️ | ⏭️ | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ |
Quality workflow — 2026-05-19 08:22 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 08:26 UTC
Download the full PDF report from the workflow artifacts.
Picks up the post-hydration stylesheet loader so canal-footer + kade-cyclist + decorative CSS no longer block first paint. Widens the package.json caret from ^2.6.1 (which hard-capped below 3.0) to ^3.10.0 so npm resolves the right major. Part of ConductionNL/.github#75 SEO epic.
chore(docs): bump @conduction/docusaurus-preset to 3.10.0 (#79)
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ❌ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-19 08:36 UTC
Download the full PDF report from the workflow artifacts.
* chore(brand): align app-store hex to canonical cobalt #21468B The icon hex was filled with the legacy '#4376FC' (the conduction-design-tokens 'Conduction Cobalt'). The design-system has retired this in preview/colors.html with the caption > Our legacy blue (#4376FC) read as 'cloud / SaaS', light, frisky, > lacking weight. Cobalt is the official blue of the Dutch flag, > Dutch by birthright, dark enough to feel serious, light enough > to stay blue, and AAA-contrast on white so it can carry body > text. Swap to #21468B (--c-blue-cobalt in tokens.css) so the app-store hex matches the navbar wordmark and the rest of the brand chrome. Fleet sweep 2026-05-13. * chore(security): bump symfony/yaml + twig/twig past advisories composer audit was flagging 14 vulnerabilities across symfony/yaml + twig/twig: - symfony/yaml v6.4.34 → v6.4.40 (CVE-2026-45304/45305 + others) - twig/twig v3.24.0 → v3.26.0 (sandbox-escape advisories chain) Lock-only update; no composer.json changes (both come in transitively via Symfony deps + edgedesign/phpqa). * fix(tests): rename OCA\AppTemplate → OCA\DeskDesk in PHPUnit tests 5 test files still carried the nextcloud-app-template scaffold's `OCA\AppTemplate\*` namespace + class names — never updated when the app was renamed to DeskDesk. PHPUnit was failing with 25 errors: "Class OCA\AppTemplate\Service\ItemService not found". Renames: - tests/Unit/AppTemplateTest.php → DeskDeskTest.php (class + namespace) - tests/unit/Controller/SettingsControllerTest.php — namespace + 'use' - tests/unit/Controller/ItemControllerTest.php — namespace + 'use' - tests/unit/Service/ItemServiceTest.php — namespace + 'use' - tests/unit/Service/SettingsServiceTest.php — namespace + 'use' Production classes already use `OCA\DeskDesk\*`; this just brings the tests in line so PHPUnit can resolve the classes under test. * fix(tests): update PHPUnit tests to match deskdesk production state Three PHPUnit failures after the namespace fix were real assertion mismatches between tests and production: 1. testGetSettingsReturnsIsAdminTrueForAdminUser + testUpdateSettings… — mocks expected IAppConfig calls to use 'app-template' app-id; production uses 'deskdesk' (Application::APP_ID). Updated both ->with(...) matchers. 2. testLoadConfigurationSuccessPathWithForce — - Stubbed configurationService had importFromApp($appId, $force) but production calls importFromFilePath($appId, $filePath, $version, $force). Replaced the stub method signature. - appManager mock was missing getAppPath() — needed for the bundle path resolution. Added stub returning a non-existent path so production falls back to the default version '0.2.0'. - Asserted version '0.1.0' but with no register file present production returns the '0.2.0' fallback. Updated assertion. Bootstrap tests/bootstrap.php — \OC_App::loadApp('app-template') also updated to 'deskdesk' so functional bootstrap matches the app ID.
#18) * chore(brand): preset ^2.10.0 + auto-derived hero status + smaller glyph @conduction/docusaurus-preset 2.10.0 ships: - deriveStability(version): 0.x → Beta, *-rc → RC, ≥1.0 → Stable, *-beta → Beta, *-alpha → Alpha - Navbar versionPill auto-uses the derived label so the chrome and the hero badge row can no longer disagree - <DetailHero/> reads version + status from customFields.appVersion (createConfig auto-populates this from appinfo/info.xml) when callers omit the props Three coordinated changes here: docs/package.json — bump @conduction/docusaurus-preset to ^2.10.0 docs/src/pages/index.js — drop hard-coded `status={...}` and `version="..."` props on <DetailHero>; the hero now auto-derives via the same source the navbar reads img/app-store.svg — shrink inner glyph (~40% of hex height instead of ~60%), better breathing room around the cobalt hex * chore(security): bump symfony/yaml + twig/twig past advisories Same fix as #15. Eliminates 14 composer audit vulnerabilities. * fix(tests): rename OCA\AppTemplate → OCA\DeskDesk in PHPUnit tests Same fix as #15. 5 scaffold-leftover test files used the wrong namespace, causing 'Class OCA\AppTemplate\Service\ItemService not found' on every test method. * fix(tests): update PHPUnit tests to match deskdesk production state Same fix as #15 — 3 real test/production mismatches (app-id, OR stub method, version assertion + bootstrap loadApp call).
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ❌ | ❌ | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ |
Quality workflow — 2026-05-20 22:44 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 576/576 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-20 22:47 UTC
Download the full PDF report from the workflow artifacts.
…fest to v2 (#31) DeskDesk is the academy tutorial reference app — it had drifted to pre-1.0 (^0.1.0-beta.7) and v1 manifest while the rest of the fleet moved to manifest v2. This brings it current so academy tutorials' code examples match what readers see when they actually build the app. - Bumps @conduction/nextcloud-vue ^0.1.0-beta.7 -> ^1.0.0-beta.66 - Aligns @nextcloud/axios (~2.5.2), @nextcloud/l10n (3.4.1), @nextcloud/router (^3.1.0) with the fleet's known-good versions; adds matching overrides[] to pin peer-dep resolution - Adds babel-loader devDep (^10.1.1) — required by webpack-vue-config but missing from the v1 lockfile, masked by the old nc-vue install - Migrates src/manifest.json v1 -> v2: * $schema URL flipped to app-manifest-v2.schema.json * version bumped to 2.0.0 * top-level id/title dropped (v2 schema rejects them via additionalProperties:false; appId is hardcoded in App.vue, manifest title was unused) * desks-detail keeps its rich sidebar.tabs (data + knowledge + metadata) — v2 carries this v1.3.0 shape forward, and the KnowledgeTab custom component stays wired via the cnCustomComponents registry * bookings-detail + floors-detail get config.sidebar:true so the lib's built-in CnObjectSidebar mounts (Files/Notes/Tags/Tasks/ Audit Trail tabs) Smoke build green (webpack 5.106.2, 0 errors, 4 warnings — asset-size + unrelated floating-vue/getScrollParents peer warnings); manifest passes ajv validation against the v2 schema.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 591/591 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-21 10:08 UTC
Download the full PDF report from the workflow artifacts.
…ling (#38) Aligns appinfo/info.xml with the fleet canonical: - <php min-version="8.3"> — matches the composer require.php constraint (^8.3 fleet-wide) - <nextcloud min-version="28" max-version="34"> — converge the fleet on one NC support range - <licence>agpl</licence> — fix the casing/value drift (fleet had agpl / eupl / EUPL-1.2 / AGPL-3.0-or-later — 4 spellings). Stays on "agpl" workaround per the EUPL store-listing pattern; switch to "EUPL-1.2" once NC 34 is the fleet floor (ConductionNL/.github#98). Per-app fields (<id>, <name>, <description>, <version>, etc.) are preserved. Drift surfaced in https://github.com/ConductionNL/nextcloud-app-template/blob/development/docs/fleet-drift-deeper.md#4-appinfoinfoxml--significant-drift
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 591/591 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-23 08:05 UTC
Download the full PDF report from the workflow artifacts.
…#40) deskdesk is an academy tutorial app with no openspec/specs/. All 11 uncovered frontend methods are wrapper/store/demo glue (manifest-bridge page wrappers, settings ADR-004 demo, store bootstrap, knowledge tab), so each is marked @SPEC exclude with a reason. Also drops a stale file-level @SPEC pointing at a non-existent example-change.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 591/591 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-25 19:51 UTC
Download the full PDF report from the workflow artifacts.
…ump nc-vue beta.101 (#41)
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 494/494 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-25 21:21 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 494/494 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-25 22:12 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 494/494 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-25 23:51 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 494/494 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-05-26 06:11 UTC
Download the full PDF report from the workflow artifacts.
Gate-5 route-auth: add #[AuthorizedAdminSetting(Application::APP_ID)] to MetricsController::index and SettingsController::load (both admin-only plumbing/config endpoints missing auth attributes). Gate-7 no-admin-idor: - SettingsController::index: convert @NoAdminRequired docblock to #[NoAdminRequired] attribute + inject IUserSession + add 401 guard; posture = any logged-in user may read settings (register/schema IDs, isAdmin flag, openregisters availability — non-sensitive SPA init data). - SettingsController::create: was false-positive — comment text contained the literal string #[NoAdminRequired] triggering the gate regex. Fixed comment, added #[AuthorizedAdminSetting] (correct admin-only posture). phpstan-baseline: add 3 AuthorizedAdminSetting class-string false-positives (fleet-wide known issue; refs decidesk#242, scholiq#169 pattern). Refs #46
…C1) (#62) Add authorization blocks to floor, desk, booking, and knowledge_article in deskdesk_register.json so that write operations are admin-only. Booking create is left open (any authed user), but update/delete are restricted to admin; OR's built-in @self.owner bypass means the booking creator retains full control over their own bookings. Bump all schema versions and the register version to 0.3.0 (manifest 0.4.0) to trigger a re-import on upgrade. Also fix a pre-existing unit-test failure in SettingsServiceTest where loadConfiguration() threw because \OC::$SERVERROOT is not resolvable in headless PHPUnit. Guard the OC class access so the test environment falls back to an empty NC-root string. Fixes #49
… deep links, booking auth (#63) - InitializeSettings: remove force:true from repair step (fixes #50 duplicate-register data corruption on upgrade — the OR version-skip guard now works as designed) - DeepLinkRegistrationListener: replace non-existent 'article' schema with real schemas desk/booking/floor pointing at actual SPA routes /desks/{uuid}, /bookings/{uuid}, /floors/{uuid} (fixes #51) - ItemService: repoint from phantom 'article' schema to 'booking'; extend isAuthorized() to also match booking.user so the booked-for user can cancel their own reservation (fixes #52, fixes #53); add is_string() guard to extractOwner() array path to mirror object path and prevent silent auth denials on non-string OR entity refs (fixes #54) - ItemControllerTest/ItemServiceTest: update namespaces + add testDeleteAllowsBookingUser and testDeleteReturnsForbiddenWhenOwnerIsNonStringArrayRef tests
…reasons, health rate limit (#64) - SettingsService::getSettings(): restrict schemaIds to admin users only; non-admin callers receive registerId/registerSlug but not internal OR numeric schema IDs, reducing enumeration surface (fixes #55) - SettingsService::loadConfiguration(): add optional isAdmin parameter; when true, error responses include a discriminated reason field (or_missing / parse_error / or_error) so admins can self-diagnose import failures without exposing internals to unprivileged callers (fixes #57) - HealthController: replace deprecated docblock @PublicPage/@NoCSRFRequired with PHP attributes and add #[AnonRateLimit(limit: 60, period: 60)] per ADR-006 (fixes #60) - SettingsController::load(): pass isAdmin: true to loadConfiguration() - Tests: add schemaIds admin/non-admin coverage and loadConfiguration reason-field tests
…bute annotations (#65) - HealthController + MetricsController: inject IAppManager and replace hardcoded '0.1.0' string with getAppVersion(APP_ID) so version is always in sync with info.xml (fixes #56) - DashboardController: convert deprecated docblock @NoAdminRequired/@NoCSRFRequired annotations to PHP 8 attribute syntax to match the rest of the codebase (fixes #61) - IndexPageWrapper: pass :filters="filters" to CnIndexPage — the prop was declared but never forwarded, silently killing the desk filter controls (fixes #58) - KnowledgeTab + DetailPageWrapper: capture targetId at the start of each async load/handler and discard responses if objectId/id has changed by the time they resolve, preventing stale content from overwriting the current selection (fixes #59)
…ield on create (#68) C1: replace non-existent ObjectService::delete() with deleteObject(uuid, register, schema) and align test stub to the canonical signature. H1: add POST /api/items create endpoint that forces booking.user to the caller's UID for non-admins, preventing user impersonation. H2: add per-user read authorization to the booking schema so users only see their own bookings; bump booking schema to 0.3.0 and register to 0.5.0 to trigger reimport. H3: bump appinfo/info.xml to 0.2.0 to bust the immutable JS bundle cache.
…tize wiki URL (#69) M1: remove hardcoded '0.4.0' version fallback in SettingsService::loadConfiguration() — now fails closed (log + return failure) when the register JSON file is missing or unreadable instead of silently importing with a stale version string. M2: tighten the SPA catch-all route with '(?!api/).+' so unlisted /api/* paths return 404 instead of the SPA's HTML. L1: add safeUrl() method to KnowledgeTab.vue that rejects non-http/https protocols, preventing javascript:/data: URIs from being rendered as links. Also update SettingsServiceTest to cover the file-missing fail-closed branch (new test) and fix the success-path test to create a real temp fixture file.
…ema, dead code (#70) C1: Fix booking schema delete/create RBAC rules so owners and booking users can manage their own bookings via OR-native enforcement instead of admin-only (which made ItemService's isAuthorized() unreachable). C2: Attach knowledge_article schema to the register-block schemas array so KnowledgeTab.vue can fetch articles — was defined but never registered. C3: Remove dead-code ItemController, ItemService, routes, and tests — the /api/items endpoint has zero frontend callers; C1 now handles booking access via OR schema rules directly. C4: Narrow info.xml NC version to min=31 max=33 to match CI matrix.
C1: booking schema update rule was admin-only; users could not cancel their own bookings (status: cancelled is only reachable via update). Changed to the same dual-match pattern as create/delete: owner OR booking.user OR admin. C2: SettingsControllerTest constructed SettingsController with 3 args while the constructor requires 4 (IUserSession added in a prior wave). Added userSession mock, IUserSession+IUser imports, and getUser() stubs on the two index()-exercising tests so the null-user 401 guard does not short-circuit. Bonus: bump twig/twig 3.26.0 → 3.27.0 in composer.lock to clear 5 CVEs (CVE-2026-48808/48805/48806/46636/48807) reported 2026-05-27. H5 (booking user field re-assignment) deferred — no app-layer controller exists; tracking issue filed at #71. All 19 unit tests green. All 19 Hydra gates green.
…17 (#76) deskdesk was one of four apps missed by the original fleet Vue 3 working set. It sat on vue@^2.7.14 with @conduction/nextcloud-vue@^1.0.0-beta.101 — the oldest nc-vue pin in the org. Dependencies @conduction/nextcloud-vue ^1.0.0-beta.101 -> 2.1.0-vue3.17 (EXACT, no caret: a caret DOES float an already-resolved prerelease when the dist-tag moves) vue ^2.7.14 -> ^3.5.13 @nextcloud/vue ^8.39.0 -> ^9.9.0 @nextcloud/dialogs ^3.2.0 -> ^7.4.1 @nextcloud/router ^3.1.0 (already v3) vue-router ^3.6.5 -> ^4.6.4 vue-loader ^15 -> ^17.4.2, vue-template-compiler DROPPED @nextcloud/webpack-vue-config ^6.0.1 -> ^7.0.2, + terser-webpack-plugin @vue/compiler-sfc added; gridstack ^12 added (nc-vue peer, CSS imported) vue-apexcharts (Vue-2-only wrapper, ZERO usages in src/) removed; apexcharts ^3.54.1 -> ^4.7.0, and overrides."vue3-apexcharts" pinned to 1.8.0 because 1.9.0+ is proprietary and forbids sublicensing in our EUPL-1.2 apps. Bootstrap (src/main.js, src/settings.js, src/router/index.js) new Vue({...}).$mount() -> createApp({...}).mount() Vue.mixin / Vue.use -> app.mixin / app.use PiniaVuePlugin -> app.use(pinia) new Router({ mode:'history'})-> createRouter({ history: createWebHistory() }) path: '*' -> path: '/:pathMatch(.*)*' (v4 REMOVED the bare wildcard; it does not error, the route just never matches and <main> is empty) Vue.observable() -> reactive() :open.sync -> v-model:open (CnObjectSidebar really does declare an `open` prop and emit `update:open` in vue3.17 — checked, not assumed; the .sync autofix would have written v-model:value) Mount target renamed #content -> #deskdesk-app in templates/index.php. Vue 2's $mount() REPLACED the matched element, so mounting on the template's <div id="content"> silently replaced Nextcloud's own #content wrapper from layout.user.php. Vue 3's mount() renders INSIDE the match, and with two #content ids it is undefined which one wins. The admin settings entry no longer mounts inside the loadTranslations callback. On installs where /custom_apps/<app>/l10n/<locale>.json 404s the callback never fires, which is a blank admin panel with no error. Build config Aliases now point at ABSOLUTE FILES, not package directories. @nextcloud/vue@9, @nextcloud/dialogs@7 and vue-router@4 ship an `exports` map with no `main` and no `module`, and webpack applies an exports map to package requests only — never to an already-absolutised path — so the old directory aliases resolved to nothing. New src/setPublicPath.js, first import of both entry points, sets __webpack_public_path__ via generateFilePath and __webpack_nonce__. The hardcoded /apps/<app>/js/ is wrong under custom_apps, and the wrong path does NOT 404 — Nextcloud answers 200 text/html, so it surfaces as a MIME refusal and ChunkLoadError. Vue 2 never exposed this because it emitted no async chunks. sideEffects:true rule for the nc-vue dist, or webpack tree-shakes the `script.render = render` wrapper and every Cn component renders as a comment node with no warning. appName / appVersion DefinePlugin entries re-added — they were being dropped by replacing webpackConfig.plugins wholesale. USE_LOCAL_LIB is now opt-IN. It was opt-OUT against ../nextcloud-vue/src, which is the Vue 2 beta line, so any build from the shared checkout silently compiled Vue 2 sources into the app. Lint eslint.config.js now spreads conductionVue3Fixes LAST. The @nextcloud v8 base is Vue-2 era and activates ZERO vue/no-deprecated-* rules; verified by SEVERITY, not by rule name — 21 of 21 now resolve to error/warn. Fixed pre-existing indentation errors in DetailPageWrapper.vue's watch handler and declared @SPEC as a known JSDoc tag, as hermiq does. Verification (npm 11 generate -> npm 10 normalise -> npm 10 ci, all exit 0) lockfile @conduction/nextcloud-vue = 2.1.0-vue3.17 lockfile vue = 3.5.40, @nextcloud/vue = 9.9.0, vue-router = 4.6.4 lockfile vue3-apexcharts = 1.8.0; bootstrap-vue ABSENT; vue-template-compiler ABSENT npm run lint -> 0 errors (was 16), 2 pre-existing jsdoc warnings npm run stylelint -> exit 0 npm run build -> exit 0, 2 asset-size warnings only quote-aware multi-line tag scan over all 5 .vue files: ZERO residual .sync, ZERO <NcButton type=, ZERO plain :value= (positive control: 33 tags matched)
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 651/651 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-08-03 11:56 UTC
Download the full PDF report from the workflow artifacts.
…-> 2026-08-01) (#74) The lockfile pinned roave/security-advisories to a commit from 2026-03-20, so the metapackage's conflict rules — and therefore the protection against installing known-vulnerable dependency versions — were frozen at that date. Refreshed to the 2026-08-01 tip. composer audit --locked: clean before and after.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 651/651 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-08-03 12:33 UTC
Download the full PDF report from the workflow artifacts.
Jobs without timeout-minutes fall back to GitHub's 360-minute default, so a hung runner burns six hours of Actions minutes before it is reaped. Bounds are derived from observed run durations and left deliberately loose: a timeout that fires under normal contention is worse than no timeout, because it turns a slow run into a phantom defect. Jobs that only call a reusable workflow (job-level `uses:`) are untouched -- they inherit their bound from the called workflow.
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 651/651 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-08-03 13:03 UTC
Download the full PDF report from the workflow artifacts.
'quality / Features Check' has failed on every pull request because
docs/features.json was never committed at all. deskdesk has no capability
specs yet (openspec/specs/ contains only README.md), so the generator's
correct output is an empty array.
It never self-healed because the push-side 'Features Extract' job cannot
land its auto-commit on development:
! [remote rejected] development -> development
(push declined due to repository rule violations)
That push failure is swallowed by a '|| echo ::warning' so the job still
reports success (ConductionNL/.github#61).
Generated with scripts/extract-features.py from ConductionNL/.github@main;
--check now exits 0. The file will need regenerating again as soon as real
specs land, until #61 is fixed.
Co-authored-by: Ruben van der Linde <juan.claude@conduction.nl>
Quality Report — ConductionNL/deskdesk @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 651/651 | |||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/3 statements)
Quality workflow — 2026-08-03 14:16 UTC
Download the full PDF report from the workflow artifacts.
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.