Files
collective-lists/analysis/analisis-funcional.md
Oier Bravo Urtasun f5903ef442 Add planning docs, design system, and Stitch mockups
- CLAUDE.md: project guidance (stack, domain model, auth, i18n, gotchas)
- DESIGN.md: full design system spec derived from Stitch mockups (slate
  monochrome, Inter, shadcn-svelte, screen patterns for all 5 views)
- README.md: development plan with Justfile commands
- analysis/: functional spec (domain model, use cases, business rules)
- plan/: phase-by-phase implementation plans (Fase 0–4)
- .stitch/designs/: generated mockups (lists, shopping session, notes,
  tasks, list detail with frequency chips)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 06:35:07 +02:00

21 KiB

Análisis Funcional — App de Gestión del Colectivo

Propósito: Base para generación de plan de desarrollo con Claude Code
Plataforma objetivo: Web + Mobile (iOS / Android) — paridad desde el día uno
Enfoque: Gestión colaborativa del colectivo: listas de la compra (núcleo), tareas y notas (complemento)
Usuarios principales: Familias y parejas con uso compartido frecuente
Stack tecnológico: A definir tras revisión del plan


Contexto y Objetivo

Desarrollar una aplicación de gestión doméstica centrada en la colaboración familiar en tiempo real. El producto resuelve el problema concreto de coordinar la compra, las tareas del colectivo y las notas entre los miembros de una familia o pareja, desde cualquier dispositivo y sin fricciones.

La unidad organizativa central es el Colectivo: una entidad compartida a la que pertenecen todos los contenidos, en lugar del modelo usuario-céntrico habitual. Esto refleja la realidad de uso: la lista de la compra no es de una persona, es del colectivo.


1. Módulos del Sistema

1.1 Colectivo y Miembros

1.2 Lista de la Compra

1.3 Tareas

1.4 Notas

1.5 Autenticación y Usuarios

1.6 Sincronización y Offline

1.7 Búsqueda


2. Módulo: Colectivo y Miembros

Este módulo es la base de toda la arquitectura. Sin colectivo no hay contenido compartido.

2.1 Concepto de Colectivo

Un Colectivo es el espacio compartido de una familia o grupo de convivencia. Agrupa listas de la compra, tareas y notas. Cada usuario pertenece a uno o más colectivos, aunque el caso habitual es uno.

Colectivo
  └── tiene muchos Miembros (con rol)
  └── tiene muchas Listas de la Compra
  └── tiene muchas Listas de Tareas
  └── tiene muchas Notas

2.2 Roles dentro del Colectivo

Rol Descripción Permisos
Administrador Creador del colectivo o promovido por otro admin CRUD completo + gestión de miembros + disolver colectivo
Miembro Miembro activo del colectivo CRUD sobre todo el contenido del colectivo
Invitado Acceso temporal o de solo lectura Solo lectura; no puede crear ni editar

Decisión de diseño: El modelo de permisos es deliberadamente simple. En un contexto familiar no tiene sentido granularidad fina por recurso. Si se necesita privacidad, el mecanismo es crear un colectivo adicional (ej: colectivo personal).

2.3 Atributos

Colectivo {
  id: UUID
  nombre: string
  emoji: string | null          ← identificador visual rápido
  creado_por: UUID
  creado_en: timestamp
}

MiembroColectivo {
  colectivo_id: UUID
  usuario_id: UUID
  rol: enum(administrador | miembro | invitado)
  unido_en: timestamp
  invitado_por: UUID
}

InvitacionColectivo {
  id: UUID
  colectivo_id: UUID
  email: string
  token: string                 ← link de invitación único
  rol_asignado: enum(miembro | invitado)
  expira_en: timestamp          ← 7 días por defecto
  aceptada: boolean
}

2.4 Casos de Uso

ID Caso de uso Actor Descripción
CU-H01 Crear colectivo Usuario autenticado Define nombre y emoji; queda como administrador
CU-H02 Invitar miembro Administrador Introduce email + rol → se envía link de invitación
CU-H03 Aceptar invitación Invitado Accede al link → registra cuenta si no tiene → se une al colectivo
CU-H04 Cambiar rol de miembro Administrador Promueve a administrador o degrada a invitado
CU-H05 Expulsar miembro Administrador El miembro pierde acceso inmediato al colectivo y su contenido
CU-H06 Abandonar colectivo Miembro / Invitado El usuario sale del colectivo; el contenido permanece
CU-H07 Cambiar nombre / emoji Administrador Edición del colectivo visible para todos los miembros
CU-H08 Disolver colectivo Administrador Elimina el colectivo y todo su contenido de forma permanente
CU-H09 Cambiar de colectivo activo Usuario con varios colectivos Selector de colectivo visible en la navegación principal

