Fix 4 Parte A: .maybeSingle() ya estaba aplicado (lo hiciste vos/el linter). Encontré y arreglé un bug adicional: con data === null (sin simulaciones), el código llamaba fromRow(null) y explotaba al leer row.id. Ahora getLatestByProcess retorna undefined limpiamente cuando no hay filas.
Fix 4 Parte B: revisé ProcessCardWithSim en LibraryPage.tsx — ya tiene guard de cancelación y dependencias estables (process.id + acción de Zustand, que es una referencia fija). No encontré un loop real; lo más probable es que "~6 queries" correspondan a 6 procesos distintos disparando una query cada uno (correcto), posiblemente duplicado visualmente en dev por StrictMode (inocuo, no pasa en producción).
Fixes 1, 2, 3 ya estaban implementados de antes y siguen verdes. Falta tu validación visual — en particular confirmar que el network tab ya no muestra 406 en simulations.
Tipos: Resource.processId? eliminado (vestigial); ResourceType ya tenía los 5 valores correctos, sin cambios.
resource-repo.ts: agregado getAllWithCreator() con JOIN a users!created_by (mismo patrón que Etapa 6) y tipo ResourceWithCreator. delete() ahora valida que no haya asignaciones activas en activity_resource_assignments antes de borrar — lanza error explicativo si las hay. Verifiqué ambos contra Supabase real: el JOIN funciona (FK reconocida por PostgREST) y el conteo de guarda también.
Nuevo — src/features/resources/:
resource-display.tsx — labels, colores/íconos por tipo (Lucide: User/Briefcase/Server/Wrench/Package) y ResourceTypeAvatar compartido
ResourceFormSheet.tsx — Sheet reutilizable para crear/editar, usado tanto en el catálogo como en el panel del workspace
ResourceCatalogPage.tsx — página /recursos: búsqueda, filtro por tipo, tabla con badge de tipo, costo, "creado por", editar/eliminar con confirmación
Nuevo — src/components/ui/sheet.tsx: componente shadcn Sheet (no existía), construido sobre @radix-ui/react-dialog que ya estaba instalado — no agregué dependencias nuevas.
ResourcesPanel.tsx rediseñado: ahora solo muestra recursos usados en el proceso actual (derivado de assignedResources), con conteo de actividades por recurso. CRUD completo se mudó a /recursos; el panel solo permite "Nuevo" (catálogo global) y tiene el link "Ver catálogo completo".
Router: ruta /recursos registrada.
ActivityPanel no se tocó, como indicaba el scope.
Sprint 3 completo — 7 etapas:
- Etapa 1-2: biblioteca de procesos con agrupación por cliente (Dexie v4,
LibraryPage, library-store, groupId/tags en Process)
- Etapa 3: modal de configuración global por proceso (horizonte, frecuencia,
inversión, moneda) con validación y persistencia
- Etapa 4: panel de recursos rediseñado con soporte de unidades y minutos
de utilización (utilizationMinutes + units)
- Etapa 5: recursos en escenario automatizado — motor de simulación,
UI de edición en ActivityPanel, comparación AS-IS/TO-BE en reporte
- Etapa 6: PDF recursos automatizados, automatedAssignedResources requerido,
561 tests pasando
- Etapa 7: identidad de marca — AppHeader gradiente naranja/magenta con logo
InQuality en 5 páginas, favicon con logo real, logo/marca navegan a home
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Etapas 3-6 del Sprint 2. Resumen de cambios:
**Reporte web (Etapa 3)**
- ActivitiesTable: filas expandibles con desglose fijo + recursos por actividad
- CumulativeSavingsChart: fix payback label superpuesto con eje Y
- BpmnCanvas: badge ⚡ 14→20px
- TECH_DEBT cerrado: chart -inversión (ya estaba), payback label, badge
**Workspace (Etapa 4)**
- WorkspacePage: edición inline de nombre de proceso y cliente
(click → input → Enter/blur guarda en IndexedDB, checkmark naranja 1.5s)
**PDF (Etapas 5-6)**
- pdf-sections: drawResourcesSection — tabla condicional de recursos por actividad
con chips de tipo (rol/persona/sistema/equipamiento/insumo)
- pdf-export: página de recursos (pág. 4 cuando hay datos, metodología pasa a pág. 5)
- Fix truncamiento: splitTextToSize en resourceName y top3 ROI
- Fix texto: "ejecución" con tilde, header "Esp. (USD)" sin truncar
- TECH_DEBT cerrado: truncamiento notas metodológicas
**Tests**
- 7 tests nuevos: drawResourcesSection (4) + comportamiento condicional PDF (3)
- Total: 541 → 548 tests verdes
BREAKING: exportScenarioPdf ahora recibe activities[] como parámetro adicional.
- OBSERVATIONS.md reseteado para Sprint 2
- STRATEGIC_DIRECTION.md con reflexiones del sprint
- TECH_DEBT.md curado: items resueltos archivados
- methodology/CASE_STUDIES/inq-roi-sprint-1-5.md generado
Sprint 1.5 cerrado:
- 11 etapas + 1 fix pre-Etapa 11
- 526 unit tests + 38 E2E al cierre
- Producto con identidad InQ aplicada en web + 3 PDFs
- Metodología documentada con casos reales (2 de mala
clasificación de iniciativa, originaron AP.8 +
refinamiento C.6)
- Material para transmisión al equipo de 5 técnicos
- Header/footer compartidos con paleta InQ naranja en los 3 PDFs (Etapa 4)
- Layout híbrido portrait+landscape en PDFs Actual/Automatizado:
página 2 landscape para diagrama BPMN heatmap (Etapa 5)
- Página 1 PDF ROI rediseñada: header denso, banner narrativo, KPI Hero
con gradiente naranja→magenta, grid 2×2 de KPIs secundarios, Top 3
actividades por ahorro (Etapa 6)
- Páginas 2-5 PDF ROI con identidad InQ: tabla con paleta naranja,
análisis del ahorro, nota metodológica, trayectoria del ahorro
acumulado con gráfico SVG nativo (Etapa 7)
- 500 tests verdes (+ 34 tests nuevos del Sprint 1.5)
- BACKLOG.md, TECH_DEBT.md, OBSERVATIONS.md: sistema de planificación
reemplaza TODO.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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)