Document Engine Deep Dive

How the Document Engine Works

A complete technical walkthrough of document generation, rendering, email delivery, agreement clauses, and invoice creation -- from Salesforce to PDF to inbox.

Layer 1: VF PDFLayer 2: React WebLayer 3: Client PDF
1

What Is the Document Engine?

The 30-second explanation

The Document Engine is a system for generating professional documents from Salesforce data. It supports three template types today: Invoices, Client Agreements, and Contractor Agreements. More templates can be added.

Invoice

Hours, line items, rates, totals, A/R

Client Agreement

8 clauses, terms, signature blocks

Contractor Agreement

8 clauses, scope, compensation, IP

Key concept: Frozen Snapshots

Each document is a frozen snapshot of data at generation time. Even if the underlying entity, work items, or rates change later, the document always reflects the state at the moment it was created. This is critical for legal and financial documents -- an invoice must never retroactively change.

Design philosophy: Try before generalizing

The current JSON metadata approach is deliberately simple. There is no separate Fields object or abstract template schema yet -- and that is intentional. The current approach of freezing all document data into a JSON snapshot works well for the three template types that exist today. The plan is to try this approach first with real production usage and generalize later only if the pattern proves it needs abstraction. Premature generalization would add complexity without proven benefit.

Key concept: Public Tokens

Every document gets a 64-character hex public token (e.g., a7f3e91b2c4d...). This token enables unauthenticated access to the document via a Salesforce Site. Anyone with the token can view the document -- no login required. Tokens are cryptographically random and practically unguessable.

2

Versioning, Approval Flow & PDF Hyperlinks

Production-grade document lifecycle

Documents in the real world go through revisions, need stakeholder sign-off, and must link back to source records. The Document Engine handles all three with versioning, an approval workflow, and clickable PDF hyperlinks.

Document Versioning

Regenerate an invoice or agreement and the engine creates a new version linked to the original document. Each version retains its own frozen JSON snapshot, so you can compare any two versions side by side. The latest version is always the active one, but prior versions remain accessible for reference and compliance.

Concrete example: Correcting an invoice

1You generate INV-025 for March 2026. Client reviews and notices 2 hours were logged to the wrong work item.
2You fix the work log in Salesforce, then click “Regenerate.” The engine creates INV-025 v2 with a fresh snapshot.
3INV-025 v1 is still accessible -- both versions have their own public token and snapshot. An audit trail shows who regenerated and when.

API: GET /v1/api/documents/:id/versions returns the full version chain with timestamps, snapshot diffs, and the user who triggered each regeneration.

Invoice Approval & Dispute Flow

Invoices go through a structured approval workflow before payment. Clients reviewing an invoice in the portal can approve it for payment or flag a dispute with specific comments attached to individual line items.

Invoice Status Flow

Draft
Pending Approval
Approved
Sent
Paid
Pending ApprovalDisputed(back to vendor for resolution)

Concrete example: Disputing a line item

1Glen generates an invoice and marks it “Pending Approval.” The client receives a notification in the portal.
2Jose at MF opens the invoice in the portal. He sees all line items and clicks “Dispute” on a 6-hour sync debugging entry.
3Jose adds a comment: “This was a platform issue, not client work.” The invoice moves to Disputed.
4Glen sees the dispute, adjusts the work log, regenerates (creates v2), and resubmits. Jose approves v2.

API: POST /v1/api/documents/:id/approve for approval, POST /v1/api/documents/:id/dispute with a JSON body containing the dispute reason and optional line item references.

PDF Hyperlink Improvements

Every line item in a PDF invoice is now a fully clickable hyperlink that opens the corresponding Salesforce record in a new tab. This means the person reviewing the PDF can jump directly to the work item or work log behind any charge.

How it works

The VF PDF controller detects at runtime whether it is running inside a managed package (namespacedelivery__) or unmanaged context. It builds the correct Salesforce URL for each line item accordingly.

Managed package: Links resolve to /lightning/r/delivery__WorkItem__c/RECORD_ID/view

Unmanaged: Links resolve to /lightning/r/WorkItem__c/RECORD_ID/view

Previously, hyperlinks only worked in unmanaged orgs because the namespace prefix was not injected. This fix ensures every Delivery Hub installation produces PDFs with working links regardless of packaging context.

