chore(frontend): swap remaining @nextcloud/vue imports to @conduction/nextcloud-vue#71
Merged
rubenvdlinde merged 1 commit intodevelopmentfrom Apr 30, 2026
Merged
Conversation
…/nextcloud-vue (ADR-004) Two stragglers added by widget-add-edit-modal (#65/#68 runtime-shell) and widget-context-menu (#60) before ADR-004 landed via #34. Swap is mechanical: NcButton + NcEmptyContent are already exported by @conduction/nextcloud-vue and used elsewhere in the codebase (TileCard, WidgetRenderer, AdminSettings).
Contributor
Quality Report — ConductionNL/mydash @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ❌ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 342/342 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-04-30 21:33 UTC
Download the full PDF report from the workflow artifacts.
This was referenced May 1, 2026
rubenvdlinde
added a commit
that referenced
this pull request
May 3, 2026
* fix(security): Stop leaking exception messages to API clients (ADR-005) `ResponseHelper::error()` was returning `\$exception->getMessage()` in the response body, which surfaces internal error detail (stack traces, DB errors, file paths) to any authenticated caller that triggered a thrown exception. ADR-005 Rule 5 forbids this: "No stack traces in API responses; generic messages." Fix closes the leak immediately by returning a generic \`"Operation failed"\` message to the client regardless of the underlying exception. The helper now accepts two optional parameters for callers that want to preserve visibility + customise the client message: - \`?LoggerInterface \$logger\` — when provided, the real exception is recorded at ERROR level with full context (`['exception' => \$exception]`) before the response is returned. - \`string \$message='Operation failed'\` — generic client-facing text. Signature stays backwards-compatible: all 20 existing \`ResponseHelper::error(exception: \$e)\` call sites across DashboardApiController, TileApiController, WidgetApiController, RuleApiController, AdminController continue to work unchanged, and they now return generic text instead of leaking. Follow-up (not in this commit): thread \`\$this->logger\` through the 6 controllers that currently don't inject a LoggerInterface so the server log regains exception visibility. Tracked in docs/adr-audit.md. * fix(licence): Remove contradictory AGPL SPDX block from 72 PHP files (ADR-014) Every PHP file in lib/ and tests/Unit/ carried TWO licence declarations that disagreed: the PHPDoc `@license EUPL-1.2` (correct, Conduction standard) plus a separate SPDX block declaring `SPDX-License-Identifier: AGPL-3.0-or-later` with `SPDX-FileCopyrightText: 2024 MyDash Contributors`. Any REUSE-based compliance tooling would reject this — two licences on one file is ambiguous. Removed the SPDX block from all 72 files. The PHPDoc `@license EUPL-1.2` + `@copyright 2024 Conduction b.v.` tags are now the single source of truth. REUSE compliance will be restored by the REUSE.toml addition in the next commit — path-based annotations map **/*.php to EUPL-1.2 + Conduction copyright. Verified: `grep -rl "SPDX-License-Identifier: AGPL" lib/ tests/` returns zero. Same for `SPDX-FileCopyrightText: 2024 MyDash Contributors`. The PHPDoc blocks now terminate cleanly after `@link` / `@license`, no trailing orphan SPDX tags. * refactor(frontend): @nextcloud/vue → @conduction/nextcloud-vue (ADR-004) ADR-004 requires Conduction apps to route all Nextcloud Vue components through the @conduction/nextcloud-vue wrapper instead of importing from @nextcloud/vue directly. Nine Vue files had direct imports: - src/components/WidgetWrapper.vue (NcButton) - src/components/TileEditor.vue (NcModal, NcButton, NcTextField, NcSelect, NcColorPicker) - src/components/WidgetPicker.vue (NcButton, NcTextField, NcEmptyContent) - src/views/Views.vue (NcButton, NcEmptyContent) - src/components/TileCard.vue (NcButton) - src/components/DashboardSwitcher.vue (NcSelect) - src/components/WidgetRenderer.vue (NcDashboardWidget, NcEmptyContent, NcLoadingIcon) - src/components/WidgetStyleEditor.vue (NcModal, NcButton, NcTextField, NcSelect, NcColorPicker, NcCheckboxRadioSwitch) - src/components/admin/AdminSettings.vue (NcButton, NcSelect, NcSelectTags, NcTextField, NcCheckboxRadioSwitch, NcEmptyContent, NcModal) All 9 now import from @conduction/nextcloud-vue. The package was already in package.json dependencies, so no dep bump needed. Verified: `grep -rn "from '@nextcloud/vue'" src/` returns zero matches. * chore: Add REUSE.toml + bump Nextcloud max-version to 34 **REUSE.toml**: closes the REUSE-compliance hole from the previous commit. The SPDX block was removed from 72 PHP files; this declaration restores machine-readable licence + copyright data via path-based annotations: - `**/*.php` → EUPL-1.2 + "2024 Conduction B.V." (matches every PHP file's PHPDoc @license/@copyright tags — reuse lint accepts the PHPDoc form when the REUSE.toml declares it explicitly) - Vue / JS / TS / CSS / SCSS / shell → EUPL-1.2 + Conduction - Config / data / markdown / JSON / YAML / XML / TOML / img / l10n / lockfiles → CC0-1.0 (standard Nextcloud-app treatment) Template-matching shape — same structure as nextcloud-app-template's REUSE.toml, year bumped to 2024 (MyDash inception) instead of 2026, and `**/*.toml` added to the CC0 block so REUSE.toml itself is covered. **info.xml**: Nextcloud max-version 33 → 34. Template supports 34; no reason MyDash shouldn't. Skipped the Makefile dev-link symlink helper from the template — the template needs it because the repo is cloned as `nextcloud-app-template` but the <id> is `app-template`. MyDash's <id> is `mydash` and the repo is cloned as `mydash`, so the symlink trick is a no-op here. * docs: Add architecture, ADR index, ADR compliance audit Three new markdown docs wire into the Docusaurus site (autogenerated sidebar picks them up automatically): - `docs/architecture.md` — component map (Controller/Service/Mapper layers with concrete class counts), request flow for dashboard update, auth posture, DI posture, capability table mapping to openspec/specs/, and an explicit "does NOT do" list covering the ADRs that are legitimately N/A for MyDash. - `docs/adr/README.md` — names the canonical ADR location (ConductionNL/hydra/openspec/architecture/) and explains why app repos no longer carry stale copies (decidesk #71 false-positive drift lesson). Quick index of the 23 ADRs. - `docs/adr-audit.md` — per-ADR compliance matrix for MyDash as of 2026-04-24. 25 compliant / 4 partial / 2 gaps / 14 N/A. Each row carries a status + evidence + link to fix when applicable. Captures the verified findings from the two-agent audit run at the start of this PR: - 0 service-locator escapes in lib/ (fixed in commit 5712903) - `ResponseHelper::error` no longer leaks (commit 9be1255) - 72 PHP files have clean EUPL-1.2 headers (commit ab9fc70) - 9 @nextcloud/vue imports swapped (commit 222cf3f) - REUSE.toml + max-version bump (commit b5ca3a4) The two remaining `❌` gaps — @SPEC annotation pass + Newman collection — are flagged for OpenSpec changes + Hydra pickup in the next commit. Corrects the earlier audit's false-alarm IDOR claim (agent 2 stopped at controller null-check, didn't trace through to the service-layer ownership verification). ADR-005 per-object auth is actually PASS once you follow DashboardApiController::update → PermissionService → DashboardService's ownership guard. * spec: Two OpenSpec changes for the remaining ADR gaps Converts the two ❌ items from docs/adr-audit.md into formal OpenSpec changes so Hydra's pipeline can pick them up once this PR merges. **spec-annotation-pass-2026-04-24/** — Close the ADR-003 `@spec` tag gap. Runs `/opsx-annotate mydash` against the 66 methods already classified by `openspec/coverage-report.md` (61 Bucket 1 + 5 Bucket 2b from the legacy-widget-bridge retrofit). Design.md resolves the 3 NEEDS-REVIEW flags from the coverage scan: - `DashboardResolver::getEffectivePermissionLevel` vs `PermissionService::getEffectivePermissionLevel` — both tag with `@spec permissions/spec.md#requirement-effective-permission-level`; PermissionService is the authoritative impl, DashboardResolver is a thin delegator. - `MyDashAdmin::getForm` + `MyDashAdminSection::getID` — treat as plumbing (Nextcloud admin-UI boilerplate, no domain behaviour), skip `@spec` annotation with an explanatory docblock note. **newman-integration-suite-2026-04-24/** — Close the ADR-008 Newman gap. Adds `tests/integration/mydash.postman_collection.json` covering all 17 OCS endpoints across 6 folders (Health+Metrics, Dashboards, Tiles, Widgets, Rules, Admin). Fixture setup/teardown pattern avoids test pollution; admin-vs-member auth branch tests verify authorization posture. `.github/workflows/code-quality.yml` already has `enable-newman: true` — the collection is all that's missing. Each change has proposal.md + design.md + tasks.md + specs/README.md explaining that they're annotation-only / test-only (no Requirement deltas needed). Format mirrors the archived retrofits in openspec/changes/archive/. GitHub issues + Hydra dispatch handled in a follow-up — spec files land on development first so Hydra can locate them. * chore: update SBOM --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
rubenvdlinde
added a commit
that referenced
this pull request
May 3, 2026
…/nextcloud-vue (ADR-004) (#71) Two stragglers added by widget-add-edit-modal (#65/#68 runtime-shell) and widget-context-menu (#60) before ADR-004 landed via #34. Swap is mechanical: NcButton + NcEmptyContent are already exported by @conduction/nextcloud-vue and used elsewhere in the codebase (TileCard, WidgetRenderer, AdminSettings).
rubenvdlinde
added a commit
that referenced
this pull request
May 3, 2026
…se Nc imports Picks up the Nc* re-exports added by ncvue PR #102 (per ADR-004 line 17: "NEVER import from @nextcloud/vue directly — use @conduction/nextcloud-vue which re-exports all"). beta.17 is the first published version with `export * from '@nextcloud/vue'` in the barrel — verified locally. Eslint impact: - Before: 32 errors, all `Nc<X> not found in '@conduction/nextcloud-vue' import/named` from PR #71's swap (the swap was correct per ADR-004 but the barrel hadn't shipped the re-exports yet) - After: 0 errors, 24 pre-existing JSDoc warnings (the `@spec` tag is a project convention, not standard JSDoc — out of scope) Side fix in AdminSettings.vue: collapse the two `from '@conduction/nextcloud-vue'` import statements (CnSettingsSection + the Nc* group) into one. eslint's `import/no-duplicates` correctly flagged them; pure cosmetic merge, no behavioural change. Once this lands, the eslint check on the next dev → beta → main release will go green automatically.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ADR-004 follow-up. Two stragglers in Views.vue (#68 runtime-shell) and WidgetContextMenu.vue (#60 context-menu) that landed before #34 swapped the rest of the codebase. Swap is mechanical — NcButton + NcEmptyContent already used from @conduction/nextcloud-vue elsewhere (TileCard, WidgetRenderer, AdminSettings). Pre-existing import/named ESLint warnings on those imports are NOT new (resolver can't introspect the package); runtime works.