feat(sprint-1-5): cierre Etapa 2 - formatPayback + fixes de marca

[
This commit is contained in:
2026-05-16 19:26:19 -03:00
parent f9a008bce5
commit eaaac88fc3
16 changed files with 1626 additions and 55 deletions

View File

@@ -0,0 +1,220 @@
# Sprint 1.5 — Etapa 1: Setup del sistema de diseño
> **Estado: COMPLETADA y APROBADA** (16 mayo 2026)
>
> Este documento es el prompt original que se ejecutó. Se preserva como referencia histórica del Sprint 1.5. La evidencia de ejecución vive en:
> - Código del repo (tokens InQ aplicados)
> - `sprints/sprint-1-5/etapa-1-audit.md` (audit de azules y hardcodes)
> - Tests en `tests/design-system/tokens.test.ts`
---
## Objetivo
Establecer la infraestructura visual del Sprint 1.5 antes de tocar cualquier componente de UI o PDF. Sin esto, los cambios de Etapas 2-9 quedarían hardcodeados con hexcodes dispersos.
---
## Plan aprobado con 4 ajustes
### Ajuste 1 — Heatmap: tokens SÍ, aplicación NO
Mantener los colores saturados actuales del heatmap (verde/ámbar/rojo). NO migrar a la paleta pastel del brief en esta etapa.
Razones:
- Romper los E2E de análisis de píxeles calibrados a colores saturados sería retroceso. Esos tests fueron el mecanismo de validación más sólido en Sprint 1.
- El producto se usa en talleres y charlas en pantallas grandes. El pastel se ve lavado a distancia.
Acciones:
- En `tailwind.config.ts`, definir tokens del heatmap saturado actual:
```typescript
heatmap: {
low: '#10B981',
mid: '#F59E0B',
high: '#EF4444',
}
```
- Reemplazar los hex hardcodeados de `HeatmapCanvas` por estos tokens.
- En `DESIGN_SYSTEM.md`, documentar la decisión.
- En `TODO.md`: anotar revisión del heatmap para Sprint 3-4.
### Ajuste 2 — Audit de azules residuales y hardcodes
Antes de finalizar Etapa 1, ejecutar auditoría:
```bash
grep -rn "blue\|sky\|indigo\|3B82F6\|2563EB\|1D4ED8" src/ \
--include="*.tsx" --include="*.ts" --include="*.css"
grep -rn "primary" src/ --include="*.tsx" --include="*.ts"
grep -rn "#[0-9a-fA-F]\{6\}" src/ --include="*.tsx" --include="*.ts"
```
Clasificar cada hallazgo en 3 categorías:
- "Migrar a token InQ"
- "Mantener azul funcional"
- "Migrar a neutral"
Documentar en `sprints/sprint-1-5/etapa-1-audit.md` con archivo:línea, color, clasificación, acción sugerida. NO resolver en Etapa 1; solo listar.
### Ajuste 3 — Tests del sistema de diseño
Crear `tests/design-system/tokens.test.ts` con al menos:
```typescript
describe('Design tokens', () => {
it('expone tokens de marca InQ vía Tailwind config', () => {
expect(config.theme.extend.colors.inq.orange.DEFAULT).toBe('#F59845');
expect(config.theme.extend.colors.inq.orange.dark).toBe('#B45309');
expect(config.theme.extend.colors.inq.orange.light).toBe('#FEF3E2');
expect(config.theme.extend.colors.inq.orange.lighter).toBe('#FFF8ED');
expect(config.theme.extend.colors.inq.magenta).toBe('#ED3E8F');
});
it('NO incluye los colores de CONCILIA', () => {
const allColors = JSON.stringify(config.theme.extend.colors);
expect(allColors).not.toContain('#572FA2');
expect(allColors).not.toContain('#CB1889');
});
it('expone tokens del heatmap saturado', () => {
expect(config.theme.extend.colors.heatmap.low).toBe('#10B981');
expect(config.theme.extend.colors.heatmap.mid).toBe('#F59E0B');
expect(config.theme.extend.colors.heatmap.high).toBe('#EF4444');
});
});
```
Adicionalmente, crear `tests/lib/format-payback.test.ts` con 7 `it.todo` que preparan Etapa 2.
### Ajuste 4 — Estructura anidada en Tailwind config
Estructura anidada (no con guiones en clases):
```typescript
inq: {
orange: {
DEFAULT: '#F59845',
dark: '#B45309',
light: '#FEF3E2',
lighter: '#FFF8ED',
},
magenta: '#ED3E8F',
},
heatmap: {
low: '#10B981',
mid: '#F59E0B',
high: '#EF4444',
}
```
Permite uso natural:
- `bg-inq-orange` (DEFAULT)
- `bg-inq-orange-dark`
- `bg-inq-orange-light`
- `bg-inq-orange-lighter`
- `bg-inq-magenta`
- `bg-heatmap-low`
Colores semánticos:
```typescript
success: { DEFAULT: '#16A34A', light: '#F0FDF4' },
warning: { DEFAULT: '#F59E0B', bg: '#FFFBEB' },
```
---
## Checklist final de Etapa 1
```
[x] DESIGN_SYSTEM.md creado con sección de decisión sobre heatmap
[x] tailwind.config.ts con tokens InQ anidados + tokens heatmap saturado
[x] src/index.css con --primary naranja y variables InQ
[x] HeatmapCanvas migrado a tokens heatmap.* (find-and-replace simple)
[x] CLAUDE.md con sección "Reglas de marca" al inicio (prominente)
[x] tests/design-system/tokens.test.ts con 3 tests verdes
[x] tests/lib/format-payback.test.ts con 7 it.todo
[x] sprints/sprint-1-5/etapa-1-audit.md con hallazgos (sin resolver)
[x] TODO.md actualizado con nota de revisión de heatmap para Sprint 3-4
[x] 440 tests previos + 3 nuevos = 443 verdes
[x] npm run build limpio
[x] npm run dev levanta sin errores
[x] Verificación visual con dev server: screenshots de CTAs naranjas,
tabs activos naranjas, switches checked naranjas
```
---
## Reporte de ejecución (resumen)
### Archivos modificados/creados
| Archivo | Acción | Líneas |
|---|---|---|
| `tailwind.config.js` | Modificado | +25 (tokens inq.*, heatmap.*, success, warning) |
| `src/styles/globals.css` | Modificado | +22 (--primary naranja, variables --inq-*) |
| `src/components/ui/tabs.tsx` | Modificado | 1 (text-inq-orange + font-semibold en activo) |
| `CLAUDE.md` | Modificado | +42 (sección "Reglas de Marca" prominente) |
| `TODO.md` | Modificado | +3 (entrada revisión heatmap Sprint 3-4) |
| `DESIGN_SYSTEM.md` | Creado | 232 |
| `sprints/sprint-1-5/etapa-1-audit.md` | Creado | 80 |
| `tests/design-system/tokens.test.ts` | Creado | 37 (3 tests) |
| `tests/lib/format-payback.test.ts` | Creado | 18 (7 it.todo) |
| `tests/e2e/screenshots-etapa-1.spec.ts` | Creado | 60 |
| `tests/screenshots/etapa-1/*.png` | Generados | 3 |
### Hallazgos del audit (9 azules + 12 hardcodes)
Categorizados por etapa de resolución:
- **Etapa 3 (charts web):** `CumulativeSavingsChart.tsx`, `TopSavingsChart.tsx`, `HeatmapLegend.tsx`, `chart-options.ts`
- **Etapa 4-8 (PDFs):** `pdf-sections.ts`, `pdf-export.ts`, `pdf-sections-roi.ts` (`PDF.blue`)
- **Etapa 9 (badge ⚡):** `BpmnCanvas.tsx`
- **NO migrar (decisión arquitectónica):** `GatewayPanel.tsx` (azul = semántica funcional info banner)
### Validación visual confirmada
3 screenshots en `tests/screenshots/etapa-1/`:
- `workspace.png` — botón Simular naranja, tab Actividad activo naranja, borde del nodo seleccionado naranja
- `report-tabs.png` — tab Actual activo naranja, Exportar PDF naranja, KPI icons naranjas
- `switch-on.png` — switch automatizable ON naranja, sección automatización con caja naranja, Guardar cambios naranja
El cambio de `--primary` de azul a naranja propagó correctamente a: Button, Switch, Tabs, Slider, Tooltip, Badge, rings de focus, bordes de selección en canvas BPMN.
### Descubrimientos no esperados
- `--primary-foreground` (210 40% 98%, blanco casi puro) funciona correctamente sobre el naranja sin modificación.
- `--ring` también está en naranja, los focus rings de inputs y botones son coherentes con la marca.
### Tests finales
- 443 tests verdes (440 previos + 3 nuevos de tokens)
- 7 `it.todo` listos para Etapa 2 (formatPayback)
- Build limpio, sin warnings TS ni lint nuevos
---
## Aprobación final del usuario
Confirmada con observaciones que se trasladan a Etapa 2:
1. La fila de `GatewayPanel.tsx` en el audit se reclasifica de "Mantener azul funcional / Evaluar Sprint 2" a "Decisión arquitectónica: mantener azul informativo. No es marca, es semántica funcional."
2. El donut chart (`chart-options.ts:123`) tiene una decisión visual pendiente: sector "directo" en naranja InQ, sector "overhead" en slate-400 o naranja claro (no en otro naranja). Decisión final en Etapa 3.
3. Contraste WCAG del naranja `#F59845` sobre blanco: ratio ~2.42:1, FAIL para AA normal y AA large. Decisión propuesta para Etapa 3: aplicar `font-weight: 700` en CTAs primarios (opción D del análisis).
Estas 3 observaciones se incorporan en Etapa 2 como pre-tareas.
---
## Lecciones operativas capturadas
1. **Pattern de auditoría preventiva**: el grep de azules y hex residuales antes de mergear cambios de paleta previno que la migración a InQ quedara incompleta. Replicar este pattern en cualquier cambio de paleta futuro.
2. **Validación visual con screenshots Playwright**: más robusto que pedirle al usuario que capture manualmente. Los PNG quedan versionados en `tests/screenshots/etapa-*/` como evidencia de la etapa.
3. **Decisiones arquitectónicas vs decisiones de marca**: `GatewayPanel` enseñó que no todo color se debe alinear con la marca. El azul informativo es una convención semántica funcional que vale la pena preservar.
4. **El audit que clasifica por etapa de resolución** evita el "tendremos que migrar todo de golpe". Tokenizar primero, aplicar después en pequeños lotes.