Files
collective-lists/plan/fase-3-tareas-notas.md
Oier Bravo Urtasun 104eeba02e feat(fase-3): Tareas + Notas — TDD complete (148 tests green)
3.0 Tests primero
  pgTAP: 005_tasks_rls.sql (5 — completion CHECK), 006_notes_trash_purge.sql (4 — purge SQL inline + pin/archive CHECK)
  Vitest RLS: rls-tasks.test.ts (14), rls-notes.test.ts (15)
  Playwright: tasks.test.ts (3), notes.test.ts (4)

3.1 Tareas
  Migration 008_tasks.sql: task_lists + tasks + task_list_collective_id() helper
  CHECK constraint: is_completed ⇔ completed_by ⇔ completed_at
  RLS by role + cross-collective isolation
  Store apps/web/src/lib/stores/tasks.ts (optimistic CRUD + reorder)
  /tasks overview (grid + sticky create input + 5s polling)
  /tasks/[id] detail with svelte-dnd-action reorder, flip animation,
    inline edit (dblclick), "Completed by …" attribution via lazy-loaded
    collective_members

3.2 Notas
  Migration 009_notes.sql: notes + note_color enum (8) + pin/archive CHECK
    + 7d trash window in RLS + fn_notes_touch trigger + pg_cron purge job
  Store apps/web/src/lib/stores/notes.ts (CRUD + pin/archive/trash/duplicate)
  /notes board (pinned section testid notes-pinned + 30s polling)
  /notes/[id] editor (title + textarea, 500ms debounced autosave,
    color picker, pin/archive/duplicate/trash actions)
  /notes/archive (restore + send to trash)
  /notes/trash (restore + permanent delete)

3.Z Verification
  just test-all → 148 verdes, 2 skipped:
    25 pgTAP (was 16, +9)
    88 Vitest integration (was 59, +29; 2 presence skipped)
    6 Vitest unit (unchanged)
    29 Playwright (was 22, +3 tasks +4 notes)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:28:19 +02:00

59 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### Fase 3 — Tareas y Notas
**Estado: ✅ Completa**
**Duración estimada: 12 semanas**
**Objetivo: completar los módulos secundarios.**
Esta fase sigue TDD: **primero los tests, al final la verificación.** Ninguna tarea de implementación se da por hecha hasta que todos los tests pasan (`just test-all`).
#### 3.0 Tests primero — escribir antes de implementar
**Vitest (`packages/test-utils/tests/`):**
- [x] `rls-tasks.test.ts` — 14 tests: T-01 (CRUD por rol en `task_lists`), T-02 (CRUD por rol en `tasks`), T-03 (invariantes de `completed_by`/`completed_at` + guest no puede marcar), T-04 (aislamiento cross-collective) ✅
- [x] `rls-notes.test.ts` — 15 tests: N-01 (CRUD por rol + cualquier miembro activo edita cualquier nota), N-02 (pin/archive mutuamente excluyentes via CHECK), N-03 (ventana de papelera 7d + hard-delete bloqueado para guest), N-04 (aislamiento cross-collective) ✅
**pgTAP (`supabase/tests/`):**
- [x] `005_tasks_rls.sql` — 5 tests: invariantes SQL de la CHECK de completion (`is_completed ⇔ completed_by ⇔ completed_at`) ✅
- [x] `006_notes_trash_purge.sql` — 4 tests: ejecuta el SQL del job de purga inline; nota a 8 días desaparece, nota a 2 días sobrevive; CHECK de pin+archive ✅
**Playwright (`apps/web/tests/e2e/`):**
- [x] `tasks.test.ts` — T-UI-01 (crear lista, añadir tarea, marcar completada, ver atribución "Completada por Borja"), T-UI-02 (eliminar tarea), T-UI-03 (guest read-only) ✅
- [x] `notes.test.ts` — N-UI-01 (crear + autosave 500ms + tablero), N-UI-02 (pin → sección "Fijadas"), N-UI-03 (papelera → restaurar desde /notes/trash), N-UI-04 (guest read-only) ✅
#### 3.1 Tareas
- [x] Migración `008_tasks.sql` — tablas `task_lists` y `tasks` + helper `task_list_collective_id()` + RLS por rol + CHECK de consistencia de completion
- [x] Pantalla `/tasks` — grid de listas de tareas con sticky create input + acción de eliminar lista
- [x] Vista de lista `/tasks/[id]`:
- Añadir tarea (input rápido en la barra inferior)
- Toggle de completado (registra `completed_by` + `completed_at`)
- Atribución "Completada por [Nombre]" en cada tarea completada (resuelta vía `collectiveMembers`)
- Edición inline del título (doble-click)
- Drag & drop para reordenar las pendientes (`svelte-dnd-action`)
- Pendientes arriba, completadas hundidas al fondo con `flip` animation
- Botón de eliminar al hover
- [x] Sincronización vía polling a intervalos de 5 segundos cuando la vista está activa
#### 3.2 Notas
- [x] Migración `009_notes.sql` — tabla `notes` con enum `note_color` (8 valores), `is_pinned`, `is_archived` (CHECK mutuamente excluyentes), `deleted_at`, trigger `fn_notes_touch` para actualizar `updated_at`/`updated_by`, RLS y job `pg_cron` `purge-deleted-notes` (3:10 AM)
- [x] Pantalla `/notes` — tablero tipo grid con sección "Fijadas" arriba (`data-testid="notes-pinned"`) y "Notas" debajo. Cards coloreadas según `note.color`.
- [x] Editor `/notes/[id]`:
- Input de título + textarea de contenido (texto plano por ahora; el Markdown rico queda como mejora)
- Guardado automático con debounce de 500ms (indicador "Guardando…/Guardado")
- Selector de color con paleta de 8 swatches + opción "default"
- Acciones en barra superior: pin/unpin, archive/unarchive, duplicar, mover a papelera
- Si la nota está en papelera: cambia a vista de solo-restaurar
- [x] Archivo `/notes/archive` (acción restaurar / papelera) y papelera `/notes/trash` (acción restaurar / borrar permanente)
- [x] Sincronización vía polling a intervalos de 30 segundos en el tablero
#### 3.Z Verificación final — todos los tests verdes
- [x] `just test-all`**148 verdes, 2 skipped**: 25 pgTAP (16 previos + 9 nuevos) + 88 Vitest integration (59 previos + 29 nuevos) + 6 Vitest unit + 29 Playwright (22 previos + 3 tasks + 4 notes). Skips: 2 tests de presence Realtime bloqueados por bug upstream `handle_out/3` (heredados de Fase 2b)
**Criterio de aceptación:** CRUD completo de tareas y notas por UI con cobertura E2E en Playwright y RLS en Vitest/pgTAP. Papelera y archive operativos. Toda la suite pasa con `just test-all`.
---