Description
Today, when content is created or updated through the workflow fire endpoints (/api/v1/workflow/actions/**/fire, firemultipart, bulk fire), a Story Block (Block Editor) field value is stored in the database exactly as sent. If a client sends HTML or Markdown instead of a Tiptap/ProseMirror JSON document, dotCMS persists that raw string. The conversion to the proper ProseMirror object only happens later, client-side, when a human opens the contentlet in the editor and re-saves it.
This is a problem for non-interactive/automated content creation (AI agents via the MCP server, headless imports, migrations): the content looks broken to any consumer that reads the field as ProseMirror JSON (GraphQL, REST, SDK renderers) until a person manually opens and re-saves each contentlet.
What we want
On the workflow fire path, when a Story Block field's incoming value is HTML or Markdown (not already a valid Tiptap JSON document), the backend should convert it to a Tiptap/ProseMirror JSON object server-side and store that, so no human editor round-trip is required.
Why this is now feasible
PR #35728 (issue #35727) adds com.dotcms.tiptap.TiptapMarkdown, a bidirectional Tiptap-JSON ⇄ Markdown converter at the Java level — including the Markdown → Tiptap JSON direction (via commonmark-java). This provides the conversion primitive needed to do the transform during content save. This issue is about wiring that converter into the fire/save path.
Related work
Depends on #35728 being merged (or its TiptapMarkdown converter being available).
Acceptance Criteria
Priority
Medium
Additional Context
Once this lands, the MCP server's existing guidance (telling agents to send HTML/Markdown for Block Editor fields) becomes fully correct with no human follow-up step. The fire endpoints already document that Block Editor fields accept HTML/Markdown.
Description
Today, when content is created or updated through the workflow fire endpoints (
/api/v1/workflow/actions/**/fire,firemultipart, bulk fire), a Story Block (Block Editor) field value is stored in the database exactly as sent. If a client sends HTML or Markdown instead of a Tiptap/ProseMirror JSON document, dotCMS persists that raw string. The conversion to the proper ProseMirror object only happens later, client-side, when a human opens the contentlet in the editor and re-saves it.This is a problem for non-interactive/automated content creation (AI agents via the MCP server, headless imports, migrations): the content looks broken to any consumer that reads the field as ProseMirror JSON (GraphQL, REST, SDK renderers) until a person manually opens and re-saves each contentlet.
What we want
On the workflow fire path, when a Story Block field's incoming value is HTML or Markdown (not already a valid Tiptap JSON document), the backend should convert it to a Tiptap/ProseMirror JSON object server-side and store that, so no human editor round-trip is required.
Why this is now feasible
PR #35728 (issue #35727) adds
com.dotcms.tiptap.TiptapMarkdown, a bidirectional Tiptap-JSON ⇄ Markdown converter at the Java level — including the Markdown → Tiptap JSON direction (viacommonmark-java). This provides the conversion primitive needed to do the transform during content save. This issue is about wiring that converter into the fire/save path.Related work
feat(tiptap): convert Story Block content to MarkdownAcceptance Criteria
Priority
Medium
Additional Context
Once this lands, the MCP server's existing guidance (telling agents to send HTML/Markdown for Block Editor fields) becomes fully correct with no human follow-up step. The fire endpoints already document that Block Editor fields accept HTML/Markdown.