2.5 Flujo: Incorporación de nuevo miembro (CU-H02 → CU-H03)

[Administrador abre "Gestionar miembros" → "Invitar"]
        ↓
Introduce email + selecciona rol (miembro / invitado)
        ↓
Sistema genera link único con token (expira en 7 días)
Sistema envía email con link
        ↓
¿El email ya tiene cuenta?
   SÍ → Al abrir el link: confirmación de unión con un tap
   NO → Al abrir el link: flujo de registro simplificado → confirmación de unión
        ↓
Miembro queda activo en el colectivo
Todos los miembros reciben notificación: "[Nombre] se ha unido al colectivo"
El nuevo miembro ve inmediatamente todo el contenido del colectivo

3. Módulo: Lista de la Compra

Módulo principal del producto. Debe ser la experiencia más pulida y rápida de la app.

3.1 Modelo de Datos

ListaCompra {
  id: UUID
  colectivo_id: UUID
  nombre: string
  estado: enum(activa | completada | archivada)
  creado_por: UUID
  creado_en: timestamp
  completada_en: timestamp | null
}

ItemCompra {
  id: UUID
  lista_id: UUID
  nombre: string
  cantidad: decimal | null
  unidad: string | null         ← "kg", "L", "uds", "paquetes"…
  marcado: boolean              ← comprado durante sesión de compra
  marcado_por: UUID | null
  marcado_en: timestamp | null
  orden: integer                ← posición en la lista
  creado_por: UUID
  creado_en: timestamp
}

3.2 Estados de una Lista

Activa → En sesión de compra → Completada → Archivada

Reglas de negocio:

  • Solo puede haber una sesión de compra activa por lista a la vez.
  • Completar una lista no elimina los ítems; quedan como historial.
  • Una lista completada puede "reiniciarse": desmarca todos los ítems y vuelve a activa.
  • Los ítems marcados durante la sesión registran quién los marcó y cuándo.

3.4 Modo "Ir de Compras"

Experiencia de UI dedicada para el momento de estar físicamente en el supermercado. Requisitos:

  • Ítems grandes y fáciles de marcar con un tap — optimizado para pantalla de teléfono con una mano.
  • Ítems pendientes arriba, marcados abajo — reordenamiento automático al marcar.
  • Indicador de presencia: si otro miembro del colectivo también tiene la lista abierta, se muestra su avatar.
  • Sincronización agresiva: cambios visibles en < 1 segundo entre dispositivos (sin esperar al intervalo normal de sync).
  • Funcional offline: si se pierde cobertura en el súper, los cambios se sincronizan al recuperar red.
  • Botón prominente "Finalizar compra" que marca la lista como completada.

3.5 Casos de Uso

ID Caso de uso Actor Descripción
CU-C01 Crear lista Miembro Nueva lista vacía
CU-C02 Añadir ítem Miembro Nombre + cantidad/unidad opcional; guardado inmediato; muestra sugerencias de ítems frecuentes del colectivo
CU-C03 Editar ítem Miembro Modifica nombre, cantidad o unidad
CU-C04 Reordenar ítems Miembro Drag & drop manual para organizar por pasillos
CU-C05 Eliminar ítem Miembro Borrado con confirmación por deslizamiento (swipe)
CU-C06 Marcar ítem como comprado Miembro (en sesión) Tap en checkbox; ítem baja al fondo automáticamente
CU-C07 Desmarcar ítem Miembro (en sesión) Tap en ítem marcado; vuelve a pendiente
CU-C08 Iniciar sesión de compra Miembro Activa el "Modo ir de compras" con UX dedicada
CU-C09 Finalizar compra Miembro Lista pasa a estado completada; se registra timestamp
CU-C10 Reiniciar lista Miembro Desmarca todos los ítems; lista vuelve a activa
CU-C11 Eliminar lista Miembro Mueve a papelera del colectivo (recuperable 7 días)
CU-C12 Archivar lista completada Sistema / Miembro Lista completada pasa a archivo; libera espacio en vista principal

3.6 Recomendaciones de ítems frecuentes

