# Sprint 3 — Brief

> **Propósito:** dos ejes paralelos — (1) construir la Process Library: una biblioteca navegable y organizada de procesos con jerarquía configurable y tags; (2) completar el Modelo A: indicador de simulación desactualizada, zoom en canvas BPMN, y recursos en el escenario automatizado.
>
> **Usuario objetivo:** equipo de InQuality. Uso interno en talleres de análisis de procesos y pre-venta de automatización.
>
> **Sprint anterior:** Sprint 2 — modelo de recursos `utilizationMinutes + units` (Dexie v3), ActivityPanel "wow", reporte web con filas expandibles, edición inline proceso/cliente, tabla de recursos en PDF. 548 tests al cierre. Ver cierre en `methodology/CASE_STUDIES/inq-roi-sprint-2.md`.

---

## 0. Reglas no negociables (heredadas)

- **Marca:** "InQ" siempre I-n-Q. "InQ ROI" nombre del producto.
- **Paleta:** naranja `#F59845`, gradiente `#F59845 → #ED3E8F`. No usar morado CONCILIA.
- **Logo:** usar PNGs de `assets/` en lugar de texto "InQ" / "InQuality" donde corresponda.
- **Footer PDFs:** "Powered by InQuality" — obligatorio en los tres PDFs.
- **Identidad visual:** estable hasta Sprint 4+. No reabrir paleta, tipografía ni sistema de componentes.
- **Validación visual:** tests verdes ≠ aprobación final. Todo artefacto visual requiere OK del director antes de cerrar etapa.
- **Iniciativa agéntica:** clasificar cambios por nivel (1/2/3). Ver `methodology/PATTERNS.md` C.6.
- **Control preventivo de scope:** incluir `git diff --name-only HEAD` en todo prompt. Archivo no autorizado en el diff → revertir y reportar. Ver `methodology/PATTERNS.md` C.7.
- **Restricciones contradictorias:** si un prompt tiene restricción `❌` sobre un archivo y el cambio solicitado genera conflicto inevitable, DETENER y reportar al director. No resolver unilateralmente. Ver `methodology/ANTI_PATTERNS.md` AP.9.

---

## 1. Contexto estratégico

### 1.1 Rebalanceo web/PDF

| Componente | Inversión esperada |
|---|---|
| Web app (workspace + reporte + features) | 60–70 % |
| PDF (refinamientos, nuevas secciones) | 15–25 % |
| Infraestructura / deuda técnica | 10–15 % |
| Documentación / metodología | 5–10 % |

### 1.2 Criterio de wow (obligatorio)

Cada etapa con feature nueva incluye:
- **Versión mínima:** cumple la funcionalidad.
- **Versión con wow:** mismo objetivo + 1–2 detalles de experiencia que generan impacto positivo.

Por defecto: versión con wow si el costo extra < 40% del tiempo de la mínima.

### 1.3 Decisión estratégica: PostgreSQL diferido

La persistencia en Dexie (IndexedDB) se mantiene hasta Sprint 5+. La decisión fue tomada conscientemente: el driver para una migración a PostgreSQL (multi-usuario, multi-tenant) no existe todavía en el uso interno de InQuality. El schema de Dexie v4 debe diseñarse con relaciones normalizadas y UUIDs para que la migración futura a SQL sea limpia.

---

## 2. Estado real del producto (pre-Sprint 3)

### 2.1 Lo que existe en la persistencia (Dexie v3)

| Tabla | Estado |
|---|---|
| `processes` | ✅ `{ id, name, clientName, bpmnXml, currency, overheadPercentage, annualFrequency, analysisHorizonYears, automationInvestment, createdAt, updatedAt }` |
| `activities` | ✅ incluye `assignedResources: ActivityResourceAssignment[]`, `automatable`, `automatedCostFixed`, `automatedTimeMinutes` |
| `resources` | ✅ `{ id, processId, name, type, costPerHour }` |
| `gateways` | ✅ `{ id, processId, bpmnElementId, gatewayType, branches }` |
| `simulations` | ✅ `{ id, processId, executedAt, result, resultAutomated? }` |

