CreaRack-SL

Kanban de Tareas + Attachments R2

Funcionalidadactiveverificado 2026-04-23#workspace#tasks#kanban#r2#attachments

Kanban de Tareas + Attachments R2

User value

Módulo de Tareas como sistema completo de seguimiento visual. Equipo organiza trabajo en columnas Kanban (Pendiente / En curso / Completada), ve badge 📎 N con número de adjuntos por tarea, abre galería de imágenes o PDFs desde la tarjeta sin entrar al modal. Campo Resolución separa respuesta/decisión final de la descripción original.

Cómo usarla

  • Vista Kanban: columnas a pantalla completa con borde izquierdo de color por estado (naranja pendiente, azul en curso, verde completada). Tarjetas con priority pill + título + badge adjuntos + assignee en una fila compacta.
  • Filtro LED: filtra por assignee/status/priority desde cabecera.
  • Adjuntar: modal edición (o creación), sección “Adjuntos” con ”+ Subir archivo”. Soporta PNG/JPG/WEBP/GIF/PDF, máx 10 MB.
  • Galería: click 📎 abre visor directamente. Navegación flechas ‹/› o ←/→ con contador n/total. Un único archivo salta al preview sin galería.
  • Preview: imágenes pantalla completa, PDFs iframe. Esc cierra preview antes que modal.

Implementación

Backend (CF Pages Functions + D1 + R2):

  • functions/api/tasks/index.ts: SELECT con subquery (SELECT COUNT(*) FROM task_attachments WHERE task_id = tasks.id) AS attachment_count evita round-trip extra.
  • functions/api/tasks/[id]/index.ts: PUT gestiona timestamps transición (started_at, completed_at) solo en primer paso a cada fase; DELETE borra blobs R2 (best-effort) antes de que FK CASCADE elimine filas.
  • functions/api/tasks/[id]/attachments.ts: GET sin exponer r2_key; POST acepta multipart/form-data, valida MIME contra whitelist, genera key tasks/{id}/{uuid}.{ext}, escribe R2 antes de INSERT D1.
  • functions/api/attachments/[id].ts: sirve blob con content-type; ?download=1 fuerza Content-Disposition: attachment; 410 Gone si row existe pero objeto R2 no.
  • migrations/0011_create_task_attachments.sql: tabla con FK task_id CASCADE, r2_key UNIQUE, índices por task_id y uploaded_at DESC.
  • wrangler.toml: binding TASK_ATTACHMENTS → bucket task-attachments.

Frontend:

  • TaskModal.tsx: tipos Task.attachment_count? y Attachment. Grid miniaturas auto-fill 120px; imágenes <img>, PDFs icono 📄 + nombre.
  • TaskTableView.tsx + Kanban: badge 📎 N si attachment_count > 0.

Decisiones

  • R2 sobre D1 BLOB: adjuntos en R2 para no saturar límite D1 con binarios. D1 solo metadata + key.
  • Whitelist MIME estricta: PNG/JPG/WEBP/GIF/PDF. Ampliar = editar Set en attachments.ts.
  • Best-effort DELETE R2: si limpieza falla, no aborta. Se acepta blobs huérfanos antes que bloquear borrado.
  • attachment_count en listado: subquery correlacionada evita N+1 fetches.
  • Timestamps inmutables por fase: started_at/completed_at solo si NULL, preservando primera transición aunque tarea vuelva atrás.

Commits relacionados

HashMensaje
fe8a912feat(tasks): attachments R2 con galería en modal
ee63b9afix: mover [id].ts a [id]/index.ts para rutas anidadas
9533304feat: rediseño Kanban + timestamps + filtro LEDs + modal 50%
03dc126feat: adjuntar archivos desde modal de crear
4dcddf0feat: campo Resolución separado de descripción
c8e995dfeat: badge 📎 abre galería directa
8443656feat: flechas ‹/› + ←/→ + contador n/total
3a4b887feat: visor único sin rejilla miniaturas
35b4e74style: textos más grandes en tarjeta Kanban
be1423afix: badge 📎 también en Kanban y Calendar
d51467dfix: badge se actualiza tras subir/borrar
95177f3fix: 1 archivo solo preview sin galería
a79418bfix: cerrar preview cierra galería detrás
b470f8bfix: preview via portal + stamps gated
b53ee63fix: preview overlay visible + timeline compacta
0c390cafix: chip Fin aparece sin refrescar

Véase también

  • [[concept—biblioteca—supercontexto]]
  • [[feature—workspace—tasks-timeline]] — Timeline chips + Badge adjuntos en el Kanban
  • [[feature—workspace—refresh-ui-2026]] — Refresh UI workspace donde vive el Kanban