Al añadir un ítem a cualquier lista, el sistema sugiere ítems basándose en el historial de uso del colectivo. Sin IA — frecuencia pura de registros en base de datos.

  • Input vacío: chips con los 5 ítems más usados del colectivo (acceso rápido)
  • Al escribir: lista filtrada por prefijo (máx. 10), ordenada por frecuencia
  • Alcance: compartido entre todos los miembros del colectivo
  • Registro: trigger en shopping_items — automático en cada añadido, sin intervención de la app
  • Normalización: los nombres se normalizan (lower(trim(name))) antes de acumular la frecuencia, evitando duplicados por mayúsculas o espacios

3.7 Flujo: Sesión de Compra (CU-C08)

[Miembro toca "Ir de compras" en lista activa]
        ↓
App entra en Modo Compra:
  - UI de ítems en formato grande
  - Ítems pendientes arriba / marcados abajo
  - Indicador de otros miembros presentes en la lista
  - Sincronización reforzada (WebSocket activo)
        ↓
Miembro va marcando ítems conforme los mete en el carro
        ↓
¿Otro miembro añade ítem desde casa?
   → Aparece en la lista en tiempo real con indicador "Nuevo"
        ↓
[Miembro toca "Finalizar compra"]
        ↓
Confirmación: "¿Marcar lista como completada?"
   SÍ → Lista pasa a estado completada
        Se registra timestamp de finalización
        Se sale del Modo Compra
        Notificación a otros miembros: "La compra ha sido completada por [Nombre]"
   NO → Se mantiene en Modo Compra

4. Módulo: Tareas

Módulo secundario. Gestión simple de tareas del colectivo, sin complejidad de project management.

4.1 Modelo de Datos

ListaTareas {
  id: UUID
  colectivo_id: UUID
  nombre: string                ← ej: "Tareas de la semana", "Reformas pendientes"
  creado_por: UUID
  creado_en: timestamp
}

Tarea {
  id: UUID
  lista_id: UUID
  titulo: string
  completada: boolean
  completada_por: UUID | null
  completada_en: timestamp | null
  orden: integer
  creado_por: UUID
  creado_en: timestamp
}

Decisión deliberada: Sin fechas límite, prioridades ni subtareas en el MVP. El foco es la simplicidad. Si el producto crece, estas features son candidatas naturales a v2.

4.2 Estados de una Tarea

Pendiente → Completada
               ↓
         (puede desmarcarse → vuelve a Pendiente)

4.3 Casos de Uso

ID Caso de uso Actor Descripción
CU-T01 Crear lista de tareas Miembro Nueva lista con nombre
CU-T02 Añadir tarea Miembro Título; se guarda inmediatamente
CU-T03 Completar tarea Miembro Tap en checkbox; registra quién y cuándo
CU-T04 Descompletar tarea Miembro Tap en tarea completada; vuelve a pendiente
CU-T05 Editar título de tarea Miembro Edición inline
CU-T06 Reordenar tareas Miembro Drag & drop
CU-T07 Eliminar tarea Miembro Swipe para eliminar con confirmación
CU-T08 Eliminar lista de tareas Miembro Elimina la lista y todas sus tareas
CU-T09 Ver quién completó una tarea Miembro Tooltip / detalle: "Completada por [Nombre] el [fecha]"

4.4 Reglas de Negocio

  • Las tareas completadas permanecen visibles en la lista (no se ocultan automáticamente), hundidas al fondo.
  • No existe papelera para tareas individuales: la eliminación es inmediata con confirmación por swipe.
  • Una lista de tareas solo puede eliminarse si está vacía o el miembro confirma borrado en cascada.

5. Módulo: Notas

Módulo de utilidad. Complementa los otros dos módulos para casos como recetas, instrucciones, información del colectivo, etc.

5.1 Modelo de Datos

Nota {
  id: UUID
  colectivo_id: UUID
  titulo: string (opcional)
  contenido: string             ← texto plano con Markdown básico
  color: enum(8 colores predefinidos) | null
  fijada: boolean
  archivada: boolean
  eliminada: boolean
  eliminada_en: timestamp | null
  creado_por: UUID
  creado_en: timestamp
  modificado_por: UUID
  modificado_en: timestamp
}

Scope reducido vs análisis original: Se eliminan tipos de nota (imagen, audio), historial de versiones y comentarios. Las notas son texto con Markdown básico. Si el producto crece, estas features son candidatas a v2.

5.2 Estados de una Nota

