Files
inq-roi-simulador-web/sprints/sprint-3/ETAPA_6_PROMPT.md
Marcos Benítez 67e259e6ed feat(sprint-3): biblioteca, recursos TO-BE, ROI mejorado e identidad de marca
Sprint 3 completo — 7 etapas:

- Etapa 1-2: biblioteca de procesos con agrupación por cliente (Dexie v4,
  LibraryPage, library-store, groupId/tags en Process)
- Etapa 3: modal de configuración global por proceso (horizonte, frecuencia,
  inversión, moneda) con validación y persistencia
- Etapa 4: panel de recursos rediseñado con soporte de unidades y minutos
  de utilización (utilizationMinutes + units)
- Etapa 5: recursos en escenario automatizado — motor de simulación,
  UI de edición en ActivityPanel, comparación AS-IS/TO-BE en reporte
- Etapa 6: PDF recursos automatizados, automatedAssignedResources requerido,
  561 tests pasando
- Etapa 7: identidad de marca — AppHeader gradiente naranja/magenta con logo
  InQuality en 5 páginas, favicon con logo real, logo/marca navegan a home

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 11:49:43 -03:00

11 KiB
Raw Blame History

Sprint 3 — Etapa 6: PDF recursos automatizados + tests del sprint

Contexto

Sos Claude Code trabajando en InQ ROI. Las reglas de implementación están en simulador-web/CLAUDE.md. El brief del sprint está en sprints/sprint-3/BRIEF.md.

Estado al iniciar esta etapa:

  • Etapas 15 completadas. Motor de simulación usa automatedAssignedResources correctamente. ActivityPanel tiene sección "Recursos TO-BE". Reporte web muestra comparación AS-IS/TO-BE en filas expandibles.
  • Activity.automatedAssignedResources sigue siendo ? (opcional) en types.ts — pendiente de esta etapa.
  • drawResourcesSection en pdf-sections.ts lee activityRow?.assignedResources para los campos utilizationMinutes y units, incluso cuando se exporta el tab "automatizado". Esto es un bug: para el escenario automatizado debería leer automatedAssignedResources.
  • Los factories de Activity en tests (makeAutoActivity, makeActivity) no incluyen automatedAssignedResources. Cuando hagamos el campo requerido, TypeScript los marcará con error.

Esta etapa cierra los tres pendientes del sprint: PDF correcto, campo promovido a requerido, tests del sprint.


Objetivo

F.1 — PDF recursos automatizados Corregir drawResourcesSection para que cuando se exporta el escenario automatizado lea automatedAssignedResources (no assignedResources) al mostrar utilizationMinutes y units por fila.

F.2 — Promover campo a requerido Cambiar automatedAssignedResources?: ActivityResourceAssignment[]automatedAssignedResources: ActivityResourceAssignment[] en types.ts. Corregir todos los factories en tests que crean Activity sin ese campo.

F.3 — Tests nuevos del sprint Tests unitarios del motor de simulación cubriendo los tres casos con automatedAssignedResources: solo fijo, solo recursos, mixto. Tests de drawResourcesSection para escenario automatizado.


Cambios autorizados

src/domain/types.ts

Remover el ? del campo:

// ANTES:
automatedAssignedResources?: ActivityResourceAssignment[]  // 🆕 Sprint 3

// DESPUÉS:
automatedAssignedResources: ActivityResourceAssignment[]   // requerido desde Etapa 6

Después de este cambio, TypeScript reportará errores en los factories de tests. Corregir todos los que aparezcan (ver sección de tests).

src/lib/export/pdf-sections.ts

Agregar parámetro scenario a drawResourcesSection:

export function drawResourcesSection(
  doc: any,
  autoTable: Function,
  result: { perActivity: ActivitySimResult[] },
  resources: Resource[],
  activities: Activity[],
  currency: string,
  startY: number,
  scenario: 'actual' | 'automatizado' = 'actual'   // 🆕 default 'actual' = retrocompatible
): void

Corregir el lookup de asignación (línea ~547 del archivo actual):

// ANTES (siempre usa AS-IS):
const assignment = activityRow?.assignedResources.find((a) => a.resourceId === br.resourceId)

// DESPUÉS (usa el array del escenario correcto):
const assignment = scenario === 'automatizado'
  ? activityRow?.automatedAssignedResources?.find((a) => a.resourceId === br.resourceId)
  : activityRow?.assignedResources.find((a) => a.resourceId === br.resourceId)