### 2.2 Lo que falta y se construye en Sprint 3

| Elemento | Estado actual | Sprint 3 |
|---|---|---|
| Agrupación de procesos | ❌ No existe | ✅ Tabla `groups` + `groupId` en `Process` |
| Tags en procesos | ❌ No existe | ✅ Campo `tags: string[]` en `Process` |
| Configuración de etiquetas | ❌ No existe | ✅ Tabla `settings` con `groupLabel` configurable |
| Vista de biblioteca | ❌ No existe | ✅ Home navegable con grupos y procesos |
| Búsqueda y filtros | ❌ No existe | ✅ Búsqueda por nombre + filtro por tags |
| Indicador stale | ❌ No existe | ✅ Badge cuando proceso tiene cambios sin simular |
| Zoom/fit canvas BPMN | ❌ No existe | ✅ Botón fit-to-viewport |
| Recursos en escenario automatizado | ❌ `automatedCostFixed` solamente | ✅ `automatedAssignedResources[]` + simulación |

---

## 3. Decisiones arquitectónicas del sprint (validadas por el director)

| Decisión | Resolución |
|---|---|
| Versión Dexie | Incrementar a v4. Migración preserva datos existentes. |
| Jerarquía de biblioteca | Dos niveles: Grupo (etiqueta configurable) + Proceso |
| Etiquetas configurables | Una sola etiqueta para el nivel de grupo (`groupLabel`). Default: `"Cliente"`. Configurable por workspace. |
| Scope de `settings` | Singleton en IndexedDB — un registro por instalación. Preparado para extensión en Sprint 5+ cuando llegue multi-tenant. |
| Indicador stale | Comparar `process.updatedAt` vs `latestSimulation.executedAt`. Requiere garantizar que guardar activity/resource/gateway actualiza `process.updatedAt`. Sin campo nuevo. |
| Recursos en automatizado | Nuevo campo `automatedAssignedResources: ActivityResourceAssignment[]` en `Activity`. Migración v4 popula con array vacío. |
| Costo automatizado total | `automatedCostTotal = automatedCostFixed + SUM(automatedResourceCosts)` — mismo patrón que AS-IS |
| UUIDs en nuevas tablas | `groups` y `settings` usan UUIDs para compatibilidad futura con PostgreSQL |
| PostgreSQL | Diferido a Sprint 5+. No afecta diseño de Sprint 3 salvo por las consideraciones de UUIDs y normalización. |

### 3.1 Schema Dexie v4 — cambios

```typescript
// NUEVA tabla — ProcessGroup
export interface ProcessGroup {
  id: UUID           // generado con crypto.randomUUID()
  name: string
  createdAt: number  // timestamp Unix ms
  updatedAt: number
}

// NUEVA tabla — AppSettings (singleton)
export interface AppSettings {
  id: 'singleton'    // siempre un solo registro
  groupLabel: string // default: 'Cliente'
}

// Process — campos NUEVOS (migración v4 popula con defaults)
export interface Process {
  // ... campos existentes sin cambio ...
  groupId: UUID | null  // 🆕 null = "Sin clasificar"
  tags: string[]        // 🆕 []
}

// Activity — campo NUEVO (migración v4 popula con [])
export interface Activity {
  // ... campos existentes sin cambio ...
  automatedAssignedResources: ActivityResourceAssignment[]  // 🆕 []
}
```

### 3.2 Migración v3 → v4

```typescript
this.version(4)
  .stores({
    processes:  'id, name, updatedAt, groupId',   // groupId indexado para queries por grupo
    activities: 'id, processId, bpmnElementId',
    gateways:   'id, processId, bpmnElementId',
    resources:  'id, processId, name',
    simulations:'id, processId, executedAt',
    groups:     'id, name, updatedAt',             // nueva tabla
    settings:   'id',                              // nueva tabla (singleton)
  })
  .upgrade(async (tx) => {
    // Processes: agregar groupId y tags
    await tx.table('processes').toCollection().modify((proc) => {
      if (proc.groupId === undefined) proc.groupId = null
      if (!Array.isArray(proc.tags))  proc.tags = []
    })
    // Activities: agregar automatedAssignedResources
    await tx.table('activities').toCollection().modify((act) => {
      if (!Array.isArray(act.automatedAssignedResources)) {
        act.automatedAssignedResources = []
      }
    })
    // Settings: crear singleton con defaults
    await tx.table('settings').put({ id: 'singleton', groupLabel: 'Cliente' })
  })
```

