rabbitmq-sdk 0.0.1-security → 1.2.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.

Potentially problematic release.


This version of rabbitmq-sdk might be problematic. Click here for more details.

Files changed (140) hide show
  1. package/.eslintrc.js +23 -0
  2. package/.kiro/specs/sdk-rabbitmq/design.md +369 -0
  3. package/.kiro/specs/sdk-rabbitmq/requirements.md +97 -0
  4. package/.kiro/specs/sdk-rabbitmq/tasks.md +248 -0
  5. package/README.md +273 -5
  6. package/bun.lock +790 -0
  7. package/config.example.json +13 -0
  8. package/dist/components/ConfigurationManager.d.ts +35 -0
  9. package/dist/components/ConfigurationManager.d.ts.map +1 -0
  10. package/dist/components/ConfigurationManager.js +118 -0
  11. package/dist/components/ConfigurationManager.js.map +1 -0
  12. package/dist/components/ConnectionManager.d.ts +93 -0
  13. package/dist/components/ConnectionManager.d.ts.map +1 -0
  14. package/dist/components/ConnectionManager.js +349 -0
  15. package/dist/components/ConnectionManager.js.map +1 -0
  16. package/dist/components/DLQHandler.d.ts +81 -0
  17. package/dist/components/DLQHandler.d.ts.map +1 -0
  18. package/dist/components/DLQHandler.js +228 -0
  19. package/dist/components/DLQHandler.js.map +1 -0
  20. package/dist/components/Logger.d.ts +77 -0
  21. package/dist/components/Logger.d.ts.map +1 -0
  22. package/dist/components/Logger.js +193 -0
  23. package/dist/components/Logger.js.map +1 -0
  24. package/dist/components/MessagePublisher.d.ts +49 -0
  25. package/dist/components/MessagePublisher.d.ts.map +1 -0
  26. package/dist/components/MessagePublisher.js +158 -0
  27. package/dist/components/MessagePublisher.js.map +1 -0
  28. package/dist/components/MessageSubscriber.d.ts +108 -0
  29. package/dist/components/MessageSubscriber.d.ts.map +1 -0
  30. package/dist/components/MessageSubscriber.js +503 -0
  31. package/dist/components/MessageSubscriber.js.map +1 -0
  32. package/dist/components/ResourceCreator.d.ts +89 -0
  33. package/dist/components/ResourceCreator.d.ts.map +1 -0
  34. package/dist/components/ResourceCreator.js +352 -0
  35. package/dist/components/ResourceCreator.js.map +1 -0
  36. package/dist/components/SdkRabbitmq.d.ts +103 -0
  37. package/dist/components/SdkRabbitmq.d.ts.map +1 -0
  38. package/dist/components/SdkRabbitmq.js +364 -0
  39. package/dist/components/SdkRabbitmq.js.map +1 -0
  40. package/dist/components/index.d.ts +9 -0
  41. package/dist/components/index.d.ts.map +1 -0
  42. package/dist/components/index.js +20 -0
  43. package/dist/components/index.js.map +1 -0
  44. package/dist/index.d.ts +5 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +27 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/interfaces/IConfiguration.d.ts +35 -0
  49. package/dist/interfaces/IConfiguration.d.ts.map +1 -0
  50. package/dist/interfaces/IConfiguration.js +3 -0
  51. package/dist/interfaces/IConfiguration.js.map +1 -0
  52. package/dist/interfaces/IConnection.d.ts +21 -0
  53. package/dist/interfaces/IConnection.d.ts.map +1 -0
  54. package/dist/interfaces/IConnection.js +3 -0
  55. package/dist/interfaces/IConnection.js.map +1 -0
  56. package/dist/interfaces/IDLQ.d.ts +12 -0
  57. package/dist/interfaces/IDLQ.d.ts.map +1 -0
  58. package/dist/interfaces/IDLQ.js +3 -0
  59. package/dist/interfaces/IDLQ.js.map +1 -0
  60. package/dist/interfaces/IErrors.d.ts +33 -0
  61. package/dist/interfaces/IErrors.d.ts.map +1 -0
  62. package/dist/interfaces/IErrors.js +56 -0
  63. package/dist/interfaces/IErrors.js.map +1 -0
  64. package/dist/interfaces/ILogger.d.ts +14 -0
  65. package/dist/interfaces/ILogger.d.ts.map +1 -0
  66. package/dist/interfaces/ILogger.js +3 -0
  67. package/dist/interfaces/ILogger.js.map +1 -0
  68. package/dist/interfaces/IMessage.d.ts +52 -0
  69. package/dist/interfaces/IMessage.d.ts.map +1 -0
  70. package/dist/interfaces/IMessage.js +3 -0
  71. package/dist/interfaces/IMessage.js.map +1 -0
  72. package/dist/interfaces/IResource.d.ts +31 -0
  73. package/dist/interfaces/IResource.d.ts.map +1 -0
  74. package/dist/interfaces/IResource.js +3 -0
  75. package/dist/interfaces/IResource.js.map +1 -0
  76. package/dist/interfaces/ISdkRabbitmq.d.ts +17 -0
  77. package/dist/interfaces/ISdkRabbitmq.d.ts.map +1 -0
  78. package/dist/interfaces/ISdkRabbitmq.js +3 -0
  79. package/dist/interfaces/ISdkRabbitmq.js.map +1 -0
  80. package/dist/interfaces/index.d.ts +9 -0
  81. package/dist/interfaces/index.d.ts.map +1 -0
  82. package/dist/interfaces/index.js +33 -0
  83. package/dist/interfaces/index.js.map +1 -0
  84. package/dist/utils/configSchema.d.ts +8 -0
  85. package/dist/utils/configSchema.d.ts.map +1 -0
  86. package/dist/utils/configSchema.js +51 -0
  87. package/dist/utils/configSchema.js.map +1 -0
  88. package/docker-compose.yml +24 -0
  89. package/example.ts +65 -0
  90. package/examples/README-dynamic-routing.md +155 -0
  91. package/examples/bind-unbind-example.js +56 -0
  92. package/examples/test-chatbot-exchange.ts +83 -0
  93. package/examples/test-dynamic-routing-flow.js +299 -0
  94. package/examples/test-dynamic-routing-flow.ts +355 -0
  95. package/examples/test-no-disconnect.ts +0 -0
  96. package/examples/test-raw-rabbitmq.js +68 -0
  97. package/examples/test-same-channel.ts +81 -0
  98. package/examples/test-schedule-flow.ts +713 -0
  99. package/examples/test-simple-greeting.ts +66 -0
  100. package/examples/test-simple-schedule.ts +76 -0
  101. package/examples/test-wildcard.ts +364 -0
  102. package/jest.config.js +17 -0
  103. package/package.json +42 -4
  104. package/preinstall.js +1 -0
  105. package/prompts/test-dynamic-routing-flow.md +46 -0
  106. package/run.js +4 -0
  107. package/scripts/run-dynamic-routing-test.ts +31 -0
  108. package/src/.gitkeep +1 -0
  109. package/src/components/.gitkeep +1 -0
  110. package/src/components/ConfigurationManager.ts +104 -0
  111. package/src/components/ConnectionManager.ts +357 -0
  112. package/src/components/DLQHandler.ts +271 -0
  113. package/src/components/Logger.ts +224 -0
  114. package/src/components/MessagePublisher.ts +180 -0
  115. package/src/components/MessageSubscriber.ts +597 -0
  116. package/src/components/ResourceCreator.ts +411 -0
  117. package/src/components/SdkRabbitmq.ts +443 -0
  118. package/src/components/__tests__/ConfigurationManager.test.ts +357 -0
  119. package/src/components/__tests__/ConnectionManager.test.ts +387 -0
  120. package/src/components/__tests__/DLQHandler.test.ts +399 -0
  121. package/src/components/__tests__/Logger.test.ts +354 -0
  122. package/src/components/__tests__/MessagePublisher.test.ts +337 -0
  123. package/src/components/__tests__/MessageSubscriber.test.ts +542 -0
  124. package/src/components/__tests__/ResourceCreator.test.ts +465 -0
  125. package/src/components/__tests__/SdkRabbitmq.integration.test.ts +433 -0
  126. package/src/components/index.ts +8 -0
  127. package/src/index.ts +11 -0
  128. package/src/interfaces/.gitkeep +1 -0
  129. package/src/interfaces/IConfiguration.ts +38 -0
  130. package/src/interfaces/IConnection.ts +27 -0
  131. package/src/interfaces/IDLQ.ts +13 -0
  132. package/src/interfaces/IErrors.ts +53 -0
  133. package/src/interfaces/ILogger.ts +16 -0
  134. package/src/interfaces/IMessage.ts +65 -0
  135. package/src/interfaces/IResource.ts +35 -0
  136. package/src/interfaces/ISdkRabbitmq.ts +26 -0
  137. package/src/interfaces/index.ts +23 -0
  138. package/src/utils/.gitkeep +1 -0
  139. package/src/utils/configSchema.ts +58 -0
  140. package/tsconfig.json +34 -0
