Salesforce Documents

Attach Generated PDFs Back to Salesforce: Naming, Versioning, and Files API

RMMS.Cloud Team · Product Team
·9 min read
  • Salesforce Files
  • ContentVersion
  • document automation
  • Salesforce admin
  • DocForge

The mess that arrives in six months

Without naming and versioning discipline, the Files tab on every Opportunity becomes a graveyard: Proposal.pdf, Proposal (1).pdf, Proposal-final.pdf, Proposal-FINAL-v2.pdf. Nobody can tell which was sent or signed. Audit takes hours, not minutes.

The fix is two decisions made on day one: a deterministic naming convention and explicit use of the Salesforce Files versioning model.

A naming convention that scales

  • Pattern: {record_type}-{record_number}-{template_code}-v{version}.pdf.
  • Example: OPP-00042-PROPOSAL-v3.pdf.
  • Why: sortable, searchable, immediately understandable, never collides.
  • Avoid: spaces, customer names in file names, "FINAL" labels, manual suffixes.

Files API model: ContentVersion vs Attachment

Salesforce has two attachment models:

  • Attachments (legacy): simple but no versioning; avoid for new automation.
  • ContentVersion + ContentDocument: versioning built in; preferred for any modern document automation.

Always write to ContentVersion. Same file name with a new version creates a new ContentVersion linked to the same ContentDocument—exactly what you want for "v2 of the proposal."

The minimum metadata to set per upload

  1. Title: the file name following the convention.
  2. VersionData: the PDF bytes.
  3. PathOnClient: the file name with extension.
  4. ContentDocumentId: link to the existing ContentDocument for versioning.
  5. FirstPublishLocationId: on first version, the Opportunity ID for sharing.
  6. Custom fields: template version, generator run ID, signer status.

Linking and sharing

Use ContentDocumentLink to attach to multiple records (Opportunity, Account, custom Document object). Set the right ShareType (V for viewer, C for collaborator, I for inferred) and Visibility (AllUsers, InternalUsers, SharedUsers) per use case.

Governor limits to design around

  • ContentVersion inserts count against DML rows—batch large jobs.
  • VersionData size limit per file (Salesforce-defined); compress before upload when possible.
  • Heap size for large PDFs—stream rather than load fully into memory.
  • Asynchronous patterns (Queueable, Batch Apex) for bulk operations.

What to log per generation

  • Run ID, template version, mapping version.
  • Source record IDs (Opportunity, Account, related objects).
  • Output ContentDocument ID and version number.
  • Timestamp and user.
  • Status: success, partial, failure with reason.

Cleanup is part of the design

  1. Mark abandoned versions (draft never sent) for purge after N days.
  2. Never delete versions tied to signed documents—legal hold.
  3. Provide a search by template + status to find specific versions fast.
  4. Export and archive after closed-won/lost based on retention policy.

Where DocForge for Salesforce fits

DocForge for Salesforce writes generated PDFs to ContentVersion with deterministic naming, version control, generator metadata, and proper sharing—your Opportunity Files tab stays clean six months in. Sign in and inspect the file structure on a test record.