### 3.3 Fórmula de costo automatizado actualizada

```
costoRecursoAutomatizado = resource.costPerHour × assignment.utilizationMinutes / 60 × assignment.units
costoAutomatizadoActividad = automatedCostFixed + SUM(costoRecursoAutomatizado por cada automatedAssignment)
```

La función `simulate(input, scenario)` ya existe. Al pasar `scenario = 'automated'`, para actividades `automatable = true`, usar `automatedAssignedResources` en lugar de `assignedResources`.

---

## 4. Features del sprint

---

### Feature A — Dexie v4: fundación del modelo de biblioteca (Etapa 1)

**Peso estimado:** 10% del sprint.

Data layer puro. Sin cambios de UI. Objetivo: que el schema esté correcto y los datos existentes preservados antes de construir cualquier UI encima.

- Nuevas interfaces `ProcessGroup` y `AppSettings` en `types.ts`
- Nuevos campos `groupId` y `tags` en `Process`, `automatedAssignedResources` en `Activity`
- `db.ts`: versión 4 con las dos nuevas tablas y función de upgrade
- Tests de migración: proceso existente conserva todos los campos, `groupId = null`, `tags = []`, `automatedAssignedResources = []`
- Test de idempotencia: ejecutar upgrade dos veces no corrompe datos

**Criterio de aceptación:**
- [ ] Migración v3→v4 sin pérdida de datos (test automatizado)
- [ ] `ProcessGroup` y `AppSettings` disponibles en TypeScript sin errores
- [ ] `settings` singleton creado con `groupLabel: 'Cliente'` por defecto
- [ ] Build limpio sin errores TypeScript
- [ ] `git diff --name-only HEAD` muestra solo los archivos autorizados

**Archivos autorizados:** `src/domain/types.ts`, `src/persistence/db.ts`, tests de migración.

---

### Feature B — Vista de biblioteca + gestión de grupos (Etapa 2)

**Peso estimado:** 20% del sprint.

La biblioteca pasa a ser la home de la aplicación. El flujo anterior (importar BPMN directamente al llegar) se mantiene como acción secundaria desde la biblioteca.

**Versión mínima:**
- Nueva ruta `/` o equivalente que muestra la biblioteca
- Lista de grupos con contador de procesos
- Sección "Sin clasificar" para `groupId = null`
- CRUD de grupos: crear, renombrar, eliminar
  - Eliminar grupo: procesos del grupo pasan a "Sin clasificar" (no se borran)
- Vista de procesos dentro de un grupo: nombre, cliente, fecha de última modificación
- Botón "Nuevo proceso" (importar BPMN) disponible globalmente y dentro de cada grupo
- Al crear/importar un proceso desde dentro de un grupo, asigna `groupId` automáticamente

**Versión con wow (recomendada):**
Todo lo anterior más:
- Empty state diseñado para la primera vez (sin grupos ni procesos): ilustración o mensaje de bienvenida con CTA para crear el primer grupo o importar un proceso
- Empty state para grupo vacío: "Este grupo no tiene procesos. Importá un BPMN para empezar."
- Hover sobre proceso: preview con fecha de última simulación y costo total (si existe)
- Breadcrumb al entrar a un grupo: `groupLabel / nombre del grupo`

**Criterio de aceptación:**
- [ ] Navegación entre biblioteca y grupos funciona sin recargar
- [ ] CRUD de grupos opera correctamente (incluyendo caso de borrado con procesos)
- [ ] Procesos existentes sin grupo aparecen en "Sin clasificar"
- [ ] Asignación automática de grupo al crear proceso desde dentro de uno
- [ ] Validación visual del director aprobada

---

### Feature C — Tags + búsqueda + configuración de etiquetas (Etapa 3)

**Peso estimado:** 15% del sprint.