Activa → [Fijada | Archivada | En papelera → Eliminada permanentemente]

Reglas de negocio:

  • Fijada y Archivada son mutuamente excluyentes.
  • La papelera retiene notas 7 días antes de eliminarlas permanentemente.
  • Las notas en papelera no aparecen en búsquedas.
  • El guardado es automático.
  • Cualquier miembro del colectivo puede editar cualquier nota del colectivo.

5.3 Casos de Uso

ID Caso de uso Actor Descripción
CU-N01 Crear nota Miembro Abre editor, introduce contenido, se guarda automáticamente
CU-N02 Editar nota Miembro Modifica contenido; se registra modificado_por y modificado_en
CU-N03 Fijar nota Miembro Nota aparece en bloque superior del tablero
CU-N04 Archivar nota Miembro Sale del tablero principal; accesible por búsqueda
CU-N05 Mover a papelera Miembro Va a papelera con timestamp
CU-N06 Restaurar nota Miembro Recupera desde papelera o archivo
CU-N07 Eliminar permanentemente Miembro Borrado definitivo desde papelera
CU-N08 Cambiar color Miembro Selección visual entre colores predefinidos
CU-N09 Duplicar nota Miembro Crea copia independiente

6. Módulo: Autenticación y Usuarios

6.1 Flujos de Autenticación

  • Registro con email + contraseña
  • Login con email + contraseña
  • OAuth — Google (requerido) y Apple (requerido en iOS)
  • Recuperación de contraseña vía email
  • Sesión persistente con refresh token
  • Flujo de registro simplificado al aceptar invitación a colectivo (el email queda prerellenado)

6.2 Atributos de Usuario

User {
  id: UUID
  email: string                         ← único, gestionado por Keycloak
  display_name: string
  language: enum(en | es)               ← preferencia del usuario; default: idioma del navegador
  avatar_type: enum(initials | emoji | upload)
  avatar_emoji: string | null           ← solo cuando avatar_type = emoji (e.g. "🐸")
  avatar_url: string | null             ← solo cuando avatar_type = upload (Supabase Storage)
  created_at: timestamp
  last_seen_at: timestamp
}

6.3 Configuración de usuario

Pantalla /settings accesible desde la navegación principal. Permite al usuario editar:

  • Display name — nombre visible en el colectivo, presencia y avatares
  • Avatar — tres opciones, excluyentes entre sí:
    1. Initials (default) — inicial(es) del display name sobre fondo slate
    2. Emoji — selector de emoji de una lista curada (~40 opciones)
    3. Upload — foto propia; almacenada en Supabase Storage (bucket privado, URL firmada)
  • Language — selector entre English y Español; efecto inmediato sin recargar

Nota: El email y la contraseña se gestionan en Keycloak, no en esta pantalla. Incluir un enlace externo a la cuenta de Keycloak para esos cambios.

6.3 Reglas de Negocio

  • Un usuario puede pertenecer a múltiples colectivos simultáneamente.
  • Eliminar una cuenta no elimina el contenido del colectivo; los ítems/tareas/notas creados por ese usuario permanecen.
  • Si el único administrador de un colectivo elimina su cuenta, el colectivo queda huérfano → el sistema debe promover automáticamente al miembro más antiguo como administrador antes de permitir la eliminación.

7. Módulo: Sincronización y Offline

7.1 Estrategia Offline-First

El escenario crítico es estar físicamente en un supermercado con cobertura inestable. La app debe ser completamente funcional sin conexión.

  • Almacenamiento local: IndexedDB en web, SQLite en mobile.
  • Todas las operaciones se ejecutan primero en local y se sincronizan en segundo plano.
  • Al recuperar conexión, se sincronizan todos los cambios pendientes.
  • Resolución de conflictos: last-write-wins con aviso visual al usuario cuando se detecta sobreescritura de cambios de otro miembro.
  • Indicador de estado de sincronización siempre visible en la UI (sincronizado / sincronizando / sin conexión).

7.2 Sincronización en Tiempo Real

La sincronización en tiempo real es un requisito no negociable para la lista de la compra compartida.

  • WebSockets para sesiones de compra activas (presencia + cambios en tiempo real).
  • Polling o SSE para el resto del contenido (menor frecuencia, menor coste de infraestructura).
  • Indicador de presencia: cuando dos miembros tienen la misma lista abierta simultáneamente, se muestran los avatares de los miembros presentes.

7.3 Prioridades de Sincronización

