Skip to content
This repository was archived by the owner on Aug 4, 2026. It is now read-only.

Release: merge development into beta - #13

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

Release: merge development into beta#13
github-actions[bot] wants to merge 40 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.

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ c86ddbc

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 493ab57

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ ab678a8

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 8afba86

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 983a3ff

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 9536012

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 3397972

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 8026912

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 1736634

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 73b5e18

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 0a400be

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 682d1c4

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ cdb0610

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ c7c1f9a

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 469f903

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 3c5a524

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 89a4827

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 781bb97

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.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 2834b71

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.

rubenvdlinde and others added 11 commits May 26, 2026 15:32
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)
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ b5c85c3

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

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 477639e

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

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 775c4f6

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

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/deskdesk @ 73d6425

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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant