This repository was archived by the owner on May 29, 2026. It is now read-only.
Repair conditional rules + admin templates + permission defaults#39
Merged
rubenvdlinde merged 1 commit intoApr 30, 2026
Merged
Conversation
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 05:22 UTC
Download the full PDF report from the workflow artifacts.
This was referenced Apr 30, 2026
Walkthrough of all 9 archived OpenSpec features uncovered three critical
runtime bugs in features marked "implemented". This commit restores them
and clears the supporting quality stack.
Critical fixes
--------------
- ConditionalRule.createdAt: switch ?DateTime to ?string ('c' format) to
match sibling entities. Doctrine DBAL cannot bind a DateTime without
an explicit addType registration; INSERT now succeeds. Same change in
AdminSetting.updatedAt.
- AdminTemplateService + TemplateService: drop the ramsey/uuid require
and inline the random_bytes(16) UUID generator already used by
DashboardFactory. The ramsey class was never autoloaded at runtime
(Application.php does not require vendor/autoload.php), so admin
template creation and template-based dashboard provisioning both
threw 500.
- DashboardService: stop hardcoding PERMISSION_FULL when auto-creating
user dashboards. Read defaultPermissionLevel and defaultGridColumns
from AdminSettingMapper and pass them to DashboardFactory.
Quality
-------
- NamedParametersSniff: skip Entity-magic accessors (set*/get*/is*) on
classes extending OCP\AppFramework\Db\Entity. Entity::__call uses
args[0], so named arguments break those calls. Eliminates 4 false
positives.
- DashboardService: add the missing WidgetPlacement import (PHPMD).
- PageController: replace \OC::server->get(IManager::class) with proper
DI (Psalm).
- UserAttributeResolver: drop the non-existent IUser::getLanguage() call
and read 'core/lang' from IConfig instead (Psalm).
Frontend warnings
-----------------
- TileEditor + WidgetStyleEditor: NcSelect was passing 'Icon' as the
vue-select label key (option.Icon does not exist). Use input-label
for the visible label and label="label" for the option key.
- AdminSettings: replace HTML <label> + bare NcSelect with input-label
prop, satisfying NcSelect's accessibility requirement.
- DashboardSwitcher / WidgetPicker / WidgetWrapper / TileEditor /
WidgetStyleEditor: add aria-label or input-label to icon-only NcButton
/ unlabeled NcTextField / inline color-pick NcButton instances.
Tests: 106 / 106 passing (293 assertions). composer phpcs / phpmd /
psalm clean. End-to-end API verified for conditional rules, admin
templates, prometheus metrics.
d9ffbb5 to
7eba48d
Compare
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:09 UTC
Download the full PDF report from the workflow artifacts.
7 tasks
rubenvdlinde
added a commit
that referenced
this pull request
May 3, 2026
…#39) Walkthrough of all 9 archived OpenSpec features uncovered three critical runtime bugs in features marked "implemented". This commit restores them and clears the supporting quality stack. Critical fixes -------------- - ConditionalRule.createdAt: switch ?DateTime to ?string ('c' format) to match sibling entities. Doctrine DBAL cannot bind a DateTime without an explicit addType registration; INSERT now succeeds. Same change in AdminSetting.updatedAt. - AdminTemplateService + TemplateService: drop the ramsey/uuid require and inline the random_bytes(16) UUID generator already used by DashboardFactory. The ramsey class was never autoloaded at runtime (Application.php does not require vendor/autoload.php), so admin template creation and template-based dashboard provisioning both threw 500. - DashboardService: stop hardcoding PERMISSION_FULL when auto-creating user dashboards. Read defaultPermissionLevel and defaultGridColumns from AdminSettingMapper and pass them to DashboardFactory. Quality ------- - NamedParametersSniff: skip Entity-magic accessors (set*/get*/is*) on classes extending OCP\AppFramework\Db\Entity. Entity::__call uses args[0], so named arguments break those calls. Eliminates 4 false positives. - DashboardService: add the missing WidgetPlacement import (PHPMD). - PageController: replace \OC::server->get(IManager::class) with proper DI (Psalm). - UserAttributeResolver: drop the non-existent IUser::getLanguage() call and read 'core/lang' from IConfig instead (Psalm). Frontend warnings ----------------- - TileEditor + WidgetStyleEditor: NcSelect was passing 'Icon' as the vue-select label key (option.Icon does not exist). Use input-label for the visible label and label="label" for the option key. - AdminSettings: replace HTML <label> + bare NcSelect with input-label prop, satisfying NcSelect's accessibility requirement. - DashboardSwitcher / WidgetPicker / WidgetWrapper / TileEditor / WidgetStyleEditor: add aria-label or input-label to icon-only NcButton / unlabeled NcTextField / inline color-pick NcButton instances. Tests: 106 / 106 passing (293 assertions). composer phpcs / phpmd / psalm clean. End-to-end API verified for conditional rules, admin templates, prometheus metrics.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
End-to-end walkthrough of all 9 archived OpenSpec features (using fresh test users
mydash-marketing-{a,b},mydash-sales-a,mydash-viewer,mydash-admin) uncovered three runtime bugs in features the spec set claims are implemented. This PR repairs them and clears the supporting quality stack.Critical bug fixes
1. Conditional visibility — broken at INSERT
ConditionalRule::createdAtwas typed?DateTimewhile sibling entities (Dashboard,Tile,WidgetPlacement) use?stringwith'c'format.DateTimeobject withoutaddType('createdAt', 'datetime'); everyPOST /api/widgets/{id}/rulesreturned 500 Object of class DateTime could not be converted to string.AdminSetting::updatedAt— fixed identically.ConditionalService::addRuleupdated to callsetCreatedAt((new DateTime())->format('c')).2. Admin templates — Ramsey UUID class missing
AdminTemplateService.php:108andTemplateService.php:143calledRamsey\Uuid\Uuid::uuid4()->toString().vendor/autoload.phpis never required byApplication.php, soRamsey\\Uuidwas unreachable at runtime even thoughcomposer.jsondeclared it.random_bytes(16)UUID generator pattern asDashboardFactory::generateUuid().ramsey/uuidremoved fromcomposer.json(it had no other consumers and was not actually loaded).POST /api/admin/templatesand template-based dashboard provisioning now succeed.3. Default permission level ignored on auto-provisioned dashboards
DashboardService::tryCreateFromTemplatehardcodedDashboard::PERMISSION_FULLfor the user-fallback dashboard.DashboardFactory::createlikewise hardcodedPERMISSION_FULLandgridColumns: 12.KEY_DEFAULT_PERMISSION_LEVELandKEY_DEFAULT_GRID_COLUMNSfromAdminSettingMapperand pass them through. Verified: setting admin default toadd_onlymakes new dashboardsadd_only.PHP quality
NamedParametersSniffnow skips Entity-magic accessors (set*/get*/is*) on classes extendingOCP\AppFramework\Db\Entity.Entity::__calluses\$args[0], so named-arg calls break those entities. Eliminates 4 false positives without weakening the rule for ordinary methods.WidgetPlacementimport inDashboardService(was inline FQN).\OC::\$server->get(IManager::class)inPageControllerwith proper DI; replaceIUser::getLanguage()(does not exist) inUserAttributeResolverwithIConfig::getUserValue(\$userId, 'core', 'lang', 'en').Frontend warnings
Walkthrough reduced console warnings from ~15 to 1 transient init warning:
option.Iconmismatch:TileEditorandWidgetStyleEditorwere passing:label="t('mydash', 'Icon')"toNcSelect, which made vue-select look up a non-existentoption.Iconkey. Switched to:input-label(visible label) +label="label"(option key).NcSelectmissing input-label inAdminSettings: replaced HTML<label>siblings with the proper:input-labelprop.NcButtonmissing aria-label on icon-only buttons inWidgetPicker,WidgetWrapper,DashboardSwitcher,TileEditor,WidgetStyleEditor— added:aria-label.NcTextFieldmissing label in the WidgetPicker search field — added:label.The 1 remaining warning (
NcInputField missing labelfrom the leading-icon variant of the search field) appears to be a Vue reactivity timing artifact: the:labelprop is set but the warning fires before props resolve. Out of scope to chase further.Out of scope (follow-ups, noted)
prompt()andconfirm()for dashboard create / rename / delete. Replacing requires a real dialog component /@nextcloud/dialogsbuilder; logged as UX follow-up rather than mixed into this PR.phpstan.neondoesn't load Nextcloud server source), separate from any real defects.Test plan
composer phpcs— cleancomposer phpmd— cleancomposer psalm— 0 errors (21 info-level types, suppressed)phpunit(run inside Docker against installed Nextcloud) — 106 / 106 passing, 293 assertions (added 2 new tests forDashboardFactorypermissionLevel + gridColumns parameters)npm run build— succeeds/api/admin/templatesadd_only→ newly auto-provisioned dashboards returnpermissionLevel: "add_only"