Files
inq-roi-simulador-web/sprints/sprint-1-5/ETAPA_4_PROMPT.md
Marcos Benítez 63c4fbac99 "chore(claude-code): configurar permisos compartidos del proyecto
- settings.json: deny patterns críticos (rm -rf root, force push, etc.)
- settings.local.json en gitignore — cada dev configura sus allows

Refs: methodology/PATTERNS.md B.4 (reglas no negociables en repo)
2026-05-17 07:49:00 -03:00

12 KiB

Sprint 1.5 — Etapa 4: PDF — Header y footer compartidos

Objetivo: refactor estructural de los headers y footers de PDFs. Crear módulo compartido que aplique identidad InQ consistente en los 3 PDFs (Actual, Automatizado, ROI). Aplicar paleta naranja InQ a elementos de marca. NO rediseñar layout de contenido — eso es Etapa 5+.

Pre-requisitos: Etapas 1, 2 y 3 cerradas. Sistema de diseño con tokens InQ disponible. Web app con identidad InQ aplicada.

Etapa siguiente: Etapa 5 — PDF: layout híbrido portrait + landscape (la página BPMN pasa a horizontal).


1. Alcance estricto de Etapa 4

Sí entra

  • Crear módulo compartido pdf-sections-shared.ts con drawHeader y drawFooter reutilizables
  • Refactorizar los 3 PDFs existentes (Actual, Automatizado, ROI) para usar el módulo compartido
  • Aplicar paleta naranja InQ en:
    • Border-bottom del header (color naranja #F59845, grosor variable según página)
    • Logo "InQ ROI" en color naranja en cada header
    • "Powered by InQuality" en color slate-500 en cada footer
  • Reemplazar PDF.blue por PDF.inqOrange en headers de tablas autotable (de pdf-sections.ts, pdf-export.ts, pdf-sections-roi.ts según audit Etapa 1)
  • Quitar versión "v0.1.0" del footer del PDF (decisión de Etapa 3 — la versión se queda solo en web app)
  • Tests E2E confirman que los 3 PDFs siguen generándose correctamente con la nueva estructura

NO entra

  • Cambio de orientación de páginas (Etapa 5)
  • Rediseño de página 1 ROI con KPI Hero gradiente (Etapa 6)
  • Tabla comparativa rediseñada con paleta (Etapa 7)
  • Top 3 ahorros en página 1 ROI (Etapa 6)
  • Sección Transparencia rediseñada (Etapa 7)
  • Modificar el contenido de cualquier página más allá del header/footer

Si encontrás algo que parece "natural" agregar pero no está en "Sí entra", PARÁ y consultá. Aplicá la política de iniciativa proactiva de CLAUDE.md.


2. Decisiones ya tomadas (no consultar de nuevo)

Decisión Justificación
Logo "InQ ROI" en header de cada página Brief sección 2.6, ya aplicado en Etapa 2
"Powered by InQuality" en footer de cada página Regla de marca CLAUDE.md, ya aplicado en Etapa 2
Border-bottom 3px naranja en página 1, 2px en páginas siguientes Brief sección 2.6
Quitar versión del PDF (mantener solo en web) Decisión de Etapa 3
Color naranja InQ #F59845 para elementos de marca Manual de marca Etapa 1
Mantener fuente actual (Roboto o equivalente) No cambiar de fuente en esta etapa
Caracteres especiales (✓, , ⚠) reemplazados por equivalentes ASCII si la fuente no soporta Decisión Etapa 2 — se mantiene

3. Estructura del módulo compartido

3.1 Archivo nuevo: src/lib/export/pdf-sections-shared.ts

Debe exportar al menos estas dos funciones:

import type { jsPDF } from 'jspdf';

export interface PdfHeaderOptions {
  pageNumber: number;       // 1, 2, 3...
  totalPages: number;       // necesario para "Página X de Y"
  productName: string;      // "InQ ROI"
  sectionTitle?: string;    // ej. "Análisis de retorno de inversión"
  clientName?: string;      // ej. "Banco Atlántico S.A."
  processName?: string;     // ej. "medium-with-gateways"
  simulatedAt: Date;        // fecha de simulación
}

export interface PdfFooterOptions {
  pageNumber: number;
  totalPages: number;
  productName: string;      // "InQ ROI"
  clientName?: string;
  simulatedAt: Date;
}

/**
 * Dibuja el header en la posición actual del documento.
 * - Página 1: border-bottom 3px naranja
 * - Otras páginas: border-bottom 2px naranja
 * - Logo "InQ ROI" en naranja InQ (esquina superior izquierda o derecha según diseño)
 * - Metadata del producto/proceso a la derecha (ver brief sección 2.6)
 */
export function drawHeader(doc: jsPDF, options: PdfHeaderOptions): void;

/**
 * Dibuja el footer en la posición fija inferior (16-20px del bottom).
 * - Border-top 0.5px slate-200
 * - Izquierda: "InQ ROI · Powered by InQuality · [cliente] · [fecha]"
 * - Derecha: "Página X de Y"
 * - NO incluir versión del producto
 */
export function drawFooter(doc: jsPDF, options: PdfFooterOptions): void;

/**
 * Constantes de paleta para PDFs.
 */
export const PDF_COLORS = {
  inqOrange:      [245, 152, 69],   // #F59845
  inqOrangeDark:  [180, 83, 9],     // #B45309
  inqMagenta:     [237, 62, 143],   // #ED3E8F
  textPrimary:    [15, 23, 42],     // #0F172A
  textSecondary: [71, 85, 105],     // #475569
  textTertiary: [148, 163, 184],    // #94A3B8
  borderLight:  [226, 232, 240],    // #E2E8F0
  // ... cualquier otro que necesites
} as const;

3.2 Eliminar PDF.blue del código

Buscar todas las ocurrencias y reemplazar por PDF_COLORS.inqOrange:

grep -rn "PDF.blue\|PDF\.blue" src/

Archivos afectados según audit Etapa 1:

  • pdf-sections.ts:9 (definición de la constante — eliminar)
  • pdf-sections.ts:112 (uso en KPI card accent)
  • pdf-export.ts:120 (header de tabla autotable)
  • pdf-sections-roi.ts:203 (header de tabla comparativa ROI)

3.3 Refactorizar los 3 PDFs

Los archivos que generan los PDFs deben:

  1. Importar drawHeader, drawFooter, PDF_COLORS del módulo compartido
  2. Reemplazar el código actual de header/footer por las llamadas al módulo
  3. Mantener todo el resto del contenido sin cambios (esto NO es Etapa 5-7)

Archivos a refactorizar:

  • src/lib/export/pdf-export.ts (PDFs Actual y Automatizado)
  • src/lib/export/pdf-sections-roi.ts (PDF de Comparación + ROI)
  • Cualquier helper que genere los PDFs anteriores

4. Validación visual mandatoria

4.1 Antes de declarar etapa completada

Generar los 3 PDFs con el setup realista de pruebas y validarlos visualmente:

Setup de referencia:

  • Proceso: medium-with-gateways
  • 3 actividades automatizables (task_recv, task_score, task_analisis)
  • Costos: directos $200, automatizados $20
  • Volumetría: 5000/año, 3 años, USD 80.000 inversión

Archivos a generar en tests/e2e/__output__/:

  • etapa-4-actual.pdf
  • etapa-4-automatizado.pdf
  • etapa-4-roi.pdf

4.2 Validaciones automatizadas mandatorias

Antes de present_files, ejecutá y confirmá:

Para cada PDF generado:

1. pdf-parse confirma palabras clave en TODAS las páginas:
   - "InQ ROI" presente
   - "Powered by InQuality" presente en footer
   
2. pdf-parse rechaza términos prohibidos:
   - "Process Cost Platform" — NO debe aparecer
   - "v0.1.0" — NO debe aparecer en el PDF (solo en web)
   - "INQ", "Inq", "inq" — NO debe aparecer (regla de marca I-n-Q)

3. Cantidad de páginas:
   - actual.pdf: 3 páginas
   - automatizado.pdf: 3 páginas
   - roi.pdf: 4 páginas
   
4. Tamaño de cada página: entre 15-80 KB
   Si alguna queda <15KB: anomalía, investigar antes de presentar
   
5. Análisis de píxeles del border-bottom del header:
   - Confirmar presencia de naranja #F59845 (al menos N píxeles)
   - Ausencia de azul `#1E40AF` (color anterior que migramos)

6. Tests previos verdes: >= 455

Si CUALQUIER validación falla, NO uses present_files. Reportá qué falló y esperá instrucciones.

4.3 Validación visual del humano

Después de las validaciones automatizadas, presentar los 3 PDFs vía present_files. El humano va a verificar visualmente:

  1. ¿El header tiene logo "InQ ROI" en naranja en las 3 (o 4) páginas?
  2. ¿Hay un border-bottom naranja consistente en cada header?
  3. ¿El footer dice exactamente "InQ ROI · Powered by InQuality · [cliente] · [fecha]" sin versión?
  4. ¿La paginación "Página X de Y" es correcta en cada PDF?
  5. ¿Las tablas internas usan headers naranjas en lugar de azules?
  6. ¿El contenido de las páginas más allá del header/footer NO cambió respecto a la versión anterior?

5. Entregables (Definition of Done)

[ ] src/lib/export/pdf-sections-shared.ts creado con drawHeader, 
    drawFooter y PDF_COLORS exportados
[ ] pdf-export.ts refactorizado para usar el módulo compartido
[ ] pdf-sections.ts refactorizado para usar el módulo compartido
[ ] pdf-sections-roi.ts refactorizado para usar el módulo compartido
[ ] Cero ocurrencias de PDF.blue en grep
[ ] Versión "v0.1.0" eliminada del footer de PDFs (mantener en web)
[ ] 3 PDFs generados en tests/e2e/__output__/:
    - etapa-4-actual.pdf (3 páginas)
    - etapa-4-automatizado.pdf (3 páginas)
    - etapa-4-roi.pdf (4 páginas)
[ ] 6 validaciones automatizadas confirmadas (palabras clave, prohibidos, 
    páginas, tamaño, píxeles naranja, tests previos)
[ ] PDFs presentados con present_files
[ ] 455 tests previos + nuevos tests del módulo compartido = ~460+ verdes
[ ] Tests nuevos para drawHeader y drawFooter (3-5 casos mínimo)
[ ] npm run build limpio (sin warnings TS nuevos)
[ ] Decisiones tomadas por iniciativa documentadas en reporte (Patrón C.6)

6. Tests obligatorios

6.1 Tests unitarios del módulo compartido

Crear tests/lib/export/pdf-sections-shared.test.ts:

describe('PDF shared sections', () => {
  describe('PDF_COLORS', () => {
    it('expone inqOrange como array RGB válido', () => {
      expect(PDF_COLORS.inqOrange).toEqual([245, 152, 69]);
    });
    
    it('NO incluye colores de CONCILIA', () => {
      const allColors = JSON.stringify(PDF_COLORS);
      expect(allColors).not.toContain('87, 47, 162');  // #572FA2
      expect(allColors).not.toContain('203, 24, 137'); // #CB1889
    });
  });

  describe('drawHeader', () => {
    it('dibuja border-bottom 3px en página 1', () => {
      // mock jsPDF, capturar llamadas, assertions
    });
    
    it('dibuja border-bottom 2px en página 2+', () => {
      // ...
    });
  });

  describe('drawFooter', () => {
    it('incluye "InQ ROI" y "Powered by InQuality"', () => {
      // ...
    });
    
    it('NO incluye versión del producto', () => {
      // ...
    });
  });
});

6.2 Tests E2E

Adaptar tests E2E existentes para verificar que los 3 PDFs siguen generándose correctamente después del refactor.


7. Reporte final a entregar

Cuando termines, devolveme:

  1. Tabla de archivos modificados/creados con líneas
  2. Resultado de las validaciones automatizadas (los 6 puntos del 4.2)
  3. Cantidad final de tests verdes (esperado 460+)
  4. 3 PDFs presentados con present_files para validación visual mía
  5. Hallazgos no esperados — cualquier cosa que merezca decisión arquitectónica
  6. Decisiones tomadas por iniciativa — si aplicaste algún cambio Nivel 2 según política de CLAUDE.md, listalo acá. Si encontrás algo Nivel 3, NO LO HAGAS y reportalo como propuesta

NO arranques Etapa 5 sin mi OK explícito.


8. Reglas operativas (recordatorios)

  1. No tocar contenido de las páginas más allá del header/footer. El rediseño de páginas viene en Etapas 5-7.
  2. No cambiar la orientación de ninguna página. La página BPMN sigue vertical en esta etapa (cambia en Etapa 5).
  3. No agregar features nuevas al PDF. Esta etapa es refactor + identidad, no nueva funcionalidad.
  4. No racionalizar problemas. Si una validación automatizada falla, investigar causa raíz.
  5. Política de iniciativa proactiva (CLAUDE.md):
    • Cambios Nivel 1 (refactor interno, mejor naming): ejecutar
    • Cambios Nivel 2 (visible pero reversible): ejecutar y reportar
    • Cambios Nivel 3 (marca, arquitectura, datos): CONSULTAR antes
  6. Si encontrás contradicción entre este prompt y la realidad del código (un archivo no está donde decía, un import no resuelve, etc.): PARÁ y consultá, no asumas.

9. Notas sobre dependencia con Etapa 5

Etapa 5 va a cambiar la orientación de la página BPMN a landscape. El módulo pdf-sections-shared.ts que crees en esta etapa debe estar preparado para esto:

  • drawHeader y drawFooter deben recibir el ancho/alto disponible como parámetros implícitos del doc (jsPDF lo provee con doc.internal.pageSize.getWidth() y getHeight())
  • NO hardcodear pageWidth = 595 (A4 portrait). Si el header se llama desde una página landscape, debe adaptarse al ancho real
  • Probá esto con un test que llame drawHeader en una página landscape mock

Esto preserva el contrato del módulo para que Etapa 5 no requiera refactor adicional.