3

How Documents Are Created

Step-by-step: from trigger to record

1

User triggers document generation

Click a button in the Salesforce LWC interface (e.g., “Generate Invoice”), or call the API programmatically. The trigger passes the entity ID, template type, and period.

2

DeliveryDocumentController.generateDocument() runs

The Apex controller method does the heavy lifting:

  • -Builds a snapshot -- queries all relevant data: entity info (name, address, email), vendor info, work items in the period, work logs (hours), hourly rates, prior unpaid invoices
  • -Freezes the snapshot as JSON in the SnapshotTxt__c field (LongTextArea). This is the immutable data source for all rendering.
  • -Creates the DeliveryDocument__c record with template type, period, status=Draft, and the snapshot JSON
  • -Generates a 64-char hex public token for unauthenticated access via the Salesforce Site
3

Document record exists in Salesforce

The document is now a DeliveryDocument__c record with all its data frozen. It can be rendered, emailed, updated to Final status, or linked to DeliveryTransaction__c payment records.

Mockup: DeliveryDocument__c Record
Document NameDOC-0024
Template TypeInvoice
StatusFinal
PeriodMarch 2026
EntityMobilization Funding
Public Tokena7f3e91b2c4d...
SnapshotTxt__c
{"entityName":"Mobilization Funding","entityAddress":"123 Main St","vendorName":"Cloud Nimbus LLC","vendorAddress":"...",...}
Snapshot JSON Structure
{
  // Entity (who the document is for)
  "entityName": "Mobilization Funding",
  "entityAddress": "123 Main St, Suite 400, Miami, FL",
  "entityEmail": "jose@mobilizationfunding.com",

  // Vendor (who created the document)
  "vendorName": "Cloud Nimbus LLC",
  "vendorAddress": "...",
  "vendorEmail": "glen@cloudnimbusllc.com",

  // Document metadata
  "templateType": "Invoice",
  "periodLabel": "March 2026",
  "documentDate": "2026-03-31",
  "dueDate": "2026-04-30",

  // Line items (work logs)
  "lineItems": [
    {
      "date": "2026-03-04",
      "description": "Risk Rating implementation",
      "hours": 3.5,
      "rate": 90.00,
      "amount": 315.00,
      "workItemNumber": "WI-040"
    },
    // ... more items
  ],

  // Totals
  "totalHours": 30.0,
  "hourlyRate": 90.00,
  "subtotal": 2700.00,
  "priorBalance": 0.00,
  "amountDue": 2700.00,

  // Unpaid invoices summary
  "unpaidInvoices": [],

  // Agreement clauses (for agreements only)
  "clauses": [...]
}
4

How Documents Are Rendered

Three rendering layers, explained

The Document Engine has three rendering layers. Each serves a different purpose, and they all read from the same frozen JSON snapshot. This means the data is always consistent across all views.

Three Rendering Layers

Layer 1: VF PDF

Server-side PDF generation

  • - Visualforce + renderAs="pdf"
  • - CSS 2.1 only (Flying Saucer)
  • - Table-based layouts
  • - Email attachment backbone
  • - Scheduled job compatible
Use case: Email attachments, automated generation, archival

Layer 2: React Web View

Rich interactive web experience

  • - React app in Static Resource
  • - Loaded via VF shell on SF Site
  • - Fetches data via public API + token
  • - Modern CSS, full styling
  • - Interactive (expand sections, etc.)
Use case: Client-facing document viewer, link in emails

Layer 3: Client-Side PDF

Download PDF from web view

  • - html2pdf.js library
  • - Captures rendered HTML to PDF
  • - Full modern CSS quality
  • - User-triggered download
  • - No server roundtrip
Use case: User clicks "Download PDF" from web view
Layer 1

Server-Side PDF (Visualforce)

The VF page DeliveryDocumentPdf.page with renderAs="pdf" generates a server-side PDF. The controller DeliveryDocumentPdfController parses the JSON snapshot into typed Apex properties that the VF markup can reference.

Why CSS 2.1 only?

Salesforce uses Flying Saucer (an open-source Java library from 2008) to render VF pages to PDF. Flying Saucer only supports CSS 2.1 -- no flexbox, no grid, no modern CSS. This means all PDF layouts must use <table>-based layouts with inline styles. It's ugly to code but it works reliably.

