Skip to content

Users cannot reach eleven dashboard features whose backend is already built #680

Open

Description

@rubenvdlinde

The capability matrix merged in #678 (merge e8dcc75e, file openspec/parity/capabilities.json on development, read at 961fc8bc) found eleven capabilities whose backend is written and routed, but which no page in the app lets a user reach. Each row below is marked built.state: "building" or "built" with a reachedOn that says nothing reaches it, or reaches only half of it.

How the matrix traced this: from the route, to the store action that wraps it, to a component that calls the store action. A route-to-caller grep is not enough. For seven of the eleven, src/services/api.js or a store module wraps the route, so a grep for the URL or the wrapper finds a hit in src/ and would credit the capability as reachable. The other four (edit lock, personal hide layer, version rollback, translations) have no wrapper anywhere in src/ at all.

Evidence links point at 961fc8bc.

  1. Edit lock (row build-edit-lock). Routes POST|PUT|DELETE|GET /api/dashboards/{uuid}/lock and /lock/force-release (appinfo/routes.php:159-174). Service: lib/Service/DashboardLockService.php:116 (acquireLock). No wrapper in src/services/api.js, no store action. reachedOn: "nothing: /api/dashboards/{uuid}/lock has no caller anywhere in src/".
  2. Personal hide layer (row build-personal-hide). Routes GET|PUT|DELETE /api/dashboards/{dashboardId}/personal-layer (appinfo/routes.php:255-262). Service: lib/Service/PersonalLayerService.php:15. No wrapper, no store action. reachedOn: "nothing: /api/dashboards/{dashboardId}/personal-layer has no caller in src/".
  3. Version rollback (row build-rollback). Routes GET|POST /api/dashboards/{uuid}/versions, GET .../versions/{versionNumber}, POST .../versions/{versionNumber}/restore (appinfo/routes.php:288-297). Service: lib/Service/DashboardVersionService.php:433 (restoreVersion). No wrapper, no store action. reachedOn: "nothing: /api/dashboards/{uuid}/versions and its restore route have no caller in src/".
  4. Dashboard tree (row dash-tree). Route GET /api/dashboards/tree (appinfo/routes.php:127), wrapped by getDashboardTree() in src/services/api.js:386, called by store action loadDashboardTree() in src/stores/dashboard.js:1106. Service: lib/Service/DashboardTreeService.php:105. reachedOn: "nothing: the store action loadDashboardTree has no caller outside src/stores/".
  5. Dashboard translations (row dash-languages). Routes under /api/dashboards/{uuid}/translations and GET /api/dashboards/{uuid}/resolved (appinfo/routes.php:79-101). Service: lib/Service/DashboardTranslationService.php:93. No wrapper, no store action. reachedOn: "nothing: /api/dashboards/{uuid}/translations and /resolved have no caller in src/".
  6. Metadata fields (row dash-metadata). Routes /api/admin/metadata-fields and GET|PUT /api/dashboards/{uuid}/metadata (appinfo/routes.php:486-503), wrapped in src/services/api.js:873-899, store actions fetchMetadataFields() and updateDashboardMetadata() in src/stores/dashboard.js:1310 and :1384. Service: lib/Service/MetadataService.php:71. reachedOn: "nothing: the store actions fetchMetadataFields and updateDashboardMetadata have no component caller".
  7. Tile-click report (row tile-clicks). Clicks are recorded from the Workspace page (src/components/TileWidget.vue:94), but the report is never shown: src/services/api.js:305 getAnalyticsTopTiles() and getTileAnalyticsCsvExport() (src/services/api.js:378) have no caller outside api.js. Routes /api/admin/analytics/tiles/top and /tiles/export (appinfo/routes.php:523-524). reachedOn: "clicks are recorded from the Workspace page; nothing shows them: getAnalyticsTopTiles and the tile CSV export have no caller in src/".
  8. Kiosk playlists (row s-kiosk). Routes /api/kiosk/playlists and the public GET /kiosk/{token} (appinfo/routes.php:206-215). Service: lib/Service/KioskService.php:263 (renderPlaylist, returns an array the controller sends as JSON). Store: src/stores/kioskPlaylists.js:19 useKioskPlaylistStore, imported by nothing. reachedOn: "nothing: /kiosk/{token} returns JSON that no page renders, and useKioskPlaylistStore has no caller, so no screen creates a playlist". Already tracked in detail in dashboard-kiosk-mode: 23 spec scenarios are unsatisfiable — the kiosk frontend was removed in 1fd075c5, backend still routed #93; listed here so the eleven stay together.
  9. Publish and schedule (row s-schedule). Routes POST /api/dashboards/{uuid}/publish, /unpublish, /schedule (appinfo/routes.php:72-76), wrapped in src/services/api.js:220-249, store actions publishDashboard() and scheduleDashboard() in src/stores/dashboard.js:518 and :558. Service: lib/Service/DashboardService.php:2069 (schedule). reachedOn: "nothing: the store actions publishDashboard and scheduleDashboard have no component caller".
  10. Acknowledgement authoring (row e-ack-ask). The read-and-confirm prompt renders on the Workspace page (src/components/WidgetWrapper.vue:155), and the backend accepts the flag (lib/Service/PlacementUpdater.php:139), but no form in src/ sends requiresAcknowledgement. Every src/ reference to it reads the flag; none writes it. reachedOn: "the prompt renders on the Workspace page, but no form sets requiresAcknowledgement; only PUT /api/widgets/{placementId} does".
  11. Reactions (row e-react). Routes under /api/dashboards/{uuid}/reactions (appinfo/routes.php:230-247), wrapped by getDashboardReactions() in src/services/api.js:1129, store actions addReaction() and fetchReactionsSummary() in src/stores/dashboard.js:1256 and :1229. Service: lib/Service/ReactionService.php:91. reachedOn: "nothing: the store actions addReaction and fetchReactionsSummary have no component caller".

Why it matters: each of these is maintained, tested and routed code that no user can use, and a tool that credits a capability because its URL appears somewhere in src/ will keep counting all eleven as shipped.

Source: #678, rows build-edit-lock, build-personal-hide, build-rollback, dash-tree, dash-languages, dash-metadata, tile-clicks, s-kiosk, s-schedule, e-ack-ask, e-react.

Activity

  1. github-actions commented on Sep 25, 2026

    @github-actions
    Contributor

    Thank you for opening this issue! It has been assigned to @rubenvdlinde for review.

    What happens next:

    1. A maintainer will review this issue and determine the appropriate action
    2. If accepted, it may be converted into an OpenSpec change for structured development
    3. You will be notified of any status changes

    Triage labels:

    • triage:accept-feature — accepted as a new feature
    • triage:accept-bugfix — accepted as a bug fix
    • triage:needs-info — more information needed
    • triage:wontfix — will not be addressed
    • triage:duplicate — duplicate of another issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

triageAwaiting triage

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions