Skip to content

Create new endpoint for expose style editor schemas#35377

Draft
dario-daza wants to merge 4 commits into35270-unify-style-editor-schema-definition-use-content-type-tab-as-single-source-of-truth-for-headless-and-traditional-pages-frontendfrom
35270-unify-style-editor-schema-definition-new-endpoint-for-schemas
Draft

Create new endpoint for expose style editor schemas#35377
dario-daza wants to merge 4 commits into35270-unify-style-editor-schema-definition-use-content-type-tab-as-single-source-of-truth-for-headless-and-traditional-pages-frontendfrom
35270-unify-style-editor-schema-definition-new-endpoint-for-schemas

Conversation

@dario-daza
Copy link
Copy Markdown
Member

@dario-daza dario-daza commented Apr 17, 2026

Proposed Changes

  • Create a new endpoint in the PageAPI to retrieve the Content Type SCHEMAS present in a page, the endpoint is GET /api/v1/page/{pageId}/contenttype-schema
  • Reuse logic to retrieve the Schemas from the Content Type metadata from the Contentlets present in a Page.
  • Create Postman test to the new endopoint.

This PR fixes: #35270

This PR fixes: #35270

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 17, 2026

Claude finished @dario-daza's task in 1m 52s —— View job


  • Read changed files
  • Review endpoint implementation
  • Review helper logic
  • Review frontend changes
  • Review OpenAPI spec and Postman tests

PR Review

1. console.log left in production code — BLOCKER

page-api.ts:237 — Debug statement was left in shipping code. Must be removed before merge.

console.log('styleEditorSchemas', styleEditorSchemas);

Fix this →

2. Schema fetch is now sequential — performance regression

Previously both the GraphQL call and the schema fetch ran concurrently via Promise.all. The refactor moved the schema fetch to happen after the GraphQL response resolves, adding its full round-trip latency to the critical path. There's no dependency between the two calls — pageId (needed for the schema endpoint) isn't available until after GraphQL, but the page identifier is present on the GraphQL response — this is the forced sequencing. If this ordering is intentional and unavoidable, it should be called out explicitly; otherwise, parallelism should be restored wherever possible.

3. Silent JSON parse failure in getStyleEditorSchemas — still unresolved

PageResourceHelper.java:900-903 — The Try.of() block still has no onFailure handler. Invalid JSON, a non-String metadata value, or any other parse error is silently dropped. Noted in the previous review cycle.

// Add onFailure logging:
Try.of(() -> {
    final String schemaStr = (String) meta.get("DOT_STYLE_EDITOR_SCHEMA");
    return (Object) mapper.readTree(schemaStr);
})
.onFailure(e -> Logger.warn(PageResourceHelper.class,
        "Could not parse DOT_STYLE_EDITOR_SCHEMA: " + e.getMessage()))
.getOrNull()

Fix this →

4. No null guard before mapper.readTree(schemaStr)

PageResourceHelper.java:901-902 — If DOT_STYLE_EDITOR_SCHEMA key exists in metadata but with a null value, meta.get(...) returns null, and mapper.readTree(null) behavior varies by Jackson version (NullNode or exception). A content type that has the metadata key but with no value set would produce unexpected output. Add a guard:

final String schemaStr = (String) meta.get("DOT_STYLE_EDITOR_SCHEMA");
if (schemaStr == null) return null;
return (Object) mapper.readTree(schemaStr);

5. OpenAPI description still incorrect — unresolved

PageResource.java:1932 — "Returns an empty object when no schemas are found" but the return type is a List. Flagged in the previous review cycle.

6. Leftover TODO comment

page-api.ts// todo: move to another class to call the endpoint — if this isn't tracked elsewhere, it's tech debt landing in main.


Clean

  • Removal of 300+ lines of hardcoded mock data is the right call.
  • The HTMLPageAssetRenderedBuilder refactor to delegate to PageResourceHelper.getStyleEditorSchemas is correct and removes duplication cleanly.
  • Permission level (READ) and rejection of unauthenticated users (rejectWhenNoUser(true)) are now correctly configured.
  • Frontend spec updated to mock the new endpoint correctly.
  • Postman collection additions look solid for the happy path.

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 17, 2026

Claude finished @dario-daza's task in 2m 35s —— View job


PR Review

  • Read changed files
  • Review endpoint implementation
  • Review helper logic
  • Review OpenAPI spec
  • Review Postman tests

Issues Found

1. Permission level too high for a read operation

PageResource.java:1965 — The endpoint requires PermissionLevel.EDIT for what is a pure read. This blocks contributors with only READ access and any headless/frontend consumer. If this data is needed for rendering headless pages, this gating is wrong.

APILocator.getPermissionAPI().checkPermission(page, PermissionLevel.EDIT, user);
// Should likely be PermissionLevel.READ

Fix this →

2. requiredBackendUser(true) blocks frontend/headless callers

PageResource.java:1959 — Combined with the EDIT permission, this double-gates the endpoint to backend editors only. If style editor schemas are consumed during headless rendering (which seems to be the intent based on the UVE/HTMLPageAssetRenderedBuilder connection), frontend API consumers are locked out.

3. Silent failure swallows JSON parse errors in getStyleEditorSchemas

PageResourceHelper.java:900-903 — The inner Try.of() has no onFailure handler. If DOT_STYLE_EDITOR_SCHEMA holds invalid JSON or is not a String, the failure is silently dropped with no log. The outer method (getStyleEditorSchemasInPage) does log contentlet load failures — this should too.

// Current: errors silently discarded
.map(meta -> Try.of(() -> {
    final String schemaStr = (String) meta.get("DOT_STYLE_EDITOR_SCHEMA");
    return (Object) mapper.readTree(schemaStr);
}).getOrNull())

// Should add onFailure:
.map(meta -> Try.of(() -> {
    final String schemaStr = (String) meta.get("DOT_STYLE_EDITOR_SCHEMA");
    return (Object) mapper.readTree(schemaStr);
})
.onFailure(e -> Logger.warn(PageResourceHelper.class, "Could not parse DOT_STYLE_EDITOR_SCHEMA: " + e.getMessage()))
.getOrNull())

Fix this →

4. ClassCastException suppressed if schema value is not a String

PageResourceHelper.java:901(String) meta.get("DOT_STYLE_EDITOR_SCHEMA") will throw ClassCastException if the metadata was stored as a non-String type (e.g., a Map or JsonNode). This is caught by Try and silently discarded (see issue #3 above). An explicit null/type check would be cleaner and catch misuse during development.

5. OpenAPI description inconsistency

PageResource.java:1932 — The @Operation description says "Returns an empty object when no schemas are found" but the actual return type is a List (array). This also appears in the generated openapi.yaml:12226.

Fix this →

6. No unit or integration tests for new code

Neither getPageContentTypeSchemas, getStyleEditorSchemasInPage, nor the static getStyleEditorSchemas method has a corresponding test. The Postman tests cover the happy path end-to-end, but there's no coverage for:

  • null/invalid schema JSON in metadata
  • page with no contentlets
  • permission denial
  • DOT_STYLE_EDITOR_SCHEMA key absent vs. present but null

7. Minor: Javadoc on getPageContentTypeSchemas says { contentType, schema } entries

PageResource.java:1924 — The @return says "List of { contentType, schema } entries" but the response is just a flat list of parsed schema objects. The contentType property exists only because it is embedded inside the schema JSON itself (as confirmed by the Postman test assertions). The Javadoc is misleading.


Clean

  • Refactoring in HTMLPageAssetRenderedBuilder.java to reuse PageResourceHelper.getStyleEditorSchemas is correct and removes duplication.
  • ResponseEntityContentTypeSchemaView wrapper follows the existing pattern correctly.
  • Multi-tree deduplication logic is solid.

…type-tab-as-single-source-of-truth-for-headless-and-traditional-pages-frontend' into 35270-unify-style-editor-schema-definition-new-endpoint-for-schemas
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant