Skip to main content

Attachment

Attachments are files (contracts, screenshots, invoices, reports, exports, etc.) linked to records across tSM (e.g., Tickets, Customers, Orders). They centralize evidence and generated outputs directly on the record where teams work:

  • Customer service: screenshots, call recordings, email exports on tickets
  • Sales/CRM: signed contracts, proposals, meeting notes
  • Operations: invoices, delivery notes, device configs, audit PDFs
  • Integrations: documents generated by workflows or received from external systems

Attachments support structured metadata for search and compliance, privacy flags for client visibility, optional previews/thumbnails, and retention via lifecycle.

Related concepts (documented in the overview):
Every supporting entity is linked to a parent using ownerType and ownerId, and may be further categorized by an entityType (here: attachmentType).


Storage

Attachments in tSM separate metadata from binary content. tSM stores searchable metadata such as name, description, mimeType, attachmentType, formData, auditInfo, and linkage (ownerType, ownerId, optional related entities). The actual file bytes are persisted in a pluggable storage backend.

Supported storage backends

  • Database – convenient for development and small demos only. Not recommended for production due to DB bloat and I/O characteristics.

  • Filesystem – production-ready default. The storage must be shared across all DMS microservice instances (e.g., NFS, SMB, object storage mounted as a POSIX share).

    • Files are organized into buckets; the bucket name is recorded on the attachment for deterministic placement and maintenance.
  • SharePoint – files live on a SharePoint drive.

    • tSM keeps pointers to the physical location; you may still use attachment fields like bucket and path to record the resolved SharePoint container/folder.
  • Custom – integrate with a third-party DMS or proprietary store.

    • Use bucket and path to hold locator hints if applicable.
    • Any extra metadata required by the external system can be placed into formData (validated by the selected attachmentType form).

Buckets & paths

  • For filesystem storage, buckets are the primary sharding/organization unit (e.g., by domain, year, tenant).
  • For SharePoint and Custom storage, you can still populate bucket/path to reflect the real target (site/library/folder or vendor-specific path) so that UI and jobs can route, display, and maintain files consistently.

Lifecycle & archiving

  • The lifecycle attribute governs retention and visibility:

    • LIVE – active, frequently accessed content.
    • ARCHIVED – retained for compliance/cost control; typically moved to a separate partition or cheaper/slower storage tier.
  • Archiving policy can be cascade-driven or time-based:

    • If the owning record is archived, all its attachments should be archived as well (recommended default).
    • You may also apply time-based rules (e.g., archive after N days); custom logic may apply per tenant or per attachmentType.
  • While archived, metadata remain queryable; retrieval of binaries may be slower or gated by policy, depending on the backend.

Typical Flows

1) Upload a small file (inline content)

Use inline Base64 only for small files. For large files, prefer the dedicated binary APIs.

@dms.attachment.create({
"ownerType": "Ticket",
"ownerId": #ticket.id,
"attachmentType": "Screenshot",
"name": "error-dialog.png",
"mimeType": "image/png",
"data": #pngBytes.encodeBase64(),
"formData": {
"capturedAt": #now(),
"environment": "UAT"
},
"private": true
})

2) Generate a PDF with Output Management and attach it

#with(
#pdf = @formatterPublicService.generateBase64("InvoiceLayout", "pdf", {
customer: #order.customer,
order: #order
})
).do(
@dms.attachment.create({
"ownerType": "Order",
"ownerId": #order.id,
"attachmentType": "Invoice",
"name": "Invoice_" + #order.number + ".pdf",
"mimeType": "application/pdf",
"data": #pdf,
"formData": {
"invoiceNumber": #order.number,
"fiscalYear": #order.created.date.year
}
})
)
@dms.attachmentRelatedEntity.create({
"attachmentId": #attachment.id,
"name": "Also linked to ticket",
"refType": "Ticket",
"refId": #ticket.id,
"data": { "relation": "also-affected" }
})

4) Fetch an attachment with on-demand content/thumbnail

