feat(nakui): Fase 1 del ERP — FieldKind Select + AutoId, seed inyecta id
Primera fase del plan maestro. La metainterfaz gana dos tipos de campo: Select (chips de un conjunto cerrado, con options validadas) y AutoId (UUID autogenerado read-only). NakuiBackend::seed inyecta el id de la entity = clave del store. El módulo CRM los adopta: etapa/canal son selects, los ids de idempotencia se autogeneran, el form de cliente ya no pide id. Ningún formulario pide un UUID a mano. Tests en meta-schema, meta-runtime y nakui-ui verdes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -68,7 +68,6 @@
|
||||
"title": "Nuevo cliente",
|
||||
"entity": "Cliente",
|
||||
"fields": [
|
||||
{ "name": "id", "label": "ID interno", "kind": "text", "help": "Opcional; el runtime genera el UUID de la entity. Dejar vacío está bien." },
|
||||
{ "name": "nombre", "label": "Nombre", "kind": "text", "required": true },
|
||||
{ "name": "email", "label": "Email", "kind": "text", "required": true },
|
||||
{ "name": "empresa", "label": "Empresa", "kind": "text" }
|
||||
@@ -102,7 +101,7 @@
|
||||
"entity": "Oportunidad",
|
||||
"fields": [
|
||||
{ "name": "cliente_ref", "label": "Cliente", "kind": "entity_ref", "ref_entity": "Cliente", "required": true, "help": "Click en un cliente de la lista para seleccionarlo." },
|
||||
{ "name": "oportunidad_id", "label": "Oportunidad UUID", "kind": "text", "required": true, "help": "UUID nuevo por cada intento (idempotencia)." },
|
||||
{ "name": "oportunidad_id", "label": "ID de la oportunidad", "kind": "auto_id" },
|
||||
{ "name": "titulo", "label": "Título", "kind": "text", "required": true },
|
||||
{ "name": "monto", "label": "Monto", "kind": "number", "required": true, "default": "0" },
|
||||
{ "name": "currency", "label": "Moneda", "kind": "text", "default": "USD" },
|
||||
@@ -122,7 +121,17 @@
|
||||
"entity": "Oportunidad",
|
||||
"fields": [
|
||||
{ "name": "oportunidad_ref", "label": "Oportunidad", "kind": "entity_ref", "ref_entity": "Oportunidad", "required": true, "help": "Click en una oportunidad de la lista." },
|
||||
{ "name": "etapa", "label": "Etapa destino", "kind": "text", "required": true, "help": "prospecto | calificado | propuesta | negociacion | ganada | perdida" },
|
||||
{
|
||||
"name": "etapa", "label": "Etapa destino", "kind": "select", "required": true,
|
||||
"options": [
|
||||
{ "value": "prospecto", "label": "Prospecto" },
|
||||
{ "value": "calificado", "label": "Calificado" },
|
||||
{ "value": "propuesta", "label": "Propuesta" },
|
||||
{ "value": "negociacion", "label": "Negociación" },
|
||||
{ "value": "ganada", "label": "Ganada" },
|
||||
{ "value": "perdida", "label": "Perdida" }
|
||||
]
|
||||
},
|
||||
{ "name": "timestamp", "label": "Fecha ISO", "kind": "text", "required": true, "default": "2026-05-21T12:00:00Z" }
|
||||
],
|
||||
"on_submit": {
|
||||
@@ -154,8 +163,15 @@
|
||||
"entity": "Interaccion",
|
||||
"fields": [
|
||||
{ "name": "cliente_ref", "label": "Cliente", "kind": "entity_ref", "ref_entity": "Cliente", "required": true, "help": "Click en un cliente de la lista." },
|
||||
{ "name": "interaccion_id", "label": "Interacción UUID", "kind": "text", "required": true, "help": "UUID nuevo por cada intento (idempotencia)." },
|
||||
{ "name": "canal", "label": "Canal", "kind": "text", "required": true, "help": "llamada | email | reunion" },
|
||||
{ "name": "interaccion_id", "label": "ID de la interacción", "kind": "auto_id" },
|
||||
{
|
||||
"name": "canal", "label": "Canal", "kind": "select", "required": true,
|
||||
"options": [
|
||||
{ "value": "llamada", "label": "Llamada" },
|
||||
{ "value": "email", "label": "Email" },
|
||||
{ "value": "reunion", "label": "Reunión" }
|
||||
]
|
||||
},
|
||||
{ "name": "nota", "label": "Nota", "kind": "multiline" },
|
||||
{ "name": "timestamp", "label": "Fecha ISO", "kind": "text", "required": true, "default": "2026-05-21T12:00:00Z" }
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user