PDF Render Module
Purpose
Section titled “Purpose”The PDF Render module (system.shopAccess.pdfRender) provides a service for generating PDF documents via the external Documint API. It acts as the system’s single integration point with Documint — all printing operations (kanban cards, labels, breadcrumbs, purchase orders) pass through this module.
The module has no domain logic of its own. It accepts a pre-constructed rendering job (template ID + payload grid) from a calling module, forwards it to Documint, and returns the resulting PDF URL. Template selection, payload construction, and post-print side effects (e.g., updating print status) are the responsibility of the calling module.
Integrations
Section titled “Integrations”- Item Module (
reference.item): CallsPdfRenderService.render()to print labels and breadcrumbs viaItemPrintingService - Kanban Cards Module (
resources.kanban): CallsPdfRenderService.render()to print kanban cards viaPrintLifecycleImpl - Documint API (external): The third-party PDF rendering service at
api.documint.me
Block Diagram
Section titled “Block Diagram”Public Interface
Section titled “Public Interface”The module exposes an interface with two methods:
PdfRenderService.render()
Section titled “PdfRenderService.render()”| Parameter | Type | Description |
|---|---|---|
job | RenderJob | The template configuration and payload grid to render |
author | String | The user who initiated the print (passed through but not included in the Documint payload) |
live | Boolean? | true for production rendering (counts against quota), false for test/preview (watermarked). null uses the module default. |
Returns: Result<RenderResult> — on success, contains the PDF URL, a generated job ID, the current timestamp, and the template ID used.
Input: RenderJob
Section titled “Input: RenderJob”A RenderJob bundles a template configuration with a grid payload:
| Field | Type | Description |
|---|---|---|
templateConfig | PrintingTemplateConfiguration | Template ID, column count, description, and active flag |
payload | Grid | The grid of JSON elements arranged into rows and columns |
The Grid is constructed from a flat list of JSON elements (one per item) chunked by the template’s column count. For a 2-column template with 5 items, the grid has 3 rows: two full rows of 2 and one row of 1 (padded with an empty JSON object).
Output: RenderResult
Section titled “Output: RenderResult”| Field | Type | Description |
|---|---|---|
url | URL | Pre-signed S3 URL to the generated PDF |
job | UUID | Unique identifier for this render job (generated server-side) |
asOF | TimeCoordinates | Bitemporal timestamp when the render occurred |
templateId | String | The Documint template ID that was used |
PdfRenderService.renderGroups()
Section titled “PdfRenderService.renderGroups()”| Parameter | Type | Description |
|---|---|---|
groups | List<Pair<PrintingTemplateConfiguration, List<JsonElement>>> | List of (template config, item JSON elements) pairs — one pair per template group |
author | String | The user who initiated the print |
live | Boolean? | Rendering mode. null uses the module default. |
debug | Boolean | When true, includes the constructed Documint payload (debugPayload) in each GroupRenderResult. Default: false. |
dryRun | Boolean | When true, constructs the payload but skips the Documint API call. Returns payload without generating PDFs. No side effects. Implies debug. Default: false. |
Returns: Result<CompositeRenderResult> — contains one GroupRenderResult per template group (or sub-batch if a group was split).
Responsibilities:
- For each group, split into sub-batches if the element count exceeds
maxItemsPerDocumintRequest - Pack each batch into a
Gridusing the template’s column count - Render all batches via
DocumintProxy.render()in parallel, limited bySemaphore(maxParallelRenders) - Map each Documint response to a
GroupRenderResult(URL on success, error message on failure) - Compose results into a
CompositeRenderResultwith a generated job UUID and current timestamp
Output: CompositeRenderResult
Section titled “Output: CompositeRenderResult”| Field | Type | Description |
|---|---|---|
job | UUID | Unique identifier for the composite print job |
asOF | TimeCoordinates | Bitemporal timestamp when the render occurred |
results | List<GroupRenderResult> | One entry per template group/sub-batch |
Output: GroupRenderResult
Section titled “Output: GroupRenderResult”| Field | Type | Description |
|---|---|---|
templateId | String | Documint template ID |
description | String | Human-readable template description (e.g., “3 x 5”) |
itemCount | Int | Number of items in this group/sub-batch |
url | URL? | PDF URL on success, null on failure or dry-run |
error | String? | Error message on failure, null on success |
debugPayload | JsonElement? | Constructed Documint payload. Present when debug=true or dryRun=true. Omitted from JSON when null. |
Sequence Diagrams
Section titled “Sequence Diagrams”Successful Render
Section titled “Successful Render”Failed Render (Documint Error)
Section titled “Failed Render (Documint Error)”Configuration
Section titled “Configuration”The module is configured via shop-access/pdf-render/application.conf with two sections:
Module Extras
Section titled “Module Extras”| Key | Type | Default | Description |
|---|---|---|---|
documint.useLive | Boolean | false | Default rendering mode. false = preview (watermarked, no quota impact). true = production (counts against Documint quota). |
documint.apiKey | String | (from build system) | API key for authenticating with the Documint service. Injected at build/deploy time. |
Server Configuration
Section titled “Server Configuration”| Key | Type | Default | Description |
|---|---|---|---|
servers.documint.protocol | String | https | HTTP protocol |
servers.documint.host | String | api.documint.me | Documint API hostname |
servers.documint.port | Int | 443 | HTTPS port |
servers.documint.basePath | String | 1/templates | API root path |
servers.documint.retries | Int | 0 | HTTP retry count |
Initialization
Section titled “Initialization”The module initializes via Application.pdfRenderService():
- Loads module configuration from path
system.shopAccess.pdfRender - Reads
documint.useLivefrom extras (defaults tofalse) - Constructs a
DocumintProxywith:- Server config (protocol, host, port, basePath) from
servers.documint - API key from
extras.documint.apiKey - A shared HTTP client
- Server config (protocol, host, port, basePath) from
- Registers the module with the
ModuleRegistry - Returns
PdfRenderService.Implconfigured with the proxy and the default live flag
The DocumintProxy can be injected for testing via the optional injectedDocumintProxy parameter on pdfRenderModule().
Documint API Contract
Section titled “Documint API Contract”The module communicates with Documint via a single HTTP endpoint:
Request:
- Method:
POST - URL:
https://api.documint.me/1/templates/{templateId}/content?preview={!live}&active={live} - Header:
api_key: {apiKey} - Content-Type:
application/json - Body: The
GridJSON — an object with arowarray ofPrintColumnobjects, each containing acolumnarray of item JSON objects
Response (success):
{ "name": "Document Name", "template": "template-id", "account": "account-id", "url": "https://documint.s3.amazonaws.com/...pdf"}The url field is a pre-signed S3 URL to the generated PDF document.
Response (error): Non-200 HTTP status with an error body. The module wraps these as AppError.ExternalService with the HTTP status code and response body.
Copyright: © Arda Systems 2025-2026, All rights reserved