**C.1 — Tags en procesos**

Chip input en el workspace del proceso (cerca del nombre y cliente) para agregar y quitar tags. Los tags son strings libres. Autocompletado con tags ya existentes en la base (evita fragmentación "BPMN" / "bpmn" / "Bpmn").

**C.2 — Búsqueda y filtros en biblioteca**

- Búsqueda en tiempo real por nombre de proceso (filtra mientras se escribe)
- Filtro por tags: chips seleccionables que muestran solo procesos con esos tags
- Los filtros activos se muestran visualmente como chips removibles
- La búsqueda opera tanto dentro de un grupo como en "todos los procesos"

**C.3 — Configuración de etiquetas**

Pantalla de configuración (ruta `/settings` o modal) donde el usuario define:
- `groupLabel`: cómo se llama el nivel de agrupación (default: "Cliente"). Este label aparece en toda la UI donde antes decía "Grupo".
- La configuración persiste en la tabla `settings` de Dexie.

**Versión con wow (recomendada):**
Todo lo anterior más:
- En la vista de biblioteca sin filtro activo: mostrar un tag cloud visual con los tags más usados — click en un tag activa el filtro
- El label configurado se refleja en tiempo real en la UI sin recargar (reactive desde el settings store)

**Criterio de aceptación:**
- [ ] Tags se guardan y persisten en el proceso
- [ ] Autocompletado funciona con tags existentes (case-insensitive)
- [ ] Búsqueda filtra procesos en tiempo real
- [ ] Filtro por tags funciona en modo AND (proceso debe tener todos los tags seleccionados)
- [ ] `groupLabel` configurable y reflejado en la UI
- [ ] Validación visual del director aprobada

---

### Feature D — Indicador de simulación desactualizada + zoom BPMN (Etapa 4)

**Peso estimado:** 10% del sprint.

**D.1 — Indicador stale**

Cuando el usuario guarda cambios en actividades, recursos o gateways de un proceso sin volver a simular, el workspace muestra un indicador persistente.

Implementación: garantizar que `db.processes.update(id, { updatedAt: Date.now() })` se ejecuta siempre que se guarden activities, resources o gateways del proceso. El indicador es `process.updatedAt > (latestSimulation?.executedAt ?? 0)`.

**Versión mínima:** badge "Simular para actualizar" en el botón Simular (o cerca). Desaparece al ejecutar.

**Versión con wow (recomendada):**
Todo lo anterior más:
- El indicador menciona cuántas actividades tienen cambios sin simular (requiere comparar `activity.updatedAt` — agregar este campo solo si el esfuerzo es < 40% del mínimo; si no, omitir)
- El indicador también aparece en el reporte web como banner sutil: "Los resultados pueden estar desactualizados — hay cambios sin simular" con botón "Simular ahora"

**D.2 — Zoom/fit canvas BPMN**

Botón "Encuadrar diagrama" (ícono fit-to-screen o similar) en la toolbar del BpmnCanvas. Al hacer click: `bpmnViewer.get('canvas').zoom('fit-viewport')`. Detectado en validación Sprint 2 como problema real en talleres.

**Criterio de aceptación:**
- [ ] Indicador aparece al guardar actividad sin re-simular
- [ ] Indicador desaparece al ejecutar simulación
- [ ] Botón fit-to-viewport funciona en BpmnCanvas
- [ ] Validación visual del director aprobada

---

### Feature E — Recursos en escenario automatizado (Etapa 5)

**Peso estimado:** 20% del sprint.

Esta es la feature más compleja de Modelo A. El campo `automatedAssignedResources` ya existe en el schema (creado en Etapa 1). Etapa 5 construye la UI y la lógica de simulación.

**E.1 — UI en ActivityPanel**

En la sección "Automatización" del ActivityPanel (visible cuando `automatable = true`), agregar una subsección "Recursos automatizados" paralela a la del escenario actual:
- Mismo componente de asignación de recursos (resourceId, utilizationMinutes, units)
- Recursos disponibles: los mismos del catálogo del proceso (tabla `resources`)
- Label diferenciador: "Recursos en AS-IS" / "Recursos en TO-BE" (o "Actual" / "Automatizado")

