Document Generation — @insureco/docman

Docman is the platform's document generation service. Generate PDFs from HTML Handlebars templates or AcroForm PDF templates, store them in S3 with presigned download links and public share URLs, and perform PDF operations (merge, split, page count) — all through @insureco/docman.

Overview

ConceptDescription
HTML templateHandlebars markup rendered to PDF via Puppeteer. Full CSS, landscape/portrait, dynamic content.
PDF templateExisting AcroForm PDF with fill-in fields. Field values injected via pdf-lib.
Template groupOrdered list of HTML and/or PDF templates merged into one output document.
Managed deliveryDocument stored in S3. Returns presigned download URL (1-hour TTL) and permanent public share URL.
Passthrough deliveryRaw PDF buffer returned directly — nothing stored. Useful for previews.

Setup

1. Declare the dependency

# catalog-info.yaml
spec:
  internalDependencies:
    - service: docman   # injects DOCMAN_URL

2. Install the SDK

npm install @insureco/docman

3. Initialize the client

import { DocmanClient } from '@insureco/docman'

// Reads DOCMAN_URL from env. Auth: BIO_CLIENT_ID/SECRET → INTERNAL_SERVICE_KEY → none
const docman = DocmanClient.fromEnv()

Generating Documents

Managed (store in S3)

const result = await docman.generate({
  templateIds: ['tmpl_abc123'],
  data: {
    insuredName: 'Acme Corp',
    policyNumber: 'POL-00123',
    effectiveDate: '2026-03-01',
  },
  name: 'Policy Declarations',
})

// result.downloadUrl  — presigned URL, 1-hour TTL
// result.publicUrl    — permanent share link
// result.documentId   — for future reference

Passthrough (raw buffer)

const pdfBuffer = await docman.generatePassthrough({
  templateIds: ['tmpl_abc123'],
  data: { ... },
})
res.set('Content-Type', 'application/pdf')
res.send(pdfBuffer)

HTML Templates

// Create an HTML template
const template = await docman.createHtmlTemplate({
  name: 'Policy Declarations',
  content: `
    <html>
      <body>
        <h1>Policy #{{policyNumber}}</h1>
        <p>Insured: {{insuredName}}</p>
        <p>Effective: {{effectiveDate}}</p>
      </body>
    </html>
  `,
  options: {
    format: 'Letter',
    landscape: false,
    margin: { top: '1in', bottom: '1in', left: '1in', right: '1in' },
  },
})

PDF Templates (AcroForm)

// Upload an AcroForm PDF template
const template = await docman.createPdfTemplate({
  name: 'ACORD 25',
  file: fs.readFileSync('acord25.pdf'),
  fieldMap: {
    'insuredName': 'policy.insuredName',
    'policyNumber': 'policy.number',
  },
})

// Generate from PDF template
const result = await docman.generate({
  templateIds: [template.id],
  data: { policy: { insuredName: 'Acme Corp', number: 'POL-001' } },
})

PDF Operations

// Merge multiple PDFs
const merged = await docman.merge([buffer1, buffer2, buffer3])

// Split a PDF into individual pages
const pages = await docman.split(pdfBuffer)

// Count pages
const count = await docman.pageCount(pdfBuffer)

Managing Documents

// Get document info
const doc = await docman.getDocument('doc_abc123')
// doc.downloadUrl, doc.publicUrl, doc.name, doc.createdAt

// List documents with filtering
const docs = await docman.listDocuments({
  page: 1,
  limit: 20,
  name: 'Policy',  // search by name
})

// Delete a document
await docman.deleteDocument('doc_abc123')

Testing

import { MockDocmanClient } from '@insureco/docman/testing'

const mockDocman = new MockDocmanClient()
mockDocman.mockGenerate({ downloadUrl: 'https://...', publicUrl: 'https://...' })

// Inject into your service
const service = new PolicyService({ docman: mockDocman })
await service.generateDeclarations(policy)

expect(mockDocman.generated).toHaveLength(1)
expect(mockDocman.generated[0].data.policyNumber).toBe('POL-001')

Key Facts

  • Service URL: docman.tawa.insureco.io — declare via internalDependencies for DOCMAN_URL
  • HTML templates use Handlebars {{variable}} syntax
  • Presigned download URLs expire after 1 hour; public share URLs never expire
  • Template groups are rendered in order and merged into a single PDF output
  • Passthrough delivery is synchronous — suitable for previews but not for large batches

Last updated: February 28, 2026