- RuleEditor simplificado: una sola acción por regla (tipo attribute),
sin selector de tipo de acción ni múltiples acciones
- Acciones de regla con estado calculado en tiempo real (rule-eval.ts):
ObjInfoPanel y AttDetail muestran badge con estado actual según
valores por defecto del catálogo
- Grafo de dependencias implementado en CatalogLayout (overlay)
- IDs de objetos/secciones/atributos especificados por el usuario con
prefijo automático (ob:slug, sc:slug, at:slug) y validación de unicidad
- Formularios de creación con nombre + slug; slug se auto-rellena desde
el nombre y puede editarse manualmente
- Botón Descartar en header para revertir cambios no guardados
- canvas/Editor.svelte persiste en localStorage (Guardar funciona)
- Target de acciones acotado al contenedor de la regla (no catálogo global)
- Paneles ObjInfo y SecInfo muestran campo ID como solo lectura
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bugs críticos:
- stores/catalog-editor.svelte.ts: añadidos activeOptId, activeOpt y
setActiveOpt que OptsPanel.svelte y OptDetail.svelte requerían pero
no existían en el store — el panel de opciones estaba completamente roto.
- session.svelte.ts: createSession recibía engine donde espera glob,
causando crash en getPrice()/resolveView(). Corregido a createSession(cat, null, engine).
- vcen/session.ts: glob ahora es optional (GlobInstance|null = null) para
permitir sesiones de solo-evaluación sin glob; añadidos null-guards en
getPrice, getAllPrices, resolveView, resolveVisual, resolveDefaultView.
Otras correcciones:
- comps/catalog-editor.svelte.ts + stores/catalog-editor.svelte.ts:
updateAttDefaultValue usaba (att.value as any).value = value (mutación
directa con cast); corregido a att.value = { ...att.value, value }.
- OptDetail.svelte: eliminado `</>` suelto dentro de la cadena de clase CSS.
- demo.store.svelte.ts: dominios option usaban estructura obsoleta
{kind:'option', options:[]} incompatible con vcen. Refactorizado para
usar la estructura correcta {kind:'option', mode:'list', list:[{optId}]}
con Opt entries en cat.opts. Actualizado addAtt, updateAttDomain y
updateAttOptions.
- demos/RuntimePanel.svelte: iteraba (domain as any).options para opciones;
ahora itera domain.list y resuelve el valor desde cat.opts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bugs críticos:
- session.ts #1: configState se reconstruía desde el Cat original al hacer
setValue, ignorando los valores del usuario y los derivados. Añadido
userValues Map y buildCurrentConfigState() que combina base + user + derived.
getAllPrices() usaba computeCatPrice (que también reconstruía desde Cat);
ahora usa this.configState.
- incremental.ts #12: evaluateObj se llamaba sin cat.opts, por lo que las
reglas de opciones nunca se re-evaluaban en evaluación incremental.
Añadido buildNestedState al import y pasados opts + nestedState.
Mejoras de arquitectura:
- engine.ts #11: lógica de evaluación de opciones duplicada en evaluateObj
extraída al helper privado applyOptionsForAtt.
- engine.ts #2: evaluateCat ahora evalúa y valida cat.atts directos (antes
solo procesaba los Obj).
- engine.ts #10: comparación JSON.stringify para detectar convergencia
reemplazada por Object.keys().some() — O(n) sin serialización.
- engine.ts #24: errors/warnings cambiados de string[] + new Set a
Set<string> directamente; añadido helper validateAttPath para evitar
duplicación.
- graph.ts #5: engine.usesData(rule.condition) se llamaba dos veces por
regla; ahora se reutiliza el resultado de la primera llamada.
- graph.ts #17: casts as unknown as AttPath consolidados en mkPath() helper.
- graph.ts #23: getDependents y getAffectedAtts eran idénticas; ahora una
delega a la otra.
- node_util.ts #6: keyToAttPath añade console.warn para paths inesperados.
- pricing.ts #16: strings hardcodeados ('A consultar', 'IVA inc.', etc.)
externalizados via labels? en FormatAmountOpts.
- pricing.ts #22: catch silencioso en evaluateAmount ahora hace console.warn.
- incremental.ts #13: bloque comentado obsoleto de findAtt eliminado.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nuevos tipos de campo: color, select, multiselect, email, phone, slug,
coordinates, markdown — con soporte completo en TypeBadge, AddFieldMenu,
FieldRow, TreeNodes y AddFieldModal
- Refactor arquitectural: FieldValueEditor sustituido por 23 componentes
individuales (fields/) + FieldForm.svelte compartido entre panel de edición
y modal de creación, garantizando coherencia de UI entre ambos contextos
- AddFieldDrawer renombrado a AddFieldModal (era un <dialog>, no un drawer);
corregido el bloqueo de botones por inertness nativo del elemento dialog
- AddFieldModal: fondo semitransparente corregido (bg-black/50), atributos
y toggle hidden ahora presentes también en creación de campo
- glob/curr: añadido getCurrencies() en tipos, engine y adaptador Svelte;
selector de divisa en CurrencyField muestra lista real o valor fijo
- CurrencyField: preview formateada con la moneda del campo, no la global
- TreeNodes: eliminado cast 'as Metadata' en template HTML; ImageField:
as any reemplazado por as ImageRef['format']
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Arquitectura / glob+ling:
- glob_engine: inicialización lazy de módulos (numr, curr, dati, unit) con ??=
- glob_types: añadido método register<NS, M>() para tipado fuerte de namespaces
- ling engine: extend() soporta namespaces con punto ('vcen.editor.mtas') via deepMerge
- ling guards: isLingRecord reforzado (comprueba typeof value !== 'function' y tipo del locale por defecto)
Validación:
- ISO_DATETIME_RE acepta HH:mm sin segundos (formato real de datetime-local)
Componentes Svelte — correcciones:
- App.svelte: corregido paso de prop glob (glob, → {glob})
- AddFieldMenu: añadida prop placement ('start'|'end') para controlar dirección del dropdown
- AddFieldMenu: reemplazados glob.t(`...` as any) por helper t() para evitar errores de parser Svelte
- FieldValueEditor: grupo muestra cuenta real de hijos en lugar de siempre "Grupo vacío"
- FieldRow: tooltip de editar/borrar cambiado a tooltip-top, eliminado overflow-hidden del card
- FieldRow: diálogo de confirmación antes de eliminar campo (modal DaisyUI)
- TreeNodes: corregido bug summary (group-hover:hidden → group-hover:block), acciones sin flex duplicado
- TreeNodes: diálogo de confirmación antes de eliminar (solo en depth=0 para evitar duplicados)
Estilos (DaisyUI):
- MetadataEditor y MetaTree: border-base-300, shadow-md, bg-base-200/60 en cabeceras
- MetaTree: breadcrumb de ruta en panel derecho, texto placeholder via glob.t()
- MetaTree: errores de validación con icono, alineados con MetadataEditor
- TreeNodes: nodo seleccionado con borde lateral (border-l-2 border-primary)
- AddFieldMenu: colores de icono por tipo, layout horizontal agrupado, contraste dropdown
- AddFieldDrawer: modal-bottom sm:modal-middle, botones Cancel/X visibles, inputs con text-base-content
- TypeBadge: colorMap aplicado correctamente al badge
- Traducciones: deleteConfirm, deleteConfirmMsg, deleteYes, deleteNo, tree.selectHint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>