**E.2 — Motor de simulación**

Al simular con `scenario = 'automated'`, para actividades `automatable = true`:
- Usar `automatedAssignedResources` en lugar de `assignedResources`
- Costo total = `automatedCostFixed + SUM(costoRecursoAutomatizado)`
- El `resourceCostBreakdown` en `ActivitySimResult` refleja los recursos automatizados

**E.3 — Reporte web**

En las filas expandibles de `ActivitiesTable` para actividades automatizables:
- **Versión mínima:** mostrar desglose de recursos del escenario que corresponde (actual en columna actual, automatizado en columna automatizado)
- **Versión con wow:** comparación lado a lado — fila expandida muestra "Actual: X recursos" / "Automatizado: Y recursos" con sus costos individuales

**Criterio de aceptación:**
- [ ] Se pueden asignar recursos al escenario automatizado desde el ActivityPanel
- [ ] La simulación usa esos recursos al calcular el costo automatizado
- [ ] El reporte muestra el desglose de recursos del escenario automatizado
- [ ] Escenario sin recursos automatizados: comportamiento idéntico al anterior (solo `automatedCostFixed`)
- [ ] Tests unitarios: costo automatizado con recursos, sin recursos, mixto (fijo + recursos)
- [ ] Validación visual del director aprobada

---

### Feature F — PDF actualizado + tests del sprint (Etapa 6)

**Peso estimado:** 15% del sprint.

**F.1 — PDF con recursos automatizados**

Si el proceso tiene actividades con `automatedAssignedResources`, la tabla de recursos en página 4 del PDF (introducida en Sprint 2) muestra ambos escenarios:
- Sección "Recursos AS-IS" (existente)
- Sección "Recursos TO-BE" (nueva, condicional — solo si hay recursos automatizados)

Si ninguna actividad tiene recursos automatizados, la tabla PDF no cambia respecto a Sprint 2.

**F.2 — Tests del sprint**

- Tests unitarios de migración Dexie v4 (cobertura de los nuevos campos)
- Tests unitarios del motor de simulación con `automatedAssignedResources`
- Test E2E del flujo completo de la biblioteca: crear grupo → importar proceso → asignar a grupo → agregar tags → buscar → filtrar
- Tests de la configuración de `groupLabel` (cambio se refleja en UI)

**Criterio de aceptación:**
- [ ] PDF con sección TO-BE aparece cuando hay recursos automatizados
- [ ] PDF sin recursos automatizados: sin cambio respecto a Sprint 2
- [ ] Todos los tests nuevos del sprint verdes
- [ ] Validación visual del director aprobada (abrir el PDF generado)

---

### Feature G — Polish + validación final (Etapa 7)

**Peso estimado:** 10% del sprint.

Refinamientos post-validación visual del director de las etapas anteriores. Edge cases de la biblioteca (nombre de grupo muy largo, proceso sin nombre, muchos tags, tag muy largo). Ajustes de animación o spacing que emerjan en uso real. Cualquier inconsistencia de estilo entre la biblioteca nueva y el resto de la app.

Esta etapa no tiene scope predefinido — se construye a partir del feedback acumulado de la validación visual de Etapas 2-6.

**Criterio de aceptación:**
- [ ] Director da OK formal al producto visual completo del sprint
- [ ] Sin regresiones en features existentes (tests E2E del sprint anterior siguen verdes)

---

## 5. Estructura de etapas

| Etapa | Contenido | Peso |
|---|---|---|
| 1 | Dexie v4: nuevas tablas, campos, migración, tests | 10% |
| 2 | Vista de biblioteca + gestión de grupos | 20% |
| 3 | Tags + búsqueda + configuración de etiquetas | 15% |
| 4 | Indicador simulación desactualizada + zoom BPMN | 10% |
| 5 | Recursos en escenario automatizado (UI + simulación + reporte) | 20% |
| 6 | PDF recursos automatizados + tests del sprint | 15% |
| 7 | Polish + validación final | 10% |

**Proporción por componente:** web app ~75% (etapas 2, 3, 4, 5) · PDF + tests ~25% (etapas 1, 6, 7).

