Skip to main content

Canonical document rendering — horizontal surface

Tier: Public
Status: As-built post RFC-0007 PR1–7 (2026-05-25); registry updated for MRP/CRP Wave 6 (2026-05-27)
Audience: module authors, API maintainers, AI consultant implementors, reviewers
Resolves: RFC-0007 — operational companion to governance text (RFC-0003 shape: commitment in RFC, engines in rationale, as-built here)
Builds on: canonical-document-rendering-engine-rationale.md, packages/platform/rendering/README.md, packages/sdk/module-sdk/README.md

Disclaimer. This is the single source of truth for registered module:template@version refs, delivery-mode behavior, and the module-author checklist. RFC-0007 commits obligations; this doc tracks what ships. Update §2 in the same PR as any new documentTemplates registration.


1. Summary

ConcernOwnerDoc / code
GovernanceRFC-0007docs/rfcs/0007-canonical-document-rendering.md
Engine picksRationalecanonical-document-rendering-engine-rationale.md
Adapter package@umbraculum/renderingpackages/platform/rendering/
Template registrationregisterModule({ documentTemplates })packages/sdk/module-sdk/src/moduleRegistry.ts
Job orchestrationAPI serviceservices/api/src/services/rendering/
Platform AI toolrender_documentdocs/AI-CONSULTANT.md

Modules MUST NOT bundle parallel PDF/XLSX/DOCX/CSV/barcode libraries or a private job queue (RFC-0007 §8).

OpenAPI: /rendering/* job routes appear under tag rendering in the alpha partial spec — API-OPENAPI.md.

Refs use <module>:<name>@v<major>. Collision across modules is forbidden; collision within a module is caught at registerModule() boot.

Template refKindModuleDelivery (typical)HTTP / entryInput schema
brewery:beerjson-export@v1jsonbrewerystream-responseGET recipes exportbrewery/documentTemplates.ts
pim:product-catalog-csv@v1csvpimpersist-to-media (async job)POST /pim/channel-feeds/product-catalog-csv/jobspim/documentTemplates.ts
mrp:work-order-pdf@v1pdfmrppersist-to-mediaPOST /mrp/work-orders/:orderId/render-jobs@umbraculum/mrp-contracts
mrp:route-card-pdf@v1pdfmrppersist-to-mediarender-job routes@umbraculum/mrp-contracts
mrp:material-requirements-xlsx@v1xlsxmrppersist-to-mediarender-job routes@umbraculum/mrp-contracts
mrp:production-order-csv@v1csvmrppersist-to-mediarender-job routes@umbraculum/mrp-contracts
crp:capacity-load-xlsx@v1xlsxcrppersist-to-mediarender-job routes@umbraculum/crp-contracts
crp:schedule-pdf@v1pdfcrppersist-to-mediarender-job routes@umbraculum/crp-contracts
crp:resource-calendar-csv@v1csvcrppersist-to-mediarender-job routes@umbraculum/crp-contracts
crp:conflict-report-pdf@v1pdfcrppersist-to-mediarender-job routes@umbraculum/crp-contracts

Update trigger: any PR that adds or renames entries in a module's documentTemplates.ts MUST add or update the row above and cite this file in the PR description.

Discovery at runtime: listRegisteredDocumentTemplates() (module registry) — see renderingJobs.test.ts for registration tests.


3. Delivery modes

ModeMeaningShipped today
stream-responseSynchronous bytes returned on the HTTP response (e.g. BeerJSON export)Yes — brewery proof
persist-to-mediaAsync BullMQ job; artifact stored; signed retrieval URL when completeYes — PIM channel feed, MRP/CRP render-jobs
emailRendered body handed to outbound deliveryRejectedRFC-0008; composition only until notifications service lands

Job state lives in Prisma rendering schema (RFC-0002 convention 4). Redis hosts BullMQ per docs/REDIS-ARCHITECTURE.md. Gotenberg sidecar: gotenberg/gotenberg:8 in Compose for HTML→PDF.


4. Module author checklist

  1. Define DocumentTemplate<TData> in the module's API documentTemplates.ts with Zod schema (RFC-0003).
  2. Export stable MODULE_*_TEMPLATE_REF constants from packages/<code>-contracts when the payload is shared or cited by routes/tests.
  3. Register via registerModule({ documentTemplates: [...] }) in services/api/src/modules/<code>/index.ts.
  4. Implement render(data, context) using @umbraculum/rendering adapters only — no direct Gotenberg/exceljs in module code except through the shared helpers used by existing templates.
  5. Expose routes: either sync stream (brewery pattern) or async RenderingJobService.submit (PIM / MRP / CRP pattern — copy pimChannelFeedsRoutes.ts).
  6. Test: registration + L2 isolation + job success (see pimChannelFeeds.test.ts, mrpCrpRendering.test.ts).
  7. Document: add a row to §2 above; add a Rendering subsection on the module surface doc pointing here for horizontal rules and listing module-specific refs.

Reference consumer for async CSV: canonical-pim-module-surface.md §8.3. Reference consumer for eight templates: mrp-crp-wave-6-rendering-templates-build-log.md.


5. Platform entry points

EntryPath
RenderingJobServiceservices/api/src/services/rendering/renderingJobService.ts
render_document AI toolservices/api/src/services/ai/tools/rendering/renderDocument.ts
HTML→PDF helperservices/api/src/services/rendering/htmlToPdf.ts
Job routes (generic)services/api/src/routes/renderingJobs.ts

6. Cross-references