@wondai/n8n-nodes-nucleo 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/nodes/Nucleo/Nucleo.node.js +28 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -32,6 +32,34 @@ parede. Isso mantém o segredo fora do workflow, a lógica num lugar só e o tok
|
|
|
32
32
|
**Resolver Produtos** é a operação inteligente: manda várias consultas numa chamada (máx 10),
|
|
33
33
|
tolera erro de digitação (`banofe`→Banoffee), falta de acento (`pao frances`→Pão Francês) e
|
|
34
34
|
apelidos; devolve no máx 3 candidatos por consulta com `status` (`achou`/`ambiguo`/`nao_achou`).
|
|
35
|
+
Produtos configuráveis também devolvem `regras_compra`. O agente deve coletar as opções
|
|
36
|
+
obrigatórias e enviá-las em `itens[].configuracao`; o Núcleo recusa com HTTP 422 qualquer combo
|
|
37
|
+
incompleto, opção inventada, quantidade inválida, prazo impossível ou personalização proibida.
|
|
38
|
+
|
|
39
|
+
Exemplo de item configurável:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"produto_id": "uuid-do-produto",
|
|
44
|
+
"quantidade": 1,
|
|
45
|
+
"configuracao": {
|
|
46
|
+
"opcoes": [
|
|
47
|
+
{
|
|
48
|
+
"grupo_id": "uuid-do-grupo",
|
|
49
|
+
"opcao_id": "uuid-da-opcao"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
O node não interpreta essas regras: ele encaminha o JSON sem alteração. A validação e o snapshot
|
|
57
|
+
imutável do contrato aplicado pertencem à API do Núcleo (ADR-035).
|
|
58
|
+
|
|
59
|
+
A partir da v0.5.6, `Pedido Criar` falha antes da requisição quando `itens` está vazio ou quando
|
|
60
|
+
alguma linha não traz `produto_id`/`alias` e `quantidade` positiva. É uma proteção de integração:
|
|
61
|
+
o Núcleo continua sendo a autoridade final das regras, mas o workflow não envia pedido vazio por
|
|
62
|
+
erro de tool schema.
|
|
35
63
|
|
|
36
64
|
**Disponibilidade na Rede** ("tem na outra loja?") é exposta como **tool** do AI Agent, mas com regra
|
|
37
65
|
estrita no prompt: **usar SÓ quando o cliente pedir explicitamente outra unidade**. Passe o `produto_id`
|
|
@@ -86,6 +86,29 @@ function asArray(value) {
|
|
|
86
86
|
}
|
|
87
87
|
return [];
|
|
88
88
|
}
|
|
89
|
+
function hasPedidoItemIdentifier(item) {
|
|
90
|
+
const produtoId = String(item.produto_id ?? "").trim();
|
|
91
|
+
const alias = String(item.alias ?? "").trim();
|
|
92
|
+
return Boolean(produtoId || alias);
|
|
93
|
+
}
|
|
94
|
+
function hasPositiveQuantidade(item) {
|
|
95
|
+
const quantidade = Number(item.quantidade);
|
|
96
|
+
return Number.isFinite(quantidade) && quantidade > 0;
|
|
97
|
+
}
|
|
98
|
+
function assertPedidoCriarItens(itens) {
|
|
99
|
+
if (!Array.isArray(itens) || itens.length === 0) {
|
|
100
|
+
throw new Error("Pedido Criar bloqueado: o campo itens precisa ser um array JSON não vazio com produto_id ou alias e quantidade. Resolva o catálogo e envie os itens estruturados antes de criar o pedido.");
|
|
101
|
+
}
|
|
102
|
+
const invalidIndex = itens.findIndex((item) => {
|
|
103
|
+
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
104
|
+
return true;
|
|
105
|
+
const itemObject = item;
|
|
106
|
+
return !hasPedidoItemIdentifier(itemObject) || !hasPositiveQuantidade(itemObject);
|
|
107
|
+
});
|
|
108
|
+
if (invalidIndex >= 0) {
|
|
109
|
+
throw new Error(`Pedido Criar bloqueado: itens[${invalidIndex}] precisa ter produto_id ou alias e quantidade positiva.`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
89
112
|
/** Lê um parâmetro JSON (string ou objeto) como objeto simples. Vazio → null. */
|
|
90
113
|
function asObject(value) {
|
|
91
114
|
if (value && typeof value === "object" && !Array.isArray(value))
|
|
@@ -189,7 +212,7 @@ class Nucleo {
|
|
|
189
212
|
name: "Resolver Produtos",
|
|
190
213
|
value: "resolver",
|
|
191
214
|
action: "Resolver produtos do catálogo",
|
|
192
|
-
description: "Busca vários produtos numa chamada
|
|
215
|
+
description: "Busca vários produtos numa chamada, tolera erro de digitação e apelidos e devolve regras_compra quando houver escolhas, limites ou restrições obrigatórias",
|
|
193
216
|
},
|
|
194
217
|
{
|
|
195
218
|
name: "Disponibilidade Na Rede",
|
|
@@ -319,7 +342,7 @@ class Nucleo {
|
|
|
319
342
|
default: "",
|
|
320
343
|
required: true,
|
|
321
344
|
placeholder: "banofe, pão francês, coxinha",
|
|
322
|
-
description: "Produtos a buscar: um por linha ou separados por vírgula (máx 10). Aceita erro de digitação, falta de acento e apelidos.
|
|
345
|
+
description: "Produtos a buscar: um por linha ou separados por vírgula (máx 10). Aceita erro de digitação, falta de acento e apelidos. Para produto configurável, use regras_compra como fonte da verdade e colete todas as opções obrigatórias antes de criar o pedido.",
|
|
323
346
|
displayOptions: { show: { resource: ["catalogo"], operation: ["resolver"] } },
|
|
324
347
|
},
|
|
325
348
|
// ----------------------------------------------------------------- catalogo:disponibilidadeRede
|
|
@@ -385,7 +408,7 @@ class Nucleo {
|
|
|
385
408
|
type: "json",
|
|
386
409
|
default: "[]",
|
|
387
410
|
required: true,
|
|
388
|
-
description: 'Array de itens. Cada item: {"produto_id" OU "alias", "variacao_id"?, "quantidade", "personalizacao"?}.
|
|
411
|
+
description: 'Array de itens. Cada item: {"produto_id" OU "alias", "variacao_id"?, "quantidade", "personalizacao"?, "configuracao"?}. Para produto configurável, copie somente escolhas devolvidas em regras_compra: {"configuracao":{"opcoes":[{"grupo_id":"uuid","opcao_id":"uuid"}],"quantidade_referencia":100,"confirmacao_humana":true}}. A API recusa combo incompleto ou opção inventada com 422.',
|
|
389
412
|
displayOptions: { show: { resource: ["pedido"], operation: ["criar"] } },
|
|
390
413
|
},
|
|
391
414
|
{
|
|
@@ -531,7 +554,7 @@ class Nucleo {
|
|
|
531
554
|
name: "adicionarItens",
|
|
532
555
|
type: "json",
|
|
533
556
|
default: "[]",
|
|
534
|
-
description: "Mesma forma de Itens. Vazio = não adiciona.",
|
|
557
|
+
description: "Mesma forma de Itens, incluindo configuracao para escolhas obrigatórias retornadas em regras_compra. Vazio = não adiciona; item incompleto é recusado com 422.",
|
|
535
558
|
displayOptions: { show: { resource: ["pedido"], operation: ["alterar"] } },
|
|
536
559
|
},
|
|
537
560
|
{
|
|
@@ -884,6 +907,7 @@ class Nucleo {
|
|
|
884
907
|
const telefone = this.getNodeParameter("telefone", i).trim();
|
|
885
908
|
const nomeCliente = this.getNodeParameter("nomeCliente", i, "").trim();
|
|
886
909
|
const itens = asArray(this.getNodeParameter("itens", i));
|
|
910
|
+
assertPedidoCriarItens(itens);
|
|
887
911
|
const tipoEntrega = this.getNodeParameter("tipoEntrega", i);
|
|
888
912
|
const observacoes = this.getNodeParameter("observacoes", i, "").trim();
|
|
889
913
|
const agendadoPara = this.getNodeParameter("agendadoPara", i, "").trim();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wondai/n8n-nodes-nucleo",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "Node n8n para o Núcleo Wondai — atendimento de IA (gate liga/desliga, cliente, catálogo fuzzy, disponibilidade em rede, pedidos, contexto operacional, telemetria) com assinatura HMAC v1. Tenant vem do token (a parede, ADR-013).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|