kamau1's picture
feat: ticket attachements
e5f65c7

Ticket Comment Attachments - Frontend Guide

What We Built

Comments now support image and document attachments. The API returns enriched attachment data so you don't need extra calls.

Upload Flow

1. Upload File First

POST /api/v1/documents/upload
Content-Type: multipart/form-data

file: <binary>
entity_type: "ticket"
entity_id: "ticket-uuid"
document_type: "comment_attachment"
document_category: "operational"

Response:

{
  "id": "doc-uuid",
  "file_name": "photo.jpg",
  "file_url": "https://storage.../photo.jpg"
}

2. Create Comment with Attachment

POST /api/v1/tickets/{ticket_id}/comments

{
  "comment_text": "Found this issue",
  "is_internal": true,
  "comment_type": "issue",
  "attachment_document_ids": ["doc-uuid"]
}

Response Structure

{
  "id": "comment-uuid",
  "comment_text": "Found this issue",
  "attachment_document_ids": ["doc-uuid"],
  "attachments": [
    {
      "id": "doc-uuid",
      "file_name": "photo.jpg",
      "file_type": "image/jpeg",
      "file_url": "https://storage.../photo.jpg",
      "file_size": 245678,
      "is_image": true
    }
  ]
}

Key Fields

  • attachment_document_ids: Array of document UUIDs
  • attachments: Full attachment details (auto-populated)
  • attachments[].is_image: Boolean flag - use this to filter images vs other files
  • attachments[].file_url: Direct URL - ready to use in <img> or download links

Multiple Attachments

{
  "comment_text": "Before and after photos",
  "attachment_document_ids": ["doc-1", "doc-2", "doc-3"]
}

All attachments returned in attachments array.

Mobile Example (React Native)

// Upload image
const formData = new FormData();
formData.append('file', {
  uri: photo.uri,
  type: 'image/jpeg',
  name: 'photo.jpg'
});
formData.append('entity_type', 'ticket');
formData.append('entity_id', ticketId);
formData.append('document_type', 'comment_attachment');

const uploadRes = await api.post('/documents/upload', formData);

// Create comment
await api.post(`/tickets/${ticketId}/comments`, {
  comment_text: "Found damaged cable",
  is_internal: true,
  comment_type: "issue",
  attachment_document_ids: [uploadRes.data.id]
});

Web Example (React)

// Upload file
const formData = new FormData();
formData.append('file', file);
formData.append('entity_type', 'ticket');
formData.append('entity_id', ticketId);
formData.append('document_type', 'comment_attachment');

const uploadRes = await api.post('/documents/upload', formData);

// Create comment
await api.post(`/tickets/${ticketId}/comments`, {
  comment_text: "See attached diagram",
  is_internal: true,
  comment_type: "resolution",
  attachment_document_ids: [uploadRes.data.id]
});

Display Logic

// Separate images from other files
const images = comment.attachments.filter(a => a.is_image);
const files = comment.attachments.filter(a => !a.is_image);

// Render images
images.forEach(img => {
  // <img src={img.file_url} alt={img.file_name} />
});

// Render file links
files.forEach(file => {
  // <a href={file.file_url} download={file.file_name}>{file.file_name}</a>
});

Notes

  • Upload files BEFORE creating comment
  • Max file size and allowed types handled by /documents/upload endpoint
  • Images auto-detected via MIME type (image/*)
  • File URLs are permanent and CDN-backed
  • No need to fetch attachment details separately - included in comment response