**Regla operativa:** ninguna etapa arranca sin su `ETAPA_X_PROMPT.md` aprobado por el director.

---

## 6. Lo que explícitamente NO entra en Sprint 3

- Catálogo global de recursos compartido entre procesos → evaluar Sprint 4 con feedback de uso real
- Modelo B (AS-IS / TO-BE con dos BPMNs) → decisión diferida a Sprint 4+
- Múltiples simulaciones / historial de escenarios → BACKLOG
- Migración a PostgreSQL → Sprint 5+ (decisión tomada explícitamente)
- Login, multi-tenant, colaboración → Fase 2
- Gateway OR inclusivo nativo → BACKLOG
- Distribuciones de probabilidad → Fase 2
- Export Excel → BACKLOG

---

## 7. Deuda técnica que se cierra en este sprint

| Ítem en TECH_DEBT.md | Etapa |
|---|---|
| Toggle automatable + Guardar requerido para badge (INVESTIGATING) | 4 — resolver como parte del indicador stale |
| Indicador visual actividades automatizables en reporte (BACKLOG) | 5 — cubierto por desglose en filas expandibles |
| Controles de zoom en canvas BPMN (BACKLOG) | 4 |

---

## 8. Definition of Done — Sprint 3

- [ ] Features A–G: todos los criterios de aceptación cumplidos
- [ ] Migración Dexie v3→v4: test automatizado confirma preservación de datos y correctos defaults
- [ ] Tests unitarios: motor de simulación con `automatedAssignedResources` (sin recursos, solo fijo, mixto, solo recursos)
- [ ] Test E2E: flujo completo de biblioteca (crear grupo, asignar proceso, tags, búsqueda, filtro)
- [ ] Validación visual: biblioteca navegable, indicador stale, comparación recursos en reporte, PDF TO-BE
- [ ] TECH_DEBT.md actualizado: ítems cerrados documentados
- [ ] OBSERVATIONS.md limpio al cerrar
- [ ] STRATEGIC_DIRECTION.md actualizado con reflexiones post-sprint
- [ ] Ratio web/PDF respetado (~75% web, ~25% PDF + infra)

---

## 9. Riesgos

| Riesgo | Probabilidad | Mitigación |
|---|---|---|
| La Etapa 5 (recursos automatizados) tiene dependencias de tipo transitivas con archivos de etapas anteriores | Media | Incluir instrucción AP.9 explícita: si hay conflicto en archivos restringidos, DETENER y reportar. |
| El indicador stale requiere rastrear `updatedAt` a nivel de actividad (actualmente no existe) | Media | Especificado en el BRIEF: solo comparar `process.updatedAt` vs `simulation.executedAt`. Si se quiere granularidad por actividad, evaluar esfuerzo antes de comprometerse. |
| La biblioteca reemplaza la home y puede romper el flujo de importación existente | Media | Diseñar la biblioteca para que el flujo de importación sea acción prominente, no secundaria. Testear el E2E de importación como parte de Etapa 2. |
| `settings` singleton asume una instalación = un usuario. Si en el futuro hay multi-usuario en el mismo browser, colisiona. | Baja | Aceptado conscientemente. El diseño con `id: 'singleton'` es limpio y fácil de migrar cuando llegue multi-tenant. |

---

## 10. Referencias

- `CLAUDE.md` (simulador-web) — reglas de implementación
- `STRATEGIC_DIRECTION.md` — decisiones estratégicas post-Sprint 2
- `BACKLOG.md` — ítems "Indicador simulación desactualizada", "Zoom BPMN", "Tags"
- `TECH_DEBT.md` — ítems toggle automatable, indicador visual, zoom
- `methodology/PATTERNS.md` — C.6, C.7
- `methodology/ANTI_PATTERNS.md` — AP.8, AP.9
- `sprints/sprint-2/BRIEF.md` — contexto del modelo de recursos y Dexie v3
- `methodology/CASE_STUDIES/inq-roi-sprint-2.md` — lecciones del sprint anterior
- `assets/InQ manual de marca- 3.0.pdf` — manual de marca oficial