This is the automation backbone. When you schedule monthly invoice runs, send document emails, or generate PDFs programmatically, this is the layer that runs. It does not require a browser.

Mockup: VF PDF Invoice Output

INVOICE

Cloud Nimbus LLC

glen@cloudnimbusllc.com

Invoice #: INV-025

Date: March 31, 2026

Due: April 30, 2026

Terms: Net 30

Bill To

Mobilization Funding

123 Main St, Suite 400

Miami, FL 33130

DateDescriptionHoursRateAmount
03/04Risk Rating implementation3.5$90$315.00
03/07User Profile lockdown4.0$90$360.00
03/11Sync engine debugging6.0$90$540.00
03/14Portal convergence work8.0$90$720.00
03/18Document Engine build8.5$90$765.00
Total Hours:30.0
Subtotal:$2,700.00
Prior Balance:$0.00
Amount Due:$2,700.00

Generated by Cloud Nimbus Document Engine -- cloudnimbusllc.com

Layer 2

Rich Web View (React in Static Resource)

A React application bundled as a Salesforce Static Resource. It's loaded via a VF page shell hosted on a Salesforce Site (public, no login required). The React app fetches document data via the public API using the 64-char token.

This is the “real” experience for viewing documents. Modern CSS, beautiful formatting, responsive layout, interactive features (expand/collapse sections, print, etc.). The link in document emails points to this web view.

How the React app loads

VF page shell on SF Site loads the Static Resource JS bundle. The bundle parses the token from the URL, calls the @HttpGet API endpoint with the token, receives the snapshot JSON, and renders the document using React components with modern CSS.

Layer 3

Client-Side PDF (html2pdf.js)

The “Download PDF” button in the web view captures the rendered HTML and converts it to PDF entirely in the browser using html2pdf.js.

This produces a much higher quality PDF than Layer 1 because it renders with full modern CSS support. No server roundtrip required -- the PDF is generated client-side and downloaded directly.

5

How Email Delivery Works

From button click to inbox

1

User clicks “Send Email” in Salesforce

LWC button on the DeliveryDocument__c record page

2

DeliveryDocumentController.sendDocumentEmail() runs

Apex method that orchestrates the entire email

3

Generates VF PDF as a blob

Creates a PageReference to the VF page with renderAs=pdf, then calls getContentAsPDF() to get the binary blob. This is the Layer 1 rendering happening server-side.

4

Creates SingleEmailMessage

Salesforce email with:

  • - To: recipient email (from entity record)
  • - CC: glen@cloudnimbusllc.com (ALWAYS -- hard requirement from DeliverySettings)
  • - Attachment: the VF PDF blob
  • - Body: includes a link to the Layer 2 web view via public token
5

Email sent via Salesforce email service

Uses Salesforce's built-in email sending. No third-party email service needed.

Mockup: Email Delivery Flow
Document Email
To:jose@mobilizationfunding.com
CC:glen@cloudnimbusllc.com (ALWAYS)
Subject:Invoice INV-025 -- Cloud Nimbus LLC -- March 2026

Dear Jose,

Please find attached your invoice for March 2026.

You can also view this document online: View Invoice

Best regards,
Cloud Nimbus LLC

INV-025_March_2026.pdf(VF-rendered PDF attachment)
6

How Agreement Clauses Work

8 standard clauses with dynamic merge fields

Client Agreement and Contractor Agreement templates auto-inject 8 default clauses. These clauses are the standard legal sections for a consulting/contractor relationship. Each clause uses dynamic merge fields to inject client-specific data.

The 8 Default Clauses

1. Scope of Services
2. Compensation
3. Term & Termination
4. Confidentiality
5. Intellectual Property Rights
6. Limitation of Liability
7. Independent Contractor Status
8. Governing Law

Dynamic Merge Fields

Clause text contains placeholder tokens that get replaced with real data at generation time:

[Client Name]-->Mobilization Funding
[rate]-->$90/hour
[Vendor Name]-->Cloud Nimbus LLC

Custom Clauses

Custom clauses can be passed via metadata override when generating the document. This allows client-specific terms without modifying the default clause set. Custom clauses appear after the 8 standard clauses.

Mockup: Agreement Clauses

Client Agreement -- Standard Clauses

1. Scope of Services

