# Feature Specification: Conversaciones múltiples del asistente con contexto

**Feature Branch**: `004-chat-conversations`

**Created**: 2026-05-25

**Status**: Draft

**Input**: User description: "El chat del asistente debe guardar conversaciones por usuario, permitir crear nuevas conversaciones (sin perder las anteriores) y preservar el contexto entre mensajes relacionados, incluidos seguimientos sobre respuestas previas."

> **Constitution (I. Spec-First)**: Este spec MUST ser agnóstico de stack.
> No mencionar Laravel, Angular ni rutas de código. El CÓMO va en `plan.md`.

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Varias conversaciones por usuario (Priority: P1)

Como operador autenticado en la pantalla del asistente, quiero tener **varias conversaciones independientes** (hilos) asociadas a mi cuenta, para separar temas de trabajo (por ejemplo, consultas comerciales de un cliente distinto de una conversación general) sin mezclar mensajes.

**Why this priority**: Hoy existe un único hilo por usuario; al iniciar «nueva conversación» se borra todo el historial. Esto impide retomar trabajos previos y es el cambio estructural base del feature.

**Independent Test**: Un usuario crea dos conversaciones, envía mensajes distintos en cada una, cambia entre ellas y ve el historial correcto en cada caso.

**Acceptance Scenarios**:

1. **Given** un usuario autenticado sin conversaciones previas, **When** envía su primer mensaje, **Then** el sistema crea automáticamente una conversación y persiste el mensaje en ella.
2. **Given** una conversación activa con mensajes, **When** el usuario elige «Nueva conversación», **Then** se crea un hilo vacío nuevo y la conversación anterior **permanece accesible** en el listado.
3. **Given** al menos dos conversaciones del mismo usuario, **When** selecciona otra del listado, **Then** la interfaz muestra únicamente los mensajes de esa conversación, en orden cronológico.
4. **Given** un usuario autenticado, **When** consulta su listado de conversaciones, **Then** solo ve las suyas, ordenadas por actividad reciente (más reciente primero).

---

### User Story 2 - Preservar contexto en mensajes de seguimiento (Priority: P1)

Como operador, quiero que el asistente **recuerde el hilo actual** al responder, para poder hacer preguntas de seguimiento (por ejemplo, «¿y cuántos contratos?» o «explícame el segundo de la lista») sin repetir todo el contexto en cada mensaje.

**Why this priority**: El historial se guarda en pantalla pero el asistente no usa turnos anteriores en muchos flujos (consultas comerciales, clasificación de intención). Sin esto, el valor de persistir conversaciones es limitado.

**Independent Test**: En una misma conversación, el usuario hace una pregunta de datos, recibe respuesta, y una segunda pregunta relacionada obtiene respuesta coherente con la primera sin reformular todo el contexto.

**Acceptance Scenarios**:

1. **Given** una conversación con al menos un intercambio previo (usuario + asistente), **When** el usuario envía un mensaje de seguimiento ambiguo fuera de contexto aislado (por ejemplo, «¿y en Barcelona?»), **Then** el asistente responde usando el hilo de esa conversación de forma coherente o pide aclaración mínima.
2. **Given** una conversación con una respuesta del asistente que incluye un listado o totales, **When** el usuario pregunta por un elemento concreto de esa respuesta, **Then** el asistente responde en coherencia con lo ya mostrado, sin contradecir datos previos del mismo hilo.
3. **Given** una conversación recién creada (sin mensajes previos), **When** el usuario envía el primer mensaje, **Then** el comportamiento es equivalente al chat actual (sin errores por historial vacío).
4. **Given** un mensaje enviado en la conversación A, **When** el usuario cambia a la conversación B y envía un mensaje, **Then** el asistente **no** usa mensajes de la conversación A como contexto.

---

### User Story 3 - Retomar conversaciones al volver (Priority: P2)

Como operador, quiero que al cerrar sesión, recargar la página o volver otro día, **recupere mis conversaciones y la última activa**, para continuar donde lo dejé.

**Why this priority**: La persistencia por usuario solo aporta valor si el hilo sobrevive entre visitas y la UI recuerda cuál estaba abierto.

**Independent Test**: Tras varios mensajes en una conversación, el usuario recarga la pantalla del asistente y ve el mismo hilo con todos los mensajes completos.

**Acceptance Scenarios**:

1. **Given** mensajes guardados en una conversación, **When** el usuario recarga la pantalla del asistente, **Then** ve el historial completo de la conversación que tenía activa (o la más reciente si no había selección previa).
2. **Given** varias conversaciones guardadas, **When** el usuario vuelve a entrar, **Then** el listado refleja todas sus conversaciones con indicación de cuál está activa.

---

### User Story 4 - Eliminar una conversación concreta (Priority: P2)

Como operador, quiero poder **eliminar una conversación** que ya no necesito, sin afectar el resto de mis hilos.

**Why this priority**: Sustituye el modelo actual de «nueva conversación = borrar todo» por gestión granular, alineada con múltiples hilos.

**Independent Test**: Usuario con tres conversaciones elimina una; las otras dos siguen intactas y accesibles.

**Acceptance Scenarios**:

1. **Given** varias conversaciones del usuario, **When** elimina una conversación concreta, **Then** desaparece del listado y sus mensajes ya no son recuperables por el usuario.
2. **Given** la conversación activa eliminada, **When** confirma el borrado, **Then** la interfaz muestra otra conversación disponible o un estado vacío listo para un nuevo hilo.
3. **Given** un intento de acceder o borrar una conversación de otro usuario, **When** se realiza la operación, **Then** el sistema lo rechaza de forma segura (sin revelar existencia de recursos ajenos).

---

### User Story 5 - Compatibilidad con streaming y adjuntos (Priority: P2)

Como operador, quiero que el envío de **texto con streaming** y de **mensajes con adjunto** sigan funcionando **dentro de la conversación activa**, sin regresiones respecto al comportamiento ya desplegado.

**Why this priority**: El producto ya tiene streaming híbrido y flujo síncrono para adjuntos; esta feature no debe romperlos.

**Independent Test**: En una conversación con identificador explícito, enviar texto (stream) y adjunto (sync) persiste ambos en el mismo hilo.

**Acceptance Scenarios**:

1. **Given** una conversación activa, **When** envío un mensaje de solo texto, **Then** se usa el canal de streaming existente y el mensaje queda en esa conversación.
2. **Given** una conversación activa, **When** envío mensaje con adjunto, **Then** se usa el flujo síncrono existente y el mensaje queda en esa conversación.
3. **Given** un stream en curso en la conversación A, **When** intento cambiar de conversación, **Then** la interfaz impide la acción o cancela el stream de forma controlada antes del cambio.

---

### Edge Cases

- Usuario sin conversaciones previas al migrar desde el modelo de un solo hilo: su historial existente aparece como **una conversación por defecto** con todos los mensajes previos.
- Conversación con título automático: se genera a partir del primer mensaje del usuario (texto recortado); si el primer mensaje es solo adjunto, usar etiqueta genérica comprensible.
- Límite de contexto del asistente: cuando el hilo supera la ventana usable, el sistema usa los turnos más recientes y mantiene coherencia en los últimos intercambios (detalle de ventana en `plan.md`).
- Mensaje de seguimiento tras error del asistente: el turno fallido no contamina el contexto como respuesta válida; el usuario puede reintentar.
- Dos pestañas abiertas con la misma cuenta: la última acción coherente gana; no se mezclan mensajes entre conversaciones distintas.
- Conversación vacía recién creada: no aparece duplicada indefinidamente en el listado si el usuario abandona sin enviar mensaje (política: no persistir hilos vacíos o limpiarlos al salir — ver Assumptions).

## Requirements *(mandatory)*

### Functional Requirements

