Platform admin invita usuarios de empresa desde /admin/usuarios.
inviteUserByEmail + insert inmediato en user_roles (org_admin).
Rollback explícito si falla el insert. /auth/confirm maneja el link
de invitación con PASSWORD_RECOVERY event. Middleware no requirió
cambios — /auth/confirm ya queda fuera del matcher de rutas protegidas.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
geo_paraguay_full.json se cargaba dos veces sin cache compartido.
Módulo lib/geo-cache.ts singleton: un fetch para toda la sesión.
Feedback visual mientras carga (disabled + placeholder) y si falla
(mensaje + texto libre). debounce 500ms en saveDraft para no escribir
en localStorage en cada keystroke.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
RPC transaccional SECURITY DEFINER (rpc_submit_response) como único camino
de escritura. Dropea las policies WITH CHECK(true): cierra la falla donde
anon podía insertar cualquier cosa. Validación server-side (7 checks)
reusando el motor. Persistencia atómica con instance_id por instancia.
Verificado contra Postgres real: instancias separadas, atomicidad, RLS.
Riesgo residual de bypass por REST documentado (SEC-004).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
applyAnswer y isRequiredAndUnanswered pasan de wizard-form.tsx al motor
como funciones puras — eran lógica de flujo en el presentador (viola ADR-005).
Limpieza de respuestas huérfanas al remover un vínculo y validación required
por instancia, ahora testeables. 20/20 tests. Verificado end-to-end con navegador.
4E sin construcción pendiente: el mini-wizard es propiedad emergente del motor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Módulo puro que interpreta el esquema v3 y resuelve pantallas.
5 operadores (eq, eq_any, not_in, contains, eq_sole), acciones show/hide
(hide = veto absoluto). Instancias con ID estable por posición de opción,
secciones-pantalla. Navegación por ID estable. 16/16 tests Node en verde.
No reemplaza aún lib/conditional.ts de v2 (lo hace 4D al migrar el componente).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Al responder "No" en las tres, el formulario salta a 6.4 (no muestra secciones 2-5 ni 6.1-6.3)
La pregunta 6.6 aparece antes del cierre
Las preguntas multiple_choice muestran el hint "Podés marcar más de una opción"
- lib/supabase.ts: ?? placeholders para que el módulo cargue en build
time sin las env vars; force-dynamic garantiza que nunca se llame
en build time.
- next.config.ts: env fallbacks vacíos para que Next.js no aborte
al no encontrar NEXT_PUBLIC_SUPABASE_* en build time.
- .gitignore: agrega .next/ (artefactos de build no van a git).
- git rm --cached .next/**: saca los artefactos ya trackeados.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>