Files
inq-roi-simulador-web/OBSERVATIONS.md
2026-07-07 17:29:48 -03:00

4.2 KiB

OBSERVATIONS — Sprint 8

Hallazgos descubiertos durante el sprint actual. Este archivo se vacía al cerrar el sprint: los hallazgos se promocionan a TECH_DEBT.md o BACKLOG.md, o quedan resueltos.

Sprint 7 cerrado el 2026-07-07. Ver reflexiones completas en STRATEGIC_DIRECTION.md.


Convención de etiquetas

  • [CURRENT-SPRINT] — Se resuelve en este sprint
  • [DEFERRED-TECH-DEBT] — Se va a TECH_DEBT.md al cerrar el sprint
  • [DEFERRED-BACKLOG] — Se va a BACKLOG.md al cerrar el sprint
  • [RESOLVED] — Resuelto durante el sprint, archivar al cierre

Hallazgos activos

(vacío)


Hallazgos resueltos durante el sprint

(vacío — sprint recién abierto)


Hallazgos diferidos (promocionar al cerrar sprint)

(vacío)


Notas operativas

  • Los hallazgos resueltos quedan acá hasta el cierre del sprint. Al cerrar, se archiva o purga.
  • Los hallazgos sin resolver se promocionan a TECH_DEBT.md o BACKLOG.md según corresponda.
  • Este archivo NO contiene roadmap futuro ni deuda histórica — solo hallazgos del sprint en curso.

Cierre del sprint (checklist)

[ ] Verificar que todos los items [CURRENT-SPRINT] están RESOLVED
[ ] Mover items [DEFERRED-TECH-DEBT] a TECH_DEBT.md
[ ] Mover items [DEFERRED-BACKLOG] a BACKLOG.md
[ ] Archivar o purgar este archivo
[ ] Crear OBSERVATIONS.md vacío para el sprint siguiente

Aprendizajes de Sprint 7 relevantes para Sprint 8

Cosecha de método — decisiones y patterns emergentes de Sprint 7 que informan cómo trabajar en Sprint 8.

Race condition en roles: isProfileLoaded como guard

buildAuthUser() asigna platformRole: 'guest' heurísticamente (por dominio de email) antes de que syncProfileFromDB complete. El rol correcto llega ~200ms después. Cualquier UI condicionada por rol que renderice antes de ese sync muestra el estado incorrecto.

Patrón validado: isProfileLoaded: boolean en AuthContext — se pone en true solo después de que syncProfileFromDB completa. Componentes que dependen del rol deben esperar isProfileLoaded antes de renderizar contenido rol-dependiente.

Aprendizaje para Sprint 8: cualquier componente nuevo que condicione su contenido por platformRole debe incluir isProfileLoaded como prerequisito en su spec de implementación.

JOIN vs fetch separado: orgName en getById

Fetch separado en useEffect para obtener el nombre de la org en WorkspacePage fue frágil: race conditions entre currentProcess cargando y el efecto, resets de estado al desmontar, y respuesta en array cuando .maybeSingle() esperaba objeto. El síntoma (botón mostrando "Biblioteca" en lugar de "Solar Banco") requirió ~8 iteraciones de diagnóstico.

Fix definitivo: JOIN en getById() con select('*, org:organizations!org_id(name)'). El dato llega embebido en el proceso — sin async adicional, sin estado local, sin race condition.

Aprendizaje para Sprint 8: cuando un componente necesita datos relacionados de otra tabla para display, preferir JOIN en el repositorio sobre fetch separado en el componente. Los fetches separados en useEffect con datos del store como dependencia son estructuralmente frágiles.

Dos sistemas paralelos de "cliente" → consolidar en Sprint 8

process_groups, clientName (texto libre) y org_id intentaban modelar el mismo concepto ("a qué cliente pertenece el proceso") desde tres ángulos distintos. La confusión generó bugs de UX (back button, agrupación en biblioteca) y deuda conceptual.

Decisión tomada: Sprint 8 consolida en organizations → areas → processes. Ver STRATEGIC_DIRECTION.md → "Consolidación del modelo de cliente".

Diagnóstico por DOM observable > teorización de librerías

El bug del freeze de perfil (Sprint 5, confirmado resuelto en Sprint 6) y el bug del back button (Sprint 7) compartieron el mismo patrón: múltiples iteraciones de diagnóstico teórico sin resolver → un dato observable del runtime (HTML del DOM, Network tab, respuesta de request) colapsó el espacio de hipótesis en 1 paso.

Aprendizaje consolidado: ante bug de UI que persiste 2+ fixes teóricos, pedir el dato observable antes de seguir. Específicamente: HTML del elemento, Network tab con el request real, o console.log del valor en runtime.