Goal
Ship the Angular Velocity Playground portlet end-to-end — UI, portlet.xml registration, and rollback toggle — in a single PR.
Frontend scope
New Nx library: core-web/libs/portlets/dot-velocity-playground/
dot-velocity-playground-shell.component.ts
dot-velocity-playground-page.component.ts
lib.routes.ts exported as dotVelocityPlaygroundRoutes
- SignalStore:
DotVelocityPlaygroundStore
- Data-access service:
core-web/libs/data-access/src/lib/dot-velocity-playground/dot-velocity-playground.service.ts calling POST /api/vtl/dynamic/
- PrimeNG:
p-splitter, Monaco editor (Velocity / VTL language mode), output panel that renders JSON, XML, and plain text outputs distinctly
- History affordance equivalent to the legacy dropdown (scope and storage location finalized by the spike — default: last 10 entries in
localStorage)
- Tests: Jest + Spectator for shell / page / store with
data-testid selectors on all interactive elements
Backend wiring
dotCMS/src/main/webapp/WEB-INF/portlet.xml:
- Replace the JSP-backed
velocity_playground portlet with the new Angular shell.
- Add a
velocity_playground-legacy entry pointing at the existing JSP as the rollback escape hatch.
- Add the corresponding
PortletID enum entry and i18n key (or reuse the existing velocity_playground key).
- Live toggle so admins can revert to the JSP without redeploy.
Inputs
- Spike output from the consolidated audit issue (parity matrix + API audit + UI sketch).
- Portlet conventions:
core-web/libs/portlets/CLAUDE.md.
Definition of Done
Every Gherkin scenario in epic #34737's Definition of Done passes manually against the local build:
- Admin runs valid Velocity code
- Output renders JSON, XML, and plain text
- Velocity error surfaces inline
- History recall
- Resizable split-pane
- Non-admin role is blocked
- Unlicensed instance blocks the portlet
- Rollback to legacy JSP without redeploy
Goal
Ship the Angular Velocity Playground portlet end-to-end — UI,
portlet.xmlregistration, and rollback toggle — in a single PR.Frontend scope
New Nx library:
core-web/libs/portlets/dot-velocity-playground/dot-velocity-playground-shell.component.tsdot-velocity-playground-page.component.tslib.routes.tsexported asdotVelocityPlaygroundRoutesDotVelocityPlaygroundStorecore-web/libs/data-access/src/lib/dot-velocity-playground/dot-velocity-playground.service.tscallingPOST /api/vtl/dynamic/p-splitter, Monaco editor (Velocity / VTL language mode), output panel that renders JSON, XML, and plain text outputs distinctlylocalStorage)data-testidselectors on all interactive elementsBackend wiring
dotCMS/src/main/webapp/WEB-INF/portlet.xml:velocity_playgroundportlet with the new Angular shell.velocity_playground-legacyentry pointing at the existing JSP as the rollback escape hatch.PortletIDenum entry and i18n key (or reuse the existingvelocity_playgroundkey).Inputs
core-web/libs/portlets/CLAUDE.md.Definition of Done
Every Gherkin scenario in epic #34737's Definition of Done passes manually against the local build: