- 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)
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.tscondrawHeaderydrawFooterreutilizables - ✅ 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
- Border-bottom del header (color naranja
- ✅ Reemplazar
PDF.blueporPDF.inqOrangeen 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:
- Importar
drawHeader,drawFooter,PDF_COLORSdel módulo compartido - Reemplazar el código actual de header/footer por las llamadas al módulo
- 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.pdfetapa-4-automatizado.pdfetapa-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:
- ¿El header tiene logo "InQ ROI" en naranja en las 3 (o 4) páginas?
- ¿Hay un border-bottom naranja consistente en cada header?
- ¿El footer dice exactamente "InQ ROI · Powered by InQuality · [cliente] · [fecha]" sin versión?
- ¿La paginación "Página X de Y" es correcta en cada PDF?
- ¿Las tablas internas usan headers naranjas en lugar de azules?
- ¿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:
- Tabla de archivos modificados/creados con líneas
- Resultado de las validaciones automatizadas (los 6 puntos del 4.2)
- Cantidad final de tests verdes (esperado 460+)
- 3 PDFs presentados con
present_filespara validación visual mía - Hallazgos no esperados — cualquier cosa que merezca decisión arquitectónica
- 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)
- No tocar contenido de las páginas más allá del header/footer. El rediseño de páginas viene en Etapas 5-7.
- No cambiar la orientación de ninguna página. La página BPMN sigue vertical en esta etapa (cambia en Etapa 5).
- No agregar features nuevas al PDF. Esta etapa es refactor + identidad, no nueva funcionalidad.
- No racionalizar problemas. Si una validación automatizada falla, investigar causa raíz.
- 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
- 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:
drawHeaderydrawFooterdeben recibir el ancho/alto disponible como parámetros implícitos deldoc(jsPDF lo provee condoc.internal.pageSize.getWidth()ygetHeight())- 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
drawHeaderen una página landscape mock
Esto preserva el contrato del módulo para que Etapa 5 no requiera refactor adicional.