Attachments & Message Templates
Attachments & Message Templates
NexusRMS provides robust file attachment handling with virus scanning and a flexible message template system with variable replacement. Both are core components of the communication module.
Attachments
Every file uploaded to a communication thread or message is stored as a CommunicationAttachment record in the communication_attachments table. Files are persisted to S3 storage.
Attachment Fields
| Field | Description |
|---|---|
| file_name | Original name of the uploaded file |
| file_path | S3 storage path |
| file_size | Size in bytes (integer) |
| mime_type | MIME type (e.g. image/png, application/pdf) |
| file_extension | File extension (e.g. pdf, docx, jpg) |
| thumbnail_url | URL for image thumbnails (optional) |
| preview_url | URL for document previews (optional) |
| uploaded_by | UUID of the user who uploaded the file |
| upload_source | Where the file was uploaded from |
Virus Scanning
All uploaded files undergo virus scanning before they become downloadable:
- virus_scanned — boolean flag indicating whether the scan has completed.
- virus_scan_status — one of: clean, infected, or failed.
- virus_scanned_at — timestamp of when the scan was performed.
- The markScanned(status) method updates all three fields at once.
- The isSafe() method returns true only when virus_scanned is true and virus_scan_status is "clean".
- The safe() query scope filters to only clean, scanned attachments.
Public Access and Download Tracking
- is_public — boolean flag controlling whether the file is accessible without authentication.
- download_count — integer tracking total downloads. Incremented by the incrementDownloadCount() method.
File Type Helpers
Convenience methods on the CommunicationAttachment model for identifying file types:
- isImage() — true when mime_type starts with "image/".
- isVideo() — true when mime_type starts with "video/".
- isPdf() — true when mime_type equals "application/pdf".
- isDocument() — true for PDFs, Word documents (.doc, .docx), Excel spreadsheets (.xls, .xlsx), and PowerPoint presentations (.ppt, .pptx).
- getFormattedFileSizeAttribute() — returns human-readable size (e.g. "2.4 MB", "156 KB").
Query Scopes for Attachments
- images() — filters to files where mime_type starts with "image/".
- documents() — filters to PDFs, Word, and Excel files.
- safe() — filters to virus-scanned clean files only.
Attachment Limits
- Maximum file size — configurable in communication settings (default 10 MB).
- Message retention — configurable in days; set to 0 for unlimited retention.
Message Templates
The CommunicationTemplate model stores reusable message templates with dynamic variable replacement. Templates are stored in the communication_templates table.
Template Fields
| Field | Description |
|---|---|
| name | Template display name |
| description | Brief explanation of when to use this template |
| subject_template | Subject line with variable placeholders |
| body_template | Message body with variable placeholders |
| context_type | Context where this template applies (e.g. Quote, Invoice, Project) |
| category | Organisational category for grouping templates |
| tags | JSON array of searchable tags |
| is_system | Boolean — true for built-in system templates (not editable) |
| is_active | Boolean — only active templates are available for use |
| available_variables | JSON array listing all supported placeholder names |
| example_usage | Sample text showing template in action |
| usage_count | Integer tracking how many times this template has been used |
| last_used_at | Timestamp of the most recent usage |
Variable Syntax
Templates use Liquid-style placeholders: {{ variable_name }}. The render(variables) method accepts a key-value array and replaces every {{ placeholder }} in both the subject and body templates, returning an array with the rendered "subject" and "body" strings.
Template Management
- duplicate(newName, createdBy) — creates a copy of the template with a new name, resets usage_count to 0, and marks it as custom (is_system = false).
- activate() — sets is_active to true.
- deactivate() — sets is_active to false.
- recordUsage() — increments usage_count and updates last_used_at.
Template Query Scopes
- active() — only active templates.
- system() — only built-in system templates.
- custom() — only user-created custom templates.
- forContext(contextType) — filters by context type (e.g. "Quote", "Invoice").
- search(query) — full-text search across name and description fields.
Was this article helpful?