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

311 lines
12 KiB
Markdown

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