fix(headers): correct email + add SPDX + @spec example#19
fix(headers): correct email + add SPDX + @spec example#19rubenvdlinde wants to merge 19 commits into
Conversation
Merge beta into main
…uctors Issues caught by every code review on apps built from this template: - <licence>agpl</licence> → <licence>eupl</licence> - OC.requestToken → getRequestToken() from @nextcloud/auth - Added SPDX-License-Identifier: EUPL-1.2 to all PHP/JS/Vue files - Constructor properties: private → private readonly
The app store only recognises agpl/apache/mit — not eupl. Source files use SPDX EUPL-1.2 headers (the actual licence). info.xml uses agpl for store compatibility only.
- Extend base webpack config instead of replacing resolve/module - Add NodePolyfillPlugin for process polyfill compatibility - Add CnObjectSidebar + objectSidebarState for proper sidebar positioning - Update deps: @nextcloud/l10n ^3.1.0, @nextcloud/dialogs ^5.3.7 - Add sass/sass-loader for SCSS support
…plitChunks Two issues found when testing builder-generated apps (decidesk): 1. main.js: loadTranslations() wraps Vue mount in a callback that never fires when l10n/en_US.json returns 404 (new apps don't have translations). Fix: mount Vue synchronously, import t/n directly. 2. webpack.config.js: Nextcloud serves chunk files from /apps/<id>/js/ but custom_apps files live at /custom_apps/<id>/js/. Any webpack code-split chunk (from lazy imports or vendor splitting) fails with ChunkLoadError. Fix: disable splitChunks entirely. Use static imports in router.
Gives the Hydra builder a working reference for the full CRUD lifecycle: - ItemList.vue: CnIndexPage + useListView composable (zero-boilerplate list) - ItemDetail.vue: CnDetailPage with sidebar, save/delete, CnObjectDataWidget - object.js: replaced hand-rolled store with createObjectStore from library - store.js: registerObjectType pattern with settings-driven schema binding - MainMenu.vue: added Items nav entry between Dashboard and Documentation - router: static imports with props factory for :id params - package.json: fix @nextcloud/dialogs ^3.2.0 (Vue 2), add apexcharts/codemirror These patterns prevent the recurring builder mistakes: lazy imports (ChunkLoadError), custom stores (should use createObjectStore), missing list/detail views, and wrong dependency versions.
Settings link should be inside NcAppNavigationSettings (the gear icon widget), not a bare NcAppNavigationItem — follows Nextcloud convention for admin-only controls and matches the procest pattern.
The correct Nextcloud pattern:
- Admin settings: /settings/admin/{appid} (via AdminSettings.php + settings.js)
- In-app settings: NcAppSettingsDialog modal opened from gear menu
- NO /settings route in the Vue router
The gear foldout (NcAppNavigationSettings) can hold additional admin
nav items. The Settings item emits @open-settings which App.vue
handles by opening the UserSettings modal.
Matches the OpenCatalogi pattern.
- Fix ReferenceError: use this.t() instead of bare t() in ItemDetail.vue - Wrap hardcoded app name in AdminRoot.vue - Add 14 missing keys to en.json and nl.json (30→44 keys)
Standardize on #actions across all components per the updated slot naming convention in @conduction/nextcloud-vue.
Update all translation keys to use sentence case (only first letter capitalized) instead of title case. Keys changed: - "Add Groups" → "Add groups" - "Active Collections" → "Active collections" - "API Key" → "API key" - And 400+ similar keys across all apps Sentence case for keys improves consistency and readability while preserving proper English grammar in translated values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- @author email: dev@conductio.nl → info@conduction.nl (the .nl typo had propagated into every Conduction app since this template is the source — 988 occurrences across 927 files org-wide). - @copyright year: 2024 → 2026. - SPDX: unified placement to // SPDX-FileCopyrightText + // SPDX-License-Identifier after the main docblock, before declare(strict_types=1). Removes the pre-docblock // SPDX line variant that had crept into some files. - @SPEC example: added a file-level @SPEC tag in Application.php as a reference for future specs (ADR-003 requires every class and public method to carry an @SPEC tag linking back to the OpenSpec change that created or last modified the file). Template files are the golden pattern builder containers copy when scaffolding a new app, so fixing them here prevents the typo and missing SPDX from recurring on every future build.
Moved SPDX-FileCopyrightText + SPDX-License-Identifier from // line comments to inside the main docblock, placed between the description and the @category tag. Reason: the standard template convention (and what reuse lint expects) is for SPDX metadata to live colocated with @author/@copyright/@license inside the file docblock, not as standalone // comments before declare. The previous commit's // SPDX-... pattern was a transitional style and should never have been promoted to the template.
See ConductionNL/nextcloud-app-template#19 for root-cause fix in the template.
ADR audit follow-up — PR #20Did a full audit of this template against every MUST/SHALL/REQUIRED rule in the 17 org-wide ADRs. Findings + minimal fixes are in #20 (stacked on top of this branch). Snapshot of the gaps found:
Full table (56 rules, 13 fixed, 5 partial with documented exceptions, 6 N/A): Follow-ups flagged but not fixed (to keep this diff scoped): |
# Conflicts: # package.json
Quality Report — ConductionNL/nextcloud-app-template @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-04-20 06:32 UTC
Download the full PDF report from the workflow artifacts.
Summary
@authoremail typo:dev@conductio.nl→info@conduction.nlacross 9 template PHP filesSPDX-FileCopyrightText+SPDX-License-Identifierafter the main docblock, consistent placement across all files (previously some had// SPDX-License-Identifierbefore the docblock, most had nothing)@copyrightyear: 2024 → 2026@spec openspec/changes/{change-name}/tasks.md#task-Nexample inApplication.phpwith explanation comment — ADR-003 mandates this for every class and public method, and having the example in the template is what propagates the convention to new app scaffoldsWhy this matters
This template is copied into every Conduction app at scaffold time, which means the
dev@conductio.nltypo has propagated into 988 occurrences across 927 files org-wide. Fixing it here is the root-cause fix; the downstream sweep follows.Similarly,
@speccoverage is currently near-zero outside decidesk because the template never shows builders what the tag looks like.Test plan
composer install+./vendor/bin/phpcsclean on template