refactor(engine): mover limpieza de instancias y validación required al motor [4E]
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>
This commit is contained in:
@@ -4,12 +4,13 @@ import type { BrandConfig, Survey } from '@/lib/types'
|
||||
import type { AnswerValue, FormAnswers, FormSchema, Screen } from '@/lib/form-engine.types'
|
||||
import {
|
||||
answerKey,
|
||||
applyAnswer,
|
||||
expandInstances,
|
||||
initialState,
|
||||
isRequiredAndUnanswered,
|
||||
next,
|
||||
back,
|
||||
resolveScreens,
|
||||
setAnswer,
|
||||
} from '@/lib/form-engine'
|
||||
import { loadDraft, saveDraft } from '@/lib/storage'
|
||||
import { ConsentScreen } from './consent-screen'
|
||||
@@ -137,20 +138,7 @@ export function WizardForm({ survey, schema }: WizardFormProps) {
|
||||
const code = screen.question.code
|
||||
const instanceId = screen.instanceId ?? undefined
|
||||
|
||||
setState((prev) => {
|
||||
const updated = setAnswer(prev, code, value, instanceId)
|
||||
// Limpia respuestas de pantallas que dejaron de ser visibles tras este cambio.
|
||||
const before = resolveScreens(schema, prev.answers)
|
||||
const after = resolveScreens(schema, updated.answers)
|
||||
const afterIds = new Set(after.map((s) => s.id))
|
||||
const disappeared = before.filter((s) => !afterIds.has(s.id) && s.question)
|
||||
if (disappeared.length === 0) return updated
|
||||
const clearedAnswers = { ...updated.answers }
|
||||
for (const s of disappeared) {
|
||||
delete clearedAnswers[answerKey(s.question!.code, s.instanceId ?? undefined)]
|
||||
}
|
||||
return { ...updated, answers: clearedAnswers }
|
||||
})
|
||||
setState((prev) => applyAnswer(prev, schema, code, value, instanceId))
|
||||
|
||||
setErrors((prev) => {
|
||||
if (!prev[code]) return prev
|
||||
@@ -160,7 +148,7 @@ export function WizardForm({ survey, schema }: WizardFormProps) {
|
||||
}
|
||||
|
||||
function handleNext() {
|
||||
if (screen.kind === 'question' && screen.question?.required && isEmpty(currentValue)) {
|
||||
if (isRequiredAndUnanswered(screen, state.answers)) {
|
||||
setErrors((e) => ({ ...e, [screen.question!.code]: 'Este campo es obligatorio.' }))
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user