Cloud Nimbus LLC agrees to provide Salesforce development services to [Client Name] as described in...

2. Compensation

Client shall pay Vendor at a rate of $[rate]/hour. Invoices are due Net 30 from date of issue...

3. Term & Termination

This Agreement shall commence on the Effective Date and continue until terminated by either party...

4. Confidentiality

Each party agrees to hold in confidence all Confidential Information received from the other party...

5. Intellectual Property Rights

All work product created by Vendor shall be owned by Client upon full payment...

6. Limitation of Liability

In no event shall either party be liable for any indirect, incidental, or consequential damages...

7. Independent Contractor Status

Vendor is an independent contractor and not an employee, agent, or partner of Client...

8. Governing Law

This Agreement shall be governed by the laws of the State of [State]...

Client Signature

Date: ___________

Vendor Signature

Date: ___________

7

How Invoices Work

Hours x Rate = Money

The Invoice template is the most data-intensive document. It pulls together entity info, work items, work logs (hours), and hourly rates to produce a complete billing statement.

What the Invoice Pulls

Entity Info

  • - Client name and address
  • - Vendor name and address
  • - Contact emails

Work Data

  • - Work items active in the period
  • - Work logs (each with date, hours, description)
  • - Hourly rate from entity config

What the Invoice Calculates

Total Hours=Sum of all work log hours in the period
Subtotal=Total Hours x Hourly Rate
Prior Balance=Sum of unpaid invoice amounts
Amount Due=Subtotal + Prior Balance

Invoice Details

Payment Terms: Net 30 (default)
Line Items: Each work log with date, description, hours, rate
Unpaid Summary: Lists all outstanding invoices with amounts
Period: Monthly (e.g., “March 2026”)
Mockup: VF PDF Invoice Output

INVOICE

Cloud Nimbus LLC

glen@cloudnimbusllc.com

Invoice #: INV-025

Date: March 31, 2026

Due: April 30, 2026

Terms: Net 30

Bill To

Mobilization Funding

123 Main St, Suite 400

Miami, FL 33130

DateDescriptionHoursRateAmount
03/04Risk Rating implementation3.5$90$315.00
03/07User Profile lockdown4.0$90$360.00
03/11Sync engine debugging6.0$90$540.00
03/14Portal convergence work8.0$90$720.00
03/18Document Engine build8.5$90$765.00
Total Hours:30.0
Subtotal:$2,700.00
Prior Balance:$0.00
Amount Due:$2,700.00

Generated by Cloud Nimbus Document Engine -- cloudnimbusllc.com

8

How This Connects to the Marketplace

Document Engine is the financial backbone

The Document Engine is not a standalone feature -- it's the financial and legal infrastructure that makes the marketplace work. Here is how each document type maps to marketplace events:

Developer claims a bounty

Auto-generate Contractor Agreement with the developer's name, scope from the bounty, compensation terms (bounty amount minus rake), and all 8 standard clauses.

Work is accepted

Auto-generate Invoice with line items (work logs from the bounty period), total amount, rake deducted, and net payable to the developer.

Org posts a bounty

Can auto-generate Client Agreement with the organization to establish the terms of their relationship with the platform.

All document emails

Every email is CC'd to glen@cloudnimbusllc.com. This is a hard requirement -- Glen sees every invoice, every agreement, every financial communication.

Payment tracking: DeliveryTransaction__c records link to DeliveryDocument__c records to track payment status. This creates a full audit trail: document generated → email sent → payment received → transaction recorded.

Quick Reference

ComponentTypePurpose
DeliveryDocumentControllerApex ControllerGenerate documents, send emails, manage lifecycle
DeliveryDocumentPdfControllerApex ControllerParse snapshot JSON for VF PDF rendering
DeliveryDocumentPdf.pageVisualforce PageVF markup for PDF rendering (CSS 2.1 / table layouts)
DeliveryDocument__cCustom ObjectStores document record + frozen JSON snapshot + public token
DeliveryTransaction__cCustom ObjectPayment tracking linked to documents
SnapshotTxt__cLongTextArea FieldFrozen JSON blob with all document data
PublicTokenTxt__cText(64) Field64-char hex token for unauthenticated web access

Feedback on the Document Engine

What's confusing? What needs more detail? What questions do you still have?