Nota: automatedAssignedResources puede ser undefined en actividades antiguas migradas sin pasar por ImportPage (aunque la migración Dexie v4 debería poblarlas con []). El optional chaining ?.find ya cubre ese caso.

El resto del cuerpo de drawResourcesSection no cambia.

src/lib/export/pdf-export.ts

En exportScenarioPdf, actualizar la llamada a drawResourcesSection para pasar el tab:

// Antes:
drawResourcesSection(docAny, autoTable, result, resources, activities, currency, y)

// Después:
drawResourcesSection(docAny, autoTable, result, resources, activities, currency, y, tab)

Esta es la única línea que cambia en este archivo.


Tests — correcciones de factories

Cuando se promueva automatedAssignedResources a requerido, TypeScript reportará error en los siguientes archivos. Agregar automatedAssignedResources: [] a cada factory que construye un Activity:

tests/domain/simulation.test.ts

Factory makeAutoActivity (~línea 218): agregar campo:

automatedCostFixed: opts.automatedCost ?? 0,
automatedTimeMinutes: opts.automatedTime ?? 0,
automatedAssignedResources: opts.automatedAssignedResources ?? [],  // 🆕

Si la interfaz de opts no incluye el campo, agregar:

automatedAssignedResources?: ActivityResourceAssignment[]

Factory genérico (~línea 77): agregar automatedAssignedResources: [].

Factory makeActivity para recursos (~línea 410): agregar automatedAssignedResources: [].

tests/integration/indexeddb-persistence.test.ts

makeActivity (~línea 40): agregar automatedAssignedResources: [] al objeto retornado.

tests/integration/sprint1-report-roi.test.ts

Factories inline (~líneas 51, 311): agregar automatedAssignedResources: [] a cada construcción de Activity.

tests/lib/export/pdf-resources-section.test.ts

mockActivity (~línea 34): agregar automatedAssignedResources: [].

tests/integration/dexie-migration.test.ts

makeLegacyActivity (~línea 19): usa Omit<Activity, 'automatable' | 'automatedCostFixed' | 'automatedTimeMinutes'>. Verificar si el tipo resultante cubre automatedAssignedResources. Si TypeScript reporta error, agregar 'automatedAssignedResources' al Omit O cambiar la función para retornar directamente el campo con [].


Tests — nuevos

tests/domain/simulation-sprint3.test.ts (NUEVO)

Cubrir los tres casos de recursos en escenario automatizado. Usar el mismo BPMN lineal simple de un nodo que ya existe en otros tests del dominio.

Caso 1: solo costo fijo, sin recursos TO-BE

Actividad automatable, automatedCostFixed=100, automatedTimeMinutes=60, automatedAssignedResources=[]
→ scenario=automated: costo esperado = 100 * execProb (sin costo de recursos)
→ resourceCostBreakdown vacío

Caso 2: solo recursos TO-BE, sin costo fijo

Actividad automatable, automatedCostFixed=0, automatedTimeMinutes=30
automatedAssignedResources=[{ resourceId: 'r1', utilizationMinutes: 60, units: 2 }]
Resource r1: costPerHour=30
→ scenario=automated: resourceCost = 30 * (60/60) * 2 * execProb = 60 * execProb
→ resourceCostBreakdown: [{ resourceId: 'r1', resourceName: 'Bot', cost: 60 * execProb }]

Caso 3: mixto — costo fijo + recurso TO-BE

Actividad automatable, automatedCostFixed=50, automatedTimeMinutes=30
automatedAssignedResources=[{ resourceId: 'r1', utilizationMinutes: 30, units: 1 }]
Resource r1: costPerHour=60
→ scenario=automated: totalCost = (50 + 60*(30/60)*1) * execProb = (50+30) * execProb = 80 * execProb

Caso 4: actividad NO automatable → usa assignedResources (regresión)

Actividad automatable=false, con assignedResources=[r1] y automatedAssignedResources=[r2]
→ scenario=automated: usa r1 (assignedResources), NO r2

Nota de arquitectura: para los tests de dominio puro, usar un grafo BPMN de un solo nodo secuencial (sin gateways), igual que en el describe('scenario=automated') ya existente en simulation.test.ts. Los inputs del motor (activities, resources, gateways, graph) se construyen inline.

tests/lib/export/pdf-resources-section.test.ts — tests nuevos (agregar al archivo existente)

