@wondai/n8n-nodes-nucleo 0.6.5 → 0.7.0
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/dist/nodes/Nucleo/Nucleo.node.js +129 -2
- package/package.json +1 -1
|
@@ -63,8 +63,11 @@ function parseConsultas(raw, max = 10) {
|
|
|
63
63
|
continue;
|
|
64
64
|
seen.add(k);
|
|
65
65
|
out.push(s);
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
}
|
|
67
|
+
// Plano 030: rejeicao EXPLICITA acima do limite. O break silencioso descartava consultas
|
|
68
|
+
// (incidente 65144: 4 consultas perdidas), produzindo resultado parcial com aparencia de sucesso.
|
|
69
|
+
if (out.length > max) {
|
|
70
|
+
throw new Error(`Catalogo Resolver: ${out.length} consultas acima do limite de ${max}. Envie no maximo ${max} consultas de PRODUTO por chamada; adicionais e opcoes ja resolvidos nao sao novas consultas.`);
|
|
68
71
|
}
|
|
69
72
|
return out;
|
|
70
73
|
}
|
|
@@ -268,9 +271,87 @@ class Nucleo {
|
|
|
268
271
|
action: "Anexar foto-referência ao pedido",
|
|
269
272
|
description: "Anexa a FOTO que o cliente mandou no WhatsApp (a decoração que ele quer) ao pedido — a imagem literal, não uma descrição. Recebe base64 (data-URL ou puro + mime). Idempotente pelo messageID.",
|
|
270
273
|
},
|
|
274
|
+
{
|
|
275
|
+
name: "Cotar",
|
|
276
|
+
value: "cotar",
|
|
277
|
+
action: "Cotar pedido (cotação canônica)",
|
|
278
|
+
description: "Gera a COTAÇÃO CANÔNICA do Núcleo (preço/quantidade/config oficiais; nada de texto) e a persiste como pending. Use os mesmos itens estruturados de Criar.",
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: "Validar Cotação (Dry-Run)",
|
|
282
|
+
value: "validarCotacao",
|
|
283
|
+
action: "Validar cotação sem escrever (shadow)",
|
|
284
|
+
description: "Roda o preparo/precificação e devolve o mesmo shape da cotação com dry_run:true, SEM escrever nada.",
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "Marcar Cotação Apresentada",
|
|
288
|
+
value: "apresentarCotacao",
|
|
289
|
+
action: "Marcar cotação apresentada",
|
|
290
|
+
description: "pending -> presented. Chamar SÓ no ramo de sucesso do envio público. Requer cotacao_id e cotacao_version.",
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: "Consultar Cotação Ativa",
|
|
294
|
+
value: "consultarCotacaoAtiva",
|
|
295
|
+
action: "Consultar cotação apresentada ativa",
|
|
296
|
+
description: "Devolve a cotação presented ativa do cliente (por telefone). Sem cotação apresentada => 404.",
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "Confirmar Cotação",
|
|
300
|
+
value: "confirmarCotacao",
|
|
301
|
+
action: "Confirmar cotação (cria 1 pedido)",
|
|
302
|
+
description: "Revalida a cotação por fingerprint e cria exatamente UM pedido (transacional). Divergência => 409 e novo resumo. Requer cotacao_id, cotacao_version e cliente_telefone.",
|
|
303
|
+
},
|
|
271
304
|
],
|
|
272
305
|
default: "criar",
|
|
273
306
|
},
|
|
307
|
+
{
|
|
308
|
+
displayName: "Cotação (Corpo JSON)",
|
|
309
|
+
name: "cotacaoBody",
|
|
310
|
+
type: "json",
|
|
311
|
+
default: "{}",
|
|
312
|
+
description: "Corpo da cotação (mesmo formato de Criar): telefone, itens[], tipo_entrega, endereco_entrega, agendado_para, forma_pagamento, taxa_entrega, desconto, cobrancas[], observacoes.",
|
|
313
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["cotar", "validarCotacao"] } },
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
displayName: "Cotação ID",
|
|
317
|
+
name: "cotacaoId",
|
|
318
|
+
type: "string",
|
|
319
|
+
default: "",
|
|
320
|
+
description: "cotacao_id retornado por Cotar (vindo por expressão do workflow, nunca da LLM).",
|
|
321
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["apresentarCotacao", "confirmarCotacao"] } },
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
displayName: "Cotação Versão",
|
|
325
|
+
name: "cotacaoVersion",
|
|
326
|
+
type: "number",
|
|
327
|
+
default: 1,
|
|
328
|
+
description: "cotacao_version retornado por Cotar.",
|
|
329
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["apresentarCotacao", "confirmarCotacao"] } },
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
displayName: "Message ID Apresentado",
|
|
333
|
+
name: "cotacaoMessageId",
|
|
334
|
+
type: "string",
|
|
335
|
+
default: "",
|
|
336
|
+
description: "ID da mensagem enviada (opcional), para auditoria da apresentação.",
|
|
337
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["apresentarCotacao"] } },
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
displayName: "Telefone do Cliente",
|
|
341
|
+
name: "cotacaoTelefone",
|
|
342
|
+
type: "string",
|
|
343
|
+
default: "",
|
|
344
|
+
description: "Telefone normalizado, injetado por expressão do workflow.",
|
|
345
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["consultarCotacaoAtiva", "confirmarCotacao"] } },
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
displayName: "Nome do Cliente",
|
|
349
|
+
name: "cotacaoNome",
|
|
350
|
+
type: "string",
|
|
351
|
+
default: "",
|
|
352
|
+
description: "Nome do cliente (opcional).",
|
|
353
|
+
displayOptions: { show: { resource: ["pedido"], operation: ["confirmarCotacao"] } },
|
|
354
|
+
},
|
|
274
355
|
{
|
|
275
356
|
displayName: "Operação",
|
|
276
357
|
name: "operation",
|
|
@@ -1446,6 +1527,52 @@ class Nucleo {
|
|
|
1446
1527
|
path = `/api/v1/agent/pedido/${encodeURIComponent(pedidoId)}/anexo`;
|
|
1447
1528
|
bodyObj = b;
|
|
1448
1529
|
}
|
|
1530
|
+
else if (resource === "pedido" && operation === "cotar") {
|
|
1531
|
+
const body = asObject(this.getNodeParameter("cotacaoBody", i, "{}")) || {};
|
|
1532
|
+
assertPedidoCriarItens(asArray(body.itens));
|
|
1533
|
+
idempotencyKey =
|
|
1534
|
+
this.getNodeParameter("idempotencyKey", i, "").trim() || undefined;
|
|
1535
|
+
method = "POST";
|
|
1536
|
+
path = "/api/v1/agent/pedido/cotacao";
|
|
1537
|
+
bodyObj = body;
|
|
1538
|
+
}
|
|
1539
|
+
else if (resource === "pedido" && operation === "validarCotacao") {
|
|
1540
|
+
const body = asObject(this.getNodeParameter("cotacaoBody", i, "{}")) || {};
|
|
1541
|
+
method = "POST";
|
|
1542
|
+
path = "/api/v1/agent/pedido/cotacao/validar";
|
|
1543
|
+
bodyObj = body;
|
|
1544
|
+
}
|
|
1545
|
+
else if (resource === "pedido" && operation === "apresentarCotacao") {
|
|
1546
|
+
const cotacaoId = this.getNodeParameter("cotacaoId", i).trim();
|
|
1547
|
+
const version = Number(this.getNodeParameter("cotacaoVersion", i));
|
|
1548
|
+
const messageId = this.getNodeParameter("cotacaoMessageId", i, "").trim();
|
|
1549
|
+
const b = { cotacao_version: version };
|
|
1550
|
+
if (messageId)
|
|
1551
|
+
b.presented_message_id = messageId;
|
|
1552
|
+
method = "POST";
|
|
1553
|
+
path = `/api/v1/agent/pedido/cotacao/${encodeURIComponent(cotacaoId)}/apresentar`;
|
|
1554
|
+
bodyObj = b;
|
|
1555
|
+
}
|
|
1556
|
+
else if (resource === "pedido" && operation === "consultarCotacaoAtiva") {
|
|
1557
|
+
const telefone = this.getNodeParameter("cotacaoTelefone", i).trim();
|
|
1558
|
+
method = "POST";
|
|
1559
|
+
path = "/api/v1/agent/pedido/cotacao/ativa";
|
|
1560
|
+
bodyObj = { telefone };
|
|
1561
|
+
}
|
|
1562
|
+
else if (resource === "pedido" && operation === "confirmarCotacao") {
|
|
1563
|
+
const cotacaoId = this.getNodeParameter("cotacaoId", i).trim();
|
|
1564
|
+
const version = Number(this.getNodeParameter("cotacaoVersion", i));
|
|
1565
|
+
const telefone = this.getNodeParameter("cotacaoTelefone", i).trim();
|
|
1566
|
+
const nome = this.getNodeParameter("cotacaoNome", i, "").trim();
|
|
1567
|
+
const b = { cotacao_version: version, cliente_telefone: telefone };
|
|
1568
|
+
if (nome)
|
|
1569
|
+
b.cliente_nome = nome;
|
|
1570
|
+
// Idempotência DETERMINÍSTICA montada pelo package (nunca pela LLM), Plano 030 §9.5.
|
|
1571
|
+
idempotencyKey = `quote-confirm:${cotacaoId}:${version}`;
|
|
1572
|
+
method = "POST";
|
|
1573
|
+
path = `/api/v1/agent/pedido/cotacao/${encodeURIComponent(cotacaoId)}/confirmar`;
|
|
1574
|
+
bodyObj = b;
|
|
1575
|
+
}
|
|
1449
1576
|
else if (resource === "conversa" && operation === "registrar") {
|
|
1450
1577
|
const resumo = this.getNodeParameter("resumo", i).trim();
|
|
1451
1578
|
const resultado = this.getNodeParameter("resultado", i);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wondai/n8n-nodes-nucleo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Node n8n para o Núcleo Wondai — atendimento de IA multi-vertical (gate liga/desliga, cliente/paciente, catálogo fuzzy, pedidos [padaria], procedimento/agenda/agendamento [odonto], contexto operacional, telemetria) com assinatura HMAC v1. Tenant e vertical vêm do token (a parede, ADR-013/038).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package",
|