@dms.attachment.get(#id, {"expand": ["Content", "Thumbnail"]})

⚠️ Performance tip: Don’t expand Content in list views; fetch it on demand.


Business & Governance

  • ClassificationattachmentType (code table) defines purpose (e.g., Contract, Invoice, Screenshot), UI icon, optional form for formData, and optional path rules.
  • MetadataformData follows the form specified by attachmentType for consistent validation and better search/reporting.
  • Visibilityprivate = true for internal-only; combine with Sharing/roles for precise access control.
  • Lifecycle — mark as ARCHIVED to enforce retention or hide from active views without hard deletion.
  • Storagebucket and optional computed path allow deterministic, policy-driven storage locationing.

Reference

Attachment (attributes)

FieldTypeRequiredRead-onlyDescription / NotesExample
idUUIDUnique identifier. Not intended for end-user display.3f2b…
ownerTypeStringYesParent record type (e.g., Ticket, Customer, Order).Ticket
ownerIdStringYesParent record ID.12345
nameStringFile name incl. extension.contract.pdf
descriptionStringUser-facing description / tooltip.Signed MSA
mimeTypeStringStandard MIME type.application/pdf
dataString (Base64)Only when expanded (Content). Use only for small files.JVBERi0x…
thumbnailString (Base64)Only when expanded (Thumbnail).iVBORw0K…
relatedEntitiesListAdditional links beyond the owner (see Attachment Related Entity).
sizeDecimalYesComputed file size.2048
sizeUnitStringYesUnit of size (B, KB, MB, …).KB
dateDateYes (default)Creation date (defaults to now).2025-01-01T10:00:00Z
formDataJSONStructured metadata validated by the attachmentType form.{ "invoiceNumber": "INV-001" }
attachmentTypeStringCode from Attachment Type registry.Invoice
bucketStringLogical storage bucket; used by backends (FS/object store).orders
privateBooleanClient visibility toggle.true
lifecycleEnumLIVE or ARCHIVED.LIVE
auditInfoObjectStandard audit fields (created by/at, updated by/at).
pathStringOptional resolved path (may be computed)./orders/2025/0001

Expansions

  • Content — includes data
  • Thumbnail — includes thumbnail

Lifecycle values

  • LIVE, ARCHIVED

Used to link an attachment to additional records beyond its owner (e.g., the same PDF linked to both a Ticket and an Order).

FieldTypeRequiredDescription
idUUIDIdentifier of the relation row.
attachmentIdUUIDYesAttachment being linked.
nameString (1–255)YesDisplay name of the link.
refIdStringID of the referenced record.
refTypeStringType of the referenced record (e.g., Ticket, Order).
dataMapOptional metadata for the relation (e.g., purpose, weight).
auditInfoObjectStandard audit fields.

Attachment Type (code table)

Defines allowed attachmentType values and behavior (UI icon, form for formData, optional path expression).

FieldTypeRequiredRead-onlyNotes
codeStringYesUnique ASCII code (no spaces). Used in APIs & configs.
nameStringYesDisplay name for users.
descriptionStringTooltip/long description.
validityFrom / validityToDateControls whether the type is currently valid.
validBooleanYesComputed from validity; not stored.
localizationDataObjectTranslations for attributes (e.g., name, description).
formStringName of the form used to validate formData.
iconStringUI icon identifier.
dataTagsList<String>Search labels / tags.
configMapArbitrary configuration.
pathExpressionString (SpEL)Computes display/storage path for attachments of this type.

Example pathExpression

'/orders/' + #root.formData?.year + '/' + #root.formData?.number

Good Practices

  • Classify attachments (attachmentType) and enforce metadata (formData) for better search, audit, and automation.
  • Prefer binary endpoints for large files; keep Base64 (data) for small/quick uploads.
  • Expand on demand (Content, Thumbnail) to minimize payloads in list screens.
  • Use private and Sharing together when client visibility must be restricted.
  • Archive rather than delete when you need retention/history.

See Also

  • Supporting Entities – Overview (ownership & typing model)
  • Output Management – generate documents to attach
  • Sharing – access control and collaboration
  • SpEL Clients – configuration & usage