Ir al contenido

Adjuntos en comentarios

Los comentarios en defectos y casos de prueba admiten imágenes adjuntas. El flujo reutiliza el mismo patrón de stage-and-commit que los adjuntos de pasos y defectos.

Las imágenes deben ponerse en espera (staging) antes de crear o modificar un comentario.

POST /api/v1/comments:stage-attachment

Este endpoint es agnóstico a la entidad — no está acotado a un defecto o caso de prueba específico. Se usa el mismo endpoint de staging para ambas superficies.

Encabezado requerido: X-Organization-Id: <orgUlid>

Rol requerido: member o superior. Los viewers reciben 403.

Cuerpo de la solicitud: multipart/form-data con uno o más campos file.

Restricciones:

  • Tipos MIME aceptados: image/png, image/jpeg, image/webp
  • Tamaño máximo por archivo: ver ATTACHMENT_MAX_UPLOAD_BYTES
  • Máximo de archivos por solicitud: ver ATTACHMENT_MAX_FILES_PER_STAGE_REQUEST

Respuesta 201:

{
"attachments": [
{
"ulid": "01HZATT0000000000000000001",
"objectKey": "staging/<orgUlid>/...",
"thumbKey": "staging/<orgUlid>/.../_thumb.webp",
"mime": "image/webp",
"width": 1024,
"height": 768,
"originalFilename": "screenshot.png"
}
]
}

Los objetos en staging están acotados a la organización que realiza la solicitud. Una ref de staging de otra organización se rechaza con 422 validation_failed al incluirla en un payload de creación o modificación.

Los objetos en staging abandonados expiran automáticamente mediante la regla de ciclo de vida de R2 (~48 horas).

Incluye las refs en espera en el arreglo attachments del payload de creación:

POST /api/v1/defects/{defectUlid}/comments
POST /api/v1/test-cases/{caseUlid}/comments
{
"body": "Adjunto captura de pantalla como referencia.",
"attachments": [
{
"ulid": "01HZATT0000000000000000001",
"position": 0,
"objectKey": "staging/<orgUlid>/...",
"thumbKey": "staging/<orgUlid>/.../_thumb.webp",
"mime": "image/webp"
}
]
}

El campo attachments es opcional. Omitirlo crea un comentario solo con texto.

En caso de éxito (201), el comentario en la respuesta incluye un arreglo attachments confirmado con claves permanentes y valores byteSize acreditados al storage.

Las claves permanentes siguen el patrón:

attachments/<orgUlid>/<projectUlid>/comments/<commentUlid>/<attUlid>.webp
attachments/<orgUlid>/<projectUlid>/comments/<commentUlid>/<attUlid>_thumb.webp

Pasa la lista completa de adjuntos deseada en attachments al hacer PATCH. El servidor reconcilia la diferencia:

  • Las refs presentes en el payload que coinciden con adjuntos confirmados existentes se conservan.
  • Las nuevas refs en staging se confirman (se copian de staging a permanente).
  • Las refs confirmadas existentes ausentes del payload se eliminan (objetos R2 borrados, storage decrementado).
PATCH /api/v1/defects/{defectUlid}/comments/{commentUlid}
PATCH /api/v1/test-cases/{caseUlid}/comments/{commentUlid}
{
"body": "Texto actualizado.",
"attachments": [{ "ulid": "01HZATT0000000000000000001", "position": 0 }]
}

Omitir attachments por completo deja la lista de adjuntos existente sin cambios. Pasar attachments: [] elimina todos los adjuntos.

{
"ulid": "01HZCMT0000000000000000001",
"body": "Adjunto captura de pantalla como referencia.",
"author": { "ulid": "...", "displayName": "Ada", "avatarKey": null, "avatarVersion": 0 },
"createdAt": 1718000000000,
"editedAt": null,
"attachments": [
{
"ulid": "01HZATT0000000000000000001",
"objectKey": "attachments/<orgUlid>/<projUlid>/comments/<cmtUlid>/<attUlid>.webp",
"thumbKey": "attachments/<orgUlid>/<projUlid>/comments/<cmtUlid>/<attUlid>_thumb.webp",
"mime": "image/webp",
"byteSize": 45678,
"width": 1024,
"height": 768,
"originalFilename": "screenshot.png",
"uploadedBy": { "ulid": "...", "displayName": "Ada", "avatarKey": null, "avatarVersion": 0 },
"url": "https://probara.net/__assets/...",
"thumbUrl": "https://probara.net/__assets/.../_thumb.webp",
"createdAt": 1718000000000
}
],
"parentUlid": null,
"pinnedAt": null,
"pinnedBy": null,
"mentions": [],
"replyCount": 0,
"replies": []
}

parentUlid, pinnedAt, pinnedBy, mentions, replyCount y replies son los campos aditivos de hilos, fijado y menciones — los adjuntos funcionan igual en una respuesta que en un comentario de primer nivel. Ver Comentarios en casos de prueba para la referencia completa de campos.

Las miniaturas también se sirven a través del proxy de assets interno en GET /__assets/{thumbKey}.

Al eliminar un defecto o caso de prueba, se activa la limpieza en cascada de todos los adjuntos de comentarios asociados:

  1. Se eliminan en lote todos los objetos R2 de adjuntos de comentarios (tamaño completo + miniaturas).
  2. El contador de storage de la organización para comment_attachment se decrementa en el total de bytes.
  3. Se eliminan las filas de comentarios (lo que elimina en cascada las filas de comment_attachments por FK).

Esto se gestiona automáticamente en el servidor. No se requiere ninguna llamada de limpieza adicional.

Los adjuntos de comentarios se contabilizan bajo la categoría de storage comment_attachment en organization_storage_usage. El storage se incrementa al confirmar y se decrementa al eliminar o en eliminaciones en cascada.