@@ -0,0 +1,713 @@
1
+ import { SdkRabbitmq } from '../src/components/SdkRabbitmq';
2
+ import { MessageCallback } from '../src/interfaces/IMessage';
3
+
4
+ // Interfaces para tipagem
5
+ interface AgentConfig {
6
+ routingKeyAgent: string;
7
+ name: string;
8
+ }
9
+
10
+ interface GlobalMemory {
11
+ flow: string[];
12
+ currentStep: Record<string, Record<string, string>>;
13
+ userData: Record<string, Record<string, any>>;
14
+ scheduleFlow: Record<string, string[]>; // Fluxo dinâmico baseado na escolha
15
+ }
16
+
17
+ interface MessagePayload {
18
+ phone: string;
19
+ timestamp: number;
20
+ metadata: {
21
+ identification: string;
22
+ senderAgent: string;
23
+ value: string;
24
+ userData?: Record<string, any>;
25
+ choice?: string; // Para escolhas do usuário
26
+ };
27
+ }
28
+
29
+ // Memória global para controlar o fluxo
30
+ const globalMemory: GlobalMemory = {
31
+ flow: ['greeting', 'patientName', 'patientCPF', 'patientEmail', 'patientBirthDate', 'scheduleNew'],
32
+ currentStep: {},
33
+ userData: {},
34
+ scheduleFlow: {} // Será preenchido dinamicamente baseado na escolha
35
+ };
36
+
37
+ // Definição dos agentes básicos
38
+ const GreetingAgent: AgentConfig = {
39
+ routingKeyAgent: 'greeting',
40
+ name: 'GreetingAgent'
41
+ };
42
+
43
+ const PatientNameAgent: AgentConfig = {
44
+ routingKeyAgent: 'patientName',
45
+ name: 'PatientNameAgent'
46
+ };
47
+
48
+ const PatientCPFAgent: AgentConfig = {
49
+ routingKeyAgent: 'patientCPF',
50
+ name: 'PatientCPFAgent'
51
+ };
52
+
53
+ const PatientEmailAgent: AgentConfig = {
54
+ routingKeyAgent: 'patientEmail',
55
+ name: 'PatientEmailAgent'
56
+ };
57
+
58
+ const PatientBirthDateAgent: AgentConfig = {
59
+ routingKeyAgent: 'patientBirthDate',
60
+ name: 'PatientBirthDateAgent'
61
+ };
62
+
63
+ // Novos agentes de agendamento
64
+ const ScheduleNewAgent: AgentConfig = {
65
+ routingKeyAgent: 'scheduleNew',
66
+ name: 'ScheduleNewAgent'
67
+ };
68
+
69
+ const ScheduleDateAgent: AgentConfig = {
70
+ routingKeyAgent: 'scheduleDate',
71
+ name: 'ScheduleDateAgent'
72
+ };
73
+
74
+ const ScheduleDentistAgent: AgentConfig = {
75
+ routingKeyAgent: 'scheduleDentist',
76
+ name: 'ScheduleDentistAgent'
77
+ };
78
+
79
+ const ScheduleServiceAgent: AgentConfig = {
80
+ routingKeyAgent: 'scheduleService',
81
+ name: 'ScheduleServiceAgent'
82
+ };
83
+
84
+ // Função para obter o próximo agente no fluxo
85
+ function getNextAgent(currentAgent: string, phone: string): string | null {
86
+ // Para o fluxo básico
87
+ const currentIndex = globalMemory.flow.indexOf(currentAgent);
88
+ if (currentIndex >= 0 && currentIndex < globalMemory.flow.length - 1) {
89
+ return globalMemory.flow[currentIndex + 1] || null;
90
+ }
91
+
92
+ // Para o fluxo de agendamento dinâmico
93
+ if (globalMemory.scheduleFlow[phone]) {
94
+ const scheduleFlow = globalMemory.scheduleFlow[phone];
95
+ const scheduleIndex = scheduleFlow.indexOf(currentAgent);
96
+ if (scheduleIndex >= 0 && scheduleIndex < scheduleFlow.length - 1) {
97
+ return scheduleFlow[scheduleIndex + 1] || null;
98
+ }
99
+ }
100
+
101
+ return null;
102
+ }
103
+
104
+ // Função para definir o fluxo de agendamento baseado na escolha
105
+ function setScheduleFlow(phone: string, choice: string): void {
106
+ switch (choice) {
107
+ case '1': // Data primeiro
108
+ globalMemory.scheduleFlow[phone] = ['scheduleDate', 'scheduleDentist', 'scheduleService'];
109
+ break;
110
+ case '2': // Dentista primeiro
111
+ globalMemory.scheduleFlow[phone] = ['scheduleDentist', 'scheduleDate', 'scheduleService'];
112
+ break;
113
+ case '3': // Serviço primeiro
114
+ globalMemory.scheduleFlow[phone] = ['scheduleService', 'scheduleDentist', 'scheduleDate'];
115
+ break;
116
+ default:
117
+ globalMemory.scheduleFlow[phone] = ['scheduleDate', 'scheduleDentist', 'scheduleService'];
118
+ }
119
+
120
+ console.log(`📋 Fluxo de agendamento definido para ${phone}:`, globalMemory.scheduleFlow[phone]);
121
+ }
122
+
123
+ // Função para marcar sucesso na memória global
124
+ function markStepAsSuccess(phone: string, step: string, value: any): void {
125
+ if (!globalMemory.currentStep[phone]) {
126
+ globalMemory.currentStep[phone] = {};
127
+ }
128
+ if (!globalMemory.userData[phone]) {
129
+ globalMemory.userData[phone] = {};
130
+ }
131
+
132
+ globalMemory.currentStep[phone][step] = 'success';
133
+ globalMemory.userData[phone][step] = value;
134
+
135
+ console.log(`✅ Step ${step} marked as success for phone ${phone}`);
136
+ }
137
+
138
+ // Função para simular processamento de dados
139
+ function simulateDataProcessing(agentName: string, phone: string): string {
140
+ const mockData: Record<string, string> = {
141
+ 'GreetingAgent': `Olá! Bem-vindo ao nosso sistema de agendamento. Telefone: ${phone}`,
142
+ 'PatientNameAgent': `Maria Silva`,
143
+ 'PatientCPFAgent': `987.654.321-00`,
144
+ 'PatientEmailAgent': `maria.silva@email.com`,
145
+ 'PatientBirthDateAgent': `15/03/1985`,
146
+ 'ScheduleNewAgent': `Vamos agendar sua consulta!`,
147
+ 'ScheduleDateAgent': `25/11/2024 às 14:00`,
148
+ 'ScheduleDentistAgent': `Dr. João Santos`,
149
+ 'ScheduleServiceAgent': `Limpeza e Check-up`
150
+ };
151
+
152
+ return mockData[agentName] || `Dados processados por ${agentName}`;
153
+ }
154
+
155
+ async function testScheduleFlow(): Promise<void> {
156
+ console.log('🦷 Teste de fluxo de agendamento odontológico...\n');
157
+
158
+ let sdk: SdkRabbitmq | undefined;
159
+
160
+ try {
161
+ sdk = await SdkRabbitmq.getInstance();
162
+ console.log('✅ SDK inicializado\n');
163
+
164
+ // Configurar subscriber de monitoramento
165
+ console.log('👂 Configurando monitor...');
166
+ const monitorCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
167
+ console.log('\n📱 MENSAGEM FINAL RECEBIDA NO MONITOR:');
168
+ console.log('📄 Payload:', JSON.stringify(payload, null, 2));
169
+ ack();
170
+ };
171
+
172
+ await sdk.subscribe('whatsapp.message.text', 'monitor-queue', 'send', monitorCallback);
173
+ console.log('✅ Monitor configurado\n');
174
+
175
+ // Configurar GreetingAgent
176
+ console.log('🤖 Configurando GreetingAgent...');
177
+ const greetingCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
178
+ console.log('\n🤖 GreetingAgent processando:', JSON.stringify(payload, null, 2));
179
+
180
+ const phone = payload.phone;
181
+ const processedValue = simulateDataProcessing('GreetingAgent', phone);
182
+
183
+ markStepAsSuccess(phone, 'greeting', processedValue);
184
+
185
+ const nextAgentKey = getNextAgent('greeting', phone);
186
+
187
+ if (nextAgentKey) {
188
+ const nextPayload: MessagePayload = {
189
+ phone: phone,
190
+ timestamp: Date.now(),
191
+ metadata: {
192
+ identification: 'greeting',
193
+ senderAgent: 'GreetingAgent',
194
+ value: processedValue
195
+ }
196
+ };
197
+
198
+ console.log(`📤 GreetingAgent enviando para: ${nextAgentKey}`);
199
+
200
+ setTimeout(async () => {
201
+ try {
202
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
203
+ } catch (error) {
204
+ console.error('❌ Erro ao enviar para próximo agente:', error);
205
+ }
206
+ }, 100);
207
+ }
208
+
209
+ ack();
210
+ };
211
+
212
+ await sdk.subscribe('test.wildcard', 'queue-greeting', 'phone.*', greetingCallback);
213
+ console.log('✅ GreetingAgent configurado\n');
214
+
215
+ // Configurar PatientNameAgent
216
+ console.log('🤖 Configurando PatientNameAgent...');
217
+ const nameCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
218
+ console.log(`\n🤖 PatientNameAgent processando:`, JSON.stringify(payload, null, 2));
219
+
220
+ const phone = payload.phone;
221
+ const processedValue = simulateDataProcessing('PatientNameAgent', phone);
222
+
223
+ markStepAsSuccess(phone, 'patientName', processedValue);
224
+
225
+ setTimeout(async () => {
226
+ try {
227
+ const specificRoutingKey = `phone.${phone}`;
228
+ await sdk!.bind('queue-patientName', 'test.wildcard', specificRoutingKey);
229
+ console.log(`🔒 PatientNameAgent bind: ${specificRoutingKey}`);
230
+
231
+ await new Promise(resolve => setTimeout(resolve, 1000));
232
+
233
+ await sdk!.unbind('queue-patientName', 'test.wildcard', specificRoutingKey);
234
+ console.log(`🔓 PatientNameAgent unbind: ${specificRoutingKey}`);
235
+
236
+ const nextAgentKey = getNextAgent('patientName', phone);
237
+
238
+ if (nextAgentKey) {
239
+ const nextPayload: MessagePayload = {
240
+ phone: phone,
241
+ timestamp: Date.now(),
242
+ metadata: {
243
+ identification: 'patientName',
244
+ senderAgent: 'PatientNameAgent',
245
+ value: processedValue
246
+ }
247
+ };
248
+
249
+ console.log(`📤 PatientNameAgent enviando para: ${nextAgentKey}`);
250
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
251
+ }
252
+ } catch (error) {
253
+ console.error('❌ Erro no PatientNameAgent:', error);
254
+ }
255
+ }, 100);
256
+
257
+ ack();
258
+ };
259
+
260
+ await sdk.subscribe('test.agents', 'queue-patientName', 'patientName', nameCallback);
261
+ console.log('✅ PatientNameAgent configurado\n');
262
+
263
+ // Configurar PatientCPFAgent
264
+ console.log('🤖 Configurando PatientCPFAgent...');
265
+ const cpfCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
266
+ console.log(`\n🤖 PatientCPFAgent processando:`, JSON.stringify(payload, null, 2));
267
+
268
+ const phone = payload.phone;
269
+ const processedValue = simulateDataProcessing('PatientCPFAgent', phone);
270
+
271
+ markStepAsSuccess(phone, 'patientCPF', processedValue);
272
+
273
+ setTimeout(async () => {
274
+ try {
275
+ const specificRoutingKey = `phone.${phone}`;
276
+ await sdk!.bind('queue-patientCPF', 'test.wildcard', specificRoutingKey);
277
+ console.log(`🔒 PatientCPFAgent bind: ${specificRoutingKey}`);
278
+
279
+ await new Promise(resolve => setTimeout(resolve, 1000));
280
+
281
+ await sdk!.unbind('queue-patientCPF', 'test.wildcard', specificRoutingKey);
282
+ console.log(`🔓 PatientCPFAgent unbind: ${specificRoutingKey}`);
283
+
284
+ const nextAgentKey = getNextAgent('patientCPF', phone);
285
+
286
+ if (nextAgentKey) {
287
+ const nextPayload: MessagePayload = {
288
+ phone: phone,
289
+ timestamp: Date.now(),
290
+ metadata: {
291
+ identification: 'patientCPF',
292
+ senderAgent: 'PatientCPFAgent',
293
+ value: processedValue
294
+ }
295
+ };
296
+
297
+ console.log(`📤 PatientCPFAgent enviando para: ${nextAgentKey}`);
298
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
299
+ }
300
+ } catch (error) {
301
+ console.error('❌ Erro no PatientCPFAgent:', error);
302
+ }
303
+ }, 100);
304
+
305
+ ack();
306
+ };
307
+
308
+ await sdk.subscribe('test.agents', 'queue-patientCPF', 'patientCPF', cpfCallback);
309
+ console.log('✅ PatientCPFAgent configurado\n');
310
+
311
+ // Configurar PatientEmailAgent
312
+ console.log('🤖 Configurando PatientEmailAgent...');
313
+ const emailCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
314
+ console.log(`\n🤖 PatientEmailAgent processando:`, JSON.stringify(payload, null, 2));
315
+
316
+ const phone = payload.phone;
317
+ const processedValue = simulateDataProcessing('PatientEmailAgent', phone);
318
+
319
+ markStepAsSuccess(phone, 'patientEmail', processedValue);
320
+
321
+ setTimeout(async () => {
322
+ try {
323
+ const specificRoutingKey = `phone.${phone}`;
324
+ await sdk!.bind('queue-patientEmail', 'test.wildcard', specificRoutingKey);
325
+ console.log(`🔒 PatientEmailAgent bind: ${specificRoutingKey}`);
326
+
327
+ await new Promise(resolve => setTimeout(resolve, 1000));
328
+
329
+ await sdk!.unbind('queue-patientEmail', 'test.wildcard', specificRoutingKey);
330
+ console.log(`🔓 PatientEmailAgent unbind: ${specificRoutingKey}`);
331
+
332
+ const nextAgentKey = getNextAgent('patientEmail', phone);
333
+
334
+ if (nextAgentKey) {
335
+ const nextPayload: MessagePayload = {
336
+ phone: phone,
337
+ timestamp: Date.now(),
338
+ metadata: {
339
+ identification: 'patientEmail',
340
+ senderAgent: 'PatientEmailAgent',
341
+ value: processedValue
342
+ }
343
+ };
344
+
345
+ console.log(`📤 PatientEmailAgent enviando para: ${nextAgentKey}`);
346
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
347
+ }
348
+ } catch (error) {
349
+ console.error('❌ Erro no PatientEmailAgent:', error);
350
+ }
351
+ }, 100);
352
+
353
+ ack();
354
+ };
355
+
356
+ await sdk.subscribe('test.agents', 'queue-patientEmail', 'patientEmail', emailCallback);
357
+ console.log('✅ PatientEmailAgent configurado\n');
358
+
359
+ // Configurar PatientBirthDateAgent
360
+ console.log('🤖 Configurando PatientBirthDateAgent...');
361
+ const birthDateCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
362
+ console.log(`\n🤖 PatientBirthDateAgent processando:`, JSON.stringify(payload, null, 2));
363
+
364
+ const phone = payload.phone;
365
+ const processedValue = simulateDataProcessing('PatientBirthDateAgent', phone);
366
+
367
+ markStepAsSuccess(phone, 'patientBirthDate', processedValue);
368
+
369
+ setTimeout(async () => {
370
+ try {
371
+ const specificRoutingKey = `phone.${phone}`;
372
+ await sdk!.bind('queue-patientBirthDate', 'test.wildcard', specificRoutingKey);
373
+ console.log(`🔒 PatientBirthDateAgent bind: ${specificRoutingKey}`);
374
+
375
+ await new Promise(resolve => setTimeout(resolve, 1000));
376
+
377
+ await sdk!.unbind('queue-patientBirthDate', 'test.wildcard', specificRoutingKey);
378
+ console.log(`🔓 PatientBirthDateAgent unbind: ${specificRoutingKey}`);
379
+
380
+ const nextAgentKey = getNextAgent('patientBirthDate', phone);
381
+
382
+ if (nextAgentKey) {
383
+ const nextPayload: MessagePayload = {
384
+ phone: phone,
385
+ timestamp: Date.now(),
386
+ metadata: {
387
+ identification: 'patientBirthDate',
388
+ senderAgent: 'PatientBirthDateAgent',
389
+ value: processedValue
390
+ }
391
+ };
392
+
393
+ console.log(`📤 PatientBirthDateAgent enviando para: ${nextAgentKey}`);
394
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
395
+ }
396
+ } catch (error) {
397
+ console.error('❌ Erro no PatientBirthDateAgent:', error);
398
+ }
399
+ }, 100);
400
+
401
+ ack();
402
+ };
403
+
404
+ await sdk.subscribe('test.agents', 'queue-patientBirthDate', 'patientBirthDate', birthDateCallback);
405
+ console.log('✅ PatientBirthDateAgent configurado\n');
406
+
407
+ // Configurar ScheduleNewAgent
408
+ console.log('🤖 Configurando ScheduleNewAgent...');
409
+ const scheduleNewCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
410
+ console.log(`\n🤖 ScheduleNewAgent processando:`, JSON.stringify(payload, null, 2));
411
+
412
+ const phone = payload.phone;
413
+ const processedValue = "Você prefere iniciar escolhendo o que?\n1) A data da consulta\n2) O dentista\n3) O serviço desejado";
414
+
415
+ markStepAsSuccess(phone, 'scheduleNew', processedValue);
416
+
417
+ // Simular escolha do usuário baseada no telefone (para teste)
418
+ let choice = '1'; // Padrão
419
+ if (phone.endsWith('1111')) choice = '1'; // Data primeiro
420
+ if (phone.endsWith('2222')) choice = '2'; // Dentista primeiro
421
+ if (phone.endsWith('3333')) choice = '3'; // Serviço primeiro
422
+
423
+ console.log(`🎯 Usuário ${phone} escolheu opção: ${choice}`);
424
+
425
+ // Definir fluxo baseado na escolha
426
+ setScheduleFlow(phone, choice);
427
+
428
+ setTimeout(async () => {
429
+ try {
430
+ const specificRoutingKey = `phone.${phone}`;
431
+ await sdk!.bind('queue-scheduleNew', 'test.wildcard', specificRoutingKey);
432
+ console.log(`🔒 ScheduleNewAgent bind: ${specificRoutingKey}`);
433
+
434
+ await new Promise(resolve => setTimeout(resolve, 1000));
435
+
436
+ await sdk!.unbind('queue-scheduleNew', 'test.wildcard', specificRoutingKey);
437
+ console.log(`🔓 ScheduleNewAgent unbind: ${specificRoutingKey}`);
438
+
439
+ // Obter primeiro agente do fluxo de agendamento
440
+ const nextAgentKey = globalMemory.scheduleFlow[phone]?.[0];
441
+
442
+ if (nextAgentKey) {
443
+ const nextPayload: MessagePayload = {
444
+ phone: phone,
445
+ timestamp: Date.now(),
446
+ metadata: {
447
+ identification: 'scheduleNew',
448
+ senderAgent: 'ScheduleNewAgent',
449
+ value: processedValue,
450
+ choice: choice
451
+ }
452
+ };
453
+
454
+ console.log(`📤 ScheduleNewAgent enviando para: ${nextAgentKey}`);
455
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
456
+ }
457
+ } catch (error) {
458
+ console.error('❌ Erro no ScheduleNewAgent:', error);
459
+ }
460
+ }, 100);
461
+
462
+ ack();
463
+ };
464
+
465
+ await sdk.subscribe('test.agents', 'queue-scheduleNew', 'scheduleNew', scheduleNewCallback);
466
+ console.log('✅ ScheduleNewAgent configurado\n');
467
+
468
+ // Configurar ScheduleDateAgent
469
+ console.log('🤖 Configurando ScheduleDateAgent...');
470
+ const scheduleDateCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
471
+ console.log(`\n🤖 ScheduleDateAgent processando:`, JSON.stringify(payload, null, 2));
472
+
473
+ const phone = payload.phone;
474
+ const processedValue = simulateDataProcessing('ScheduleDateAgent', phone);
475
+
476
+ markStepAsSuccess(phone, 'scheduleDate', processedValue);
477
+
478
+ setTimeout(async () => {
479
+ try {
480
+ const specificRoutingKey = `phone.${phone}`;
481
+ await sdk!.bind('queue-scheduleDate', 'test.wildcard', specificRoutingKey);
482
+ console.log(`🔒 ScheduleDateAgent bind: ${specificRoutingKey}`);
483
+
484
+ await new Promise(resolve => setTimeout(resolve, 1000));
485
+
486
+ await sdk!.unbind('queue-scheduleDate', 'test.wildcard', specificRoutingKey);
487
+ console.log(`🔓 ScheduleDateAgent unbind: ${specificRoutingKey}`);
488
+
489
+ const nextAgentKey = getNextAgent('scheduleDate', phone);
490
+
491
+ if (nextAgentKey) {
492
+ const nextPayload: MessagePayload = {
493
+ phone: phone,
494
+ timestamp: Date.now(),
495
+ metadata: {
496
+ identification: 'scheduleDate',
497
+ senderAgent: 'ScheduleDateAgent',
498
+ value: processedValue
499
+ }
500
+ };
501
+
502
+ console.log(`📤 ScheduleDateAgent enviando para: ${nextAgentKey}`);
503
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
504
+ } else {
505
+ // Finalizar fluxo
506
+ console.log(`🏁 ScheduleDateAgent finalizando fluxo para ${phone}`);
507
+
508
+ const finalPayload: MessagePayload = {
509
+ phone: phone,
510
+ timestamp: Date.now(),
511
+ metadata: {
512
+ identification: 'schedule_completed',
513
+ senderAgent: 'ScheduleDateAgent',
514
+ value: 'Agendamento completo finalizado',
515
+ userData: globalMemory.userData[phone] || {}
516
+ }
517
+ };
518
+
519
+ await sdk!.publish('whatsapp.message.text', 'send', finalPayload);
520
+ }
521
+ } catch (error) {
522
+ console.error('❌ Erro no ScheduleDateAgent:', error);
523
+ }
524
+ }, 100);
525
+
526
+ ack();
527
+ };
528
+
529
+ await sdk.subscribe('test.agents', 'queue-scheduleDate', 'scheduleDate', scheduleDateCallback);
530
+ console.log('✅ ScheduleDateAgent configurado\n');
531
+
532
+ // Configurar ScheduleDentistAgent
533
+ console.log('🤖 Configurando ScheduleDentistAgent...');
534
+ const scheduleDentistCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
535
+ console.log(`\n🤖 ScheduleDentistAgent processando:`, JSON.stringify(payload, null, 2));
536
+
537
+ const phone = payload.phone;
538
+ const processedValue = simulateDataProcessing('ScheduleDentistAgent', phone);
539
+
540
+ markStepAsSuccess(phone, 'scheduleDentist', processedValue);
541
+
542
+ setTimeout(async () => {
543
+ try {
544
+ const specificRoutingKey = `phone.${phone}`;
545
+ await sdk!.bind('queue-scheduleDentist', 'test.wildcard', specificRoutingKey);
546
+ console.log(`🔒 ScheduleDentistAgent bind: ${specificRoutingKey}`);
547
+
548
+ await new Promise(resolve => setTimeout(resolve, 1000));
549
+
550
+ await sdk!.unbind('queue-scheduleDentist', 'test.wildcard', specificRoutingKey);
551
+ console.log(`🔓 ScheduleDentistAgent unbind: ${specificRoutingKey}`);
552
+
553
+ const nextAgentKey = getNextAgent('scheduleDentist', phone);
554
+
555
+ if (nextAgentKey) {
556
+ const nextPayload: MessagePayload = {
557
+ phone: phone,
558
+ timestamp: Date.now(),
559
+ metadata: {
560
+ identification: 'scheduleDentist',
561
+ senderAgent: 'ScheduleDentistAgent',
562
+ value: processedValue
563
+ }
564
+ };
565
+
566
+ console.log(`📤 ScheduleDentistAgent enviando para: ${nextAgentKey}`);
567
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
568
+ } else {
569
+ // Finalizar fluxo
570
+ console.log(`🏁 ScheduleDentistAgent finalizando fluxo para ${phone}`);
571
+
572
+ const finalPayload: MessagePayload = {
573
+ phone: phone,
574
+ timestamp: Date.now(),
575
+ metadata: {
576
+ identification: 'schedule_completed',
577
+ senderAgent: 'ScheduleDentistAgent',
578
+ value: 'Agendamento completo finalizado',
579
+ userData: globalMemory.userData[phone] || {}
580
+ }
581
+ };
582
+
583
+ await sdk!.publish('whatsapp.message.text', 'send', finalPayload);
584
+ }
585
+ } catch (error) {
586
+ console.error('❌ Erro no ScheduleDentistAgent:', error);
587
+ }
588
+ }, 100);
589
+
590
+ ack();
591
+ };
592
+
593
+ await sdk.subscribe('test.agents', 'queue-scheduleDentist', 'scheduleDentist', scheduleDentistCallback);
594
+ console.log('✅ ScheduleDentistAgent configurado\n');
595
+
596
+ // Configurar ScheduleServiceAgent
597
+ console.log('🤖 Configurando ScheduleServiceAgent...');
598
+ const scheduleServiceCallback: MessageCallback = (payload: MessagePayload, ack: () => void, nack: () => void) => {
599
+ console.log(`\n🤖 ScheduleServiceAgent processando:`, JSON.stringify(payload, null, 2));
600
+
601
+ const phone = payload.phone;
602
+ const processedValue = simulateDataProcessing('ScheduleServiceAgent', phone);
603
+
604
+ markStepAsSuccess(phone, 'scheduleService', processedValue);
605
+
606
+ setTimeout(async () => {
607
+ try {
608
+ const specificRoutingKey = `phone.${phone}`;
609
+ await sdk!.bind('queue-scheduleService', 'test.wildcard', specificRoutingKey);
610
+ console.log(`🔒 ScheduleServiceAgent bind: ${specificRoutingKey}`);
611
+
612
+ await new Promise(resolve => setTimeout(resolve, 1000));
613
+
614
+ await sdk!.unbind('queue-scheduleService', 'test.wildcard', specificRoutingKey);
615
+ console.log(`🔓 ScheduleServiceAgent unbind: ${specificRoutingKey}`);
616
+
617
+ const nextAgentKey = getNextAgent('scheduleService', phone);
618
+
619
+ if (nextAgentKey) {
620
+ const nextPayload: MessagePayload = {
621
+ phone: phone,
622
+ timestamp: Date.now(),
623
+ metadata: {
624
+ identification: 'scheduleService',
625
+ senderAgent: 'ScheduleServiceAgent',
626
+ value: processedValue
627
+ }
628
+ };
629
+
630
+ console.log(`📤 ScheduleServiceAgent enviando para: ${nextAgentKey}`);
631
+ await sdk!.publish('test.agents', nextAgentKey, nextPayload);
632
+ } else {
633
+ // Finalizar fluxo
634
+ console.log(`🏁 ScheduleServiceAgent finalizando fluxo para ${phone}`);
635
+
636
+ const finalPayload: MessagePayload = {
637
+ phone: phone,
638
+ timestamp: Date.now(),
639
+ metadata: {
640
+ identification: 'schedule_completed',
641
+ senderAgent: 'ScheduleServiceAgent',
642
+ value: 'Agendamento completo finalizado',
643
+ userData: globalMemory.userData[phone] || {}
644
+ }
645
+ };
646
+
647
+ await sdk!.publish('whatsapp.message.text', 'send', finalPayload);
648
+ }
649
+ } catch (error) {
650
+ console.error('❌ Erro no ScheduleServiceAgent:', error);
651
+ }
652
+ }, 100);
653
+
654
+ ack();
655
+ };
656
+
657
+ await sdk.subscribe('test.agents', 'queue-scheduleService', 'scheduleService', scheduleServiceCallback);
658
+ console.log('✅ ScheduleServiceAgent configurado\n');
659
+
660
+ // Aguardar configuração
661
+ console.log('⏳ Aguardando 5 segundos para todos os agentes ficarem ativos...');
662
+ await new Promise<void>(resolve => setTimeout(resolve, 5000));
663
+
664
+ // Enviar mensagens de teste para os 3 cenários
665
+ console.log('\n🦷 Iniciando fluxo para os 3 cenários de agendamento...');
666
+
667
+ const testPhones = [
668
+ '5511999991111', // Escolherá opção 1 (Data primeiro)
669
+ '5511999992222', // Escolherá opção 2 (Dentista primeiro)
670
+ '5511999993333' // Escolherá opção 3 (Serviço primeiro)
671
+ ];
672
+
673
+ for (const phone of testPhones) {
674
+ console.log(`\n🔥 Iniciando fluxo para telefone: ${phone}`);
675
+
676
+ const initialPayload: MessagePayload = {
677
+ phone: phone,
678
+ timestamp: Date.now(),
679
+ metadata: {
680
+ identification: 'initial',
681
+ senderAgent: 'TestSystem',
682
+ value: 'Mensagem inicial do sistema de agendamento'
683
+ }
684
+ };
685
+
686
+ await sdk.publish('test.wildcard', `phone.${phone}`, initialPayload);
687
+
688
+ // Aguardar entre telefones
689
+ await new Promise<void>(resolve => setTimeout(resolve, 5000));
690
+ }
691
+
692
+ // Aguardar processamento completo
693
+ console.log('\n⏳ Aguardando processamento completo (30 segundos)...');
694
+ await new Promise<void>(resolve => setTimeout(resolve, 30000));
695
+
696
+ console.log('\n🎉 Teste concluído!');
697
+ console.log('\n📊 Estado final da memória global:');
698
+ console.log(JSON.stringify(globalMemory, null, 2));
699
+
700
+ } catch (error) {
701
+ console.error('❌ Erro:', error);
702
+ } finally {
703
+ if (sdk) {
704
+ await sdk.disconnect();
705
+ }
706
+ }
707
+ }
708
+
709
+ if (require.main === module) {
710
+ testScheduleFlow().catch(console.error);
711
+ }
712
+
713
+ export { testScheduleFlow };