Pulp Engine Document Rendering
Get started
Release v0.36.0

Pulp Engine v0.36.0 — Release Notes

This release fixes the version-history lazy boundary in the editor: the modal now mounts on-demand when the user opens it, eliminating hidden API traffic and adding an explicit loading state in place of the previous invisible fallback.


What changed

1. Version-history modal is now genuinely on-demand

Before: VersionHistoryModal was mounted into the React tree as soon as any API-backed template was open (gated on isApiTemplate, not on the user actually opening the history panel). Its data-fetch effect ran on every templateKey / currentVersion change — even while the modal was closed — producing hidden API calls that the user never requested.

After: The component only mounts when the user opens version history (showHistory && template && isApiTemplate). The data-fetch effect also carries an explicit open guard (if (!open) return) as a secondary safety for future refactors.

Net effect: no version-list API calls until the user clicks History.

2. Explicit loading state instead of invisible Suspense fallback

The Suspense boundary for the lazy VersionHistoryModal chunk previously used fallback={null}, so the first-time code-split download produced no visible feedback.

After: The fallback renders an open dialog shell with a spinner and the title “Version History”, matching the style of the component that is about to appear.

The internal “Loading…” text shown while the version list is fetched now also includes a spinner, consistent with the style used in PublishGateDialog.

3. Close/reopen behavior

Each open now triggers a fresh version-list fetch rather than reusing data pre-loaded while the modal was closed. This is the correct behavior — it ensures the list always reflects the current server state, including any saves made since the last open.

4. Documentation — auth/trust-model corrections in api-guide and runbook

A doc-truth audit found three drifted statements in the auth/trust-model sections:

  1. docs/api-guide.md — renderConfig trust model, “These fields can be set via” Was: POST /templates and PUT /templates/:key — require admin scope Now: POST /templates and PUT /templates/:key — require editor or admin scope Justified by: apps/api/src/plugins/auth.plugin.ts:53return ['admin', 'editor'] for all non-DELETE, non-restore template routes. The old text contradicted both the code and the authorization matrix earlier in the same document.

  2. docs/api-guide.md — renderConfig table, customCss trust level column Was: Trusted authors / preview callers Now: Template authors (\editor` or `admin`) / preview callersThe phrase "trusted authors" was ambiguous and could be read as admin-only. The code applies no scope restriction tocustomCssbeyond the route-level check atauth.plugin.ts:53`.

  3. docs/runbook.md — “Verify templates” section, GET examples Was: (admin key required) on the GET /templates and GET /templates/:key/sample curl examples. Now: (admin or editor key) The adjacent POST /render/validate example already correctly said “(editor or admin key)”; the GET comments were inconsistent. Justified by auth.plugin.ts:53.

No code changes. No migration required.

5. Accessibility — publish dialog accessible description

PublishGateDialog was missing a DialogDescription, causing Radix UI to emit a console warning on every open of the publish/update flow.

After: A visually-hidden (sr-only) DialogDescription is now rendered inside the dialog header, satisfying Radix’s accessibility requirement and giving screen readers a static description of the dialog’s purpose. The visible UI is unchanged.

6. README — commercial positioning pass

Repositioned README.md for a developer product audience. No content was removed; sections were reordered to lead with value proposition, quick start, and API demo before deployment detail. Specific changes:

  • Opening rewritten: removed “for internal engineering teams” framing; replaced with a plain developer-facing value proposition
  • New “What’s included” section added after the opening
  • New “How it works” paragraph added (editor → storage → render API story)
  • Docker quick start and local quick start moved above storage/security detail
  • API demo (“API at a glance”) moved up to follow “How it works”
  • “Storage modes” section renamed to “Storage backends”
  • docs/runbook.md H1 updated: “First Internal Deployment Runbook” → “Operator Runbook”

No code changes. No API changes. No migration required.


Upgrade

No server-side changes. Editor-only fix; no environment variables, no schema migrations.

docker pull ghcr.io/OWNER/pulp-engine:v0.36.0