[Spike] Tools: consolidated audit — backend API contract, target UI mapping, delete semantics
@hmoreras is already working on this.
Since Sep 2, 2026.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Goal
Produce every input the backend and frontend tasks need to start: the endpoint contract for section and tool management, a screen-by-screen mapping of the design onto PrimeNG components and endpoints, the answers to the destructive-action questions the design leaves open, and the security findings on the surface as it stands.
Deliverables
Post the artifacts below as a comment on this issue, then back-link a one-line summary on epic #37351.
1. Feature inventory
One table covering every capability the Tools portlet ships, derived from the design and from the tool-group screen it absorbs. Classify each row Angular / Backend / Drop / Defer with a one-line why. Group rows by target surface — sections panel, available-tools panel, section dialog, tool dialog — so the frontend task can be sized.
Capabilities to account for: list sections in navigation order; select a section; create, rename, delete a section; pick a section icon; reorder sections; list the available-tools catalog; search that catalog; add a tool to a section; remove a tool from a section; reorder tools inside a section; create a custom content tool with name, id, content types and data view mode.
2. Backend API contract
For each capability, state what exists and what has to be built. Group as:
- Consumed as-is —
POST/PUT/DELETE /v1/portlet/customfor custom content tools, whoseCustomPortletFormalready carriesportletId,portletName,baseTypes,contentTypesanddataViewMode. - Exists but not usable as-is —
GET /v1/roles/layoutsreturns the catalog withportletTitlesbut is gated on nothing and lives under the roles path;PUT /v1/portlet/custom/{portletId}/_addtolayout/{layoutId}only handles custom portlets and appends without ordering;DELETE /v1/portlet/portletId/{portletId}removes a portlet from every layout rather than from one section. Say for each whether Tools reuses it, replaces it, or ignores it. - Missing entirely — the available-tools catalog, section create / update / delete, section reorder, and the ordered set of tools inside a section. All four exist only as
RoleAjaxDWR methods (getAllAvailablePortletInfoList,addNewLayout,updateLayout,deleteLayout), which Angular cannot call.
Close with the concrete request and response shape for each endpoint the backend task will add, including how Layout.description (icon) and Layout.tabOrder (position) are named on the wire, and whether the ordered set of tools inside a section is expressed as a full replace or as add/remove/move operations.
Explicit gaps to validate
- Whether
LayoutAPI.setPortletIdsToLayoutpreserves the given order on read, since the tool order inside a section depends on it. - Whether the tools catalog should honour the same filtering
RoleAjax.getAllAvailablePortletInfoListapplies —PortletAPI.canAddPortletToLayoutplus theHIDE_OLD_LANGUAGES_PORTLETskip. - Whether the icon field has a supported value set today, or whether the picker defines one.
3. Destructive-action semantics
The design offers Delete on a section and does not say what it costs. Answer, from the code and from a running instance:
- What
LayoutAPI.removeLayoutdoes to the roles and users that have the section granted, and whether their menus degrade cleanly. - What happens when the last section a role has is deleted.
- What happens to a custom content tool that is deleted while it still sits in one or more sections.
- Whether the confirmation dialog needs to state a consequence (how many roles are affected) or whether a plain confirm is enough.
4. Target UI mapping — design walkthrough
Screen by screen, name the PrimeNG component and the endpoint behind each surface:
- Sections panel — the
SECTIONSheader and New Section button, the drag-ordered rows with icon and name, the nested tool rows under the selected section with their drag handle and remove control, the per-row overflow menu with Edit and Delete, and the footer hint. - Available Tools panel — the section header with its icon, name and info tooltip, the instruction line, the
AVAILABLE TOOLScard header with the New Tool button, the search field, and the checkbox rows with their checked state derived from the selected section. - New Section / Edit Section dialog — name, icon picker, the note that order comes from dragging, and the Cancel / Create action pair.
- New Tool dialog — name, id defaulted from the name with its help text, the content-to-display multi-select over base types and content types, the List / Card data view mode toggle, and the Cancel / Create pair.
State which existing component this reuses and which is new, and which portlet in core-web/libs/portlets/ is the closest structural reference.
5. Security findings
GET /v1/roles/layouts(RoleResource.java:1151) has noWebResource.InitBuilderat all — the navigation catalog is readable by any authenticated caller. Confirm against a running instance and state the fix.- Every
/v1/portlet/customwrite gates onrequiredPortlet("roles"), so a user granted Tools but not Roles cannot create a custom tool. State whether the gate moves to thetoolsportlet id, accepts either, or stays. - Whether the new section and tool endpoints need a license check, or whether role gating is the whole story.
6. Follow-up backlog
The list of [Task] issues this spike files, if any beyond the backend and frontend tasks already on the epic. Filing them is part of the spike.
Inputs
- Design: https://claude.ai/design/p/879ff4e6-1b23-486d-9926-327709e91953?via=share&file=Tools.dc.html (internal — auth required)
dotCMS/src/main/webapp/html/portlet/ext/roleadmin/view_roles.jsp— the tool-group surface at lines 340-365 and the add/edit dialog at lines 75-137dotCMS/src/main/webapp/html/portlet/ext/roleadmin/view_roles_js_inc.jsp—createNewLayout,saveLayout,updateLayout,deleteLayout,addPortletToLayoutListdotCMS/src/main/java/com/dotmarketing/business/ajax/RoleAjax.java—getAllLayouts,getAllAvailablePortletInfoList,addNewLayout,updateLayout,deleteLayoutdotCMS/src/main/java/com/dotcms/rest/api/v1/portlet/PortletResource.java,CustomPortletForm.java,ToolGroupResource.javadotCMS/src/main/java/com/dotcms/rest/api/v1/system/role/RoleResource.java— the layout endpointsdotCMS/src/main/java/com/dotmarketing/business/LayoutAPI.javaandcom/dotmarketing/business/portal/PortletAPI.javacore-web/libs/dotcms-models/src/lib/dot-tool-group.model.ts
Definition of Done
- All six artifacts are posted as a comment on this issue.
- The endpoint contract is concrete enough that the backend task can be worked without reopening the design.
- The destructive-action answers are settled, so the frontend task knows what its confirmation dialogs say.
- Any follow-up tasks are filed and linked from this issue.
- A one-line summary is back-linked on epic #37351.
Refs #37351
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.