legend-transactional 2.2.2 → 2.3.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/index.d.mts +202 -4
- package/dist/index.d.ts +202 -4
- package/dist/index.js +171 -12
- package/dist/index.mjs +169 -13
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -72,6 +72,12 @@ declare const availableMicroservices: {
|
|
|
72
72
|
* Represents the "legend-storage" microservice.
|
|
73
73
|
*/
|
|
74
74
|
readonly Storage: "legend-storage";
|
|
75
|
+
/**
|
|
76
|
+
* Represents the "audit-eda" microservice for event-driven architecture auditing.
|
|
77
|
+
* This microservice consumes audit events (audit.received, audit.processed, audit.dead_letter)
|
|
78
|
+
* to track event lifecycle and debugging purposes.
|
|
79
|
+
*/
|
|
80
|
+
readonly AuditEda: "audit-eda";
|
|
75
81
|
};
|
|
76
82
|
/**
|
|
77
83
|
* Type of available microservices in the system.
|
|
@@ -345,6 +351,17 @@ interface EventPayload {
|
|
|
345
351
|
'legend_rankings.rankings_finished': {
|
|
346
352
|
completedRankings: CompletedRanking[];
|
|
347
353
|
};
|
|
354
|
+
/**
|
|
355
|
+
* Event to deliver intermediate reward (e.g., first game)
|
|
356
|
+
*/
|
|
357
|
+
'legend_rankings.intermediate_reward': {
|
|
358
|
+
userId: string;
|
|
359
|
+
rankingId: number;
|
|
360
|
+
intermediateRewardType: string;
|
|
361
|
+
rewardConfig: Record<string, unknown>;
|
|
362
|
+
templateName: string;
|
|
363
|
+
templateData: Record<string, unknown>;
|
|
364
|
+
};
|
|
348
365
|
/**
|
|
349
366
|
* Event to notify when a ranking is created
|
|
350
367
|
*/
|
|
@@ -449,6 +466,89 @@ interface EventPayload {
|
|
|
449
466
|
bucketName: string;
|
|
450
467
|
filePaths: string[];
|
|
451
468
|
};
|
|
469
|
+
/**
|
|
470
|
+
* Emitted when an event is received by a microservice before processing starts (audit tracking)
|
|
471
|
+
*/
|
|
472
|
+
'audit.received': {
|
|
473
|
+
/**
|
|
474
|
+
* The microservice that received the event
|
|
475
|
+
*/
|
|
476
|
+
microservice: string;
|
|
477
|
+
/**
|
|
478
|
+
* The event that was received
|
|
479
|
+
*/
|
|
480
|
+
receivedEvent: string;
|
|
481
|
+
/**
|
|
482
|
+
* Timestamp when the event was received (UNIX timestamp in seconds)
|
|
483
|
+
*/
|
|
484
|
+
receivedAt: number;
|
|
485
|
+
/**
|
|
486
|
+
* The queue name from which the event was consumed
|
|
487
|
+
*/
|
|
488
|
+
queueName: string;
|
|
489
|
+
/**
|
|
490
|
+
* Optional event identifier for tracking
|
|
491
|
+
*/
|
|
492
|
+
eventId?: string;
|
|
493
|
+
};
|
|
494
|
+
/**
|
|
495
|
+
* Emitted when an event is successfully processed by a microservice for audit tracking
|
|
496
|
+
*/
|
|
497
|
+
'audit.processed': {
|
|
498
|
+
/**
|
|
499
|
+
* The microservice that processed the event
|
|
500
|
+
*/
|
|
501
|
+
microservice: string;
|
|
502
|
+
/**
|
|
503
|
+
* The original event that was processed
|
|
504
|
+
*/
|
|
505
|
+
processedEvent: string;
|
|
506
|
+
/**
|
|
507
|
+
* Timestamp when the event was processed (UNIX timestamp in seconds)
|
|
508
|
+
*/
|
|
509
|
+
processedAt: number;
|
|
510
|
+
/**
|
|
511
|
+
* The queue name where the event was consumed
|
|
512
|
+
*/
|
|
513
|
+
queueName: string;
|
|
514
|
+
/**
|
|
515
|
+
* Optional event identifier for tracking
|
|
516
|
+
*/
|
|
517
|
+
eventId?: string;
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Emitted when a message is rejected/nacked and sent to dead letter queue
|
|
521
|
+
*/
|
|
522
|
+
'audit.dead_letter': {
|
|
523
|
+
/**
|
|
524
|
+
* The microservice that rejected the event
|
|
525
|
+
*/
|
|
526
|
+
microservice: string;
|
|
527
|
+
/**
|
|
528
|
+
* The original event that was rejected
|
|
529
|
+
*/
|
|
530
|
+
rejectedEvent: string;
|
|
531
|
+
/**
|
|
532
|
+
* Timestamp when the event was rejected (UNIX timestamp in seconds)
|
|
533
|
+
*/
|
|
534
|
+
rejectedAt: number;
|
|
535
|
+
/**
|
|
536
|
+
* The queue name where the event was rejected from
|
|
537
|
+
*/
|
|
538
|
+
queueName: string;
|
|
539
|
+
/**
|
|
540
|
+
* Reason for rejection (delay, fibonacci_strategy, etc.)
|
|
541
|
+
*/
|
|
542
|
+
rejectionReason: 'delay' | 'fibonacci_strategy';
|
|
543
|
+
/**
|
|
544
|
+
* Optional retry count
|
|
545
|
+
*/
|
|
546
|
+
retryCount?: number;
|
|
547
|
+
/**
|
|
548
|
+
* Optional event identifier for tracking
|
|
549
|
+
*/
|
|
550
|
+
eventId?: string;
|
|
551
|
+
};
|
|
452
552
|
}
|
|
453
553
|
/**
|
|
454
554
|
* Represents the available events in the system.
|
|
@@ -456,6 +556,9 @@ interface EventPayload {
|
|
|
456
556
|
declare const microserviceEvent: {
|
|
457
557
|
readonly 'TEST.IMAGE': "test.image";
|
|
458
558
|
readonly 'TEST.MINT': "test.mint";
|
|
559
|
+
readonly 'AUDIT.RECEIVED': "audit.received";
|
|
560
|
+
readonly 'AUDIT.PROCESSED': "audit.processed";
|
|
561
|
+
readonly 'AUDIT.DEAD_LETTER': "audit.dead_letter";
|
|
459
562
|
readonly 'AUTH.DELETED_USER': "auth.deleted_user";
|
|
460
563
|
readonly 'AUTH.LOGOUT_USER': "auth.logout_user";
|
|
461
564
|
readonly 'AUTH.NEW_USER': "auth.new_user";
|
|
@@ -472,6 +575,7 @@ declare const microserviceEvent: {
|
|
|
472
575
|
readonly 'LEGEND_MISSIONS.SEND_EMAIL_NFT_MISSION_COMPLETED': "legend_missions.send_email_nft_mission_completed";
|
|
473
576
|
readonly 'LEGEND_RANKINGS.RANKINGS_FINISHED': "legend_rankings.rankings_finished";
|
|
474
577
|
readonly 'LEGEND_RANKINGS.NEW_RANKING_CREATED': "legend_rankings.new_ranking_created";
|
|
578
|
+
readonly 'LEGEND_RANKINGS.INTERMEDIATE_REWARD': "legend_rankings.intermediate_reward";
|
|
475
579
|
readonly 'LEGEND_SHOWCASE.PRODUCT_VIRTUAL_DELETED': "legend_showcase.product_virtual_deleted";
|
|
476
580
|
readonly 'LEGEND_SHOWCASE.UPDATE_ALLOWED_MISSION_SUBSCRIPTION_IDS': "legend_showcase.update_allowed_mission_subscription_ids";
|
|
477
581
|
readonly 'LEGEND_SHOWCASE.UPDATE_ALLOWED_RANKING_SUBSCRIPTION_IDS': "legend_showcase.update_allowed_ranking_subscription_ids";
|
|
@@ -547,7 +651,7 @@ declare abstract class ConsumeChannel {
|
|
|
547
651
|
*
|
|
548
652
|
* @see NACKING_DELAY_MS
|
|
549
653
|
*/
|
|
550
|
-
nackWithDelay
|
|
654
|
+
nackWithDelay(delay?: number, maxRetries?: number): {
|
|
551
655
|
count: number;
|
|
552
656
|
delay: number;
|
|
553
657
|
};
|
|
@@ -564,7 +668,7 @@ declare abstract class ConsumeChannel {
|
|
|
564
668
|
* - `occurrence`: The current occurrence count for the Fibonacci sequence.
|
|
565
669
|
* @see MAX_OCCURRENCE
|
|
566
670
|
*/
|
|
567
|
-
nackWithFibonacciStrategy
|
|
671
|
+
nackWithFibonacciStrategy(maxOccurrence?: number, maxRetries?: number): {
|
|
568
672
|
count: number;
|
|
569
673
|
delay: number;
|
|
570
674
|
occurrence: number;
|
|
@@ -583,14 +687,48 @@ declare abstract class ConsumeChannel {
|
|
|
583
687
|
|
|
584
688
|
/**
|
|
585
689
|
* Represents a **_consume_** channel for handling saga events/commands.
|
|
586
|
-
* Extends the abstract ConsumeChannel class.
|
|
690
|
+
* Extends the abstract ConsumeChannel class with automatic audit event emission.
|
|
587
691
|
*
|
|
588
692
|
*/
|
|
589
693
|
declare class EventsConsumeChannel extends ConsumeChannel {
|
|
694
|
+
/**
|
|
695
|
+
* The microservice name that is processing the event
|
|
696
|
+
*/
|
|
697
|
+
private readonly microservice;
|
|
698
|
+
/**
|
|
699
|
+
* The original event that was received
|
|
700
|
+
*/
|
|
701
|
+
private readonly processedEvent;
|
|
702
|
+
/**
|
|
703
|
+
* Creates a new EventsConsumeChannel instance
|
|
704
|
+
*
|
|
705
|
+
* @param channel - The AMQP Channel
|
|
706
|
+
* @param msg - The consumed message
|
|
707
|
+
* @param queueName - The queue name
|
|
708
|
+
* @param microservice - The microservice name processing the event
|
|
709
|
+
* @param processedEvent - The event type being processed
|
|
710
|
+
*/
|
|
711
|
+
constructor(channel: Channel, msg: ConsumeMessage, queueName: string, microservice: string, processedEvent: string);
|
|
590
712
|
/**
|
|
591
713
|
* Acknowledges the consumed saga event/command.
|
|
714
|
+
* Automatically emits audit.processed event after successful ACK.
|
|
592
715
|
*/
|
|
593
716
|
ackMessage(): void;
|
|
717
|
+
/**
|
|
718
|
+
* Override nackWithDelay to emit audit.dead_letter event
|
|
719
|
+
*/
|
|
720
|
+
nackWithDelay(delay?: number, maxRetries?: number): {
|
|
721
|
+
count: number;
|
|
722
|
+
delay: number;
|
|
723
|
+
};
|
|
724
|
+
/**
|
|
725
|
+
* Override nackWithFibonacciStrategy to emit audit.dead_letter event
|
|
726
|
+
*/
|
|
727
|
+
nackWithFibonacciStrategy(maxOccurrence?: number, maxRetries?: number): {
|
|
728
|
+
count: number;
|
|
729
|
+
delay: number;
|
|
730
|
+
occurrence: number;
|
|
731
|
+
};
|
|
594
732
|
}
|
|
595
733
|
|
|
596
734
|
/**
|
|
@@ -611,6 +749,13 @@ type MicroserviceConsumeEvents<T extends MicroserviceEvent> = {
|
|
|
611
749
|
* Represents the names of specific message queues in the RabbitMQ context.
|
|
612
750
|
*/
|
|
613
751
|
declare const queue: {
|
|
752
|
+
/**
|
|
753
|
+
* Audit queue names for separate audit event types
|
|
754
|
+
* @constant
|
|
755
|
+
*/
|
|
756
|
+
readonly AuditReceived: "audit_received_commands";
|
|
757
|
+
readonly AuditProcessed: "audit_processed_commands";
|
|
758
|
+
readonly AuditDeadLetter: "audit_dead_letter_commands";
|
|
614
759
|
/**
|
|
615
760
|
* Queue used for sending replies in response to saga events.
|
|
616
761
|
*/
|
|
@@ -624,6 +769,10 @@ declare const queue: {
|
|
|
624
769
|
* Represents the names of exchanges, which act as message routing hubs in the RabbitMQ context.
|
|
625
770
|
*/
|
|
626
771
|
declare const exchange: {
|
|
772
|
+
/**
|
|
773
|
+
* Audit exchange name for direct routing of audit events
|
|
774
|
+
*/
|
|
775
|
+
readonly Audit: "audit_exchange";
|
|
627
776
|
/**
|
|
628
777
|
* Exchange dedicated to requeueing messages that require further processing in a saga process
|
|
629
778
|
*/
|
|
@@ -681,6 +830,15 @@ declare const authCommands: {
|
|
|
681
830
|
*/
|
|
682
831
|
type AuthCommands = (typeof authCommands)[keyof typeof authCommands];
|
|
683
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Different commands related to the "audit-eda" microservice.
|
|
835
|
+
*/
|
|
836
|
+
declare const auditEdaCommands: {};
|
|
837
|
+
/**
|
|
838
|
+
* Available commands for the "audit-eda" microservice.
|
|
839
|
+
*/
|
|
840
|
+
type AuditEdaCommands = (typeof auditEdaCommands)[keyof typeof auditEdaCommands];
|
|
841
|
+
|
|
684
842
|
/**
|
|
685
843
|
* Different commands related to the "blockchain" microservice.
|
|
686
844
|
*/
|
|
@@ -895,6 +1053,10 @@ interface CommandMap {
|
|
|
895
1053
|
* Represents the mapping of "auth" microservice commands.
|
|
896
1054
|
*/
|
|
897
1055
|
[availableMicroservices.Auth]: AuthCommands;
|
|
1056
|
+
/**
|
|
1057
|
+
* Represents the mapping of "audit-eda" microservice commands.
|
|
1058
|
+
*/
|
|
1059
|
+
[availableMicroservices.AuditEda]: AuditEdaCommands;
|
|
898
1060
|
/**
|
|
899
1061
|
* Represents the mapping of "blockchain" microservice commands.
|
|
900
1062
|
*/
|
|
@@ -1160,6 +1322,24 @@ declare const createConsumers: (consumers: QueueConsumerProps[]) => Promise<void
|
|
|
1160
1322
|
*/
|
|
1161
1323
|
declare const createHeaderConsumers: (queueName: string, events: MicroserviceEvent[]) => Promise<void>;
|
|
1162
1324
|
|
|
1325
|
+
/**
|
|
1326
|
+
* Creates audit logging infrastructure with direct exchange and separate queues
|
|
1327
|
+
* Uses direct exchange for efficient single-consumer delivery to audit microservice
|
|
1328
|
+
*
|
|
1329
|
+
* This function sets up the RabbitMQ infrastructure needed for audit event tracking:
|
|
1330
|
+
* - Creates a direct exchange for audit events
|
|
1331
|
+
* - Creates 3 separate queues (audit.received, audit.processed, audit.dead_letter)
|
|
1332
|
+
* - Binds each queue to the audit exchange with appropriate routing keys
|
|
1333
|
+
*
|
|
1334
|
+
* The direct exchange strategy ensures that:
|
|
1335
|
+
* - Only the audit microservice consumes audit events
|
|
1336
|
+
* - Routing is efficient (no pattern matching needed)
|
|
1337
|
+
* - Each audit event type has its own queue for isolation
|
|
1338
|
+
*
|
|
1339
|
+
* @internal This is called automatically when connecting to events
|
|
1340
|
+
*/
|
|
1341
|
+
declare const createAuditLoggingResources: () => Promise<void>;
|
|
1342
|
+
|
|
1163
1343
|
declare const sagaTitle: {
|
|
1164
1344
|
/**
|
|
1165
1345
|
* Saga used in the flow to purchase resources and deduct coins from the user.
|
|
@@ -1745,4 +1925,22 @@ declare const getEventObject: (event: MicroserviceEvent) => {
|
|
|
1745
1925
|
[x: string]: MicroserviceEvent;
|
|
1746
1926
|
};
|
|
1747
1927
|
|
|
1748
|
-
|
|
1928
|
+
/**
|
|
1929
|
+
* Extracts the microservice name from a queue name
|
|
1930
|
+
*
|
|
1931
|
+
* Queue names follow the pattern: `{microservice}_match_commands` or `{microservice}_saga_commands`
|
|
1932
|
+
* This utility extracts the microservice part from the queue name.
|
|
1933
|
+
*
|
|
1934
|
+
* @param queueName - The queue name (e.g., 'auth_match_commands', 'coins_saga_commands')
|
|
1935
|
+
* @returns The microservice name (e.g., 'auth', 'coins')
|
|
1936
|
+
*
|
|
1937
|
+
* @example
|
|
1938
|
+
* ```typescript
|
|
1939
|
+
* extractMicroserviceFromQueue('auth_match_commands'); // Returns: 'auth'
|
|
1940
|
+
* extractMicroserviceFromQueue('coins_saga_commands'); // Returns: 'coins'
|
|
1941
|
+
* extractMicroserviceFromQueue('audit-eda_match_commands'); // Returns: 'audit-eda'
|
|
1942
|
+
* ```
|
|
1943
|
+
*/
|
|
1944
|
+
declare function extractMicroserviceFromQueue(queueName: string): string;
|
|
1945
|
+
|
|
1946
|
+
export { type AuditEdaCommands, type AuthCommands, type AvailableMicroservices, type BlockchainCommands, type CoinsCommands, type CommandMap, type CommenceSaga, type CommenceSagaEvents, type CommenceSagaHandler, type CompletedRanking, type EventPayload, EventsConsumeChannel, type EventsHandler, type Exchange, type Gender, MAX_NACK_RETRIES, MAX_OCCURRENCE, type MicroserviceCommand, MicroserviceConsumeChannel, type MicroserviceConsumeEvents, type MicroserviceConsumeSagaEvents, type MicroserviceEvent, type MicroserviceHandler, NACKING_DELAY_MS, type Nack, type PaymentEmailType, PaymentEmailTypes, type QueueConsumerProps, type RankingWinners, type RankingsCommands, type RapidMessagingCommands, type Room, type RoomCreatorCommands, type RoomInventoryCommands, type RoomSnapshotCommands, type RoomType, RoomTypes, Saga, SagaCommenceConsumeChannel, type SagaCommencePayload, SagaConsumeChannel, type SagaConsumeSagaEvents, type SagaHandler, type SagaStep, type SagaStepDefaults, type SagaTitle, type SendEmailCommands, type ShowcaseCommands, type SocialCommands, type SocialMediaRoomsCommands, type SocialUser, type Status, type StorageCommands, type TestImageCommands, type TestMintCommands, Transactional, type TransactionalConfig, type UserLocation, auditEdaCommands, authCommands, availableMicroservices, blockchainCommands, closeConsumeChannel, closeRabbitMQConn, closeSendChannel, coinsCommands, commenceSaga, commenceSagaConsumeCallback, commenceSagaListener, connectToEvents, connectToSagaCommandEmitter, consume, createAuditLoggingResources, createConsumers, createHeaderConsumers, eventCallback, exchange, extractMicroserviceFromQueue, fibonacci, gender, getConsumeChannel, getEventKey, getEventObject, getQueueConsumer, getQueueName, getRabbitMQConn, getSendChannel, isConnectionHealthy, microserviceEvent, nodeDataDefaults, publishEvent, queue, rankingsCommands, rapidMessagingCommands, roomCreatorCommands, roomInventoryCommands, roomSnapshotCommands, sagaConsumeCallback, sagaStepCallback, sagaTitle, saveQueueForHealthCheck, saveUri, sendEmailCommands, sendToQueue, showcaseCommands, socialCommands, socialMediaRoomsCommands, startGlobalSagaStepListener, status, stopRabbitMQ, storageCommands, testImageCommands, testMintCommands };
|
package/dist/index.d.ts
CHANGED
|
@@ -72,6 +72,12 @@ declare const availableMicroservices: {
|
|
|
72
72
|
* Represents the "legend-storage" microservice.
|
|
73
73
|
*/
|
|
74
74
|
readonly Storage: "legend-storage";
|
|
75
|
+
/**
|
|
76
|
+
* Represents the "audit-eda" microservice for event-driven architecture auditing.
|
|
77
|
+
* This microservice consumes audit events (audit.received, audit.processed, audit.dead_letter)
|
|
78
|
+
* to track event lifecycle and debugging purposes.
|
|
79
|
+
*/
|
|
80
|
+
readonly AuditEda: "audit-eda";
|
|
75
81
|
};
|
|
76
82
|
/**
|
|
77
83
|
* Type of available microservices in the system.
|
|
@@ -345,6 +351,17 @@ interface EventPayload {
|
|
|
345
351
|
'legend_rankings.rankings_finished': {
|
|
346
352
|
completedRankings: CompletedRanking[];
|
|
347
353
|
};
|
|
354
|
+
/**
|
|
355
|
+
* Event to deliver intermediate reward (e.g., first game)
|
|
356
|
+
*/
|
|
357
|
+
'legend_rankings.intermediate_reward': {
|
|
358
|
+
userId: string;
|
|
359
|
+
rankingId: number;
|
|
360
|
+
intermediateRewardType: string;
|
|
361
|
+
rewardConfig: Record<string, unknown>;
|
|
362
|
+
templateName: string;
|
|
363
|
+
templateData: Record<string, unknown>;
|
|
364
|
+
};
|
|
348
365
|
/**
|
|
349
366
|
* Event to notify when a ranking is created
|
|
350
367
|
*/
|
|
@@ -449,6 +466,89 @@ interface EventPayload {
|
|
|
449
466
|
bucketName: string;
|
|
450
467
|
filePaths: string[];
|
|
451
468
|
};
|
|
469
|
+
/**
|
|
470
|
+
* Emitted when an event is received by a microservice before processing starts (audit tracking)
|
|
471
|
+
*/
|
|
472
|
+
'audit.received': {
|
|
473
|
+
/**
|
|
474
|
+
* The microservice that received the event
|
|
475
|
+
*/
|
|
476
|
+
microservice: string;
|
|
477
|
+
/**
|
|
478
|
+
* The event that was received
|
|
479
|
+
*/
|
|
480
|
+
receivedEvent: string;
|
|
481
|
+
/**
|
|
482
|
+
* Timestamp when the event was received (UNIX timestamp in seconds)
|
|
483
|
+
*/
|
|
484
|
+
receivedAt: number;
|
|
485
|
+
/**
|
|
486
|
+
* The queue name from which the event was consumed
|
|
487
|
+
*/
|
|
488
|
+
queueName: string;
|
|
489
|
+
/**
|
|
490
|
+
* Optional event identifier for tracking
|
|
491
|
+
*/
|
|
492
|
+
eventId?: string;
|
|
493
|
+
};
|
|
494
|
+
/**
|
|
495
|
+
* Emitted when an event is successfully processed by a microservice for audit tracking
|
|
496
|
+
*/
|
|
497
|
+
'audit.processed': {
|
|
498
|
+
/**
|
|
499
|
+
* The microservice that processed the event
|
|
500
|
+
*/
|
|
501
|
+
microservice: string;
|
|
502
|
+
/**
|
|
503
|
+
* The original event that was processed
|
|
504
|
+
*/
|
|
505
|
+
processedEvent: string;
|
|
506
|
+
/**
|
|
507
|
+
* Timestamp when the event was processed (UNIX timestamp in seconds)
|
|
508
|
+
*/
|
|
509
|
+
processedAt: number;
|
|
510
|
+
/**
|
|
511
|
+
* The queue name where the event was consumed
|
|
512
|
+
*/
|
|
513
|
+
queueName: string;
|
|
514
|
+
/**
|
|
515
|
+
* Optional event identifier for tracking
|
|
516
|
+
*/
|
|
517
|
+
eventId?: string;
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Emitted when a message is rejected/nacked and sent to dead letter queue
|
|
521
|
+
*/
|
|
522
|
+
'audit.dead_letter': {
|
|
523
|
+
/**
|
|
524
|
+
* The microservice that rejected the event
|
|
525
|
+
*/
|
|
526
|
+
microservice: string;
|
|
527
|
+
/**
|
|
528
|
+
* The original event that was rejected
|
|
529
|
+
*/
|
|
530
|
+
rejectedEvent: string;
|
|
531
|
+
/**
|
|
532
|
+
* Timestamp when the event was rejected (UNIX timestamp in seconds)
|
|
533
|
+
*/
|
|
534
|
+
rejectedAt: number;
|
|
535
|
+
/**
|
|
536
|
+
* The queue name where the event was rejected from
|
|
537
|
+
*/
|
|
538
|
+
queueName: string;
|
|
539
|
+
/**
|
|
540
|
+
* Reason for rejection (delay, fibonacci_strategy, etc.)
|
|
541
|
+
*/
|
|
542
|
+
rejectionReason: 'delay' | 'fibonacci_strategy';
|
|
543
|
+
/**
|
|
544
|
+
* Optional retry count
|
|
545
|
+
*/
|
|
546
|
+
retryCount?: number;
|
|
547
|
+
/**
|
|
548
|
+
* Optional event identifier for tracking
|
|
549
|
+
*/
|
|
550
|
+
eventId?: string;
|
|
551
|
+
};
|
|
452
552
|
}
|
|
453
553
|
/**
|
|
454
554
|
* Represents the available events in the system.
|
|
@@ -456,6 +556,9 @@ interface EventPayload {
|
|
|
456
556
|
declare const microserviceEvent: {
|
|
457
557
|
readonly 'TEST.IMAGE': "test.image";
|
|
458
558
|
readonly 'TEST.MINT': "test.mint";
|
|
559
|
+
readonly 'AUDIT.RECEIVED': "audit.received";
|
|
560
|
+
readonly 'AUDIT.PROCESSED': "audit.processed";
|
|
561
|
+
readonly 'AUDIT.DEAD_LETTER': "audit.dead_letter";
|
|
459
562
|
readonly 'AUTH.DELETED_USER': "auth.deleted_user";
|
|
460
563
|
readonly 'AUTH.LOGOUT_USER': "auth.logout_user";
|
|
461
564
|
readonly 'AUTH.NEW_USER': "auth.new_user";
|
|
@@ -472,6 +575,7 @@ declare const microserviceEvent: {
|
|
|
472
575
|
readonly 'LEGEND_MISSIONS.SEND_EMAIL_NFT_MISSION_COMPLETED': "legend_missions.send_email_nft_mission_completed";
|
|
473
576
|
readonly 'LEGEND_RANKINGS.RANKINGS_FINISHED': "legend_rankings.rankings_finished";
|
|
474
577
|
readonly 'LEGEND_RANKINGS.NEW_RANKING_CREATED': "legend_rankings.new_ranking_created";
|
|
578
|
+
readonly 'LEGEND_RANKINGS.INTERMEDIATE_REWARD': "legend_rankings.intermediate_reward";
|
|
475
579
|
readonly 'LEGEND_SHOWCASE.PRODUCT_VIRTUAL_DELETED': "legend_showcase.product_virtual_deleted";
|
|
476
580
|
readonly 'LEGEND_SHOWCASE.UPDATE_ALLOWED_MISSION_SUBSCRIPTION_IDS': "legend_showcase.update_allowed_mission_subscription_ids";
|
|
477
581
|
readonly 'LEGEND_SHOWCASE.UPDATE_ALLOWED_RANKING_SUBSCRIPTION_IDS': "legend_showcase.update_allowed_ranking_subscription_ids";
|
|
@@ -547,7 +651,7 @@ declare abstract class ConsumeChannel {
|
|
|
547
651
|
*
|
|
548
652
|
* @see NACKING_DELAY_MS
|
|
549
653
|
*/
|
|
550
|
-
nackWithDelay
|
|
654
|
+
nackWithDelay(delay?: number, maxRetries?: number): {
|
|
551
655
|
count: number;
|
|
552
656
|
delay: number;
|
|
553
657
|
};
|
|
@@ -564,7 +668,7 @@ declare abstract class ConsumeChannel {
|
|
|
564
668
|
* - `occurrence`: The current occurrence count for the Fibonacci sequence.
|
|
565
669
|
* @see MAX_OCCURRENCE
|
|
566
670
|
*/
|
|
567
|
-
nackWithFibonacciStrategy
|
|
671
|
+
nackWithFibonacciStrategy(maxOccurrence?: number, maxRetries?: number): {
|
|
568
672
|
count: number;
|
|
569
673
|
delay: number;
|
|
570
674
|
occurrence: number;
|
|
@@ -583,14 +687,48 @@ declare abstract class ConsumeChannel {
|
|
|
583
687
|
|
|
584
688
|
/**
|
|
585
689
|
* Represents a **_consume_** channel for handling saga events/commands.
|
|
586
|
-
* Extends the abstract ConsumeChannel class.
|
|
690
|
+
* Extends the abstract ConsumeChannel class with automatic audit event emission.
|
|
587
691
|
*
|
|
588
692
|
*/
|
|
589
693
|
declare class EventsConsumeChannel extends ConsumeChannel {
|
|
694
|
+
/**
|
|
695
|
+
* The microservice name that is processing the event
|
|
696
|
+
*/
|
|
697
|
+
private readonly microservice;
|
|
698
|
+
/**
|
|
699
|
+
* The original event that was received
|
|
700
|
+
*/
|
|
701
|
+
private readonly processedEvent;
|
|
702
|
+
/**
|
|
703
|
+
* Creates a new EventsConsumeChannel instance
|
|
704
|
+
*
|
|
705
|
+
* @param channel - The AMQP Channel
|
|
706
|
+
* @param msg - The consumed message
|
|
707
|
+
* @param queueName - The queue name
|
|
708
|
+
* @param microservice - The microservice name processing the event
|
|
709
|
+
* @param processedEvent - The event type being processed
|
|
710
|
+
*/
|
|
711
|
+
constructor(channel: Channel, msg: ConsumeMessage, queueName: string, microservice: string, processedEvent: string);
|
|
590
712
|
/**
|
|
591
713
|
* Acknowledges the consumed saga event/command.
|
|
714
|
+
* Automatically emits audit.processed event after successful ACK.
|
|
592
715
|
*/
|
|
593
716
|
ackMessage(): void;
|
|
717
|
+
/**
|
|
718
|
+
* Override nackWithDelay to emit audit.dead_letter event
|
|
719
|
+
*/
|
|
720
|
+
nackWithDelay(delay?: number, maxRetries?: number): {
|
|
721
|
+
count: number;
|
|
722
|
+
delay: number;
|
|
723
|
+
};
|
|
724
|
+
/**
|
|
725
|
+
* Override nackWithFibonacciStrategy to emit audit.dead_letter event
|
|
726
|
+
*/
|
|
727
|
+
nackWithFibonacciStrategy(maxOccurrence?: number, maxRetries?: number): {
|
|
728
|
+
count: number;
|
|
729
|
+
delay: number;
|
|
730
|
+
occurrence: number;
|
|
731
|
+
};
|
|
594
732
|
}
|
|
595
733
|
|
|
596
734
|
/**
|
|
@@ -611,6 +749,13 @@ type MicroserviceConsumeEvents<T extends MicroserviceEvent> = {
|
|
|
611
749
|
* Represents the names of specific message queues in the RabbitMQ context.
|
|
612
750
|
*/
|
|
613
751
|
declare const queue: {
|
|
752
|
+
/**
|
|
753
|
+
* Audit queue names for separate audit event types
|
|
754
|
+
* @constant
|
|
755
|
+
*/
|
|
756
|
+
readonly AuditReceived: "audit_received_commands";
|
|
757
|
+
readonly AuditProcessed: "audit_processed_commands";
|
|
758
|
+
readonly AuditDeadLetter: "audit_dead_letter_commands";
|
|
614
759
|
/**
|
|
615
760
|
* Queue used for sending replies in response to saga events.
|
|
616
761
|
*/
|
|
@@ -624,6 +769,10 @@ declare const queue: {
|
|
|
624
769
|
* Represents the names of exchanges, which act as message routing hubs in the RabbitMQ context.
|
|
625
770
|
*/
|
|
626
771
|
declare const exchange: {
|
|
772
|
+
/**
|
|
773
|
+
* Audit exchange name for direct routing of audit events
|
|
774
|
+
*/
|
|
775
|
+
readonly Audit: "audit_exchange";
|
|
627
776
|
/**
|
|
628
777
|
* Exchange dedicated to requeueing messages that require further processing in a saga process
|
|
629
778
|
*/
|
|
@@ -681,6 +830,15 @@ declare const authCommands: {
|
|
|
681
830
|
*/
|
|
682
831
|
type AuthCommands = (typeof authCommands)[keyof typeof authCommands];
|
|
683
832
|
|
|
833
|
+
/**
|
|
834
|
+
* Different commands related to the "audit-eda" microservice.
|
|
835
|
+
*/
|
|
836
|
+
declare const auditEdaCommands: {};
|
|
837
|
+
/**
|
|
838
|
+
* Available commands for the "audit-eda" microservice.
|
|
839
|
+
*/
|
|
840
|
+
type AuditEdaCommands = (typeof auditEdaCommands)[keyof typeof auditEdaCommands];
|
|
841
|
+
|
|
684
842
|
/**
|
|
685
843
|
* Different commands related to the "blockchain" microservice.
|
|
686
844
|
*/
|
|
@@ -895,6 +1053,10 @@ interface CommandMap {
|
|
|
895
1053
|
* Represents the mapping of "auth" microservice commands.
|
|
896
1054
|
*/
|
|
897
1055
|
[availableMicroservices.Auth]: AuthCommands;
|
|
1056
|
+
/**
|
|
1057
|
+
* Represents the mapping of "audit-eda" microservice commands.
|
|
1058
|
+
*/
|
|
1059
|
+
[availableMicroservices.AuditEda]: AuditEdaCommands;
|
|
898
1060
|
/**
|
|
899
1061
|
* Represents the mapping of "blockchain" microservice commands.
|
|
900
1062
|
*/
|
|
@@ -1160,6 +1322,24 @@ declare const createConsumers: (consumers: QueueConsumerProps[]) => Promise<void
|
|
|
1160
1322
|
*/
|
|
1161
1323
|
declare const createHeaderConsumers: (queueName: string, events: MicroserviceEvent[]) => Promise<void>;
|
|
1162
1324
|
|
|
1325
|
+
/**
|
|
1326
|
+
* Creates audit logging infrastructure with direct exchange and separate queues
|
|
1327
|
+
* Uses direct exchange for efficient single-consumer delivery to audit microservice
|
|
1328
|
+
*
|
|
1329
|
+
* This function sets up the RabbitMQ infrastructure needed for audit event tracking:
|
|
1330
|
+
* - Creates a direct exchange for audit events
|
|
1331
|
+
* - Creates 3 separate queues (audit.received, audit.processed, audit.dead_letter)
|
|
1332
|
+
* - Binds each queue to the audit exchange with appropriate routing keys
|
|
1333
|
+
*
|
|
1334
|
+
* The direct exchange strategy ensures that:
|
|
1335
|
+
* - Only the audit microservice consumes audit events
|
|
1336
|
+
* - Routing is efficient (no pattern matching needed)
|
|
1337
|
+
* - Each audit event type has its own queue for isolation
|
|
1338
|
+
*
|
|
1339
|
+
* @internal This is called automatically when connecting to events
|
|
1340
|
+
*/
|
|
1341
|
+
declare const createAuditLoggingResources: () => Promise<void>;
|
|
1342
|
+
|
|
1163
1343
|
declare const sagaTitle: {
|
|
1164
1344
|
/**
|
|
1165
1345
|
* Saga used in the flow to purchase resources and deduct coins from the user.
|
|
@@ -1745,4 +1925,22 @@ declare const getEventObject: (event: MicroserviceEvent) => {
|
|
|
1745
1925
|
[x: string]: MicroserviceEvent;
|
|
1746
1926
|
};
|
|
1747
1927
|
|
|
1748
|
-
|
|
1928
|
+
/**
|
|
1929
|
+
* Extracts the microservice name from a queue name
|
|
1930
|
+
*
|
|
1931
|
+
* Queue names follow the pattern: `{microservice}_match_commands` or `{microservice}_saga_commands`
|
|
1932
|
+
* This utility extracts the microservice part from the queue name.
|
|
1933
|
+
*
|
|
1934
|
+
* @param queueName - The queue name (e.g., 'auth_match_commands', 'coins_saga_commands')
|
|
1935
|
+
* @returns The microservice name (e.g., 'auth', 'coins')
|
|
1936
|
+
*
|
|
1937
|
+
* @example
|
|
1938
|
+
* ```typescript
|
|
1939
|
+
* extractMicroserviceFromQueue('auth_match_commands'); // Returns: 'auth'
|
|
1940
|
+
* extractMicroserviceFromQueue('coins_saga_commands'); // Returns: 'coins'
|
|
1941
|
+
* extractMicroserviceFromQueue('audit-eda_match_commands'); // Returns: 'audit-eda'
|
|
1942
|
+
* ```
|
|
1943
|
+
*/
|
|
1944
|
+
declare function extractMicroserviceFromQueue(queueName: string): string;
|
|
1945
|
+
|
|
1946
|
+
export { type AuditEdaCommands, type AuthCommands, type AvailableMicroservices, type BlockchainCommands, type CoinsCommands, type CommandMap, type CommenceSaga, type CommenceSagaEvents, type CommenceSagaHandler, type CompletedRanking, type EventPayload, EventsConsumeChannel, type EventsHandler, type Exchange, type Gender, MAX_NACK_RETRIES, MAX_OCCURRENCE, type MicroserviceCommand, MicroserviceConsumeChannel, type MicroserviceConsumeEvents, type MicroserviceConsumeSagaEvents, type MicroserviceEvent, type MicroserviceHandler, NACKING_DELAY_MS, type Nack, type PaymentEmailType, PaymentEmailTypes, type QueueConsumerProps, type RankingWinners, type RankingsCommands, type RapidMessagingCommands, type Room, type RoomCreatorCommands, type RoomInventoryCommands, type RoomSnapshotCommands, type RoomType, RoomTypes, Saga, SagaCommenceConsumeChannel, type SagaCommencePayload, SagaConsumeChannel, type SagaConsumeSagaEvents, type SagaHandler, type SagaStep, type SagaStepDefaults, type SagaTitle, type SendEmailCommands, type ShowcaseCommands, type SocialCommands, type SocialMediaRoomsCommands, type SocialUser, type Status, type StorageCommands, type TestImageCommands, type TestMintCommands, Transactional, type TransactionalConfig, type UserLocation, auditEdaCommands, authCommands, availableMicroservices, blockchainCommands, closeConsumeChannel, closeRabbitMQConn, closeSendChannel, coinsCommands, commenceSaga, commenceSagaConsumeCallback, commenceSagaListener, connectToEvents, connectToSagaCommandEmitter, consume, createAuditLoggingResources, createConsumers, createHeaderConsumers, eventCallback, exchange, extractMicroserviceFromQueue, fibonacci, gender, getConsumeChannel, getEventKey, getEventObject, getQueueConsumer, getQueueName, getRabbitMQConn, getSendChannel, isConnectionHealthy, microserviceEvent, nodeDataDefaults, publishEvent, queue, rankingsCommands, rapidMessagingCommands, roomCreatorCommands, roomInventoryCommands, roomSnapshotCommands, sagaConsumeCallback, sagaStepCallback, sagaTitle, saveQueueForHealthCheck, saveUri, sendEmailCommands, sendToQueue, showcaseCommands, socialCommands, socialMediaRoomsCommands, startGlobalSagaStepListener, status, stopRabbitMQ, storageCommands, testImageCommands, testMintCommands };
|
package/dist/index.js
CHANGED
|
@@ -75,7 +75,13 @@ var availableMicroservices = {
|
|
|
75
75
|
/**
|
|
76
76
|
* Represents the "legend-storage" microservice.
|
|
77
77
|
*/
|
|
78
|
-
Storage: "legend-storage"
|
|
78
|
+
Storage: "legend-storage",
|
|
79
|
+
/**
|
|
80
|
+
* Represents the "audit-eda" microservice for event-driven architecture auditing.
|
|
81
|
+
* This microservice consumes audit events (audit.received, audit.processed, audit.dead_letter)
|
|
82
|
+
* to track event lifecycle and debugging purposes.
|
|
83
|
+
*/
|
|
84
|
+
AuditEda: "audit-eda"
|
|
79
85
|
};
|
|
80
86
|
|
|
81
87
|
// src/@types/event/events.ts
|
|
@@ -98,6 +104,11 @@ var microserviceEvent = {
|
|
|
98
104
|
"TEST.IMAGE": "test.image",
|
|
99
105
|
"TEST.MINT": "test.mint",
|
|
100
106
|
///////////////////////////
|
|
107
|
+
// AUDIT EVENTS - For tracking event lifecycle
|
|
108
|
+
"AUDIT.RECEIVED": "audit.received",
|
|
109
|
+
"AUDIT.PROCESSED": "audit.processed",
|
|
110
|
+
"AUDIT.DEAD_LETTER": "audit.dead_letter",
|
|
111
|
+
///////////////////////////
|
|
101
112
|
"AUTH.DELETED_USER": "auth.deleted_user",
|
|
102
113
|
"AUTH.LOGOUT_USER": "auth.logout_user",
|
|
103
114
|
"AUTH.NEW_USER": "auth.new_user",
|
|
@@ -114,6 +125,7 @@ var microserviceEvent = {
|
|
|
114
125
|
"LEGEND_MISSIONS.SEND_EMAIL_NFT_MISSION_COMPLETED": "legend_missions.send_email_nft_mission_completed",
|
|
115
126
|
"LEGEND_RANKINGS.RANKINGS_FINISHED": "legend_rankings.rankings_finished",
|
|
116
127
|
"LEGEND_RANKINGS.NEW_RANKING_CREATED": "legend_rankings.new_ranking_created",
|
|
128
|
+
"LEGEND_RANKINGS.INTERMEDIATE_REWARD": "legend_rankings.intermediate_reward",
|
|
117
129
|
"LEGEND_SHOWCASE.PRODUCT_VIRTUAL_DELETED": "legend_showcase.product_virtual_deleted",
|
|
118
130
|
"LEGEND_SHOWCASE.UPDATE_ALLOWED_MISSION_SUBSCRIPTION_IDS": "legend_showcase.update_allowed_mission_subscription_ids",
|
|
119
131
|
"LEGEND_SHOWCASE.UPDATE_ALLOWED_RANKING_SUBSCRIPTION_IDS": "legend_showcase.update_allowed_ranking_subscription_ids",
|
|
@@ -131,6 +143,13 @@ var microserviceEvent = {
|
|
|
131
143
|
|
|
132
144
|
// src/@types/rabbit-mq.ts
|
|
133
145
|
var queue = {
|
|
146
|
+
/**
|
|
147
|
+
* Audit queue names for separate audit event types
|
|
148
|
+
* @constant
|
|
149
|
+
*/
|
|
150
|
+
AuditReceived: "audit_received_commands",
|
|
151
|
+
AuditProcessed: "audit_processed_commands",
|
|
152
|
+
AuditDeadLetter: "audit_dead_letter_commands",
|
|
134
153
|
/**
|
|
135
154
|
* Queue used for sending replies in response to saga events.
|
|
136
155
|
*/
|
|
@@ -141,6 +160,10 @@ var queue = {
|
|
|
141
160
|
CommenceSaga: "commence_saga"
|
|
142
161
|
};
|
|
143
162
|
var exchange = {
|
|
163
|
+
/**
|
|
164
|
+
* Audit exchange name for direct routing of audit events
|
|
165
|
+
*/
|
|
166
|
+
Audit: "audit_exchange",
|
|
144
167
|
/**
|
|
145
168
|
* Exchange dedicated to requeueing messages that require further processing in a saga process
|
|
146
169
|
*/
|
|
@@ -175,6 +198,9 @@ var authCommands = {
|
|
|
175
198
|
CreateUser: "create_user"
|
|
176
199
|
};
|
|
177
200
|
|
|
201
|
+
// src/@types/saga/commands/audit-eda.ts
|
|
202
|
+
var auditEdaCommands = {};
|
|
203
|
+
|
|
178
204
|
// src/@types/saga/commands/blockchain.ts
|
|
179
205
|
var blockchainCommands = {
|
|
180
206
|
/**
|
|
@@ -457,6 +483,11 @@ var getEventObject = (event) => {
|
|
|
457
483
|
};
|
|
458
484
|
};
|
|
459
485
|
|
|
486
|
+
// src/utils/extractMicroservice.ts
|
|
487
|
+
function extractMicroserviceFromQueue(queueName) {
|
|
488
|
+
return queueName.replace(/_match_commands$/, "").replace(/_saga_commands$/, "");
|
|
489
|
+
}
|
|
490
|
+
|
|
460
491
|
// src/Consumer/channels/Consume.ts
|
|
461
492
|
var ConsumeChannel = class {
|
|
462
493
|
/**
|
|
@@ -496,10 +527,10 @@ var ConsumeChannel = class {
|
|
|
496
527
|
*
|
|
497
528
|
* @see NACKING_DELAY_MS
|
|
498
529
|
*/
|
|
499
|
-
nackWithDelay
|
|
530
|
+
nackWithDelay(delay = NACKING_DELAY_MS, maxRetries) {
|
|
500
531
|
const { delay: delayNackRetry, count } = this.nack({ delay, maxRetries });
|
|
501
532
|
return { count, delay: delayNackRetry };
|
|
502
|
-
}
|
|
533
|
+
}
|
|
503
534
|
/**
|
|
504
535
|
* Negatively acknowledges (NACKs) the message using a Fibonacci backoff strategy.
|
|
505
536
|
*
|
|
@@ -513,9 +544,9 @@ var ConsumeChannel = class {
|
|
|
513
544
|
* - `occurrence`: The current occurrence count for the Fibonacci sequence.
|
|
514
545
|
* @see MAX_OCCURRENCE
|
|
515
546
|
*/
|
|
516
|
-
nackWithFibonacciStrategy
|
|
547
|
+
nackWithFibonacciStrategy(maxOccurrence = MAX_OCCURRENCE, maxRetries) {
|
|
517
548
|
return this.nack({ maxOccurrence, maxRetries });
|
|
518
|
-
}
|
|
549
|
+
}
|
|
519
550
|
/**
|
|
520
551
|
* Private helper function to handle the actual NACK logic.
|
|
521
552
|
*
|
|
@@ -525,11 +556,7 @@ var ConsumeChannel = class {
|
|
|
525
556
|
* - `delay` and `maxRetries`: For linear backoff with a fixed delay and retry limit.
|
|
526
557
|
* - `maxOccurrence`: For Fibonacci backoff with a maximum occurrence count.
|
|
527
558
|
*/
|
|
528
|
-
nack
|
|
529
|
-
maxRetries,
|
|
530
|
-
maxOccurrence,
|
|
531
|
-
delay
|
|
532
|
-
}) => {
|
|
559
|
+
nack({ maxRetries, maxOccurrence, delay }) {
|
|
533
560
|
const { msg, queueName, channel } = this;
|
|
534
561
|
channel.nack(msg, false, false);
|
|
535
562
|
let count = 0;
|
|
@@ -586,7 +613,7 @@ var ConsumeChannel = class {
|
|
|
586
613
|
});
|
|
587
614
|
}
|
|
588
615
|
return { count, delay: nackDelay, occurrence };
|
|
589
|
-
}
|
|
616
|
+
}
|
|
590
617
|
};
|
|
591
618
|
var Consume_default = ConsumeChannel;
|
|
592
619
|
|
|
@@ -618,13 +645,109 @@ var commenceSagaConsumeCallback = (msg, channel, e, queueName) => {
|
|
|
618
645
|
e.emit(saga.title, { saga, channel: responseChannel });
|
|
619
646
|
};
|
|
620
647
|
|
|
648
|
+
// src/Broker/PublishAuditEvent.ts
|
|
649
|
+
async function publishAuditEvent(channel, eventType, payload) {
|
|
650
|
+
try {
|
|
651
|
+
const routingKey = eventType;
|
|
652
|
+
const messageBuffer = Buffer.from(JSON.stringify(payload));
|
|
653
|
+
channel.publish(exchange.Audit, routingKey, messageBuffer, {
|
|
654
|
+
contentType: "application/json",
|
|
655
|
+
deliveryMode: 2
|
|
656
|
+
// persistent
|
|
657
|
+
});
|
|
658
|
+
} catch (error) {
|
|
659
|
+
console.error(`Failed to publish audit event ${eventType}:`, error);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
async function publishAuditReceived(channel, payload) {
|
|
663
|
+
await publishAuditEvent(channel, "audit.received", payload);
|
|
664
|
+
}
|
|
665
|
+
async function publishAuditProcessed(channel, payload) {
|
|
666
|
+
await publishAuditEvent(channel, "audit.processed", payload);
|
|
667
|
+
}
|
|
668
|
+
async function publishAuditDeadLetter(channel, payload) {
|
|
669
|
+
await publishAuditEvent(channel, "audit.dead_letter", payload);
|
|
670
|
+
}
|
|
671
|
+
|
|
621
672
|
// src/Consumer/channels/Events.ts
|
|
622
673
|
var EventsConsumeChannel = class extends Consume_default {
|
|
674
|
+
/**
|
|
675
|
+
* The microservice name that is processing the event
|
|
676
|
+
*/
|
|
677
|
+
microservice;
|
|
678
|
+
/**
|
|
679
|
+
* The original event that was received
|
|
680
|
+
*/
|
|
681
|
+
processedEvent;
|
|
682
|
+
/**
|
|
683
|
+
* Creates a new EventsConsumeChannel instance
|
|
684
|
+
*
|
|
685
|
+
* @param channel - The AMQP Channel
|
|
686
|
+
* @param msg - The consumed message
|
|
687
|
+
* @param queueName - The queue name
|
|
688
|
+
* @param microservice - The microservice name processing the event
|
|
689
|
+
* @param processedEvent - The event type being processed
|
|
690
|
+
*/
|
|
691
|
+
constructor(channel, msg, queueName, microservice, processedEvent) {
|
|
692
|
+
super(channel, msg, queueName);
|
|
693
|
+
this.microservice = microservice;
|
|
694
|
+
this.processedEvent = processedEvent;
|
|
695
|
+
}
|
|
623
696
|
/**
|
|
624
697
|
* Acknowledges the consumed saga event/command.
|
|
698
|
+
* Automatically emits audit.processed event after successful ACK.
|
|
625
699
|
*/
|
|
626
700
|
ackMessage() {
|
|
627
701
|
this.channel.ack(this.msg, false);
|
|
702
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
703
|
+
publishAuditProcessed(this.channel, {
|
|
704
|
+
microservice: this.microservice,
|
|
705
|
+
processedEvent: this.processedEvent,
|
|
706
|
+
processedAt: timestamp,
|
|
707
|
+
queueName: this.queueName,
|
|
708
|
+
eventId: void 0
|
|
709
|
+
// Optional: can be enhanced later
|
|
710
|
+
}).catch((error) => {
|
|
711
|
+
console.error("Failed to emit audit.processed event:", error);
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Override nackWithDelay to emit audit.dead_letter event
|
|
716
|
+
*/
|
|
717
|
+
nackWithDelay(delay = NACKING_DELAY_MS, maxRetries) {
|
|
718
|
+
const parentNack = super.nackWithDelay(delay, maxRetries);
|
|
719
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
720
|
+
publishAuditDeadLetter(this.channel, {
|
|
721
|
+
microservice: this.microservice,
|
|
722
|
+
rejectedEvent: this.processedEvent,
|
|
723
|
+
rejectedAt: timestamp,
|
|
724
|
+
queueName: this.queueName,
|
|
725
|
+
rejectionReason: "delay",
|
|
726
|
+
retryCount: parentNack.count,
|
|
727
|
+
eventId: void 0
|
|
728
|
+
}).catch((error) => {
|
|
729
|
+
console.error("Failed to emit audit.dead_letter event:", error);
|
|
730
|
+
});
|
|
731
|
+
return parentNack;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Override nackWithFibonacciStrategy to emit audit.dead_letter event
|
|
735
|
+
*/
|
|
736
|
+
nackWithFibonacciStrategy(maxOccurrence = MAX_OCCURRENCE, maxRetries) {
|
|
737
|
+
const parentNack = super.nackWithFibonacciStrategy(maxOccurrence, maxRetries);
|
|
738
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
739
|
+
publishAuditDeadLetter(this.channel, {
|
|
740
|
+
microservice: this.microservice,
|
|
741
|
+
rejectedEvent: this.processedEvent,
|
|
742
|
+
rejectedAt: timestamp,
|
|
743
|
+
queueName: this.queueName,
|
|
744
|
+
rejectionReason: "fibonacci_strategy",
|
|
745
|
+
retryCount: parentNack.count,
|
|
746
|
+
eventId: void 0
|
|
747
|
+
}).catch((error) => {
|
|
748
|
+
console.error("Failed to emit audit.dead_letter event:", error);
|
|
749
|
+
});
|
|
750
|
+
return parentNack;
|
|
628
751
|
}
|
|
629
752
|
};
|
|
630
753
|
|
|
@@ -667,7 +790,20 @@ var eventCallback = (msg, channel, e, queueName) => {
|
|
|
667
790
|
{ headersReceived: headers, eventsDetected: event }
|
|
668
791
|
);
|
|
669
792
|
}
|
|
670
|
-
const
|
|
793
|
+
const microservice = extractMicroserviceFromQueue(queueName);
|
|
794
|
+
const receivedEvent = event[0];
|
|
795
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
796
|
+
publishAuditReceived(channel, {
|
|
797
|
+
microservice,
|
|
798
|
+
receivedEvent,
|
|
799
|
+
receivedAt: timestamp,
|
|
800
|
+
queueName,
|
|
801
|
+
eventId: void 0
|
|
802
|
+
// Optional: can be enhanced later with message ID tracking
|
|
803
|
+
}).catch((error) => {
|
|
804
|
+
console.error("Failed to emit audit.received event:", error);
|
|
805
|
+
});
|
|
806
|
+
const responseChannel = new EventsConsumeChannel(channel, msg, queueName, microservice, receivedEvent);
|
|
671
807
|
e.emit(event[0], { payload, channel: responseChannel });
|
|
672
808
|
};
|
|
673
809
|
|
|
@@ -834,6 +970,25 @@ var createHeaderConsumers = async (queueName, events) => {
|
|
|
834
970
|
}
|
|
835
971
|
}
|
|
836
972
|
};
|
|
973
|
+
|
|
974
|
+
// src/Consumer/auditInfrastructure.ts
|
|
975
|
+
var createAuditLoggingResources = async () => {
|
|
976
|
+
const channel = await getConsumeChannel();
|
|
977
|
+
await Promise.all([
|
|
978
|
+
// Create direct exchange for audit events
|
|
979
|
+
channel.assertExchange(exchange.Audit, "direct", { durable: true }),
|
|
980
|
+
// Create queues for audit events
|
|
981
|
+
channel.assertQueue(queue.AuditReceived, { durable: true }),
|
|
982
|
+
channel.assertQueue(queue.AuditProcessed, { durable: true }),
|
|
983
|
+
channel.assertQueue(queue.AuditDeadLetter, { durable: true })
|
|
984
|
+
]);
|
|
985
|
+
await Promise.all([
|
|
986
|
+
// Bind each queue to its specific routing key
|
|
987
|
+
channel.bindQueue(queue.AuditReceived, exchange.Audit, "audit.received"),
|
|
988
|
+
channel.bindQueue(queue.AuditProcessed, exchange.Audit, "audit.processed"),
|
|
989
|
+
channel.bindQueue(queue.AuditDeadLetter, exchange.Audit, "audit.dead_letter")
|
|
990
|
+
]);
|
|
991
|
+
};
|
|
837
992
|
var isReady = false;
|
|
838
993
|
var prepare = async (url2) => {
|
|
839
994
|
if (isReady) return;
|
|
@@ -893,6 +1048,7 @@ var connectToEvents = async (config) => {
|
|
|
893
1048
|
const queueName = `${config.microservice}_match_commands`;
|
|
894
1049
|
const e = mitt__default.default();
|
|
895
1050
|
await createHeaderConsumers(queueName, config.events);
|
|
1051
|
+
await createAuditLoggingResources();
|
|
896
1052
|
void consume(e, queueName, eventCallback);
|
|
897
1053
|
return e;
|
|
898
1054
|
};
|
|
@@ -978,6 +1134,7 @@ exports.Saga = Saga;
|
|
|
978
1134
|
exports.SagaCommenceConsumeChannel = SagaCommenceConsumeChannel;
|
|
979
1135
|
exports.SagaConsumeChannel = SagaConsumeChannel;
|
|
980
1136
|
exports.Transactional = Transactional;
|
|
1137
|
+
exports.auditEdaCommands = auditEdaCommands;
|
|
981
1138
|
exports.authCommands = authCommands;
|
|
982
1139
|
exports.availableMicroservices = availableMicroservices;
|
|
983
1140
|
exports.blockchainCommands = blockchainCommands;
|
|
@@ -991,10 +1148,12 @@ exports.commenceSagaListener = commenceSagaListener;
|
|
|
991
1148
|
exports.connectToEvents = connectToEvents;
|
|
992
1149
|
exports.connectToSagaCommandEmitter = connectToSagaCommandEmitter;
|
|
993
1150
|
exports.consume = consume;
|
|
1151
|
+
exports.createAuditLoggingResources = createAuditLoggingResources;
|
|
994
1152
|
exports.createConsumers = createConsumers;
|
|
995
1153
|
exports.createHeaderConsumers = createHeaderConsumers;
|
|
996
1154
|
exports.eventCallback = eventCallback;
|
|
997
1155
|
exports.exchange = exchange;
|
|
1156
|
+
exports.extractMicroserviceFromQueue = extractMicroserviceFromQueue;
|
|
998
1157
|
exports.fibonacci = fibonacci;
|
|
999
1158
|
exports.gender = gender;
|
|
1000
1159
|
exports.getConsumeChannel = getConsumeChannel;
|
package/dist/index.mjs
CHANGED
|
@@ -68,7 +68,13 @@ var availableMicroservices = {
|
|
|
68
68
|
/**
|
|
69
69
|
* Represents the "legend-storage" microservice.
|
|
70
70
|
*/
|
|
71
|
-
Storage: "legend-storage"
|
|
71
|
+
Storage: "legend-storage",
|
|
72
|
+
/**
|
|
73
|
+
* Represents the "audit-eda" microservice for event-driven architecture auditing.
|
|
74
|
+
* This microservice consumes audit events (audit.received, audit.processed, audit.dead_letter)
|
|
75
|
+
* to track event lifecycle and debugging purposes.
|
|
76
|
+
*/
|
|
77
|
+
AuditEda: "audit-eda"
|
|
72
78
|
};
|
|
73
79
|
|
|
74
80
|
// src/@types/event/events.ts
|
|
@@ -91,6 +97,11 @@ var microserviceEvent = {
|
|
|
91
97
|
"TEST.IMAGE": "test.image",
|
|
92
98
|
"TEST.MINT": "test.mint",
|
|
93
99
|
///////////////////////////
|
|
100
|
+
// AUDIT EVENTS - For tracking event lifecycle
|
|
101
|
+
"AUDIT.RECEIVED": "audit.received",
|
|
102
|
+
"AUDIT.PROCESSED": "audit.processed",
|
|
103
|
+
"AUDIT.DEAD_LETTER": "audit.dead_letter",
|
|
104
|
+
///////////////////////////
|
|
94
105
|
"AUTH.DELETED_USER": "auth.deleted_user",
|
|
95
106
|
"AUTH.LOGOUT_USER": "auth.logout_user",
|
|
96
107
|
"AUTH.NEW_USER": "auth.new_user",
|
|
@@ -107,6 +118,7 @@ var microserviceEvent = {
|
|
|
107
118
|
"LEGEND_MISSIONS.SEND_EMAIL_NFT_MISSION_COMPLETED": "legend_missions.send_email_nft_mission_completed",
|
|
108
119
|
"LEGEND_RANKINGS.RANKINGS_FINISHED": "legend_rankings.rankings_finished",
|
|
109
120
|
"LEGEND_RANKINGS.NEW_RANKING_CREATED": "legend_rankings.new_ranking_created",
|
|
121
|
+
"LEGEND_RANKINGS.INTERMEDIATE_REWARD": "legend_rankings.intermediate_reward",
|
|
110
122
|
"LEGEND_SHOWCASE.PRODUCT_VIRTUAL_DELETED": "legend_showcase.product_virtual_deleted",
|
|
111
123
|
"LEGEND_SHOWCASE.UPDATE_ALLOWED_MISSION_SUBSCRIPTION_IDS": "legend_showcase.update_allowed_mission_subscription_ids",
|
|
112
124
|
"LEGEND_SHOWCASE.UPDATE_ALLOWED_RANKING_SUBSCRIPTION_IDS": "legend_showcase.update_allowed_ranking_subscription_ids",
|
|
@@ -124,6 +136,13 @@ var microserviceEvent = {
|
|
|
124
136
|
|
|
125
137
|
// src/@types/rabbit-mq.ts
|
|
126
138
|
var queue = {
|
|
139
|
+
/**
|
|
140
|
+
* Audit queue names for separate audit event types
|
|
141
|
+
* @constant
|
|
142
|
+
*/
|
|
143
|
+
AuditReceived: "audit_received_commands",
|
|
144
|
+
AuditProcessed: "audit_processed_commands",
|
|
145
|
+
AuditDeadLetter: "audit_dead_letter_commands",
|
|
127
146
|
/**
|
|
128
147
|
* Queue used for sending replies in response to saga events.
|
|
129
148
|
*/
|
|
@@ -134,6 +153,10 @@ var queue = {
|
|
|
134
153
|
CommenceSaga: "commence_saga"
|
|
135
154
|
};
|
|
136
155
|
var exchange = {
|
|
156
|
+
/**
|
|
157
|
+
* Audit exchange name for direct routing of audit events
|
|
158
|
+
*/
|
|
159
|
+
Audit: "audit_exchange",
|
|
137
160
|
/**
|
|
138
161
|
* Exchange dedicated to requeueing messages that require further processing in a saga process
|
|
139
162
|
*/
|
|
@@ -168,6 +191,9 @@ var authCommands = {
|
|
|
168
191
|
CreateUser: "create_user"
|
|
169
192
|
};
|
|
170
193
|
|
|
194
|
+
// src/@types/saga/commands/audit-eda.ts
|
|
195
|
+
var auditEdaCommands = {};
|
|
196
|
+
|
|
171
197
|
// src/@types/saga/commands/blockchain.ts
|
|
172
198
|
var blockchainCommands = {
|
|
173
199
|
/**
|
|
@@ -450,6 +476,11 @@ var getEventObject = (event) => {
|
|
|
450
476
|
};
|
|
451
477
|
};
|
|
452
478
|
|
|
479
|
+
// src/utils/extractMicroservice.ts
|
|
480
|
+
function extractMicroserviceFromQueue(queueName) {
|
|
481
|
+
return queueName.replace(/_match_commands$/, "").replace(/_saga_commands$/, "");
|
|
482
|
+
}
|
|
483
|
+
|
|
453
484
|
// src/Consumer/channels/Consume.ts
|
|
454
485
|
var ConsumeChannel = class {
|
|
455
486
|
/**
|
|
@@ -489,10 +520,10 @@ var ConsumeChannel = class {
|
|
|
489
520
|
*
|
|
490
521
|
* @see NACKING_DELAY_MS
|
|
491
522
|
*/
|
|
492
|
-
nackWithDelay
|
|
523
|
+
nackWithDelay(delay = NACKING_DELAY_MS, maxRetries) {
|
|
493
524
|
const { delay: delayNackRetry, count } = this.nack({ delay, maxRetries });
|
|
494
525
|
return { count, delay: delayNackRetry };
|
|
495
|
-
}
|
|
526
|
+
}
|
|
496
527
|
/**
|
|
497
528
|
* Negatively acknowledges (NACKs) the message using a Fibonacci backoff strategy.
|
|
498
529
|
*
|
|
@@ -506,9 +537,9 @@ var ConsumeChannel = class {
|
|
|
506
537
|
* - `occurrence`: The current occurrence count for the Fibonacci sequence.
|
|
507
538
|
* @see MAX_OCCURRENCE
|
|
508
539
|
*/
|
|
509
|
-
nackWithFibonacciStrategy
|
|
540
|
+
nackWithFibonacciStrategy(maxOccurrence = MAX_OCCURRENCE, maxRetries) {
|
|
510
541
|
return this.nack({ maxOccurrence, maxRetries });
|
|
511
|
-
}
|
|
542
|
+
}
|
|
512
543
|
/**
|
|
513
544
|
* Private helper function to handle the actual NACK logic.
|
|
514
545
|
*
|
|
@@ -518,11 +549,7 @@ var ConsumeChannel = class {
|
|
|
518
549
|
* - `delay` and `maxRetries`: For linear backoff with a fixed delay and retry limit.
|
|
519
550
|
* - `maxOccurrence`: For Fibonacci backoff with a maximum occurrence count.
|
|
520
551
|
*/
|
|
521
|
-
nack
|
|
522
|
-
maxRetries,
|
|
523
|
-
maxOccurrence,
|
|
524
|
-
delay
|
|
525
|
-
}) => {
|
|
552
|
+
nack({ maxRetries, maxOccurrence, delay }) {
|
|
526
553
|
const { msg, queueName, channel } = this;
|
|
527
554
|
channel.nack(msg, false, false);
|
|
528
555
|
let count = 0;
|
|
@@ -579,7 +606,7 @@ var ConsumeChannel = class {
|
|
|
579
606
|
});
|
|
580
607
|
}
|
|
581
608
|
return { count, delay: nackDelay, occurrence };
|
|
582
|
-
}
|
|
609
|
+
}
|
|
583
610
|
};
|
|
584
611
|
var Consume_default = ConsumeChannel;
|
|
585
612
|
|
|
@@ -611,13 +638,109 @@ var commenceSagaConsumeCallback = (msg, channel, e, queueName) => {
|
|
|
611
638
|
e.emit(saga.title, { saga, channel: responseChannel });
|
|
612
639
|
};
|
|
613
640
|
|
|
641
|
+
// src/Broker/PublishAuditEvent.ts
|
|
642
|
+
async function publishAuditEvent(channel, eventType, payload) {
|
|
643
|
+
try {
|
|
644
|
+
const routingKey = eventType;
|
|
645
|
+
const messageBuffer = Buffer.from(JSON.stringify(payload));
|
|
646
|
+
channel.publish(exchange.Audit, routingKey, messageBuffer, {
|
|
647
|
+
contentType: "application/json",
|
|
648
|
+
deliveryMode: 2
|
|
649
|
+
// persistent
|
|
650
|
+
});
|
|
651
|
+
} catch (error) {
|
|
652
|
+
console.error(`Failed to publish audit event ${eventType}:`, error);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
async function publishAuditReceived(channel, payload) {
|
|
656
|
+
await publishAuditEvent(channel, "audit.received", payload);
|
|
657
|
+
}
|
|
658
|
+
async function publishAuditProcessed(channel, payload) {
|
|
659
|
+
await publishAuditEvent(channel, "audit.processed", payload);
|
|
660
|
+
}
|
|
661
|
+
async function publishAuditDeadLetter(channel, payload) {
|
|
662
|
+
await publishAuditEvent(channel, "audit.dead_letter", payload);
|
|
663
|
+
}
|
|
664
|
+
|
|
614
665
|
// src/Consumer/channels/Events.ts
|
|
615
666
|
var EventsConsumeChannel = class extends Consume_default {
|
|
667
|
+
/**
|
|
668
|
+
* The microservice name that is processing the event
|
|
669
|
+
*/
|
|
670
|
+
microservice;
|
|
671
|
+
/**
|
|
672
|
+
* The original event that was received
|
|
673
|
+
*/
|
|
674
|
+
processedEvent;
|
|
675
|
+
/**
|
|
676
|
+
* Creates a new EventsConsumeChannel instance
|
|
677
|
+
*
|
|
678
|
+
* @param channel - The AMQP Channel
|
|
679
|
+
* @param msg - The consumed message
|
|
680
|
+
* @param queueName - The queue name
|
|
681
|
+
* @param microservice - The microservice name processing the event
|
|
682
|
+
* @param processedEvent - The event type being processed
|
|
683
|
+
*/
|
|
684
|
+
constructor(channel, msg, queueName, microservice, processedEvent) {
|
|
685
|
+
super(channel, msg, queueName);
|
|
686
|
+
this.microservice = microservice;
|
|
687
|
+
this.processedEvent = processedEvent;
|
|
688
|
+
}
|
|
616
689
|
/**
|
|
617
690
|
* Acknowledges the consumed saga event/command.
|
|
691
|
+
* Automatically emits audit.processed event after successful ACK.
|
|
618
692
|
*/
|
|
619
693
|
ackMessage() {
|
|
620
694
|
this.channel.ack(this.msg, false);
|
|
695
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
696
|
+
publishAuditProcessed(this.channel, {
|
|
697
|
+
microservice: this.microservice,
|
|
698
|
+
processedEvent: this.processedEvent,
|
|
699
|
+
processedAt: timestamp,
|
|
700
|
+
queueName: this.queueName,
|
|
701
|
+
eventId: void 0
|
|
702
|
+
// Optional: can be enhanced later
|
|
703
|
+
}).catch((error) => {
|
|
704
|
+
console.error("Failed to emit audit.processed event:", error);
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Override nackWithDelay to emit audit.dead_letter event
|
|
709
|
+
*/
|
|
710
|
+
nackWithDelay(delay = NACKING_DELAY_MS, maxRetries) {
|
|
711
|
+
const parentNack = super.nackWithDelay(delay, maxRetries);
|
|
712
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
713
|
+
publishAuditDeadLetter(this.channel, {
|
|
714
|
+
microservice: this.microservice,
|
|
715
|
+
rejectedEvent: this.processedEvent,
|
|
716
|
+
rejectedAt: timestamp,
|
|
717
|
+
queueName: this.queueName,
|
|
718
|
+
rejectionReason: "delay",
|
|
719
|
+
retryCount: parentNack.count,
|
|
720
|
+
eventId: void 0
|
|
721
|
+
}).catch((error) => {
|
|
722
|
+
console.error("Failed to emit audit.dead_letter event:", error);
|
|
723
|
+
});
|
|
724
|
+
return parentNack;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Override nackWithFibonacciStrategy to emit audit.dead_letter event
|
|
728
|
+
*/
|
|
729
|
+
nackWithFibonacciStrategy(maxOccurrence = MAX_OCCURRENCE, maxRetries) {
|
|
730
|
+
const parentNack = super.nackWithFibonacciStrategy(maxOccurrence, maxRetries);
|
|
731
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
732
|
+
publishAuditDeadLetter(this.channel, {
|
|
733
|
+
microservice: this.microservice,
|
|
734
|
+
rejectedEvent: this.processedEvent,
|
|
735
|
+
rejectedAt: timestamp,
|
|
736
|
+
queueName: this.queueName,
|
|
737
|
+
rejectionReason: "fibonacci_strategy",
|
|
738
|
+
retryCount: parentNack.count,
|
|
739
|
+
eventId: void 0
|
|
740
|
+
}).catch((error) => {
|
|
741
|
+
console.error("Failed to emit audit.dead_letter event:", error);
|
|
742
|
+
});
|
|
743
|
+
return parentNack;
|
|
621
744
|
}
|
|
622
745
|
};
|
|
623
746
|
|
|
@@ -660,7 +783,20 @@ var eventCallback = (msg, channel, e, queueName) => {
|
|
|
660
783
|
{ headersReceived: headers, eventsDetected: event }
|
|
661
784
|
);
|
|
662
785
|
}
|
|
663
|
-
const
|
|
786
|
+
const microservice = extractMicroserviceFromQueue(queueName);
|
|
787
|
+
const receivedEvent = event[0];
|
|
788
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
789
|
+
publishAuditReceived(channel, {
|
|
790
|
+
microservice,
|
|
791
|
+
receivedEvent,
|
|
792
|
+
receivedAt: timestamp,
|
|
793
|
+
queueName,
|
|
794
|
+
eventId: void 0
|
|
795
|
+
// Optional: can be enhanced later with message ID tracking
|
|
796
|
+
}).catch((error) => {
|
|
797
|
+
console.error("Failed to emit audit.received event:", error);
|
|
798
|
+
});
|
|
799
|
+
const responseChannel = new EventsConsumeChannel(channel, msg, queueName, microservice, receivedEvent);
|
|
664
800
|
e.emit(event[0], { payload, channel: responseChannel });
|
|
665
801
|
};
|
|
666
802
|
|
|
@@ -827,6 +963,25 @@ var createHeaderConsumers = async (queueName, events) => {
|
|
|
827
963
|
}
|
|
828
964
|
}
|
|
829
965
|
};
|
|
966
|
+
|
|
967
|
+
// src/Consumer/auditInfrastructure.ts
|
|
968
|
+
var createAuditLoggingResources = async () => {
|
|
969
|
+
const channel = await getConsumeChannel();
|
|
970
|
+
await Promise.all([
|
|
971
|
+
// Create direct exchange for audit events
|
|
972
|
+
channel.assertExchange(exchange.Audit, "direct", { durable: true }),
|
|
973
|
+
// Create queues for audit events
|
|
974
|
+
channel.assertQueue(queue.AuditReceived, { durable: true }),
|
|
975
|
+
channel.assertQueue(queue.AuditProcessed, { durable: true }),
|
|
976
|
+
channel.assertQueue(queue.AuditDeadLetter, { durable: true })
|
|
977
|
+
]);
|
|
978
|
+
await Promise.all([
|
|
979
|
+
// Bind each queue to its specific routing key
|
|
980
|
+
channel.bindQueue(queue.AuditReceived, exchange.Audit, "audit.received"),
|
|
981
|
+
channel.bindQueue(queue.AuditProcessed, exchange.Audit, "audit.processed"),
|
|
982
|
+
channel.bindQueue(queue.AuditDeadLetter, exchange.Audit, "audit.dead_letter")
|
|
983
|
+
]);
|
|
984
|
+
};
|
|
830
985
|
var isReady = false;
|
|
831
986
|
var prepare = async (url2) => {
|
|
832
987
|
if (isReady) return;
|
|
@@ -886,6 +1041,7 @@ var connectToEvents = async (config) => {
|
|
|
886
1041
|
const queueName = `${config.microservice}_match_commands`;
|
|
887
1042
|
const e = mitt();
|
|
888
1043
|
await createHeaderConsumers(queueName, config.events);
|
|
1044
|
+
await createAuditLoggingResources();
|
|
889
1045
|
void consume(e, queueName, eventCallback);
|
|
890
1046
|
return e;
|
|
891
1047
|
};
|
|
@@ -960,4 +1116,4 @@ var publishEvent = async (msg, event) => {
|
|
|
960
1116
|
});
|
|
961
1117
|
};
|
|
962
1118
|
|
|
963
|
-
export { EventsConsumeChannel, MAX_NACK_RETRIES, MAX_OCCURRENCE, MicroserviceConsumeChannel, NACKING_DELAY_MS, PaymentEmailTypes, RoomTypes, Saga, SagaCommenceConsumeChannel, SagaConsumeChannel, Transactional, authCommands, availableMicroservices, blockchainCommands, closeConsumeChannel, closeRabbitMQConn, closeSendChannel, coinsCommands, commenceSaga, commenceSagaConsumeCallback, commenceSagaListener, connectToEvents, connectToSagaCommandEmitter, consume, createConsumers, createHeaderConsumers, eventCallback, exchange, fibonacci, gender, getConsumeChannel, getEventKey, getEventObject, getQueueConsumer, getQueueName, getRabbitMQConn, getSendChannel, isConnectionHealthy, microserviceEvent, nodeDataDefaults, publishEvent, queue, rankingsCommands, rapidMessagingCommands, roomCreatorCommands, roomInventoryCommands, roomSnapshotCommands, sagaConsumeCallback, sagaStepCallback, sagaTitle, saveQueueForHealthCheck, saveUri, sendEmailCommands, sendToQueue, showcaseCommands, socialCommands, socialMediaRoomsCommands, startGlobalSagaStepListener, status, stopRabbitMQ, storageCommands, testImageCommands, testMintCommands };
|
|
1119
|
+
export { EventsConsumeChannel, MAX_NACK_RETRIES, MAX_OCCURRENCE, MicroserviceConsumeChannel, NACKING_DELAY_MS, PaymentEmailTypes, RoomTypes, Saga, SagaCommenceConsumeChannel, SagaConsumeChannel, Transactional, auditEdaCommands, authCommands, availableMicroservices, blockchainCommands, closeConsumeChannel, closeRabbitMQConn, closeSendChannel, coinsCommands, commenceSaga, commenceSagaConsumeCallback, commenceSagaListener, connectToEvents, connectToSagaCommandEmitter, consume, createAuditLoggingResources, createConsumers, createHeaderConsumers, eventCallback, exchange, extractMicroserviceFromQueue, fibonacci, gender, getConsumeChannel, getEventKey, getEventObject, getQueueConsumer, getQueueName, getRabbitMQConn, getSendChannel, isConnectionHealthy, microserviceEvent, nodeDataDefaults, publishEvent, queue, rankingsCommands, rapidMessagingCommands, roomCreatorCommands, roomInventoryCommands, roomSnapshotCommands, sagaConsumeCallback, sagaStepCallback, sagaTitle, saveQueueForHealthCheck, saveUri, sendEmailCommands, sendToQueue, showcaseCommands, socialCommands, socialMediaRoomsCommands, startGlobalSagaStepListener, status, stopRabbitMQ, storageCommands, testImageCommands, testMintCommands };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "legend-transactional",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "A simple transactional, event-driven communication framework for microservices using RabbitMQ",
|
|
5
5
|
"author": "Jorge Clavijo <jym272@gmail.com> (https://github.com/jym272)",
|
|
6
6
|
"license": "MIT",
|