504 lines
32 KiB
Markdown
504 lines
32 KiB
Markdown
# Dirección estratégica — InQ ROI
|
||
|
||
> Documento de decisiones estratégicas del director (Marcos) que orientan el desarrollo del producto en sprints futuros. Se actualiza al cerrar cada sprint con reflexiones del director.
|
||
>
|
||
> NO es backlog (ver `BACKLOG.md`) ni deuda técnica (ver `TECH_DEBT.md`). Es **el "por qué" detrás de las decisiones de prioridad**.
|
||
|
||
---
|
||
|
||
## Versión actual: post-Sprint 1.5 (mayo 2026)
|
||
|
||
### Reorientación estratégica detectada al cerrar Sprint 1.5
|
||
|
||
Durante el Sprint 1.5, el director identificó que la inversión de tiempo en el producto estaba desbalanceada:
|
||
|
||
- **7 de 11 etapas del Sprint 1.5 fueron sobre PDF** (Etapas 4, 5, 6, 7, 8 + porción de 1 y 11)
|
||
- **3 de 11 etapas fueron sobre web app** (Etapas 1, 3, 9)
|
||
- **1 etapa fue mixta** (Etapa 2: helper compartido)
|
||
|
||
Esta proporción tuvo justificación válida en Sprint 1.5 porque se establecía identidad visual y sistema de diseño desde cero. Pero **replicar esa proporción en Sprint 2+ sería un error estratégico.**
|
||
|
||
### Decisión: rebalanceo de prioridades
|
||
|
||
**El producto es la herramienta web. El PDF es entregable final del producto.**
|
||
|
||
A partir de Sprint 2:
|
||
|
||
| Componente | Inversión esperada |
|
||
|---|---|
|
||
| Web app (workspace + reporte + features) | 60-70% del tiempo del sprint |
|
||
| PDF (refinamientos, nuevas secciones) | 15-25% |
|
||
| Infraestructura (deuda técnica, build, deploy) | 10-15% |
|
||
| Documentación / metodología | 5-10% |
|
||
|
||
**Razón:** el consultor de InQuality usa el web app **decenas de veces** mientras itera sobre un caso. Exporta el PDF **una vez** al final. Una mejora en el web app tiene 10× más impacto en la productividad del consultor que un refinamiento del PDF.
|
||
|
||
### Implicancia operativa para Sprint 2+
|
||
|
||
- No abrir sprints con foco principal en PDF
|
||
- Si un sprint requiere trabajo de PDF, que sea acotado a una etapa puntual, no transversal
|
||
- Los refinamientos del PDF se acumulan en `TECH_DEBT.md` para resolver en sprints periódicos de "polish", no continuamente
|
||
- Features nuevas del producto se construyen en el web app primero, exporte al PDF segundo
|
||
|
||
---
|
||
|
||
## Decisión: criterio de "wow" como parte del scope de cada feature
|
||
|
||
Detectado durante validación visual del Sprint 1.5 (Etapa 6). Se observó que la implementación "mínima" cumple la funcionalidad pero pierde el efecto de experiencia que diferencia un producto profesional de un funcional.
|
||
|
||
### Política a partir de Sprint 2
|
||
|
||
Cada `ETAPA_PROMPT.md` que defina una feature nueva debe incluir una sección explícita **"Criterio de wow"** con dos versiones del scope:
|
||
|
||
- **Versión mínima:** lo que cumple la funcionalidad
|
||
- **Versión con wow:** mismo objetivo + 1-2 detalles de experiencia que generen impacto positivo en el usuario
|
||
|
||
El director decide en cada feature si se implementa la mínima o la con wow. **Por defecto, la versión con wow es la recomendada** si el costo extra es menor al 40% del tiempo de la versión mínima.
|
||
|
||
### Ejemplo aplicado: feature "Recursos con costo por hora"
|
||
|
||
- **Mínimo:** input numérico, cálculo en backend, número en tabla
|
||
- **Con wow:** input con sugerencias de salario por rol (CEO, Analista, etc.), validación en tiempo real, cálculo actualiza mientras escribís, helper que dice "esta actividad cuesta el equivalente a X días de trabajo de Y persona"
|
||
|
||
Ambas resuelven el problema. La segunda es lo que diferencia InQ ROI de una calculadora Excel.
|
||
|
||
---
|
||
|
||
## Definiciones estables — no se reabren hasta nuevo aviso
|
||
|
||
### Identidad visual (estable hasta Sprint 4+)
|
||
|
||
- Paleta cromática: naranja InQ `#F59845`, magenta `#ED3E8F`, gradiente identidad
|
||
- Tipografía: system-ui stack
|
||
- Sistema de componentes (KPI cards, banners, tablas, botones)
|
||
- Reglas de marca no negociables: "InQ" siempre I-n-Q, "Powered by InQuality" en footer
|
||
- Tono: técnico-pragmático, profesional, sin marketing-speak
|
||
|
||
### Lo que NO está definido pero NO bloquea
|
||
|
||
- Logo SVG de InQuality (es texto por ahora, OK)
|
||
- Ícono ⚡ refinado (es emoji, OK)
|
||
- Color de tipos de recurso (se define cuando aparezca la feature)
|
||
- Manual de marca formal de InQuality (cuando exista, se incorpora)
|
||
|
||
### Cuándo reabrir identidad
|
||
|
||
Solo si InQuality consolida manual de marca formal con assets nuevos, o si feedback de uso real en talleres revela un problema específico.
|
||
|
||
---
|
||
|
||
## Definiciones por consolidar — requieren input externo
|
||
|
||
### Posicionamiento de mercado de InQ ROI
|
||
|
||
**Estado:** indefinido más allá de "herramienta interna de InQuality + consultoras LATAM".
|
||
|
||
**Preguntas abiertas:**
|
||
- ¿InQ ROI se vende a otras consultoras o se mantiene interno?
|
||
- Si se vende, ¿con qué pricing?
|
||
- ¿Qué pasa si una consultora competidora descubre el producto?
|
||
- ¿El nombre "InQ ROI" sobrevive cuando se venda fuera de InQuality?
|
||
|
||
**Decisión pendiente:** post-Sprint 2 con feedback de uso real en InQuality.
|
||
|
||
### Métricas de éxito del producto
|
||
|
||
**Estado:** no definidas formalmente.
|
||
|
||
**Sugerencia para definir:** post-Sprint 2 con datos reales de uso interno. Algunas candidatas:
|
||
- Cantidad de procesos costeados por consultor por semana
|
||
- Tiempo promedio de la primera simulación útil
|
||
- NPS interno del equipo InQuality
|
||
- Cantidad de propuestas pre-venta que incluyen output de InQ ROI
|
||
|
||
---
|
||
|
||
## Filosofía operativa que orienta las decisiones
|
||
|
||
### El equipo es héroe, el director es guía (Donald Miller)
|
||
|
||
El equipo de 5 técnicos de InQuality va a ser el operador del día a día. El director (Marcos) los guía con metodología, pero **no es el operador**. Las decisiones del producto y del método se documentan para que sean transferibles.
|
||
|
||
### Validación humana es ojo, no test
|
||
|
||
Los artefactos visibles requieren validación visual del director (o un miembro del equipo capacitado) antes del cierre de etapa. Tests verdes no equivalen a aprobación final. Este principio se aplicará en todos los sprints futuros.
|
||
|
||
### Iniciativa agéntica con consulta clasificada
|
||
|
||
Los agentes pueden proponer cambios proactivos, pero se clasifican por impacto:
|
||
- Nivel 1 (trivial): ejecutar
|
||
- Nivel 2 (visible reversible): ejecutar y reportar
|
||
- Nivel 3 (marca, arquitectura, datos): consultar antes
|
||
|
||
Esta política aplica indefinidamente. Documentada en `methodology/PRINCIPLES.md`.
|
||
|
||
### Anti-perfeccionismo prematuro
|
||
|
||
Refinamientos visuales finos se acumulan en `TECH_DEBT.md` y se resuelven en sprints periódicos de "polish", no continuamente. Esto evita gastar 3 horas refinando un componente que va a tener que tocarse otra vez al agregar features.
|
||
|
||
---
|
||
|
||
## Decisiones de método aprendidas durante Sprint 1.5
|
||
|
||
Estas son aprendizajes operativos validados con casos reales. Se documentan acá como guía estratégica, no como reglas dogmáticas.
|
||
|
||
### Briefs versionados son innegociables
|
||
|
||
Sin un brief en `sprints/sprint-N/BRIEF.md`, cualquier sesión con Claude Code es improvisación. Esta práctica aplica a todos los sprints futuros.
|
||
|
||
### Mockups son contratos visuales
|
||
|
||
Cuando un cambio es visual, el mockup interactivo aprobado por el director es el ground truth. El agente lo replica, no lo interpreta libremente.
|
||
|
||
### La metodología evoluciona caso por caso
|
||
|
||
Los patrones documentados en `methodology/` se validan en proyectos reales. No se inventan patrones especulativos. Cuando un problema operativo aparece, se registra como observación; cuando aparece dos veces, se promueve a patrón.
|
||
|
||
---
|
||
|
||
## Próxima revisión de este documento
|
||
|
||
**Fecha:** al cerrar Sprint 3.
|
||
|
||
**Qué actualizar:**
|
||
- Confirmar decisión sobre Modelo B (AS-IS/TO-BE con dos BPMNs)
|
||
- Evaluar catálogo global de recursos vs por proceso con datos de uso real
|
||
- Refinar posicionamiento y métricas con feedback de talleres InQuality
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 1.5
|
||
|
||
> Agregado el 2026-05-18 al cerrar formalmente el sprint.
|
||
|
||
### Lo que funcionó bien
|
||
|
||
**El brief como ancla de coherencia.** Las 11 etapas mantuvieron consistencia de marca, paleta y arquitectura sin re-explicar el contexto en cada sesión. El `BRIEF.md` de ~850 líneas más `CLAUDE.md` con reglas no negociables resultaron suficientes para que el agente retomara contexto en sesiones nuevas incluso con compactación de contexto.
|
||
|
||
**La validación visual como capa de calidad independiente.** En dos casos los tests estaban 100% verdes pero el output visual tenía problemas reales: compactación de páginas (Etapa 5) y artefactos de esquinas en el KPI Hero (Etapa 11). La validación visual del director los cazó en ambos casos. Esta práctica se consolida como mandatoria en todos los sprints futuros.
|
||
|
||
**La documentación del método en tiempo real.** AP.8, el refinamiento de C.6 y D.4 surgieron de problemas reales durante el sprint y se documentaron en el momento. El material resultante para transmisión al equipo es concreto, no especulativo.
|
||
|
||
**Los PDFs como entregable de clase profesional.** Al cierre del sprint, los 3 PDFs tienen identidad visual coherente, son 100% reproducibles via E2E, y pasan inspección visual de nivel "presentable a cliente". Esto no era el caso al abrir el sprint.
|
||
|
||
### Lo que costó más de lo esperado
|
||
|
||
**Las esquinas redondeadas del KPI Hero.** 3 iteraciones para resolver un problema aparentemente simple: (1) overlay de rectángulos blancos + arcos naranja → colisión con el gradiente magenta en esquina derecha; (2) canvas clip con transparencia PNG → jsPDF no renderiza alpha correctamente; (3) canvas con fondo blanco opaco + clip → solución definitiva. El tiempo invertido fue desproporcionado al impacto visual.
|
||
|
||
**La proporción PDF/web.** 7 de 11 etapas fueron sobre PDF. El rebalanceo debió haberse decidido en el brief del sprint, no al cerrarlo. La decisión de "establecer identidad visual desde cero" fue correcta para Sprint 1.5, pero el método de trabajo no contempló explícitamente el límite de inversión en PDF antes de empezar.
|
||
|
||
**Los casos de mala clasificación de iniciativa.** Dos casos (Etapas 5 y 7-8) requirieron revisión retroactiva y discusión meta sobre el método. El costo no fue solo el tiempo de corrección, sino la incertidumbre sobre qué otros cambios podrían haberse aplicado sin consulta. Originaron el refinamiento más detallado del Patrón C.6.
|
||
|
||
### Decisiones arquitectónicas tomadas en el sprint
|
||
|
||
| Decisión | Estado al cierre |
|
||
|---|---|
|
||
| Gráfico de trayectoria SVG nativo en jsPDF (sin html2canvas) | Definitiva — aplicada en página 5 del PDF ROI |
|
||
| Fórmulas ASCII puro en notas metodológicas | Definitiva — alineada con terminología financiera de la audiencia |
|
||
| Portrait en todas las páginas del PDF ROI | Definitiva — consistencia con los otros PDFs |
|
||
| Canvas clip con fondo blanco para esquinas redondeadas | Definitiva — sin artefactos de color |
|
||
| `automatable` persiste solo al Guardar (no auto-save) | Provisional — revisar en Sprint 2 con feedback de uso real |
|
||
|
||
### Estado de definiciones del producto al cierre de Sprint 1.5
|
||
|
||
**Estables (no se reabren):**
|
||
- Identidad visual completa: paleta naranja, gradiente, reglas de marca
|
||
- Stack tecnológico: sin cambios respecto al MVP
|
||
- Modelo de escenarios: Modelo A (dos campos por actividad, un BPMN)
|
||
- ROI: cálculos nominales simples sin VPN ni Monte Carlo
|
||
|
||
**Pendientes de input externo:**
|
||
- Posicionamiento de mercado (¿herramienta interna o venta a otras consultoras?)
|
||
- Métricas de éxito del producto (post-Sprint 2 con datos reales de uso)
|
||
- Nombre comercial definitivo ("InQ ROI" es nombre de trabajo)
|
||
- Manual de marca formal de InQuality (cuando exista, se incorpora)
|
||
|
||
**Nueva prioridad para Sprint 2:**
|
||
- Rebalanceo web/PDF: 60-70% features de web app, 15-25% PDF
|
||
- Criterio de wow obligatorio en cada ETAPA_PROMPT.md
|
||
- Feedback de uso real en talleres InQuality como insumo para decisiones de UX
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 2
|
||
|
||
> Agregado el 2026-05-20 al cerrar formalmente el sprint.
|
||
|
||
### Rebalanceo web/PDF — cumplido
|
||
|
||
Sprint 2 tuvo 4 etapas de web app (1, 2, 3, 4), 2 de PDF (5, 6) y 0 de infraestructura pura. Proporción aproximada: 65% web, 30% PDF, 5% tests/fixes. Dentro del rango comprometido. El criterio de wow se aplicó en ActivityPanel (Etapa 2) y en la tabla expandible del reporte (Etapa 3).
|
||
|
||
### Decisiones arquitectónicas tomadas en el sprint
|
||
|
||
| Decisión | Estado al cierre |
|
||
|---|---|
|
||
| Modelo de recursos: `utilizationMinutes + units` reemplaza `utilizationPercent` | Definitiva — migración Dexie v3 aplicada |
|
||
| Catálogo de recursos por proceso (no global) | Provisional — revisar en Sprint 3 con uso real |
|
||
| Recursos solo en AS-IS en Sprint 2 | Provisional — TO-BE con Modelo B en Sprint 3 |
|
||
| Modelo A mantenido (un BPMN, dos sets de campos) | Provisional — Modelo B evaluado en Sprint 3 |
|
||
| Badge ⚡ en 20×20px | Definitiva — validado visualmente |
|
||
| Tabla de recursos en PDF como página condicional (4 o 5) | Definitiva |
|
||
|
||
### Lo que funcionó bien
|
||
|
||
**El control preventivo `git diff`** agregado a partir de Etapa 2 eliminó completamente las sorpresas de scope en Etapas 3-6. Ningún archivo no autorizado apareció en el diff sin explicación. El aprendizaje de Etapa 1 (AP.9) se capturó en tiempo real y se aplicó inmediatamente.
|
||
|
||
**El modelo de recursos `utilizationMinutes + units`** resultó más natural para documentar en talleres que el `utilizationPercent` anterior. La pregunta "¿cuántos minutos dedica el analista a esta actividad?" es verificable en una entrevista; "¿qué porcentaje de utilización tiene?" no lo es.
|
||
|
||
**La separación de CLAUDE.md en dos archivos** (implementación vs. estrategia) funcionó bien operativamente. Claude Code lee su propio archivo sin contexto innecesario; el asesor en Cowork lee el estratégico.
|
||
|
||
### Lo que costó más de lo esperado
|
||
|
||
**El bug del slider en Etapa 1.** La restricción contradictoria en el prompt (`❌ ActivityPanel.tsx` + `build sin errores TypeScript`) generó una decisión unilateral del agente que requirió una etapa completa para corregir. Originó AP.9 y C.7 — dos adiciones al método que valen más que el tiempo perdido.
|
||
|
||
**rowSpan en jsPDF-autotable.** No está soportado en body cells. El prompt lo advirtió y dio la salida de emergencia correcta, pero fue tiempo de investigación que podría haberse ahorrado con ese conocimiento documentado. Va a `TECH_DEBT.md` como anotación para futuros prompts de PDF con tablas agrupadas.
|
||
|
||
### Decisiones de producto pendientes para Sprint 3
|
||
|
||
- **Modelo B (AS-IS / TO-BE):** ¿abrimos esa puerta o seguimos con Modelo A y mejoramos la experiencia del modelo actual?
|
||
- **Catálogo global de recursos:** ¿el valor de compartir recursos entre procesos justifica la complejidad en Sprint 3, o esperar a Sprint 4 con más procesos cargados?
|
||
- **Indicador de simulación desactualizada:** alto impacto en talleres, bajo esfuerzo. Candidato a entrar en Sprint 3.
|
||
- **Posicionamiento:** post-Sprint 2 es el momento comprometido para una primera conversación sobre herramienta interna vs. venta externa.
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 4
|
||
|
||
> Agregado el 2026-06-23 al cerrar formalmente Sprint 4 y 5 juntos (Sprint 5 Etapa 6).
|
||
|
||
### Decisión estratégica
|
||
|
||
Refactor arquitectural completo: migración de IndexedDB (Dexie) a Supabase, con autenticación Google Workspace OAuth. **Sin features de producto nuevas** — el sprint completo fue inversión en infraestructura.
|
||
|
||
**Justificación:** la deuda técnica de IndexedDB (persistencia local, sin colaboración multi-usuario) bloqueaba cualquier feature colaborativa futura (compartir procesos entre consultores, catálogo de recursos entre cuentas, identidad de "quién editó qué"). Postergar el refactor habría compuesto el costo de migración a medida que crecía el volumen de datos en producción.
|
||
|
||
### Resultado
|
||
|
||
Auth Google OAuth + Supabase, migración completa IndexedDB→PostgreSQL, RLS (`is_platform_admin()` + políticas granulares), catálogo global de recursos (sin `processId`), identidad en UI (avatar/dropdown, "Actualizado por"), `ResourceCatalogPage` + `ResourceFormSheet`, fix Web Locks API deadlock (`processLock`). ~550+ tests al cierre.
|
||
|
||
**Cerrado:** 2026-06-18.
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 5
|
||
|
||
> Agregado el 2026-06-23 al cerrar formalmente el sprint.
|
||
|
||
### Decisión estratégica
|
||
|
||
Retorno al rebalanceo normal (60-70% features de producto web, 10-15% infraestructura/deuda técnica) tras el sprint 100% infraestructural de Sprint 4. Foco en UX polish y quick wins de alto impacto/bajo esfuerzo — explícitamente sin features de gran escala (historial de simulaciones, `setShared()` real, Keycloak, PWA, i18n, Excel).
|
||
|
||
### Resultado
|
||
|
||
Fix crítico workspace loading (race condition auth/processId), zoom BPMN (fit-viewport con padding + controles +/−/fit), heatmap con gradiente continuo de 4 stops + toggle percentile/min-max persistido en localStorage, "ver procesos por recurso" en catálogo, campo empresa en perfil de usuario, columna "Eficiencia de automatización" en `ComparisonTable` (A/B con "Ahorro esperado" para focus group), reescritura de specs E2E Dexie→Supabase, fix de flakiness en botón "Guardar cambios".
|
||
|
||
**Hallazgo operativo del sprint:** el bug de freeze al guardar perfil (Etapa 4) requirió 12 commits y ~10 iteraciones de diagnóstico basado en lectura de código fuente de Supabase/Radix antes de resolverse. El quiebre llegó cuando el director compartió el HTML real de la pantalla congelada en vez de seguir teorizando sobre el comportamiento esperado de las librerías — un dato observable (`document.body.style.pointerEvents = 'none'`) colapsó el espacio de hipótesis de inmediato. Ver `sprints/sprint-5/INFORME_ETAPA_4_FREEZE_PERFIL.md` y memoria de feedback asociada.
|
||
|
||
**Cerrado:** 2026-06-23 (pendiente validación visual final del director sobre Etapas 5 y 6).
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 6
|
||
|
||
> Agregado el 2026-06-24 al cerrar formalmente el sprint.
|
||
|
||
### Decisión estratégica
|
||
|
||
Sprint orientado a "client-readiness": cerrar los dos gaps que impedían usar InQ ROI en vivo con un cliente externo — PDF sin marca visual y ROI sin capacidad de análisis what-if. Se abrió también la planificación de Sprint 7 (multi-usuario y acceso de clientes) a partir de una evaluación estratégica de posicionamiento del producto.
|
||
|
||
### Resultado
|
||
|
||
**Etapa 1:** logo InQuality en header de PDFs (páginas 2+, isotipo 15mm proporcional, fallback a texto si falla el fetch); `whitespace-nowrap` en MetricCell de Eficiencia. Bug detectado en proceso: Claude Code agregó logo en portada sin autorización (fuera del scope explícito del prompt) — revertido. Aprendizaje de método: auditar archivos adyacentes al scope declarado.
|
||
|
||
**Etapa 2:** panel de análisis de sensibilidad con dos sliders (volumen −50%/+100%, inversión −50%/+100%), recálculo de KPIs en tiempo real vía `calculateRoi()` sin re-simulación, badge "Análisis activo", versión wow con doble línea en `CumulativeSavingsChart` (base gris dashed + área sombreada + ajustada naranja). Layout del tab ROI reordenado post-validación: `CumulativeSavingsChart` sube por encima de `ComparisonTable` para mantener adyacencia visual con los sliders.
|
||
|
||
**Etapa 3:** bug real confirmado y corregido — `ProfileSheet.getAccessToken()` leía `'supabase.auth.token'` (clave inexistente en supabase-js v2); el guardado de perfil nunca llegó a Supabase desde Sprint 4. Fix: calcular `sb-${projectRef}-auth-token`. `setTimeout(350)` eliminado de ProfileSheet; fix de `sheet.tsx` es suficiente. Specs E2E de diagnóstico y validación de auth. 552 tests al cierre.
|
||
|
||
### Decisiones estratégicas tomadas durante el sprint
|
||
|
||
**Modelo de negocio clarificado:** InQ ROI es herramienta de consultor, no de cliente final. El "trabajo de prep" (modelar BPMN, cargar costos, configurar recursos) es el relevamiento de consultoría facturable. Funnel: relevamiento pago → diagnóstico ROI → venta de automatización. El consultor usa InQ ROI como argumento de precio (de "horas de desarrollo" a "valor percibido por ahorro potencial").
|
||
|
||
**Clientes piloto definidos:** Banco Solar → Banco Itaú → Aseguradora Yacyretá → Negofin (en ese orden).
|
||
|
||
**Sprint 7 abierto:** multi-usuario y acceso de clientes. Modelo de 4 roles (`platform_admin`, `member`, `client_editor`, `client_viewer`). Patrón de InQ Sizing (documento de referencia: `cowork/InQ ROI - Simulador de procesos/autenticacion-y-usuarios.md`). InQuality como organización administradora de la plataforma.
|
||
|
||
**Cerrado:** 2026-06-24.
|
||
|
||
---
|
||
|
||
## Reflexiones del cierre de Sprint 7
|
||
|
||
> Agregado el 2026-07-06 al cerrar formalmente el sprint.
|
||
|
||
### Decisión estratégica
|
||
|
||
Sprint de mayor escala arquitectónica desde Sprint 4 (refactorización Dexie→Supabase). Sprint 7 abrió el producto a usuarios externos con control de acceso real: tabla `organizations`, 4 roles de plataforma, Edge Functions de invitación, panel de administración de InQuality, y ajustes de UX para cada rol. La fundación de multi-tenancy está operativa.
|
||
|
||
### Resultado
|
||
|
||
**Etapa 1 (DB):** migración 014 — tabla `organizations`, `org_id` en `users` y `processes`, constraint de roles ampliado (platform_admin, member, client_editor, client_viewer, guest). Migración 015 — SECURITY DEFINER helpers (`current_org()`, `is_inquality()`, `current_platform_role()`), trigger `handle_new_user`, RLS completa con 4 roles en 7 tablas.
|
||
|
||
**Etapa 2 (Edge Functions):** `invite-user` (invita via Supabase Auth Admin API + UPSERT en public.users) y `revoke-user` (baja a 'guest', suspensión suave). Diseño simplificado respecto al BRIEF: 2 funciones en lugar de 3 separadas (create/suspend/delete). Limitación documentada: "eliminar" es soft (baja a guest), hard delete queda para sprint futuro.
|
||
|
||
**Etapa 3 (Auth layer):** fix crítico — `syncProfileFromDB` ahora lee `platform_role` y `org_id` desde DB en lugar de inferir del email. `AuthUser` extendido con `orgId`. Login email/password. Página `/reset-password` para flujo de invite. Guard `TOKEN_REFRESHED` en `onAuthStateChange`. 558 tests.
|
||
|
||
**Etapa 4 (Admin UI):** panel `/admin` con guard `platform_admin`, páginas de Organizations y Users con CRUD completo, invitación de usuarios via Edge Function, suspensión/reactivación, badges de rol, skeletons, alertdialogs para acciones destructivas, ícono Shield en AppHeader. 558 tests.
|
||
|
||
**Etapa 5 (Client UX):** routing por rol — `client_viewer` redirigido desde workspace al reporte, `client_editor` bloqueado de importar BPMNs. Library con lista plana para clientes (sin panel de grupos). Reporte abre en tab ROI para `client_viewer`. Fix bug: `normalizeGroupLabel()` limpia artículos iniciales del label de grupos (dato corrupto en Supabase). 578 tests.
|
||
|
||
### Decisiones arquitectónicas tomadas en el sprint
|
||
|
||
| Decisión | Estado al cierre |
|
||
|---|---|
|
||
| Estrategia de migración: Opción A (auto-crear orgs desde `processes.client`) | Definitiva — migración 014 aplicada |
|
||
| Trigger `handle_new_user`: rol `member` por defecto (no `platform_admin`) | Definitiva — confirmada por director |
|
||
| UPSERT en Edge Function invite-user (race condition handle_new_user) | Definitiva — patrón de InQ Sizing |
|
||
| "Eliminar" usuario como soft delete (baja a 'guest') | Provisional — hard delete en sprint futuro |
|
||
| "Reactivar" restaura a 'client_editor' por defecto | Provisional — limitación documentada |
|
||
|
||
### Patrón recurrente identificado: guards de rol via `useEffect`
|
||
|
||
En tres etapas (AdminLayout, WorkspacePage, ImportPage), Claude Code implementó guards de rol como efectos de componente en lugar de `beforeLoad` de TanStack Router. El patrón es funcional (RLS garantiza seguridad de datos) pero subóptimo para TanStack Router, que provee `beforeLoad` precisamente para evitar que rutas protegidas monten. Este patrón surgió como heurística del agente cuando el guard se especificó en la descripción del comportamiento en lugar de en la spec de la ruta. **Aprendizaje para Sprint 8+:** especificar guards siempre en la sección de router con el código exacto de `beforeLoad`.
|
||
|
||
### Lo que funcionó bien
|
||
|
||
**La auditoría previa de policy names por parte de Claude Code (Etapa 1).** Antes de escribir los DROP POLICY, Claude Code leyó las migraciones 001-013 y reportó los nombres exactos con discrepancias respecto al brief. Sin esta auditoría, `"all_activity_resource_assignments"` habría dejado la policy permisiva original activa. Este comportamiento proactivo de verificación debería solicitarse explícitamente en futuros prompts de migración RLS.
|
||
|
||
**El flujo de validación con cambio temporal de rol en Supabase Studio.** El director pudo validar el comportamiento de `client_editor` y `client_viewer` sin necesidad de crear usuarios reales de prueba, editando su propio `platform_role` temporalmente. Técnica útil para validación rápida pre-onboarding de clientes reales.
|
||
|
||
**La normalización de datos en capa de repositorio.** `normalizeGroupLabel()` en `settings-repo.ts` resolvió un dato corrupto en Supabase sin migración ni intervención manual — limpieza transparente al leer/escribir. Patrón replicable para otros datos con formato variable en la DB.
|
||
|
||
### Estado del producto al cierre de Sprint 7
|
||
|
||
- Auth completo con 4 roles, organizaciones, y panel de administración operativo
|
||
- Primer acceso de cliente posible: invitación → magic link → set password → library filtrada por org → workspace (editor) o reporte (viewer)
|
||
- Datos: 578 tests Vitest, build limpio
|
||
- Deuda técnica identificada: 2 ítems (guards via useEffect × 3 componentes, doble suscripción onAuthStateChange)
|
||
- Backlog identificado: 1 ítem (Settings accesible para roles de cliente)
|
||
|
||
### Próxima revisión — Sprint 8
|
||
|
||
**Prioridades candidatas (sin decisión tomada aún):**
|
||
- Primer onboarding real de cliente (Banco Solar) — smoke test end-to-end del flujo de invite
|
||
- Hard delete de usuarios (Edge Function `delete-user`)
|
||
- Migrar guards de rol a `beforeLoad` de TanStack Router
|
||
- Email visible en panel admin (requiere join con `auth.users` via service_role)
|
||
- Historial de simulaciones (diferido desde Sprint 3)
|
||
|
||
**Cerrado:** 2026-07-07 (con extensión de hotfixes: Etapa 6 ConfirmInvitePage, fix upsert→update en process-repo, Etapa 7 race condition AuthContext + simulations_update policy, Etapa 7B back button contextual en workspace).
|
||
|
||
---
|
||
|
||
## Decisiones estratégicas confirmadas para Sprint 8
|
||
|
||
> Registradas el 2026-07-07 durante la sesión de cierre de Sprint 7.
|
||
|
||
### client_editor: permisos de BPMN ampliados
|
||
|
||
**Decisión del director:** `client_editor` podrá:
|
||
1. **Actualizar BPMN de procesos existentes** asignados a su org (reemplazar `bpmn_xml` vía UPDATE)
|
||
2. **Importar procesos nuevos** con el botón "Importar BPMN", creándolos con `org_id = current_org()`
|
||
|
||
**Implicancias técnicas para el brief:**
|
||
- `updateEditable()` debe incluir `bpmn_xml` cuando el caller tiene permisos para modificarlo
|
||
- Política INSERT en `processes`: agregar rama `client_editor AND org_id = current_org()` (los procesos nuevos quedan dentro de su org)
|
||
- Botón "Importar BPMN" visible para `client_editor` (actualmente bloqueado en Etapa 5)
|
||
- Los procesos creados por `client_editor` tienen `owner_id = auth.uid()` y `org_id = current_org()`
|
||
- `client_editor` NO puede mover procesos entre orgs ni cambiar `owner_id`
|
||
|
||
**Precaución:** relajar INSERT en processes para client_editor es cambio de modelo. El brief de Sprint 8 debe incluir una migración que ajuste la política y tests E2E que validen el scope (no pueden crear procesos sin org_id, no pueden crear procesos en otra org).
|
||
|
||
### Versionado profesional con changelog
|
||
|
||
**Decisión del director:** a partir de Sprint 8, Claude Code es responsable del ciclo completo de versiones:
|
||
|
||
1. **Commits:** formato Conventional Commits obligatorio
|
||
- `feat(scope): descripción` — feature nueva
|
||
- `fix(scope): descripción` — corrección de bug
|
||
- `refactor(scope): descripción` — refactor sin cambio de comportamiento
|
||
- `test(scope): descripción` — solo tests
|
||
- `docs(scope): descripción` — solo documentación
|
||
- `chore(scope): descripción` — tareas de infra/build
|
||
|
||
2. **CHANGELOG.md:** actualizar al cerrar cada etapa, formato Keep a Changelog
|
||
|
||
3. **SemVer para versiones:** `MAJOR.MINOR.PATCH`
|
||
- MAJOR: cambio incompatible de producto (nuevo modelo de datos, cambio de rol fundamental)
|
||
- MINOR: feature nueva visible al usuario
|
||
- PATCH: fix de bug, mejora de UX sin feature nueva
|
||
|
||
4. **Git tags:** `git tag -a vX.Y.Z -m "Release vX.Y.Z: descripción"` + `git push --tags`
|
||
|
||
5. **Versión visible en la app:** footer de todas las páginas, leer de `package.json` o `src/lib/version.ts`. Formato: `InQ ROI v1.2.3`.
|
||
|
||
**Instrucción:** la sección "Gestión de versiones y commits" se agrega a `simulador-web/CLAUDE.md` como Sprint 8 Etapa 0, antes de cualquier feature nueva.
|
||
|
||
### Página de ayuda (`/help`)
|
||
|
||
**Decisión del director:** Sprint 8 incluye una ruta `/help` con documentación interna del producto para todos los roles.
|
||
|
||
**Contenido mínimo:**
|
||
- Cómo parametrizar actividades (tiempos, costos, recursos)
|
||
- Cómo simular y leer el reporte
|
||
- Cómo exportar PDF y CSV
|
||
- Referencia rápida de los campos del panel Global
|
||
|
||
**Requisito de método añadido al pipeline de sprints:** cualquier `ETAPA_X_PROMPT.md` que modifique la UI incluirá un ítem en los criterios de validación: `[ ] Verificar si el cambio afecta el contenido de /help — actualizar si corresponde`. Agregar al template de etapa en `methodology/` antes de abrir Sprint 8.
|
||
|
||
### Botón "volver" contextual en workspace
|
||
|
||
**Decisión del director:** implementado en Sprint 7 como Etapa 7B. Brief en `sprints/sprint-7/ETAPA_7B_PROMPT.md`.
|
||
|
||
Comportamiento **post-hotfix (2026-07-07):**
|
||
- Admin en proceso de cliente → "← [nombre del cliente]" → `/library` (sin `?org=`)
|
||
- Admin en proceso sin org → "← Biblioteca" → `/library`
|
||
- client_editor/viewer → "← Procesos" → `/library`
|
||
|
||
**Nota:** La navegación con `?org=<uuid>` + scroll fue descartada porque `LibraryPage` agrupa por `clientName` (texto libre), no por `org_id`. No existe una vista filtrada por org. El label contextual se mantiene ("← Solar Banco") porque aporta información al usuario; la navegación destino simplifica a `/library` hasta que exista la vista filtrada.
|
||
|
||
---
|
||
|
||
### Consolidación del modelo de cliente: `organizations` → `areas` → procesos
|
||
|
||
**Decisión del director (2026-07-07):** reemplazar los tres conceptos paralelos de "cliente" por una jerarquía unificada en dos niveles.
|
||
|
||
**Estado actual — tres conceptos no reconciliados:**
|
||
|
||
| Campo | Uso actual | Problema |
|
||
|---|---|---|
|
||
| `process_groups` (tabla) | Agrupador "Clientes" en LibraryPage | Nombre confuso, duplica el rol de organizations |
|
||
| `clientName` (texto libre) | Editable en workspace sidebar | Sin normalización, sin FK, sin validación |
|
||
| `org_id` (FK a organizations) | Multi-tenant Sprint 7 | Correcto pero desconectado de lo que muestra la UI |
|
||
|
||
**Modelo objetivo:**
|
||
|
||
```
|
||
organizations (org_id) ← el cliente → entidad registrada por admin
|
||
└─ areas (area_id) ← área / equipo / unidad → normalizado por org, creado por admin
|
||
└─ processes ← tiene org_id + area_id (ambos nullables con lógica clara)
|
||
```
|
||
|
||
**Implicancias técnicas:**
|
||
- Nueva tabla `areas (id, org_id, name, description?, created_at)` — reemplaza `process_groups`
|
||
- Campo `area_id uuid REFERENCES areas(id)` reemplaza `group_id` en `processes`
|
||
- Campo `clientName` (texto libre) se elimina del dominio — el display viene de `org.name` + `area.name`
|
||
- `LibraryPage` agrupa por `org_id` (organización) y sub-agrupa por `area_id` (área)
|
||
- Workspace sidebar: el campo "cliente" pasa a ser un selector de área (dropdown de áreas de la org del proceso)
|
||
- Admin UI: CRUD de áreas por org (similar a CRUD de resources, scoped por org)
|
||
- RLS: `areas_select` — acceso transitivo por org (si ves la org, ves sus áreas)
|
||
|
||
**Datos actuales:** los 154 procesos "sin cliente asignado" son datos de prueba. El plan de migración es:
|
||
1. Bulk-assign a InQuality org (`UPDATE processes SET org_id = '<inq_uuid>' WHERE org_id IS NULL`) o eliminarlos
|
||
2. Los `process_groups` existentes ("david-dev", "InQuality") se eliminan — eran grupos de prueba
|
||
3. Sin datos reales en riesgo — el producto no tiene clientes externos activos al momento de la migración
|
||
|
||
**Sprint objetivo:** Sprint 8. Es refactorización de modelo de datos con impacto en DB + repositorios + UI. No entra en Sprint 5 (UX polish en curso). El brief de Sprint 8 incluye esta consolidación como prioridad 1 antes de features nuevas.
|
||
|
||
**Criterio de done:**
|
||
- `process_groups` eliminada (con migración que dropea la tabla y transfiere datos si aplica)
|
||
- `clientName` eliminado del tipo `Process` y de la UI
|
||
- `areas` table con RLS + CRUD en Admin
|
||
- `LibraryPage` agrupa por org → área
|
||
- Workspace sidebar muestra org asignada (read-only para client_editor) + selector de área
|
||
- Tests E2E: flujo admin crea org → crea área → asigna proceso → client_editor ve sus procesos agrupados
|