@wondai/n8n-nodes-nucleo 0.2.1 → 0.2.3

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 CHANGED
@@ -20,9 +20,11 @@ parede. Isso mantém o segredo fora do workflow, a lógica num lugar só e o tok
20
20
  |---|---|---|---|
21
21
  | Cliente | Buscar | `GET /api/v1/agent/cliente` | `cliente:ler` |
22
22
  | Catálogo | Resolver Produtos | `POST /api/v1/agent/catalogo/resolver` | `catalogo:ler` |
23
+ | Pedido | Detalhar | `GET /api/v1/agent/pedido/:ref` | `pedido:ler` |
23
24
  | Pedido | Criar | `POST /api/v1/agent/pedido` | `pedido:escrever` |
24
25
  | Pedido | Alterar | `PATCH /api/v1/agent/pedido/:id` | `pedido:escrever` |
25
26
  | Pedido | Cancelar | `POST /api/v1/agent/pedido/:id/cancelar` | `pedido:escrever` |
27
+ | Conversa | Registrar | `POST /api/v1/agent/conversa/fechar` | `conversa:escrever` |
26
28
 
27
29
  **Resolver Produtos** é a operação inteligente: manda várias consultas numa chamada (máx 10),
28
30
  tolera erro de digitação (`banofe`→Banoffee), falta de acento (`pao frances`→Pão Francês) e
@@ -31,6 +33,10 @@ apelidos; devolve no máx 3 candidatos por consulta com `status` (`achou`/`ambig
31
33
  **Criar** é idempotente: deixe *Idempotency Key* vazio (gera uma) ou repita a mesma chave num retry
32
34
  — o Núcleo nunca duplica o pedido.
33
35
 
36
+ No **Pedido Criar**, `Nome do Cliente` e `Endereço de Entrega (JSON)` são opcionais e existem para
37
+ carregar o que a IA já coletou no atendimento. O node continua burro: só envia `nome_cliente` e
38
+ `endereco_entrega`; quem decide tenant, valida e grava snapshot em `crm.entregas` é o Núcleo.
39
+
34
40
  ## Instalação (n8n self-hosted)
35
41
 
36
42
  1. **Settings → Community Nodes → Install** → `@wondai/n8n-nodes-nucleo`.
@@ -85,6 +85,24 @@ function asArray(value) {
85
85
  }
86
86
  return [];
87
87
  }
88
+ /** Lê um parâmetro JSON (string ou objeto) como objeto simples. Vazio → null. */
89
+ function asObject(value) {
90
+ if (value && typeof value === "object" && !Array.isArray(value))
91
+ return value;
92
+ if (typeof value === "string") {
93
+ const t = value.trim();
94
+ if (!t)
95
+ return null;
96
+ try {
97
+ const j = JSON.parse(t);
98
+ return j && typeof j === "object" && !Array.isArray(j) ? j : null;
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ }
104
+ return null;
105
+ }
88
106
  /** IDs separados por vírgula ou JSON array → string[]. */
89
107
  function parseIds(value) {
90
108
  if (Array.isArray(value))
@@ -268,6 +286,14 @@ class Nucleo {
268
286
  description: "Telefone do cliente (E.164). Resolve o cliente existente ou cria um novo.",
269
287
  displayOptions: { show: { resource: ["pedido"], operation: ["criar"] } },
270
288
  },
289
+ {
290
+ displayName: "Nome do Cliente",
291
+ name: "nomeCliente",
292
+ type: "string",
293
+ default: "",
294
+ description: "Opcional. Preenche cliente novo ou cliente existente ainda sem nome. Não sobrescreve nome já cadastrado.",
295
+ displayOptions: { show: { resource: ["pedido"], operation: ["criar"] } },
296
+ },
271
297
  {
272
298
  displayName: "Itens (JSON)",
273
299
  name: "itens",
@@ -304,6 +330,14 @@ class Nucleo {
304
330
  description: "Data/hora ISO 8601 para encomenda. Vazio = imediato.",
305
331
  displayOptions: { show: { resource: ["pedido"], operation: ["criar"] } },
306
332
  },
333
+ {
334
+ displayName: "Endereço de Entrega (JSON)",
335
+ name: "enderecoEntrega",
336
+ type: "json",
337
+ default: "{}",
338
+ description: 'Opcional. Para entrega, snapshot do endereço escolhido: {"logradouro","numero","complemento","bairro","cidade","estado","cep","referencia"}. Logradouro e cidade são obrigatórios quando enviado.',
339
+ displayOptions: { show: { resource: ["pedido"], operation: ["criar"] } },
340
+ },
307
341
  {
308
342
  displayName: "Loja (unit_id)",
309
343
  name: "unitId",
@@ -455,20 +489,27 @@ class Nucleo {
455
489
  }
456
490
  else if (resource === "pedido" && operation === "criar") {
457
491
  const telefone = this.getNodeParameter("telefone", i).trim();
492
+ const nomeCliente = this.getNodeParameter("nomeCliente", i, "").trim();
458
493
  const itens = asArray(this.getNodeParameter("itens", i));
459
494
  const tipoEntrega = this.getNodeParameter("tipoEntrega", i);
460
495
  const observacoes = this.getNodeParameter("observacoes", i, "").trim();
461
496
  const agendadoPara = this.getNodeParameter("agendadoPara", i, "").trim();
497
+ const enderecoEntrega = asObject(this.getNodeParameter("enderecoEntrega", i, "{}"));
462
498
  const unitId = this.getNodeParameter("unitId", i, "").trim();
463
499
  idempotencyKey =
464
500
  this.getNodeParameter("idempotencyKey", i, "").trim() || (0, node_crypto_1.randomUUID)();
465
501
  const b = { telefone, itens };
502
+ if (nomeCliente)
503
+ b.nome_cliente = nomeCliente;
466
504
  if (tipoEntrega)
467
505
  b.tipo_entrega = tipoEntrega;
468
506
  if (observacoes)
469
507
  b.observacoes = observacoes;
470
508
  if (agendadoPara)
471
509
  b.agendado_para = agendadoPara;
510
+ if (enderecoEntrega && Object.keys(enderecoEntrega).length) {
511
+ b.endereco_entrega = enderecoEntrega;
512
+ }
472
513
  if (unitId)
473
514
  b.unit_id = unitId;
474
515
  method = "POST";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wondai/n8n-nodes-nucleo",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Node n8n para o Núcleo Wondai — atendimento de IA (cliente, catálogo fuzzy, pedidos) com assinatura HMAC v1. Tenant vem do token (a parede, ADR-013).",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",