# 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.*
