# Feature Specification: Chatbot PDF Extractor (Baseline)

**Feature Branch**: `001-chatbot-pdf-extractor`  
**Created**: 2026-05-21  
**Status**: Baseline (brownfield — producto existente documentado)  
**Input**: Plataforma IA para chat conversacional y extracción estructurada de PDFs con plantillas, JWT y SPA Angular.

## User Scenarios & Testing

### User Story 1 - Acceso seguro al panel (Priority: P1)

Como operador, quiero iniciar sesión con email y contraseña para acceder al panel IA y a los agentes disponibles.

**Why this priority**: Sin autenticación no hay acceso a ninguna capacidad del producto.

**Independent Test**: Login con credenciales válidas redirige al dashboard; credenciales inválidas muestran error; token persiste en sesión del navegador.

**Acceptance Scenarios**:

1. **Given** credenciales válidas, **When** envío el formulario de login, **Then** recibo token JWT y accedo al dashboard.
2. **Given** credenciales inválidas, **When** intento login, **Then** veo mensaje de error y no accedo al panel.
3. **Given** sesión activa, **When** recargo la app, **Then** `/auth/me` restaura el usuario o limpia sesión si el token expiró.

---

### User Story 2 - Chat conversacional con agente (Priority: P1)

Como operador, quiero conversar con un asistente IA (texto y opcionalmente PDF/JPG adjunto) y ver el historial de mi hilo para continuar el trabajo.

**Why this priority**: Es el canal principal de consulta e interacción con el agente.

**Independent Test**: Usuario autenticado envía mensaje, recibe respuesta, ve historial ordenado y puede borrar conversación.

**Acceptance Scenarios**:

1. **Given** usuario autenticado en `/assistant`, **When** envío un mensaje de texto, **Then** el asistente responde y ambos mensajes aparecen en el hilo.
2. **Given** historial previo, **When** abro `/assistant`, **Then** veo mensajes en orden cronológico.
3. **Given** conversación existente, **When** solicito nueva conversación, **Then** el hilo se borra en servidor y la UI se reinicia.

---

### User Story 3 - Extracción estructurada desde PDF (Priority: P1)

Como operador, quiero subir un PDF, seleccionar plantilla/referencia y obtener JSON estructurado según el esquema definido, con historial de documentos procesados.

**Why this priority**: Core del negocio — extracción de datos tabulares y campos del documento.

**Independent Test**: Upload PDF + reference_id completa extracción; historial lista documentos; errores muestran feedback claro.

**Acceptance Scenarios**:

1. **Given** PDF válido y plantilla conocida, **When** subo el archivo con reference_id, **Then** el sistema extrae JSON alineado al esquema y lo persiste.
2. **Given** documentos previos, **When** consulto historial, **Then** veo filename, estado, fecha y payload de extracción.
3. **Given** PDF ilegible o fallo LLM, **When** procesa, **Then** el documento queda en estado failed con código/mensaje comprensible.

---

### User Story 4 - Gestión de plantillas de extracción (Priority: P2)

Como operador, quiero definir y gestionar plantillas (esquema JSON, reglas de identificación) para clasificar y extraer distintos formatos de PDF.

**Why this priority**: Permite escalar a múltiples tipos de documento sin cambiar código.

**Independent Test**: CRUD de plantillas en `/templates`; modo entrenamiento crea plantilla desde upload con esquema.

**Acceptance Scenarios**:

1. **Given** modo entrenamiento activo, **When** subo PDF con esquema JSON, **Then** se crea plantilla y se extraen datos de prueba.
2. **Given** plantillas existentes, **When** subo PDF en modo normal, **Then** el clasificador elige plantilla y extrae con su esquema.

---

### User Story 5 - Sincronización con BD secundaria (Priority: P2)

Como sistema integrador, quiero que los datos extraídos se escriban en una tabla destino de la BD secundaria usando reference_id, para alimentar aplicaciones downstream.

**Why this priority**: Integración con el ecosistema del cliente (p. ej. condiciones económicas).

**Independent Test**: Tras extracción exitosa, fila en tabla destino actualizada en columna JSON configurada.

**Acceptance Scenarios**:

1. **Given** conexión secundaria válida y target_table, **When** extracción completa, **Then** se actualiza el registro `id = reference_id` con el JSON.
2. **Given** BD secundaria inaccesible, **When** se intenta persistir, **Then** error `secondary_db_unreachable` con mensaje claro.

---

### Edge Cases

- PDF escaneado sin capa de texto en modo normal (clasificación por texto Smalot puede fallar antes de visión).
- PDF > límite de tamaño (`PDF_MAX_FILE_BYTES` / límites del proveedor).
- Token JWT expirado durante upload largo → 401 y redirección a login.
- Plantilla no reconocida con modo entrenamiento desactivado.
- Drawer/modal de UI bloqueando navegación (frontend).

## Requirements

### Functional Requirements

- **FR-001**: Sistema MUST autenticar usuarios vía JWT (`POST /auth/login`, `GET /auth/me`).
- **FR-002**: Sistema MUST exponer chat conversacional multipart (`POST /chat/message`, historial GET/DELETE `/chat/conversation`).
- **FR-003**: Sistema MUST aceptar upload PDF con `reference_id` obligatorio (`POST /chat/upload`).
- **FR-004**: Sistema MUST extraer JSON estructurado según esquema/plantilla sin inventar datos.
- **FR-005**: Sistema MUST listar historial de documentos por usuario (`GET /chat/history`).
- **FR-006**: Sistema MUST soportar plantillas (`document_templates`) y clasificación automática.
- **FR-007**: Sistema MUST persistir extracciones en BD principal (`documents`, `extracted_data`).
- **FR-008**: Sistema MUST opcionalmente sincronizar JSON en BD secundaria (`DB_SEC_*`, columna `DB_SEC_JSON_COLUMN`).
- **FR-009**: SPA MUST proteger rutas autenticadas con guard JWT.
- **FR-010**: Extracción PDF MUST usar visión nativa (PDF al proveedor) por defecto sin Imagick.

### Key Entities

- **User**: operador con rol (ADMINISTRADOR | OPERADOR).
- **ChatMessage**: mensaje de hilo (`session_id`, role, content, meta).
- **Document**: PDF almacenado con estado (processing, completed, failed).
- **ExtractedData**: payload JSON + template_id + modelo LLM usado.
- **DocumentTemplate**: esquema, reglas de identificación, instrucciones LLM, target_table.

## Success Criteria

- **SC-001**: Operador completa login y accede al dashboard en < 30 s en entorno local.
- **SC-002**: Extracción de PDF típico (< 20 páginas) completa sin error de infraestructura en modo native + claves válidas.
- **SC-003**: 100% de respuestas API autenticadas rechazan requests sin Bearer con 401.
- **SC-004**: JSON devuelto respeta claves del esquema de plantilla (campos ausentes como null, no valores ficticios).

## Assumptions

- Usuarios son operadores internos con credenciales preprovisionadas.
- OpenAI o Gemini configurados vía variables de entorno.
- BD secundaria es opcional para desarrollo local pero requerida en integración productiva.
- Nuevas features incrementales se documentan en `specs/002-*`, no sobrescriben este baseline sin revisión.