Tipo de contenido Mecanismo Latencia objetivo
Ítems de lista en sesión de compra activa WebSocket < 1 segundo
Listas de la compra (fuera de sesión) SSE / polling < 5 segundos
Tareas SSE / polling < 5 segundos
Notas Polling < 30 segundos
Miembros del colectivo Polling < 60 segundos

8. Módulo: Búsqueda

8.1 Alcance

Ámbito ¿Incluido? Notas
Listas de la compra activas Busca también en nombres de ítems
Listas de la compra archivadas
Listas en papelera
Plantillas
Tareas Busca en títulos de tarea y nombre de lista
Notas activas Busca en título y contenido
Notas archivadas
Notas en papelera

8.2 Filtros

  • Por tipo de contenido (lista de compra / tareas / notas)
  • Por miembro creador
  • Por rango de fechas
  • Por estado (activo / archivado / completado)

9. Reglas de Negocio Globales

# Regla
RN-01 Todo el contenido pertenece al Colectivo, no a un usuario individual.
RN-02 Cualquier miembro activo del colectivo puede crear, editar y eliminar contenido.
RN-03 Solo los administradores pueden gestionar miembros e invitaciones.
RN-04 Solo los administradores pueden disolver el colectivo.
RN-05 El guardado es automático en todos los módulos. No existe botón "Guardar".
RN-06 Offline-first: los cambios locales se aplican inmediatamente y se sincronizan en segundo plano.
RN-07 Los conflictos de sincronización se registran y son visibles al usuario afectado.
RN-08 La búsqueda no opera sobre la papelera.
RN-09 Eliminar una cuenta de usuario no elimina el contenido del colectivo.
RN-10 Un colectivo debe tener siempre al menos un administrador activo.
RN-11 Solo puede existir una sesión de compra activa por lista a la vez.
RN-12 Las plantillas de lista son inmutables durante una sesión de compra activa basada en ellas.

10. Requerimientos No Funcionales

  • Sincronización en sesión de compra: cambios visibles en < 1 segundo entre dispositivos.
  • Sincronización general: cambios visibles en < 5 segundos entre dispositivos.
  • Offline: la app debe ser 100% funcional sin conexión en todos los módulos.
  • Seguridad: datos cifrados en tránsito (TLS) y en reposo; aislamiento estricto entre colectivos.
  • Multiplataforma: paridad de funcionalidades entre web y mobile desde el día uno.
  • Rendimiento mobile: el Modo Compra debe funcionar con fluidez en gama media (60fps, respuesta a tap < 100ms).
  • Stack tecnológico: a definir — el plan de desarrollo debe ser agnóstico al stack.

11. Entidades del Dominio (Resumen)

Usuario
  └── pertenece a muchos Colectivos (a través de MiembroColectivo)

Colectivo
  ├── tiene muchos MiembroColectivo
  ├── tiene muchas ListasCompra
  ├── tiene muchas ListasTareas
  └── tiene muchas Notas

MiembroColectivo
  ├── referencia Usuario
  ├── referencia Colectivo
  └── tiene rol: enum(administrador | miembro | invitado)

ListaCompra
  ├── pertenece a Colectivo
  ├── tiene muchos ItemCompra
  └── puede ser Plantilla (es_plantilla = true)

ItemCompra
  └── pertenece a ListaCompra

ListaTareas
  ├── pertenece a Colectivo
  └── tiene muchas Tareas

Tarea
  └── pertenece a ListaTareas

Nota
  └── pertenece a Colectivo

InvitacionColectivo
  └── referencia Colectivo

12. Pantallas Principales del MVP

Esta sección orienta el plan de desarrollo sobre el alcance de UI esperado.

Pantalla Descripción
Onboarding Login + creación o unión a colectivo
Home Vista principal con listas activas, tareas pendientes destacadas y notas fijadas
Lista de la compra — vista normal Ítems con cantidad/unidad, opción de editar, añadir y reordenar
Lista de la compra — Modo Compra UI dedicada: ítems grandes, marcado fácil, indicador de presencia
Tareas Lista de tareas con checkboxes
Notas Tablero de notas del colectivo
Editor de nota Editor de texto con Markdown básico
Gestión del colectivo Miembros, roles, invitaciones
Búsqueda Búsqueda global con filtros
Configuración de usuario (/settings) Display name, avatar (initials / emoji / upload), idioma

Documento generado como base para plan de desarrollo. Stack tecnológico a definir tras revisión del plan.