# 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:

```typescript
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`:

```bash
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`:

```typescript
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.