From 3db415449988626fcf734aa30bc8190eef820aef Mon Sep 17 00:00:00 2001 From: borja Date: Thu, 16 Oct 2025 11:26:28 +0200 Subject: [PATCH] docs: actualizar plan-web-fases.md con fases 6-10 y plan detallado Co-authored-by: aider (openrouter/openai/gpt-5) --- docs/plan-web-fases.md | 156 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 147 insertions(+), 9 deletions(-) diff --git a/docs/plan-web-fases.md b/docs/plan-web-fases.md index 2583d0b..efda0fc 100644 --- a/docs/plan-web-fases.md +++ b/docs/plan-web-fases.md @@ -170,16 +170,33 @@ Resultado (implementado) - Unificación de UI en escritorio y móvil. - No se requirieron cambios de backend; los endpoints ya devolvían assignees[]. -Fase 6 — Pulido y peso visual de “Integraciones” -Objetivos -- Mantener “Integraciones” accesible pero de menor jerarquía en móvil. -- Ajustar densidad, estados vacíos y mensajes, y recordar colapsado por grupo en localStorage. -Archivos a editar -- apps/web/src/lib/ui/layout/AppShell.svelte (tono/estilo de pestaña Integraciones). -- apps/web/src/routes/app/groups/+page.svelte (estado colapsado persistente). -- apps/web/src/routes/app/+page.svelte (estados vacíos claros). +Fase 6 — Pulido y peso visual de “Integraciones” — Estado: Completada +Objetivos (cumplidos) +- Mantener “Integraciones” (renombrada a “Calendarios”) accesible pero con menor jerarquía en móvil. +- Ajustar densidad, estados vacíos y recordar colapsado por grupo en localStorage. + +Decisiones aplicadas y resultado +- Etiqueta y jerarquía: + - La pestaña se renombra a “Calendarios” en navegación de escritorio y tabbar móvil; títulos y aria-labels actualizados. + - Atenuación en móvil cuando inactiva; estado activo mantiene color primario y foco visible. +- Safe-areas y solapes: + - Offsets en main y Toast para no solapar con la tabbar; sticky de topbar móvil verificado. +- Estados vacíos: + - Opción B aplicada: mensajes con pista de acción (“Crea o reclama…” / “Crea una nueva o invita…”). +- Persistencia de colapsado por usuario en /app/groups: + - Clave localStorage: groupsCollapsed:v1:{userId}. + - Por defecto: abiertos los grupos con al menos una tarea abierta; colapsados los que no tienen tareas abiertas. + - Limpieza de IDs obsoletos; restauración en onMount, SSR-safe (sin parpadeos apreciables). +- Accesibilidad: + - Foco visible en tabs; uso de
/ con estado coherente con aria-expanded implícito. -Criterios de aceptación resumidos +Archivos editados +- apps/web/src/lib/ui/layout/AppShell.svelte (renombrado a “Calendarios”, atenuación móvil, offsets). +- apps/web/src/routes/app/groups/+page.svelte (persistencia de colapsado por usuario + defaults basados en tareas). +- apps/web/src/routes/app/+page.svelte (textos de estados vacíos opción B). +- apps/web/src/lib/ui/feedback/Toast.svelte (offset móvil contra tabbar). + +Criterios de aceptación (OK) - /app muestra dos secciones con todas las tareas requeridas; sin truncar descripciones; orden conmutado. - /app/groups muestra todas las tareas abiertas por grupo; secciones colapsables; “Unassigned first” operativo. - Completar y Deshacer completar funcionan desde ambas páginas; ventana de 24h configurable; gating correcto. @@ -187,6 +204,127 @@ Criterios de aceptación resumidos - Navegación móvil no rebosa; barra inferior accesible. - Asignados: conteo visible, “tú” resaltado y lista en popover con wa.me. +Fase 7 — Densidad y acciones en una sola fila (TaskItem) +Objetivos +- Compactar la fila de acciones de TaskItem: + - Convertir el botón/indicador de responsables en “icono + número” sin texto (“personas asignadas” → solo icono + contador), manteniendo aria-label y tooltip accesibles. + - Ubicar en la misma fila: Responsables (icono+conteo), Reclamar/Soltar, Editar, Fecha. +- Reducir padding vertical excesivo para ganar densidad, manteniendo objetivos de accesibilidad (área táctil ≈44px y foco visible). + +Plan de trabajo +1) TaskItem.svelte + - Sustituir texto “Responsables: n” por icono + n; aria-label dinámico (“n responsables; tú incluido/excluido”). + - Reorganizar contenedor de acciones para una sola fila en móvil y desktop; permitir wrap en pantallas muy pequeñas si es necesario. + - Ajustar tamaños (icon-size 16–18px) y gaps a 6–8px. +2) Estilos globales y utilidades + - Revisar variables de espacio en tokens.css/base.css; reducir ligeramente los márgenes/paddings verticales de: + - Listas de tareas (ul.list > li o contenedor del TaskItem). + - Card.svelte (padding vertical). + - AppShell .main en móvil (si procede). + - Mantener contraste y focus-visible. +3) QA + - Verificar que en ≤480px no haya desbordes; que los tooltips/aria sean correctos; y targets táctiles respeten accesibilidad. + +Archivos a editar +- apps/web/src/lib/ui/data/TaskItem.svelte (layout de acciones, icono+conteo). +- apps/web/src/lib/styles/base.css (ajustes finos de paddings/gaps). +- apps/web/src/lib/styles/tokens.css (si se decide ajustar variables globales de spacing). +- apps/web/src/lib/ui/layout/Card.svelte (si requiere reducir padding vertical interno). + +Criterios de aceptación +- TaskItem muestra todas las acciones en una sola fila en móvil estándar (≥360px) sin saltos. +- El indicador de responsables conserva accesibilidad (aria-label/tooltip) y se entiende su semántica. +- La densidad aumenta perceptiblemente sin comprometer legibilidad ni foco. + +Fase 8 — Orden por fecha o por grupo (corrección y alineación) +Objetivos +- Alinear el comportamiento de “Orden: Fecha | Grupo” con expectativas: + - Fecha: due_date asc; NULL al final; estable por id. + - Grupo: agrupar por grupo (Personal al final); dentro de cada grupo ordenar por due_date asc; NULL al final. +- Que el orden seleccionado afecte coherentemente a las secciones relevantes (asignadas y/o sin responsable), evitando inconsistencias entre cliente y servidor. + +Plan de trabajo +1) Auditoría actual + - Revisar apps/web/src/routes/app/+page.server.ts y el consumo de /api/me/tasks/overview. + - Revisar apps/web/src/routes/app/+page.svelte (groupByGroup/sortByDue) para evitar doble orden contradictorio. +2) Backend + - apps/web/src/routes/api/me/tasks/overview/+server.ts: asegurar order=due|group_then_due y aplicar NULLS LAST consistente. + - Añadir tests que validen el orden en ambos modos. +3) UI + - apps/web/src/routes/app/+page.server.ts: pasar order al backend y confiar en su orden siempre que sea posible. + - apps/web/src/routes/app/+page.svelte: limitar orden en cliente a casos estrictamente necesarios; evitar reordenar lo ya ordenado por servidor. +4) QA y tests + - Casos con due_date iguales, NULLs, mezcla de grupos, y tareas personales. + +Archivos a editar +- apps/web/src/routes/api/me/tasks/overview/+server.ts +- apps/web/src/routes/app/+page.server.ts +- apps/web/src/routes/app/+page.svelte +- tests/web/* (añadir/ajustar tests de orden) + +Criterios de aceptación +- El cambio de orden se refleja de forma predecible y consistente en toda la página /app. +- Tests cubren due_date NULL, empates y orden de grupos (Personal al final). + +Fase 9 — Semilla de desarrollo enriquecida +Objetivos +- Disponer de una BD de desarrollo amplia para probar casos reales: + - Grupos con y sin tareas; tareas personales; varias tareas sin responsable; tareas con múltiples responsables; tareas completadas recientemente y antiguas; due_dates en pasado/presente/sin fecha. + - Varios usuarios para validar “tú” y múltiples assignees. + +Plan de trabajo +1) Semilla + - apps/web/src/lib/server/dev-seed.ts: ampliar dataset con: + - 3–4 usuarios (incluido el por defecto). + - 4–5 grupos; al menos 1 sin tareas, 1 con muchas tareas, 1 mixto. + - 25–40 tareas variadas (diferentes due, estados, grupos/personales). + - Relaciones de asignación múltiples en algunas tareas. + - Asegurar idempotencia y que no se sobreescriba si ya hay datos. +2) Helpers de test (si procede) + - tests/web/helpers/db.ts: exponer utilidades para crear fixtures específicas. +3) Documentación + - Añadir nota en docs/operations.md sobre cómo regenerar BD local y variables relacionadas. + +Archivos a editar +- apps/web/src/lib/server/dev-seed.ts +- tests/web/helpers/db.ts (si se añaden utilidades) +- docs/operations.md (documentación de uso de seed) + +Criterios de aceptación +- Entorno dev listo tras bootstrap: datos variados y suficientes para probar todas las vistas/secciones. +- Tests pueden apoyarse en fixtures reproducibles. + +Fase 10 — Completar tarea sin responsable: auto-asignación al completador +Objetivos +- Resolver el edge case: al completar una tarea sin responsables, debe aparecer en “Completadas (24h)” del usuario y permitir “Deshacer”. +- Mantener gating y trazabilidad coherentes. + +Plan de trabajo +1) Backend + - apps/web/src/routes/api/tasks/[id]/complete/+server.ts: + - Si la tarea no tiene responsables, añadir (de forma atómica) una asignación al usuario que completa antes de marcar completed=1. + - Registrar completed_by (si existe) o equivalente. + - apps/web/src/routes/api/tasks/[id]/uncomplete/+server.ts: + - Mantener ventana; permitir deshacer si el usuario es responsable (lo será por la auto-asignación) o fue quien completó. + - apps/web/src/routes/api/me/tasks/overview/+server.ts y/o consultas de “recent”: + - Asegurar que la consulta de recientes recoge estas tareas asignadas durante el complete. +2) UI + - apps/web/src/lib/ui/data/TaskItem.svelte: + - Mensaje de feedback claro al completar una tarea que no tenía responsables (p.ej., “Te has asignado y completado la tarea”). +3) Tests + - Flujo: tarea sin responsables → complete → aparece en completadas → uncomplete permitido dentro de ventana. + +Archivos a editar +- apps/web/src/routes/api/tasks/[id]/complete/+server.ts +- apps/web/src/routes/api/tasks/[id]/uncomplete/+server.ts +- apps/web/src/routes/api/me/tasks/overview/+server.ts (si la consulta de recientes depende de esto) +- apps/web/src/lib/ui/data/TaskItem.svelte (feedback UI) +- tests/web/* (casos de integración) + +Criterios de aceptación +- Completar una tarea sin responsables la vincula al usuario y aparece inmediatamente en “Completadas (24h)”. +- “Deshacer completar” funciona para ese caso dentro de la ventana configurada. + Notas de implementación y buenas prácticas - Mantener cabeceras cache-control: no-store en endpoints de listas/acciones. - Reutilizar el gating ya presente en claim/unassign/complete; factorizar si conviene (pero sin sobre-ingeniería).