Skip to content

Document templates

Status: smart parsing, bulk filling, sharing, and bulk file management enabled.

Template creation has a dedicated page reached from the library. Uploads use the shared drag-and-drop zone and accept one DOCX file up to 20 MB. Ideal placeholders are short, unique names in square brackets, for example [first_name], [address], and [contract_date]. One placeholder may be reused throughout a document, but a placeholder should remain inside one continuous Word formatting run. Node extracts unique placeholders and supplies resolved values to docxtemplater with the same delimiters.

After field parsing has made the template ready, a separate job renders the first page through headless LibreOffice and Poppler and stores a private PNG preview. Grid cards and the template detail page show the page image at document proportions, while list rows use the same image as a small thumbnail. Processing templates show a skeleton and unavailable previews fall back to a document icon. A preview failure is recorded separately and does not prevent an otherwise valid template from becoming ready. Smart parsing regenerates the preview after rewriting the DOCX.

Deployment runs php artisan templates:generate-previews to queue an idempotent backfill for ready templates created before preview support. Templates with an existing preview are skipped; templates with a recorded preview error are retried after the worker environment is corrected.

Members generate DOCX or PDF. PDF requires headless LibreOffice. Templates and generations move through processing, ready, or failed, with errors stored for operations.

Originals, previews, and outputs are private; downloads and preview responses always pass membership authorization. Preview URLs expose no storage path and return private browser-cache headers. Template records use soft deletion, with object lifecycle cleanup deferred.

Parsing and field intelligence

Standard parsing warns the member when it finds no placeholders instead of presenting an empty fill form.

Smart parse is an asynchronous, metered capability. It sends extracted template text—not the DOCX binary—to the configured OpenAI Responses API with storage disabled, asks for JSON Schema-constrained field candidates, and rewrites exact dotted, underscored, or otherwise blank source tokens to stable [snake_case] placeholders. The original file path stays private. Failures are visible on the template and create an admin operational notification.

Every template stores backward-compatible placeholder keys plus structured field definitions: key, label, optional group, source, and resolver. The resolver registry currently supports user/API-provided values and internal variables (current_date, current_datetime, workspace.name, user.name, user.email, and template.name). This is the extension seam for later field groups, recurring field intelligence, and additional trusted resolver plugins.

Bulk filling

Bulk filling is a three-step workflow:

  1. Select a ready template.
  2. Upload an XLSX whose first row contains unique column headings. The batch name is derived from the selected template.
  3. Map each provided field to a spreadsheet column, then generate one normal workspace document per non-empty data row and optionally build a private ZIP archive.

Free and paid row caps are configuration-driven. Oversized workbooks fail before queue dispatch. Generated records use the same private storage, quota, activity stream, downloads, and resolver pipeline as single-document generation.

Library and generated files

The signed-in dashboard shows recent templates. The template library is reserved for browsing and storage status, while template upload lives on its own page. Template and generated-file directories both support list and grid views. Generated files always display their source template, and members can select files for ZIP download or deletion.

Ready documents can be shared by email. The email contains a signed, throttled, expiring download URL; it does not expose the private object path or attach the stored document.

Parsing and generation status changes are delivered over one authenticated server-sent event connection. The browser performs a full page refresh when the queue work finishes. The client does not poll the application with repeated requests.