Files
fn_registry/dev/issues/0128-kanban-files-attachments.md
T

3.7 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0128 kanban: adjuntar archivos (drag&drop desc/chat + tab Archivos) in_progress feature
apps-tools
frontend
app media
2026-05-27 2026-05-27
kanban
files
upload
sqlite
mantine

0128 — kanban: adjuntos de archivos en cards

Hoy el tab "Archivos" del CardEditPanel esta disabled ("Proximamente"). Se habilita con tres vias de upload y vista agregada estilo CardLinksPanel.

Alcance

  • Adjuntar archivos a una card desde:
    1. Drag&drop en el editor de descripcion → inserta markdown ref.
    2. Drag&drop / boton paperclip en el chat → mensaje con ref.
    3. Boton "Subir" en el tab Archivos (sin embed).
  • Render inline en chat y descripcion:
    • Imagenes (png/jpg/webp/gif): thumb clickable.
    • PDFs, excel, csv, txt, resto: chip con icono + nombre + size.
  • Tab "Archivos" agrega:
    • Uploads directos sobre la card.
    • Refs detectadas en description.
    • Refs detectadas en mensajes del chat.
  • MIME soportado: cualquiera. Limite 10 MB por archivo. Sin quota agregada.
  • Borrado: cualquier usuario del board borra. Soft delete (deleted_at). Cron purge fuera de scope.

Backend

  • Migracion backend/migrations/014_card_files.sql (aditiva, idempotente):
    • card_files(id TEXT PK, card_id TEXT FK, uploader_id TEXT, filename TEXT, mime TEXT, size INTEGER, stored_path TEXT, source TEXT, created_at TEXT, deleted_at TEXT NULL)
    • source IN ('upload','description','chat') — informativo, no condiciona logica.
    • Index (card_id, deleted_at).
  • Endpoints nuevos en backend/files.go:
    • POST /api/cards/{id}/files multipart, max 10MB, devuelve metadata.
    • GET /api/cards/{id}/files lista activa (deleted_at IS NULL).
    • GET /api/files/{id} sirve binario con Content-Type + Content-Disposition.
    • DELETE /api/files/{id} soft delete.
  • Storage en disco: apps/kanban/uploads/<card_id>/<file_id>__<safe_filename>.
  • apps/kanban/uploads/ gitignored en el sub-repo.

Frontend

  • CardFilesPanel.tsx (replica de CardLinksPanel):
    • Carga /api/cards/{id}/files al montar.
    • Detecta refs en description + mensajes (regex sobre /api/files/<id>).
    • Render grid: imagenes en <Image> Mantine como thumb 120px, resto como chip con IconFile* segun MIME.
    • Boton borrar por archivo (confirm modal).
    • Boton "Subir" → input file → POST.
  • CardChatPanel: dropzone + boton paperclip. Tras upload, inyecta mensaje con ![](url) (imagen) o [name](url) (resto).
  • CardForm (editor desc): <Dropzone> Mantine envolviendo el textarea. Tras upload, insertar ref en posicion del cursor.
  • Render inline en chat: parser markdown ya existente (revisar) o componente simple. Imagenes via <Image fit="contain" maw={200}>. Resto chip.

Tests

  • e2e/files_smoke.sh (bash):
    • Login.
    • Crear card.
    • POST imagen 1KB → asserts 200 + JSON con id.
    • GET lista archivos → asserts 1 elemento.
    • GET binario → asserts content-type image/png.
    • DELETE → asserts 204.
    • GET lista → asserts 0 elementos.

Versionado

  • Bump apps/kanban/app.md 0.4.0 → 0.5.0.
  • Anadir entrada en ## Capability growth log: v0.5.0 (2026-05-27) — adjuntos de archivos por card (issue 0128): drag&drop en desc/chat, tab Archivos agregado, soft delete, 10MB max.

DoD

  • Migracion aplicada, schema verificable con sqlite3 operations.db ".schema card_files".
  • 4 endpoints responden segun spec (testeados con curl).
  • Tab Archivos lista uploads + refs.
  • Drag&drop funciona en desc y en chat.
  • Render inline de imagenes en chat y desc.
  • Soft delete oculta el archivo de la lista y los embeds rompen (esperado).
  • e2e smoke pasa.
  • PR draft a dataforge/kanban.