CALCULATOR - Calculadora Matemática
O que é este Node?
O CALCULATOR é o node responsável por realizar cálculos matemáticos complexos com suporte a variáveis, expressões aritméticas e operações avançadas.
Por que este Node existe?
Flows precisam processar números e realizar cálculos. O CALCULATOR existe para:
- Cálculos dinâmicos: Processar valores capturados do usuário em tempo real
- Operações complexas: Suporta +, -, *, /, parênteses e múltiplas operações
- Uso de variáveis: Pode referenciar valores de outras partes do flow
- Segurança: Avalia expressões de forma segura sem permitir código arbitrário
- Formatação de resultados: Retorna valores numéricos prontos para uso
Como funciona internamente?
Quando o CALCULATOR é executado, o sistema:
- Recebe a expressão matemática com possíveis variáveis
- Substitui variáveis pelos valores do contexto ({{variavel}})
- Valida segurança - apenas caracteres permitidos: números, +, -, *, /, ., (, )
- Avalia a expressão de forma segura
- Retorna o resultado numérico
- Se inválido: Retorna erro com mensagem específica
- Se válido: Salva resultado para uso em próximos nodes
Código interno (ai-processing-executor.service.ts:604-648):
private async executeCalculator(parameters: any, context: any): Promise<any> {
const { expression, variables: calcVariables } = parameters;
this.logger.log(`🧮 CALCULATOR - Calculating: ${expression}`);
if (!expression) {
throw new Error('Expression is required for calculation');
}
try {
// Replace variables in expression
let processedExpression = expression;
const allVariables = { ...context.variables, ...calcVariables };
Object.keys(allVariables).forEach(key => {
const placeholder = `{{${key}}}`;
processedExpression = processedExpression.replace(
new RegExp(placeholder, 'g'),
allVariables[key]
);
});
// Safe evaluation (in production, use a proper math expression evaluator)
const allowedChars = /^[0-9+\-*/.() ]+$/;
if (!allowedChars.test(processedExpression)) {
throw new Error('Expression contains invalid characters');
}
const result = Function(`"use strict"; return (${processedExpression})`)();
return {
success: true,
action: 'calculation_completed',
expression: expression,
processedExpression: processedExpression,
result: result,
resultType: typeof result,
timestamp: new Date().toISOString()
};
} catch (error) {
throw new Error(`Calculation failed: ${error.message}`);
}
}
Quando você DEVE usar este Node?
Use CALCULATOR quando precisar de cálculos matemáticos:
Casos de uso
- Calcular totais: Somar múltiplos valores capturados
- Calcular descontos: Aplicar porcentagens sobre valores
- Conversões: Converter unidades (km para milhas, etc)
- Fórmulas: IMC, taxas, juros, proporções
- Preços dinâmicos: Calcular preço final com impostos/descontos
- Comissões: Calcular valores baseados em porcentagens
Quando NÃO usar CALCULATOR
- Formatação de números: Use FORMATTER ao invés
- Validação numérica: Use VALIDATOR
- Lógica condicional: Use CONDITION
Parâmetros Detalhados
expression (string, obrigatório)
O que é: A expressão matemática a ser calculada. Pode conter números, operadores (+, -, *, /, parênteses) e variáveis no formato {{variavel}}.
Operações suportadas:
- Adição:
+ - Subtração:
- - Multiplicação:
* - Divisão:
/ - Parênteses:
(e) - Decimais:
.
Flow completo para testar:
{
"name": "Teste CALCULATOR - Expressão Simples",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Calcular",
"parameters": {
"expression": "(10 + 5) * 2"
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Mostrar Resultado",
"parameters": {
"message": "Resultado: {{calculator_result}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 700, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "calculator_1" },
{ "source": "calculator_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: O resultado será 30 (15 * 2)
variables (object, opcional)
O que é: Objeto contendo variáveis adicionais para usar na expressão. Variáveis do contexto também são automaticamente disponibilizadas.
Flow completo para testar:
{
"name": "Teste CALCULATOR - Com Variáveis",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "number_1",
"type": "number",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Pedir Valor",
"parameters": {
"message": "Digite o valor do produto:",
"variable": "valor_produto",
"decimals": 2
}
}
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Calcular com Desconto",
"parameters": {
"expression": "{{valor_produto}} * 0.9",
"variables": {}
}
}
},
{
"id": "message_1",
"type": "message",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Mostrar",
"parameters": {
"message": "Valor original: R$ {{valor_produto}}\nValor com 10% desconto: R$ {{calculator_result}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 900, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "number_1" },
{ "source": "number_1", "target": "calculator_1" },
{ "source": "calculator_1", "target": "message_1" },
{ "source": "message_1", "target": "end_1" }
]
}
Teste: Digite 100 - o resultado será 90.00 (100 com 10% de desconto)
Parâmetros
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| expression | string | Sim | Expressão matemática a calcular |
| variables | object | Não | Variáveis adicionais para usar na expressão |
Exemplo 1: Calcular IMC (Índice de Massa Corporal)
Objetivo: Capturar peso e altura do usuário e calcular o IMC automaticamente.
JSON para Importar
{
"name": "Calculadora de IMC",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "Calculadora de IMC\n\nVamos calcular seu Índice de Massa Corporal!"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Pedir Peso",
"parameters": {
"message": "Qual seu peso em kg?",
"variable": "peso",
"min": 30,
"max": 300,
"decimals": 1
}
}
},
{
"id": "number_2",
"type": "number",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Pedir Altura",
"parameters": {
"message": "Qual sua altura em metros? (Ex: 1.75)",
"variable": "altura",
"min": 1,
"max": 2.5,
"decimals": 2
}
}
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Calcular IMC",
"parameters": {
"expression": "{{peso}} / ({{altura}} * {{altura}})"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Mostrar Resultado",
"parameters": {
"message": "SEU IMC\n\nPeso: {{peso}} kg\nAltura: {{altura}} m\nIMC: {{calculator_result}}\n\nInterpretação:\n• Abaixo de 18.5: Abaixo do peso\n• 18.5 - 24.9: Peso normal\n• 25.0 - 29.9: Sobrepeso\n• Acima de 30: Obesidade"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1300, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "number_1" },
{ "source": "number_1", "target": "number_2" },
{ "source": "number_2", "target": "calculator_1" },
{ "source": "calculator_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Calculadora de IMC - Vamos calcular seu Índice de Massa Corporal!
Sistema: Qual seu peso em kg?
Usuário: 75.5
Sistema: Qual sua altura em metros? (Ex: 1.75)
Usuário: 1.75
Sistema: SEU IMC
Peso: 75.5 kg
Altura: 1.75 m
IMC: 24.65
Exemplo 2: Calcular Preço com Desconto e Frete
Objetivo: Calcular preço final de uma compra com desconto progressivo e frete.
JSON para Importar
{
"name": "Calculadora de Preço Final",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "Calculadora de Preço Final\n\nVamos calcular o valor da sua compra!"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Valor do Produto",
"parameters": {
"message": "Qual o valor do produto?",
"variable": "valor",
"min": 0.01,
"decimals": 2
}
}
},
{
"id": "number_2",
"type": "number",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Quantidade",
"parameters": {
"message": "Quantas unidades?",
"variable": "quantidade",
"min": 1,
"max": 100
}
}
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Calcular Subtotal",
"parameters": {
"expression": "{{valor}} * {{quantidade}}"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Salvar Subtotal",
"parameters": {
"name": "subtotal",
"value": "{{calculator_result}}"
}
}
},
{
"id": "calculator_2",
"type": "calculator",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Aplicar Desconto 15%",
"parameters": {
"expression": "{{subtotal}} * 0.85"
}
}
},
{
"id": "variable_2",
"type": "variable",
"position": { "x": 1500, "y": 100 },
"data": {
"label": "Salvar Com Desconto",
"parameters": {
"name": "com_desconto",
"value": "{{calculator_result}}"
}
}
},
{
"id": "calculator_3",
"type": "calculator",
"position": { "x": 1700, "y": 100 },
"data": {
"label": "Adicionar Frete",
"parameters": {
"expression": "{{com_desconto}} + 15.90"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1900, "y": 100 },
"data": {
"label": "Mostrar Resumo",
"parameters": {
"message": "RESUMO DO PEDIDO\n\nProduto: R$ {{valor}} x {{quantidade}} unidades\nSubtotal: R$ {{subtotal}}\nDesconto 15%: -R$ {{subtotal}} → R$ {{com_desconto}}\nFrete: +R$ 15.90\n\nTOTAL: R$ {{calculator_result}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 2100, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "number_1" },
{ "source": "number_1", "target": "number_2" },
{ "source": "number_2", "target": "calculator_1" },
{ "source": "calculator_1", "target": "variable_1" },
{ "source": "variable_1", "target": "calculator_2" },
{ "source": "calculator_2", "target": "variable_2" },
{ "source": "variable_2", "target": "calculator_3" },
{ "source": "calculator_3", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Calculadora de Preço Final - Vamos calcular o valor da sua compra!
Sistema: Qual o valor do produto?
Usuário: 50.00
Sistema: Quantas unidades?
Usuário: 3
Sistema: RESUMO DO PEDIDO
Produto: R$ 50.00 x 3 unidades
Subtotal: R$ 150.00
Desconto 15%: -R$ 150.00 → R$ 127.50
Frete: +R$ 15.90
TOTAL: R$ 143.40
Exemplo 3: Calcular Porcentagem e Proporção
Objetivo: Demonstrar cálculos com porcentagens e proporções complexas.
JSON para Importar
{
"name": "Cálculos de Porcentagem",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Introdução",
"parameters": {
"message": "Calculadora de Porcentagens\n\nVamos calcular várias porcentagens de um valor!"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Valor Base",
"parameters": {
"message": "Digite o valor base:",
"variable": "valor_base",
"decimals": 2
}
}
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 700, "y": 50 },
"data": {
"label": "Calcular 10%",
"parameters": {
"expression": "{{valor_base}} * 0.10"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 900, "y": 50 },
"data": {
"label": "Salvar 10%",
"parameters": {
"name": "dez_porcento",
"value": "{{calculator_result}}"
}
}
},
{
"id": "calculator_2",
"type": "calculator",
"position": { "x": 700, "y": 150 },
"data": {
"label": "Calcular 25%",
"parameters": {
"expression": "{{valor_base}} * 0.25"
}
}
},
{
"id": "variable_2",
"type": "variable",
"position": { "x": 900, "y": 150 },
"data": {
"label": "Salvar 25%",
"parameters": {
"name": "vinte_cinco_porcento",
"value": "{{calculator_result}}"
}
}
},
{
"id": "calculator_3",
"type": "calculator",
"position": { "x": 700, "y": 250 },
"data": {
"label": "Calcular 50%",
"parameters": {
"expression": "{{valor_base}} / 2"
}
}
},
{
"id": "variable_3",
"type": "variable",
"position": { "x": 900, "y": 250 },
"data": {
"label": "Salvar 50%",
"parameters": {
"name": "cinquenta_porcento",
"value": "{{calculator_result}}"
}
}
},
{
"id": "merge_1",
"type": "merge",
"position": { "x": 1100, "y": 150 },
"data": {
"label": "Juntar Resultados"
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 150 },
"data": {
"label": "Mostrar Todos",
"parameters": {
"message": "CÁLCULOS DE PORCENTAGEM\n\nValor Base: R$ {{valor_base}}\n\n10% = R$ {{dez_porcento}}\n25% = R$ {{vinte_cinco_porcento}}\n50% = R$ {{cinquenta_porcento}}"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 150 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "number_1" },
{ "source": "number_1", "target": "calculator_1" },
{ "source": "calculator_1", "target": "variable_1" },
{ "source": "number_1", "target": "calculator_2" },
{ "source": "calculator_2", "target": "variable_2" },
{ "source": "number_1", "target": "calculator_3" },
{ "source": "calculator_3", "target": "variable_3" },
{ "source": "variable_1", "target": "merge_1" },
{ "source": "variable_2", "target": "merge_1" },
{ "source": "variable_3", "target": "merge_1" },
{ "source": "merge_1", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Calculadora de Porcentagens - Vamos calcular várias porcentagens de um valor!
Sistema: Digite o valor base:
Usuário: 1000
Sistema: CÁLCULOS DE PORCENTAGEM
Valor Base: R$ 1000
10% = R$ 100
25% = R$ 250
50% = R$ 500
Exemplo 4: Conversão de Unidades
Objetivo: Converter valores entre diferentes unidades de medida.
JSON para Importar
{
"name": "Conversor de Unidades",
"nodes": [
{
"id": "start_1",
"type": "start",
"position": { "x": 100, "y": 100 },
"data": { "label": "Início" }
},
{
"id": "message_1",
"type": "message",
"position": { "x": 300, "y": 100 },
"data": {
"label": "Boas-vindas",
"parameters": {
"message": "Conversor de Unidades\n\nVamos converter Celsius para Fahrenheit!"
}
}
},
{
"id": "number_1",
"type": "number",
"position": { "x": 500, "y": 100 },
"data": {
"label": "Temperatura Celsius",
"parameters": {
"message": "Digite a temperatura em Celsius:",
"variable": "celsius",
"min": -273.15,
"decimals": 1
}
}
},
{
"id": "calculator_1",
"type": "calculator",
"position": { "x": 700, "y": 100 },
"data": {
"label": "Converter para Fahrenheit",
"parameters": {
"expression": "({{celsius}} * 9 / 5) + 32"
}
}
},
{
"id": "variable_1",
"type": "variable",
"position": { "x": 900, "y": 100 },
"data": {
"label": "Salvar Fahrenheit",
"parameters": {
"name": "fahrenheit",
"value": "{{calculator_result}}"
}
}
},
{
"id": "calculator_2",
"type": "calculator",
"position": { "x": 1100, "y": 100 },
"data": {
"label": "Converter para Kelvin",
"parameters": {
"expression": "{{celsius}} + 273.15"
}
}
},
{
"id": "message_2",
"type": "message",
"position": { "x": 1300, "y": 100 },
"data": {
"label": "Mostrar Conversões",
"parameters": {
"message": "CONVERSÕES DE TEMPERATURA\n\nCelsius: {{celsius}}°C\nFahrenheit: {{fahrenheit}}°F\nKelvin: {{calculator_result}}K"
}
}
},
{
"id": "end_1",
"type": "end",
"position": { "x": 1500, "y": 100 },
"data": { "label": "Fim" }
}
],
"edges": [
{ "source": "start_1", "target": "message_1" },
{ "source": "message_1", "target": "number_1" },
{ "source": "number_1", "target": "calculator_1" },
{ "source": "calculator_1", "target": "variable_1" },
{ "source": "variable_1", "target": "calculator_2" },
{ "source": "calculator_2", "target": "message_2" },
{ "source": "message_2", "target": "end_1" }
]
}
Saída esperada:
Sistema: Conversor de Unidades - Vamos converter Celsius para Fahrenheit!
Sistema: Digite a temperatura em Celsius:
Usuário: 25
Sistema: CONVERSÕES DE TEMPERATURA
Celsius: 25°C
Fahrenheit: 77°F
Kelvin: 298.15K
Resposta do Node
{
"success": true,
"action": "calculation_completed",
"expression": "{{peso}} / ({{altura}} * {{altura}})",
"processedExpression": "75.5 / (1.75 * 1.75)",
"result": 24.653061224489797,
"resultType": "number",
"timestamp": "2025-01-15T10:30:00.000Z"
}
Operações Matemáticas Suportadas
| Operação | Símbolo | Exemplo | Resultado |
|---|---|---|---|
| Adição | + | 10 + 5 | 15 |
| Subtração | - | 10 - 5 | 5 |
| Multiplicação | * | 10 * 5 | 50 |
| Divisão | / | 10 / 5 | 2 |
| Parênteses | ( ) | (10 + 5) * 2 | 30 |
| Decimais | . | 10.5 * 2 | 21 |
| Múltiplas operações | - | (100 - 20) * 1.1 | 88 |
Casos de Uso Comuns
| Caso | Expressão | Descrição |
|---|---|---|
| IMC | {{peso}} / ({{altura}} * {{altura}}) |
Índice de Massa Corporal |
| Desconto 10% | {{valor}} * 0.9 |
Aplicar desconto de 10% |
| Desconto 15% | {{valor}} * 0.85 |
Aplicar desconto de 15% |
| Acréscimo 10% | {{valor}} * 1.1 |
Adicionar 10% |
| Calcular 30% | {{valor}} * 0.30 |
Obter 30% do valor |
| Média | ({{n1}} + {{n2}} + {{n3}}) / 3 |
Média de 3 números |
| Total com Frete | {{subtotal}} + {{frete}} |
Somar frete ao subtotal |
| Celsius → Fahrenheit | ({{celsius}} * 9 / 5) + 32 |
Converter temperatura |
| Comissão 5% | {{vendas}} * 0.05 |
Calcular comissão |
| Juros simples | {{valor}} * {{taxa}} * {{meses}} |
Calcular juros |
Boas Práticas
✅ SIM:
- Use parênteses para garantir ordem de operações:
(a + b) * c - Salve resultados intermediários em variáveis para cálculos complexos
- Teste expressões simples antes de complicar
- Use nomes de variáveis descritivos:
{{valor_produto}}em vez de{{v}} - Combine com FORMATTER para exibir valores formatados
❌ NÃO:
- Não use caracteres especiais ou letras fora de variáveis
- Não tente usar funções (sin, cos, log) - apenas operações básicas
- Não divida por zero - valide inputs antes
- Não use vírgula como decimal - use ponto:
10.5não10,5
Dicas
💡 Ordem de operações: O CALCULATOR segue ordem matemática padrão (parênteses, multiplicação/divisão, adição/subtração)
💡 Arredondamento: Use FORMATTER após CALCULATOR para formatar casas decimais: {{calculator_result}} → FORMATTER → "150.99"
💡 Variáveis do contexto: Todas as variáveis do flow estão disponíveis automaticamente sem precisar passar no parâmetro variables
💡 Validação: Use VALIDATOR antes do CALCULATOR para garantir que números são válidos
💡 Debug: Teste expressões simples primeiro, depois adicione complexidade gradualmente
💡 Performance: Cálculos são executados instantaneamente - sem delay
Expressões Avançadas
Calcular porcentagem de aumento/diminuição
Aumento: (({{novo}} - {{antigo}}) / {{antigo}}) * 100
Regra de três simples
{{valor1}} * {{valor3}} / {{valor2}}
Área do círculo
3.14159 * {{raio}} * {{raio}}
Teorema de Pitágoras
(({{a}} * {{a}}) + ({{b}} * {{b}}))
Próximo Node
→ FORMATTER - Formatar números e textos → VALIDATOR - Validar dados → VARIABLE - Salvar valores calculados