Agregar un describe nuevo: drawResourcesSection — escenario automatizado:

Test 1: escenario automatizado usa automatedAssignedResources para min/unidades

mockActivity con assignedResources=[{ utilMin: 30, units: 1 }] y automatedAssignedResources=[{ utilMin: 5, units: 3 }]
Llamar drawResourcesSection(..., scenario='automatizado')
→ autoTable debe recibir min='5' y units='3' (no '30' y '1')

Test 2: escenario actual usa assignedResources (regresión)

Mismo mockActivity
Llamar drawResourcesSection(..., scenario='actual')  [o sin el param]
→ autoTable recibe min='30' y units='1'

Lo que NO entra en esta etapa

  • Tests E2E de la biblioteca (Playwright) — diferido a Etapa 7 o post-sprint si hay tiempo
  • PDF de ROI — no modificar pdf-sections-roi.ts
  • Cambios en simulation.ts, ActivityPanel.tsx, ActivitiesTable.tsx — ya cerrados en Etapa 5
  • Cambios en WorkspacePage.tsx, BpmnCanvas.tsx, stores — ya cerrados en Etapas anteriores
  • Nuevas features de UI

Verificación antes de entregar

# 1. Build limpio (verifica que el campo requerido no deja ningún any suelto)
npm run build

# 2. Tests — el count debe subir respecto a 555
npm run test

# 3. Control de scope
git diff --name-only HEAD

El diff debe mostrar únicamente:

  • src/domain/types.ts
  • src/lib/export/pdf-sections.ts
  • src/lib/export/pdf-export.ts
  • tests/domain/simulation.test.ts
  • tests/domain/simulation-sprint3.test.ts (nuevo)
  • tests/lib/export/pdf-resources-section.test.ts
  • tests/integration/indexeddb-persistence.test.ts
  • tests/integration/sprint1-report-roi.test.ts
  • tests/integration/dexie-migration.test.ts

Si aparece cualquier archivo de src/features/, src/store/, o src/persistence/: revertir y reportar.

Verificación funcional mandatoria

Antes de reportar, verificar manualmente:

  1. PDF automatizado muestra min/unidades correctas: asignar un recurso TO-BE con utilizationMinutes=5, units=3 → exportar PDF desde el tab Automatizado → verificar que la tabla de recursos muestra 5 y 3 (no los valores del AS-IS).
  2. PDF actual no regresiona: exportar PDF desde tab Actual → tabla de recursos muestra los valores de assignedResources sin cambio.
  3. TypeScript limpio: npm run build sin errores — el campo promovido a requerido no deja any ni errores de tipo.

Criterios de aceptación

  • automatedAssignedResources requerido en types.ts sin errores TypeScript en build.
  • PDF tab "Automatizado": tabla de recursos muestra utilizationMinutes y units de automatedAssignedResources.
  • PDF tab "Actual": sin regresión, tabla sin cambio.
  • Todos los tests previos siguen verdes (555+).
  • 4 nuevos tests en simulation-sprint3.test.ts (casos 14) verdes.
  • 2 nuevos tests en pdf-resources-section.test.ts verdes.
  • Validación visual del director aprobada (PDF tab Automatizado con datos correctos).

Reporte esperado al terminar

  1. Resultado de git diff --name-only HEAD.
  2. Resultado de npm run build y npm run test (incluir count final de tests).
  3. Confirmación de los 3 casos de verificación funcional.
  4. Lista de factories de tests corregidos (archivo + línea aproximada).
  5. Cualquier decisión de iniciativa (Nivel 1/2/3).
  6. Si algún archivo de test tuvo más cambios de los esperados: declararlo.

Referencias

  • sprints/sprint-3/BRIEF.md — sección 4, Feature F
  • src/lib/export/pdf-sections.tsdrawResourcesSection (~línea 479), lookup de assignedResources (~línea 547)
  • src/lib/export/pdf-export.tsexportScenarioPdf (~línea 54), llamada a drawResourcesSection (~línea 147)
  • tests/domain/simulation.test.ts — factories makeAutoActivity (~línea 218) y genérico (~línea 77)
  • tests/lib/export/pdf-resources-section.test.tsmockActivity fixture (~línea 34)
  • methodology/ANTI_PATTERNS.md — AP.8 (adelanto silencioso), AP.9 (restricciones contradictorias)
  • methodology/PATTERNS.md — C.7 (git diff como control preventivo)