feat(nakui): Fase 7 del ERP — pulido (cierra el plan maestro)

Validación inline: al fallar un submit por campos required vacíos, el
form los marca (label destructivo + mensaje debajo), no sólo un toast.
MetaApp.form_errors + validate_required_fields. Secciones de formulario:
FieldSpec.section agrupa campos bajo encabezados; abrir_form del CRM las
usa. Campos condicionales y pulido puramente visual: scope-out conciente.

El plan docs/nakui-erp-masterplan.md queda completo (7/7 fases). Tests
verdes (meta-schema 16, meta-runtime 70, meta-form 8, nakui-ui 14);
clippy limpio en las libs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-21 19:43:44 +00:00
parent b13486e240
commit c56ef25546
9 changed files with 168 additions and 12 deletions
+19
View File
@@ -461,6 +461,25 @@ mod tests {
"el panorama debe tener al menos un breakdown",
);
// Fase 7: el formulario «abrir_form» agrupa sus campos en
// secciones.
let nahual_meta_schema::View::Form(abrir) = &m.views["abrir_form"] else {
panic!("abrir_form debe ser un formulario");
};
assert!(
abrir.fields.iter().all(|f| f.section.is_some()),
"todos los campos de abrir_form deben tener sección",
);
let secciones: std::collections::BTreeSet<&str> = abrir
.fields
.iter()
.filter_map(|f| f.section.as_deref())
.collect();
assert!(
secciones.len() >= 2,
"abrir_form debe tener varias secciones"
);
// Fase 2: la lista de oportunidades resuelve `cliente_id` al
// label del cliente y formatea `monto` como moneda.
let nahual_meta_schema::View::List(lv) = &m.views["oportunidad_list"] else {