- **FR-001**: El sistema MUST asociar cada conversación a **un único usuario autenticado**; un usuario MUST poder tener **múltiples conversaciones** simultáneas.
- **FR-002**: El sistema MUST persistir **todos los mensajes** (usuario y asistente) dentro de la conversación a la que pertenecen, con orden cronológico estable.
- **FR-003**: El usuario MUST poder **crear una nueva conversación** sin eliminar las conversaciones existentes.
- **FR-004**: El usuario MUST poder **listar sus conversaciones** y **seleccionar cuál está activa** en la pantalla del asistente.
- **FR-005**: El sistema MUST **aislar el contexto**: mensajes y razonamiento del asistente MUST limitarse a la conversación activa; MUST NOT filtrarse contexto entre conversaciones del mismo usuario.
- **FR-006**: Al procesar un mensaje, el asistente MUST considerar el **historial de turnos previos de esa conversación** (usuario y asistente), incluidos flujos de consulta comercial y clasificación de intención, dentro de una ventana acotada documentada en planificación.
- **FR-007**: El sistema MUST **migrar** el historial existente del modelo «un hilo por usuario» a **al menos una conversación por defecto** por usuario, sin pérdida de mensajes visibles.
- **FR-008**: El usuario MUST poder **eliminar una conversación concreta**; la eliminación MUST NOT afectar otras conversaciones del mismo usuario.
- **FR-009**: El sistema MUST **rechazar** acceso, lectura, envío o borrado de conversaciones que no pertenezcan al usuario autenticado.
- **FR-010**: La pantalla del asistente MUST **restaurar** al reabrir la conversación activa (o la más reciente) con su historial completo persistido.
- **FR-011**: Los envíos con **texto streaming** y con **adjunto** MUST seguir funcionando en el contexto de la conversación activa, sin regresiones funcionales respecto al baseline y al streaming ya especificado.
- **FR-012**: Cada conversación MUST tener un **identificador estable** y un **título visible** (automático desde el primer mensaje o etiqueta por defecto hasta que exista texto).
- **FR-013**: Al completar una respuesta del asistente en flujos que consultan datos externos, el sistema SHOULD almacenar metadatos mínimos del turno (por ejemplo, tipo de consulta y resumen) asociados al mensaje, para mejorar seguimientos posteriores dentro del mismo hilo.

### Key Entities

- **Conversation**: hilo de chat propiedad de un usuario; atributos conceptuales: identificador, título visible, fechas de creación y última actividad, estado activo/archivado (archivado opcional fuera de v1).
- **ConversationMessage**: mensaje dentro de un hilo; rol (usuario o asistente), contenido, metadatos opcionales (adjunto, consulta ejecutada), marca temporal.
- **ConversationContext**: ventana de turnos recientes de una conversación usada por el asistente al generar la siguiente respuesta; acotada para no exceder límites del servicio de IA.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: En pruebas con 10 usuarios, el **100%** puede crear al menos **3 conversaciones** distintas y alternar entre ellas viendo el historial correcto en cada una.
- **SC-002**: En pruebas de seguimiento (mínimo **5 escenarios**: conteos, listados, aclaración «¿y…?», referencia a elemento previo, cambio de conversación), el **80%** de seguimientos dentro del **mismo hilo** reciben respuesta coherente sin obligar al usuario a repetir la pregunta original completa.
- **SC-003**: Tras recargar la pantalla del asistente, el **100%** de conversaciones con mensajes persistidos se muestran completas e inalteradas.
- **SC-004**: **Cero** casos en pruebas de autorización donde un usuario accede a conversaciones o mensajes de otro usuario.
- **SC-005**: **Cero regresiones** en envío con adjunto y en streaming de texto según criterios de aceptación de User Story 5.
- **SC-006**: Tras migración, el **100%** de usuarios con historial previo al despliegue conserva al menos una conversación visible con sus mensajes anteriores.

## Assumptions

- Los usuarios acceden al asistente **autenticados** con el mismo mecanismo de identidad ya existente en el producto.
- La pantalla afectada es la de **conversación del asistente**; otras vistas de chat (por ejemplo, extracción de documentos PDF) quedan fuera de alcance salvo reutilización de componentes compartidos.
- **Ventana de contexto v1**: se usan los turnos más recientes de la conversación activa hasta un límite razonable (orden de **24 mensajes** o equivalente en tokens); turnos más antiguos no se envían al modelo pero permanecen visibles en el historial de la UI.
- **Conversaciones vacías**: si el usuario crea «Nueva conversación» y abandona sin enviar mensaje, el hilo vacío no se persiste en el listado (o se elimina automáticamente al cambiar de conversación).
- **Renombrado manual** de conversaciones y **búsqueda** en el listado quedan fuera de alcance v1.
- **Compartir conversaciones** entre usuarios o roles queda fuera de alcance v1.
- Esta feature **depende** del chat conversacional baseline (historial, autenticación, adjuntos) y es **compatible** con el streaming híbrido ya especificado; los detalles de integración van en `plan.md`.
- El título automático se deriva del primer mensaje de texto del usuario (longitud máxima visible acordada en planificación, por ejemplo 60 caracteres).

## Dependencies

- Feature baseline de chat conversacional del asistente (historial, mensajes, autenticación).
- Feature de streaming híbrido en chat (mensajes de texto); adjuntos permanecen en flujo síncrono.
- Feature de consultas comerciales del agente (para validar contexto en seguimientos de datos).
