feat(crm): align shared attachment payloads

This commit is contained in:
2026-06-05 23:17:05 +08:00
parent ad5d864944
commit f8263a3402
10 changed files with 209 additions and 30 deletions
@@ -832,6 +832,36 @@ func (h *ContactHandler) ContactableInboxes(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"payload": payload})
}
// ListAttachments returns a contact's shared files across all visible conversations.
// GET /api/v1/accounts/:id/contacts/:contact_id/attachments
// Reference: Chatwoot Api::V1::Accounts::Contacts::AttachmentsController#index
func (h *ContactHandler) ListAttachments(c *gin.Context) {
accountID := parseAccountIDParam(c)
if accountID == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid account id"})
return
}
contactID, err := parseUintParam(c, "contact_id")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid contact id"})
return
}
p := pagination.Parse(c)
attachments, total, svcErr := h.svc.ListAttachments(c.Request.Context(), accountID, contactID, p.Offset, p.PerPage)
if svcErr != nil {
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": "failed to list contact attachments"})
return
}
payload := make([]any, 0, len(attachments))
for i := range attachments {
payload = append(payload, serializeAttachmentWithConversation(c.Request.Context(), h.svc.DB(), &attachments[i]))
}
c.JSON(http.StatusOK, gin.H{"meta": gin.H{"total_count": total}, "payload": payload})
}
// DeleteCustomAttributes removes all custom attributes from a contact.
// DELETE /api/v1/accounts/:id/contacts/:contact_id/custom_attributes
// Reference: Chatwoot contacts#destroy_custom_attributes