124 lines
6.3 KiB
Markdown
124 lines
6.3 KiB
Markdown
# ETAPA 4C — Motor de resolución de flujo (módulo puro, cliente)
|
|
|
|
## 1. Objetivo
|
|
Construir el motor que interpreta el esquema declarativo del formulario y resuelve
|
|
la secuencia de pantallas según el estado de respuestas. Es un módulo puro y aislado
|
|
en `lib/`, sin dependencias de React ni del DOM — entrada→salida determinista,
|
|
testeable con Node. El componente (Etapa 4D) lo consume; el motor no conoce al componente.
|
|
|
|
## 2. Contexto previo
|
|
- ADR-005: la lógica de flujo vive en el esquema (datos). El motor la interpreta.
|
|
- El esquema v3 está en la DB: questions con `type`, `conditional_rules`,
|
|
`instance_generator`, `instance_of`, `hint`, más filas `type='section'`.
|
|
- Decisión confirmada: el motor corre en el CLIENTE (interpretación de flujo, no validación
|
|
de seguridad — esa va server-side en 4G).
|
|
- Decisión confirmada: las secciones (`type='section'`) son PANTALLAS propias en el grafo.
|
|
- La lógica de v2 (`lib/conditional.ts`, `survey-form.tsx`) es INCOMPATIBLE y se reemplaza:
|
|
- v2 evalúa AND (`rules.every`); v3 necesita OR entre condiciones de ocultamiento.
|
|
- v2 solo conoce `eq`/`eq_any` y acción `show`; v3 necesita `contains`, `eq_sole`, `not_in`, acción `hide`.
|
|
- v2 infiere secciones por regex de prefijo; v3 las tiene como datos.
|
|
- El comportamiento esperado está validado en el mockup `wizard_formulario_mapeo_v3.html`
|
|
(función `buildVisible` y navegación) — usar como referencia de comportamiento, NO de arquitectura.
|
|
|
|
## 3. DECISIONES YA TOMADAS — no consultar de nuevo
|
|
- Motor puro en `lib/` (proponé el nombre: ej. `lib/form-engine.ts`), sin React/DOM.
|
|
- Vocabulario de operadores: `eq`, `eq_any`, `not_in` (escalares), `contains`, `eq_sole` (array).
|
|
- Acciones: `show`, `hide`.
|
|
- Combinación: múltiples reglas en el array de una pregunta se evalúan en OR.
|
|
(Una pregunta se oculta si CUALQUIER regla `hide` aplica; se muestra si CUALQUIER regla `show` aplica.
|
|
Definí la semántica precisa de show+hide combinados y documentala.)
|
|
- Secciones = pantallas propias en el grafo.
|
|
- Instancias: 4.1 (`instance_generator=true`) genera N instancias; las preguntas con
|
|
`instance_of='4.1'` se repiten una vez por instancia activa, en orden por familiar
|
|
(familiar1: 4.2→4.3, familiar2: 4.2→4.3, ...) como en el mockup.
|
|
- Estado de respuestas con clave compuesta `question_code:instance_id` (instancias) o
|
|
`question_code` con `instance_id='default'` (normales).
|
|
|
|
## 4. Tareas
|
|
|
|
### 4.1 Tipos del motor (`lib/types.ts` ampliado o nuevo)
|
|
Definir/ampliar:
|
|
- `ConditionalRule`: operadores y acciones completos del vocabulario v3.
|
|
- `FormSchema`: la representación del formulario que el motor consume (secciones, preguntas,
|
|
reglas, instanciación) — derivada de las filas de `questions`.
|
|
- `WizardState`: respuestas (con instancias), instancia activa, pantalla actual.
|
|
- `Screen`: una pantalla resoluble (sección-intro | pregunta | pregunta-de-instancia | fin).
|
|
|
|
### 4.2 Evaluador de reglas
|
|
Reescribir la evaluación (reemplaza `lib/conditional.ts`):
|
|
- Implementar los 5 operadores y 2 acciones.
|
|
- `contains` / `eq_sole` operan sobre respuestas array (multiple_choice).
|
|
- Semántica OR documentada y correcta para el caso `r_hide_ning_sn`.
|
|
- Función pura: `(rule, answers) => boolean` y `(question, answers) => 'show'|'hide'`.
|
|
|
|
### 4.3 Resolución del grafo de pantallas
|
|
Función pura que dado el esquema + estado devuelve la lista ordenada de pantallas visibles:
|
|
- Expande instancias (4.2/4.3 por cada familiar activo declarado en 4.1).
|
|
- Aplica visibilidad (oculta secciones/preguntas según reglas).
|
|
- Incluye las pantallas de sección.
|
|
- Equivale conceptualmente al `buildVisible()` del mockup, pero como módulo puro.
|
|
|
|
### 4.4 Navegación
|
|
Funciones puras `next(state, schema)` y `back(state, schema)` que devuelven el nuevo
|
|
estado (pantalla actual actualizada), resolviendo saltos. Identificar la pantalla actual
|
|
por ID estable, no por índice (lección del mockup: el índice se desincroniza cuando
|
|
cambian las instancias).
|
|
|
|
### 4.5 Carga del esquema
|
|
Actualizar la query (`app/page.tsx`) para traer las 3 columnas nuevas
|
|
(`hint`, `instance_generator`, `instance_of`). Transformar las filas de `questions`
|
|
en el `FormSchema` que consume el motor.
|
|
|
|
### 4.6 Tests del motor (Node, sin navegador)
|
|
Tests puros que verifiquen:
|
|
- Recorrido completo (todos los vínculos) genera las pantallas esperadas.
|
|
- "Solo niño sin discapacidad" (eq_sole) → recorrido liviano correcto (5.3, 8.4, 9.1, 9.4).
|
|
- "Ninguna de las anteriores" (contains) → salta a sección 10.
|
|
- 3.1='No' oculta 3.2-3.5.
|
|
- 3 familiares → 6 pantallas de instancia en orden por familiar.
|
|
- Navegación next/back coherente cuando cambian las instancias.
|
|
|
|
## 5. Entregables (DoD)
|
|
- [ ] Motor puro en `lib/` sin dependencias de React/DOM.
|
|
- [ ] Los 5 operadores y 2 acciones implementados y testeados.
|
|
- [ ] Resolución de grafo con instancias y secciones-pantalla.
|
|
- [ ] Navegación por ID estable, no por índice.
|
|
- [ ] Query actualizada con las 3 columnas nuevas.
|
|
- [ ] Tests Node que cubren los recorridos del punto 4.6, todos en verde.
|
|
- [ ] NO se toca el componente todavía (es 4D) — el motor se entrega standalone + tests.
|
|
|
|
## 6. Qué reportar
|
|
```
|
|
Verificado:
|
|
- Motor en [archivo], puro (sin React/DOM) ✓
|
|
- Operadores implementados: eq, eq_any, not_in, contains, eq_sole ✓
|
|
- Acciones: show, hide ✓ — semántica de combinación: [descripción]
|
|
- Tests: N/N en verde
|
|
- recorrido completo ✓
|
|
- solo niño (eq_sole) → 5.3/8.4/9.1/9.4 ✓
|
|
- ninguna (contains) → salta S10 ✓
|
|
- 3.1=No oculta 3.2-3.5 ✓
|
|
- 3 familiares → 6 pantallas en orden ✓
|
|
- next/back coherente ✓
|
|
|
|
Asumido:
|
|
- [supuestos de diseño del motor]
|
|
```
|
|
|
|
## 7. Qué NO hacer
|
|
- ❌ No poner lógica de flujo en un componente React (el motor es puro, lib/).
|
|
- ❌ No tocar el componente de formulario todavía (es 4D).
|
|
- ❌ No implementar validación de seguridad acá (es 4G, server-side).
|
|
- ❌ No usar índices numéricos para la pantalla actual — usar ID estable.
|
|
- ❌ No tocar v2.1.0-stable ni el seed.
|
|
|
|
## 8. Versionado
|
|
Commit sugerido:
|
|
```
|
|
feat(engine): motor de resolución de flujo declarativo [4C]
|
|
|
|
Módulo puro que interpreta el esquema v3 y resuelve pantallas.
|
|
5 operadores (eq, eq_any, not_in, contains, eq_sole), acciones show/hide.
|
|
Instancias de vínculo y secciones-pantalla. Navegación por ID estable.
|
|
Tests Node cubren los 3 recorridos. Reemplaza lib/conditional.ts de v2.
|
|
``` |