@hed-hog/core 0.0.295 → 0.0.296
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/auth/auth.controller.d.ts +4 -4
- package/dist/auth/auth.service.d.ts +4 -4
- package/dist/challenge/challenge.service.d.ts +2 -2
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +4 -1
- package/dist/core.module.js.map +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +1 -1
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +2 -2
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/index.d.ts +4 -0
- package/dist/integration/index.d.ts.map +1 -0
- package/dist/integration/index.js +20 -0
- package/dist/integration/index.js.map +1 -0
- package/dist/integration/integration-api.validation.d.ts +2 -0
- package/dist/integration/integration-api.validation.d.ts.map +1 -0
- package/dist/integration/integration-api.validation.js +126 -0
- package/dist/integration/integration-api.validation.js.map +1 -0
- package/dist/integration/integration.module.d.ts +3 -0
- package/dist/integration/integration.module.d.ts.map +1 -0
- package/dist/integration/integration.module.js +54 -0
- package/dist/integration/integration.module.js.map +1 -0
- package/dist/integration/services/domain-event.publisher.d.ts +31 -0
- package/dist/integration/services/domain-event.publisher.d.ts.map +1 -0
- package/dist/integration/services/domain-event.publisher.js +79 -0
- package/dist/integration/services/domain-event.publisher.js.map +1 -0
- package/dist/integration/services/event-subscriber.registry.d.ts +37 -0
- package/dist/integration/services/event-subscriber.registry.d.ts.map +1 -0
- package/dist/integration/services/event-subscriber.registry.js +86 -0
- package/dist/integration/services/event-subscriber.registry.js.map +1 -0
- package/dist/integration/services/inbox.service.d.ts +55 -0
- package/dist/integration/services/inbox.service.d.ts.map +1 -0
- package/dist/integration/services/inbox.service.js +173 -0
- package/dist/integration/services/inbox.service.js.map +1 -0
- package/dist/integration/services/index.d.ts +12 -0
- package/dist/integration/services/index.d.ts.map +1 -0
- package/dist/integration/services/index.js +28 -0
- package/dist/integration/services/index.js.map +1 -0
- package/dist/integration/services/integration-developer-api.service.d.ts +30 -0
- package/dist/integration/services/integration-developer-api.service.d.ts.map +1 -0
- package/dist/integration/services/integration-developer-api.service.js +55 -0
- package/dist/integration/services/integration-developer-api.service.js.map +1 -0
- package/dist/integration/services/integration-link.service.d.ts +52 -0
- package/dist/integration/services/integration-link.service.d.ts.map +1 -0
- package/dist/integration/services/integration-link.service.js +128 -0
- package/dist/integration/services/integration-link.service.js.map +1 -0
- package/dist/integration/services/integration-settings.service.d.ts +23 -0
- package/dist/integration/services/integration-settings.service.d.ts.map +1 -0
- package/dist/integration/services/integration-settings.service.js +81 -0
- package/dist/integration/services/integration-settings.service.js.map +1 -0
- package/dist/integration/services/outbox-polling.coordinator.d.ts +45 -0
- package/dist/integration/services/outbox-polling.coordinator.d.ts.map +1 -0
- package/dist/integration/services/outbox-polling.coordinator.js +143 -0
- package/dist/integration/services/outbox-polling.coordinator.js.map +1 -0
- package/dist/integration/services/outbox.notifier.d.ts +30 -0
- package/dist/integration/services/outbox.notifier.d.ts.map +1 -0
- package/dist/integration/services/outbox.notifier.js +57 -0
- package/dist/integration/services/outbox.notifier.js.map +1 -0
- package/dist/integration/services/outbox.processor.d.ts +42 -0
- package/dist/integration/services/outbox.processor.d.ts.map +1 -0
- package/dist/integration/services/outbox.processor.job.d.ts +43 -0
- package/dist/integration/services/outbox.processor.job.d.ts.map +1 -0
- package/dist/integration/services/outbox.processor.job.js +100 -0
- package/dist/integration/services/outbox.processor.job.js.map +1 -0
- package/dist/integration/services/outbox.processor.js +208 -0
- package/dist/integration/services/outbox.processor.js.map +1 -0
- package/dist/integration/services/outbox.service.d.ts +53 -0
- package/dist/integration/services/outbox.service.d.ts.map +1 -0
- package/dist/integration/services/outbox.service.js +149 -0
- package/dist/integration/services/outbox.service.js.map +1 -0
- package/dist/integration/types/event.types.d.ts +88 -0
- package/dist/integration/types/event.types.d.ts.map +1 -0
- package/dist/integration/types/event.types.js +35 -0
- package/dist/integration/types/event.types.js.map +1 -0
- package/dist/integration/types/index.d.ts +3 -0
- package/dist/integration/types/index.d.ts.map +1 -0
- package/dist/integration/types/index.js +19 -0
- package/dist/integration/types/index.js.map +1 -0
- package/dist/integration/types/subscriber.types.d.ts +31 -0
- package/dist/integration/types/subscriber.types.d.ts.map +1 -0
- package/dist/integration/types/subscriber.types.js +3 -0
- package/dist/integration/types/subscriber.types.js.map +1 -0
- package/dist/oauth/oauth.controller.js.map +1 -1
- package/dist/oauth/oauth.service.d.ts +3 -3
- package/dist/oauth/oauth.service.d.ts.map +1 -1
- package/dist/oauth/oauth.service.js.map +1 -1
- package/dist/profile/profile.controller.d.ts +3 -3
- package/dist/profile/profile.service.d.ts +3 -3
- package/dist/setting/setting.controller.d.ts +12 -8
- package/dist/setting/setting.controller.d.ts.map +1 -1
- package/dist/setting/setting.service.d.ts +12 -8
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +21 -1
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/user/user.controller.d.ts +4 -4
- package/dist/user/user.service.d.ts +9 -9
- package/hedhog/data/dashboard_component_role.yaml +223 -223
- package/hedhog/data/dashboard_role.yaml +18 -18
- package/hedhog/data/route.yaml +2 -0
- package/hedhog/data/setting_group.yaml +955 -470
- package/hedhog/data/setting_subgroup.yaml +303 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +44 -18
- package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +134 -27
- package/hedhog/frontend/app/configurations/layout.tsx.ejs +84 -23
- package/hedhog/frontend/app/dashboard/components/widgets/permissions-chart.tsx.ejs +62 -62
- package/hedhog/frontend/app/dashboard/page.tsx.ejs +29 -29
- package/hedhog/frontend/app/preferences/page.tsx.ejs +2 -5
- package/hedhog/table/inbox_event.yaml +40 -0
- package/hedhog/table/integration_link.yaml +33 -0
- package/hedhog/table/outbox_event.yaml +45 -0
- package/hedhog/table/setting.yaml +7 -0
- package/hedhog/table/setting_subgroup.yaml +19 -0
- package/package.json +8 -8
- package/src/ai/ai.service.ts +3 -3
- package/src/auth/auth.controller.ts +11 -11
- package/src/auth/auth.service.ts +8 -8
- package/src/core.module.ts +4 -1
- package/src/index.ts +15 -0
- package/src/integration/README.md +397 -0
- package/src/integration/USAGE_EXAMPLE.md +279 -0
- package/src/integration/index.ts +4 -0
- package/src/integration/integration-api.validation.ts +154 -0
- package/src/integration/integration.module.ts +53 -0
- package/src/integration/services/domain-event.publisher.ts +136 -0
- package/src/integration/services/event-subscriber.registry.ts +89 -0
- package/src/integration/services/inbox.service.ts +218 -0
- package/src/integration/services/index.ts +12 -0
- package/src/integration/services/integration-developer-api.service.ts +96 -0
- package/src/integration/services/integration-link.service.ts +154 -0
- package/src/integration/services/integration-settings.service.ts +128 -0
- package/src/integration/services/outbox-polling.coordinator.ts +146 -0
- package/src/integration/services/outbox.notifier.ts +48 -0
- package/src/integration/services/outbox.processor.job.ts +97 -0
- package/src/integration/services/outbox.processor.ts +266 -0
- package/src/integration/services/outbox.service.ts +209 -0
- package/src/integration/types/event.types.ts +93 -0
- package/src/integration/types/index.ts +3 -0
- package/src/integration/types/subscriber.types.ts +37 -0
- package/src/oauth/oauth.controller.ts +17 -17
- package/src/oauth/oauth.service.ts +20 -20
- package/src/setting/setting.service.ts +27 -2
- package/src/task/task.service.ts +5 -5
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var OutboxProcessorJob_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.OutboxProcessorJob = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const integration_settings_service_1 = require("./integration-settings.service");
|
|
16
|
+
const outbox_polling_coordinator_1 = require("./outbox-polling.coordinator");
|
|
17
|
+
const outbox_notifier_1 = require("./outbox.notifier");
|
|
18
|
+
const outbox_processor_1 = require("./outbox.processor");
|
|
19
|
+
/**
|
|
20
|
+
* Hybrid background job for outbox processing
|
|
21
|
+
* Combines startup recovery, immediate notification reactions, and periodic polling
|
|
22
|
+
*/
|
|
23
|
+
let OutboxProcessorJob = OutboxProcessorJob_1 = class OutboxProcessorJob {
|
|
24
|
+
constructor(processor, notifier, coordinator, integrationSettingsService) {
|
|
25
|
+
this.processor = processor;
|
|
26
|
+
this.notifier = notifier;
|
|
27
|
+
this.coordinator = coordinator;
|
|
28
|
+
this.integrationSettingsService = integrationSettingsService;
|
|
29
|
+
this.logger = new common_1.Logger(OutboxProcessorJob_1.name);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Called when module initializes
|
|
33
|
+
* 1. Drain pending events from startup
|
|
34
|
+
* 2. Start hybrid processing loop
|
|
35
|
+
*/
|
|
36
|
+
async onModuleInit() {
|
|
37
|
+
const settings = await this.integrationSettingsService.getRuntimeSettings();
|
|
38
|
+
const isEnabled = settings.outboxEnabled;
|
|
39
|
+
if (!isEnabled) {
|
|
40
|
+
this.logger.debug('Outbox integration disabled in settings');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Step 1: Startup drain
|
|
44
|
+
const startupDrainEnabled = settings.startupDrainEnabled;
|
|
45
|
+
if (startupDrainEnabled) {
|
|
46
|
+
this.logger.log('Starting outbox startup drain...');
|
|
47
|
+
try {
|
|
48
|
+
const processed = await this.processor.startupDrain();
|
|
49
|
+
this.logger.log(`Outbox startup drain completed: ${processed} events`);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.logger.error('Outbox startup drain failed:', error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Step 2: Start hybrid processing loop
|
|
56
|
+
const processorEnabled = settings.outboxProcessorEnabled;
|
|
57
|
+
if (processorEnabled) {
|
|
58
|
+
this.logger.log('Starting outbox hybrid processing loop');
|
|
59
|
+
try {
|
|
60
|
+
await this.coordinator.startProcessingLoop();
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
this.logger.error('Failed to start outbox processing loop:', error);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.logger.debug('Outbox processor disabled in settings');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Called when module is destroyed
|
|
72
|
+
* Gracefully stop the processing loop
|
|
73
|
+
*/
|
|
74
|
+
async onModuleDestroy() {
|
|
75
|
+
this.logger.log('Shutting down outbox processing');
|
|
76
|
+
try {
|
|
77
|
+
await this.coordinator.stopProcessingLoop();
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.logger.error('Error stopping outbox processing loop:', error);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get current processing statistics
|
|
85
|
+
* Useful for health checks and monitoring
|
|
86
|
+
*/
|
|
87
|
+
async getStats() {
|
|
88
|
+
const stats = await this.processor.getStats();
|
|
89
|
+
return Object.assign(Object.assign({}, stats), { pollingLoopRunning: this.coordinator.isRunning() });
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.OutboxProcessorJob = OutboxProcessorJob;
|
|
93
|
+
exports.OutboxProcessorJob = OutboxProcessorJob = OutboxProcessorJob_1 = __decorate([
|
|
94
|
+
(0, common_1.Injectable)(),
|
|
95
|
+
__metadata("design:paramtypes", [outbox_processor_1.OutboxProcessor,
|
|
96
|
+
outbox_notifier_1.OutboxNotifier,
|
|
97
|
+
outbox_polling_coordinator_1.OutboxPollingCoordinator,
|
|
98
|
+
integration_settings_service_1.IntegrationSettingsService])
|
|
99
|
+
], OutboxProcessorJob);
|
|
100
|
+
//# sourceMappingURL=outbox.processor.job.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.processor.job.js","sourceRoot":"","sources":["../../../src/integration/services/outbox.processor.job.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAKwB;AACxB,iFAA4E;AAC5E,6EAAwE;AACxE,uDAAmD;AACnD,yDAAqD;AAErD;;;GAGG;AAEI,IAAM,kBAAkB,0BAAxB,MAAM,kBAAkB;IAG7B,YACmB,SAA0B,EAC1B,QAAwB,EACxB,WAAqC,EACrC,0BAAsD;QAHtD,cAAS,GAAT,SAAS,CAAiB;QAC1B,aAAQ,GAAR,QAAQ,CAAgB;QACxB,gBAAW,GAAX,WAAW,CAA0B;QACrC,+BAA0B,GAA1B,0BAA0B,CAA4B;QANxD,WAAM,GAAG,IAAI,eAAM,CAAC,oBAAkB,CAAC,IAAI,CAAC,CAAC;IAO3D,CAAC;IAEJ;;;;OAIG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,kBAAkB,EAAE,CAAC;QAC5E,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC;QACzC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,wBAAwB;QACxB,MAAM,mBAAmB,GAAG,QAAQ,CAAC,mBAAmB,CAAC;QAEzD,IAAI,mBAAmB,EAAE,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;gBACtD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,mCAAmC,SAAS,SAAS,CACtD,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,MAAM,gBAAgB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;QAEzD,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;YAC/C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe;QACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,wCAAwC,EACxC,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC9C,uCACK,KAAK,KACR,kBAAkB,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,IAChD;IACJ,CAAC;CACF,CAAA;AAhFY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;qCAKmB,kCAAe;QAChB,gCAAc;QACX,qDAAwB;QACT,yDAA0B;GAP9D,kBAAkB,CAgF9B"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var OutboxProcessor_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.OutboxProcessor = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const types_1 = require("../types");
|
|
16
|
+
const event_subscriber_registry_1 = require("./event-subscriber.registry");
|
|
17
|
+
const inbox_service_1 = require("./inbox.service");
|
|
18
|
+
const integration_link_service_1 = require("./integration-link.service");
|
|
19
|
+
const integration_settings_service_1 = require("./integration-settings.service");
|
|
20
|
+
const outbox_service_1 = require("./outbox.service");
|
|
21
|
+
let OutboxProcessor = OutboxProcessor_1 = class OutboxProcessor {
|
|
22
|
+
constructor(outboxService, inboxService, linkService, registry, integrationSettingsService) {
|
|
23
|
+
this.outboxService = outboxService;
|
|
24
|
+
this.inboxService = inboxService;
|
|
25
|
+
this.linkService = linkService;
|
|
26
|
+
this.registry = registry;
|
|
27
|
+
this.integrationSettingsService = integrationSettingsService;
|
|
28
|
+
this.logger = new common_1.Logger(OutboxProcessor_1.name);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Process a batch of pending events
|
|
32
|
+
* Called in a loop or by scheduled job
|
|
33
|
+
*/
|
|
34
|
+
async processBatch(options) {
|
|
35
|
+
var _a;
|
|
36
|
+
const settings = await this.integrationSettingsService.getRuntimeSettings();
|
|
37
|
+
const batchSize = (_a = options === null || options === void 0 ? void 0 : options.batchSizeOverride) !== null && _a !== void 0 ? _a : settings.batchSize;
|
|
38
|
+
const leaseMs = settings.processingLeaseMs;
|
|
39
|
+
// Find pending events
|
|
40
|
+
const events = await this.outboxService.findPending(batchSize, leaseMs);
|
|
41
|
+
if (events.length === 0) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
this.logger.debug(`Processing ${events.length} outbox events`);
|
|
45
|
+
let processedCount = 0;
|
|
46
|
+
for (const event of events) {
|
|
47
|
+
try {
|
|
48
|
+
// Mark as processing with lease
|
|
49
|
+
await this.outboxService.markProcessing(event.id, leaseMs);
|
|
50
|
+
// Get handlers for this event
|
|
51
|
+
const handlers = this.registry.getHandlers(event.eventName);
|
|
52
|
+
if (handlers.length === 0) {
|
|
53
|
+
this.logger.warn(`No handlers registered for event: ${event.eventName}`);
|
|
54
|
+
// Mark as processed even though no handlers
|
|
55
|
+
await this.outboxService.updateStatus(event.id, types_1.OutboxEventStatus.PROCESSED, {
|
|
56
|
+
processedAt: new Date(),
|
|
57
|
+
});
|
|
58
|
+
processedCount++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Execute each handler
|
|
62
|
+
let anyFailed = false;
|
|
63
|
+
for (const handlerDef of handlers) {
|
|
64
|
+
const inboxEvent = await this.inboxService.getOrCreate(event.id, handlerDef.consumerName);
|
|
65
|
+
// Skip if already processed
|
|
66
|
+
if (inboxEvent.status === types_1.InboxEventStatus.PROCESSED) {
|
|
67
|
+
this.logger.debug(`Event ${event.id} already processed by ${handlerDef.consumerName}`);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
await this.inboxService.markProcessing(inboxEvent.id);
|
|
71
|
+
try {
|
|
72
|
+
// Execute handler
|
|
73
|
+
await handlerDef.handler({
|
|
74
|
+
eventName: event.eventName,
|
|
75
|
+
sourceModule: event.sourceModule,
|
|
76
|
+
aggregateType: event.aggregateType,
|
|
77
|
+
aggregateId: event.aggregateId,
|
|
78
|
+
payload: event.payload,
|
|
79
|
+
timestamp: event.createdAt,
|
|
80
|
+
}, {
|
|
81
|
+
logger: this.logger,
|
|
82
|
+
inboxService: this.inboxService,
|
|
83
|
+
linkService: this.linkService,
|
|
84
|
+
});
|
|
85
|
+
// Mark as processed
|
|
86
|
+
await this.inboxService.markProcessed(inboxEvent.id);
|
|
87
|
+
this.logger.debug(`Handler ${handlerDef.consumerName} processed event ${event.id}`);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
anyFailed = true;
|
|
91
|
+
this.logger.error(`Handler ${handlerDef.consumerName} failed for event ${event.id}:`, error);
|
|
92
|
+
await this.inboxService.markFailed(inboxEvent.id, error instanceof Error ? error.message : String(error));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Update outbox event status based on handler results
|
|
96
|
+
if (!anyFailed) {
|
|
97
|
+
await this.outboxService.updateStatus(event.id, types_1.OutboxEventStatus.PROCESSED, {
|
|
98
|
+
processedAt: new Date(),
|
|
99
|
+
});
|
|
100
|
+
processedCount++;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// At least one handler failed, retry logic applies
|
|
104
|
+
await this.handleEventFailure(event.id);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
this.logger.error(`Error processing event ${event.id}:`, error);
|
|
109
|
+
await this.handleEventFailure(event.id);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return processedCount;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Handle event that failed to process
|
|
116
|
+
*/
|
|
117
|
+
async handleEventFailure(eventId) {
|
|
118
|
+
const settings = await this.integrationSettingsService.getRuntimeSettings();
|
|
119
|
+
const maxAttempts = settings.maxAttempts;
|
|
120
|
+
const retryBaseDelayMs = settings.retryBaseDelayMs;
|
|
121
|
+
const deadLetterEnabled = settings.deadLetterEnabled;
|
|
122
|
+
const event = await this.outboxService.getById(eventId);
|
|
123
|
+
if (!event) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const nextAttemptCount = event.attemptCount + 1;
|
|
127
|
+
if (nextAttemptCount >= maxAttempts) {
|
|
128
|
+
if (deadLetterEnabled) {
|
|
129
|
+
this.logger.warn(`Event ${eventId} moved to dead letter after ${maxAttempts} attempts`);
|
|
130
|
+
await this.outboxService.updateStatus(eventId, types_1.OutboxEventStatus.DEAD_LETTER, {
|
|
131
|
+
attemptCount: nextAttemptCount,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.logger.warn(`Event ${eventId} failed after ${maxAttempts} attempts (dead letter disabled)`);
|
|
136
|
+
await this.outboxService.updateStatus(eventId, types_1.OutboxEventStatus.FAILED, {
|
|
137
|
+
attemptCount: nextAttemptCount,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Calculate exponential backoff
|
|
143
|
+
const delayMs = retryBaseDelayMs * Math.pow(2, event.attemptCount);
|
|
144
|
+
const availableAt = new Date(Date.now() + delayMs);
|
|
145
|
+
this.logger.debug(`Retrying event ${eventId} in ${delayMs}ms (attempt ${nextAttemptCount}/${maxAttempts})`);
|
|
146
|
+
await this.outboxService.updateStatus(eventId, types_1.OutboxEventStatus.PENDING, {
|
|
147
|
+
attemptCount: nextAttemptCount,
|
|
148
|
+
availableAt,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Process all pending events at startup (drain)
|
|
154
|
+
*/
|
|
155
|
+
async startupDrain() {
|
|
156
|
+
const settings = await this.integrationSettingsService.getRuntimeSettings();
|
|
157
|
+
const drainBatchSize = settings.startupDrainBatchSize;
|
|
158
|
+
this.logger.log(`Starting outbox drain with batch size: ${drainBatchSize}`);
|
|
159
|
+
let totalProcessed = 0;
|
|
160
|
+
// Keep processing until no more events
|
|
161
|
+
let processed = 1;
|
|
162
|
+
while (processed > 0) {
|
|
163
|
+
processed = await this.processBatch({
|
|
164
|
+
batchSizeOverride: drainBatchSize,
|
|
165
|
+
});
|
|
166
|
+
totalProcessed += processed;
|
|
167
|
+
// Small delay to prevent overwhelming the system
|
|
168
|
+
if (processed > 0) {
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
this.logger.log(`Startup drain completed. Processed ${totalProcessed} events`);
|
|
173
|
+
return totalProcessed;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get processor statistics
|
|
177
|
+
*/
|
|
178
|
+
async getStats() {
|
|
179
|
+
const pendingCount = await this.outboxService.countByStatus(types_1.OutboxEventStatus.PENDING);
|
|
180
|
+
const processingCount = await this.outboxService.countByStatus(types_1.OutboxEventStatus.PROCESSING);
|
|
181
|
+
const processedCount = await this.outboxService.countByStatus(types_1.OutboxEventStatus.PROCESSED);
|
|
182
|
+
const failedCount = await this.outboxService.countByStatus(types_1.OutboxEventStatus.FAILED);
|
|
183
|
+
const deadLetterCount = await this.outboxService.countByStatus(types_1.OutboxEventStatus.DEAD_LETTER);
|
|
184
|
+
return {
|
|
185
|
+
pending: pendingCount,
|
|
186
|
+
processing: processingCount,
|
|
187
|
+
processed: processedCount,
|
|
188
|
+
failed: failedCount,
|
|
189
|
+
dead_letter: deadLetterCount,
|
|
190
|
+
total: pendingCount +
|
|
191
|
+
processingCount +
|
|
192
|
+
processedCount +
|
|
193
|
+
failedCount +
|
|
194
|
+
deadLetterCount,
|
|
195
|
+
handlerCount: this.registry.getHandlerCount(),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
exports.OutboxProcessor = OutboxProcessor;
|
|
200
|
+
exports.OutboxProcessor = OutboxProcessor = OutboxProcessor_1 = __decorate([
|
|
201
|
+
(0, common_1.Injectable)(),
|
|
202
|
+
__metadata("design:paramtypes", [outbox_service_1.OutboxService,
|
|
203
|
+
inbox_service_1.InboxService,
|
|
204
|
+
integration_link_service_1.IntegrationLinkService,
|
|
205
|
+
event_subscriber_registry_1.EventSubscriberRegistry,
|
|
206
|
+
integration_settings_service_1.IntegrationSettingsService])
|
|
207
|
+
], OutboxProcessor);
|
|
208
|
+
//# sourceMappingURL=outbox.processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.processor.js","sourceRoot":"","sources":["../../../src/integration/services/outbox.processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PrismaService } from '@hed-hog/api-prisma';
|
|
2
|
+
import { OutboxEvent, OutboxEventStatus } from '../types';
|
|
3
|
+
export interface CreateOutboxEventDto {
|
|
4
|
+
eventName: string;
|
|
5
|
+
sourceModule: string;
|
|
6
|
+
aggregateType: string;
|
|
7
|
+
aggregateId: string;
|
|
8
|
+
payload: Record<string, any>;
|
|
9
|
+
}
|
|
10
|
+
export interface OutboxEventPersistenceClient {
|
|
11
|
+
outbox_event: PrismaService['outbox_event'];
|
|
12
|
+
}
|
|
13
|
+
export declare class OutboxService {
|
|
14
|
+
private readonly prisma;
|
|
15
|
+
constructor(prisma: PrismaService);
|
|
16
|
+
private toDomainEvent;
|
|
17
|
+
private toDatabaseId;
|
|
18
|
+
private toDatabaseUpdate;
|
|
19
|
+
/**
|
|
20
|
+
* Write a new event to the outbox
|
|
21
|
+
*/
|
|
22
|
+
createEvent(dto: CreateOutboxEventDto, persistenceClient?: OutboxEventPersistenceClient): Promise<OutboxEvent>;
|
|
23
|
+
/**
|
|
24
|
+
* Find pending events available for processing, ordered by creation time
|
|
25
|
+
*/
|
|
26
|
+
findPending(limit: number, leaseMs: number): Promise<OutboxEvent[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Update event status and related fields
|
|
29
|
+
*/
|
|
30
|
+
updateStatus(eventId: string | number, status: OutboxEventStatus, partialUpdate?: {
|
|
31
|
+
attemptCount?: number;
|
|
32
|
+
lastError?: string | null;
|
|
33
|
+
availableAt?: Date;
|
|
34
|
+
processedAt?: Date | null;
|
|
35
|
+
}): Promise<OutboxEvent>;
|
|
36
|
+
/**
|
|
37
|
+
* Mark event as processing and set lease time
|
|
38
|
+
*/
|
|
39
|
+
markProcessing(eventId: string | number, leaseMs: number): Promise<OutboxEvent>;
|
|
40
|
+
/**
|
|
41
|
+
* Increment attempt count and optionally update error
|
|
42
|
+
*/
|
|
43
|
+
incrementAttempt(eventId: string | number, error?: string): Promise<OutboxEvent>;
|
|
44
|
+
/**
|
|
45
|
+
* Get event by ID
|
|
46
|
+
*/
|
|
47
|
+
getById(eventId: string | number): Promise<OutboxEvent | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Count events by status
|
|
50
|
+
*/
|
|
51
|
+
countByStatus(status: OutboxEventStatus): Promise<number>;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=outbox.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.service.d.ts","sourceRoot":"","sources":["../../../src/integration/services/outbox.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CAC7C;AAkBD,qBACa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAElD,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACG,WAAW,CACf,GAAG,EAAE,oBAAoB,EACzB,iBAAiB,CAAC,EAAE,4BAA4B,GAC/C,OAAO,CAAC,WAAW,CAAC;IAmBvB;;OAEG;IACG,WAAW,CACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,CAAC;IAqBzB;;OAEG;IACG,YAAY,CAChB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,MAAM,EAAE,iBAAiB,EACzB,aAAa,CAAC,EAAE;QACd,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,WAAW,CAAC,EAAE,IAAI,CAAC;QACnB,WAAW,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;KAC3B,GACA,OAAO,CAAC,WAAW,CAAC;IAYvB;;OAEG;IACG,cAAc,CAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC;IAOvB;;OAEG;IACG,gBAAgB,CACpB,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,WAAW,CAAC;IAgBvB;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAQpE;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;CAKhE"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.OutboxService = void 0;
|
|
13
|
+
const api_prisma_1 = require("@hed-hog/api-prisma");
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const types_1 = require("../types");
|
|
16
|
+
let OutboxService = class OutboxService {
|
|
17
|
+
constructor(prisma) {
|
|
18
|
+
this.prisma = prisma;
|
|
19
|
+
}
|
|
20
|
+
toDomainEvent(record) {
|
|
21
|
+
return {
|
|
22
|
+
id: String(record.id),
|
|
23
|
+
eventName: record.event_name,
|
|
24
|
+
sourceModule: record.source_module,
|
|
25
|
+
aggregateType: record.aggregate_type,
|
|
26
|
+
aggregateId: record.aggregate_id,
|
|
27
|
+
payload: record.payload,
|
|
28
|
+
status: record.status,
|
|
29
|
+
attemptCount: record.attempt_count,
|
|
30
|
+
lastError: record.last_error,
|
|
31
|
+
availableAt: record.available_at,
|
|
32
|
+
processedAt: record.processed_at,
|
|
33
|
+
createdAt: record.created_at,
|
|
34
|
+
updatedAt: record.updated_at,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
toDatabaseId(eventId) {
|
|
38
|
+
return typeof eventId === 'number' ? eventId : Number(eventId);
|
|
39
|
+
}
|
|
40
|
+
toDatabaseUpdate(partialUpdate) {
|
|
41
|
+
if (!partialUpdate) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
attempt_count: partialUpdate.attemptCount,
|
|
46
|
+
last_error: partialUpdate.lastError,
|
|
47
|
+
available_at: partialUpdate.availableAt,
|
|
48
|
+
processed_at: partialUpdate.processedAt,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Write a new event to the outbox
|
|
53
|
+
*/
|
|
54
|
+
async createEvent(dto, persistenceClient) {
|
|
55
|
+
const client = persistenceClient !== null && persistenceClient !== void 0 ? persistenceClient : this.prisma;
|
|
56
|
+
const record = await client.outbox_event.create({
|
|
57
|
+
data: {
|
|
58
|
+
event_name: dto.eventName,
|
|
59
|
+
source_module: dto.sourceModule,
|
|
60
|
+
aggregate_type: dto.aggregateType,
|
|
61
|
+
aggregate_id: dto.aggregateId,
|
|
62
|
+
payload: dto.payload,
|
|
63
|
+
status: types_1.OutboxEventStatus.PENDING,
|
|
64
|
+
available_at: new Date(),
|
|
65
|
+
attempt_count: 0,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return this.toDomainEvent(record);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Find pending events available for processing, ordered by creation time
|
|
72
|
+
*/
|
|
73
|
+
async findPending(limit, leaseMs) {
|
|
74
|
+
const now = new Date();
|
|
75
|
+
const leaseThreshold = new Date(now.getTime() - leaseMs);
|
|
76
|
+
const records = await this.prisma.outbox_event.findMany({
|
|
77
|
+
where: {
|
|
78
|
+
OR: [
|
|
79
|
+
{ status: types_1.OutboxEventStatus.PENDING },
|
|
80
|
+
{
|
|
81
|
+
status: types_1.OutboxEventStatus.PROCESSING,
|
|
82
|
+
available_at: { lte: leaseThreshold },
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
orderBy: { created_at: 'asc' },
|
|
87
|
+
take: limit,
|
|
88
|
+
});
|
|
89
|
+
return records.map((record) => this.toDomainEvent(record));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Update event status and related fields
|
|
93
|
+
*/
|
|
94
|
+
async updateStatus(eventId, status, partialUpdate) {
|
|
95
|
+
const record = await this.prisma.outbox_event.update({
|
|
96
|
+
where: { id: this.toDatabaseId(eventId) },
|
|
97
|
+
data: Object.assign({ status }, this.toDatabaseUpdate(partialUpdate)),
|
|
98
|
+
});
|
|
99
|
+
return this.toDomainEvent(record);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Mark event as processing and set lease time
|
|
103
|
+
*/
|
|
104
|
+
async markProcessing(eventId, leaseMs) {
|
|
105
|
+
const leaseUntil = new Date(Date.now() + leaseMs);
|
|
106
|
+
return this.updateStatus(eventId, types_1.OutboxEventStatus.PROCESSING, {
|
|
107
|
+
availableAt: leaseUntil,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Increment attempt count and optionally update error
|
|
112
|
+
*/
|
|
113
|
+
async incrementAttempt(eventId, error) {
|
|
114
|
+
const record = await this.prisma.outbox_event.findUnique({
|
|
115
|
+
where: { id: this.toDatabaseId(eventId) },
|
|
116
|
+
});
|
|
117
|
+
if (!record) {
|
|
118
|
+
throw new Error(`Event ${eventId} not found`);
|
|
119
|
+
}
|
|
120
|
+
const event = this.toDomainEvent(record);
|
|
121
|
+
return this.updateStatus(eventId, event.status, {
|
|
122
|
+
attemptCount: event.attemptCount + 1,
|
|
123
|
+
lastError: error || null,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get event by ID
|
|
128
|
+
*/
|
|
129
|
+
async getById(eventId) {
|
|
130
|
+
const record = await this.prisma.outbox_event.findUnique({
|
|
131
|
+
where: { id: this.toDatabaseId(eventId) },
|
|
132
|
+
});
|
|
133
|
+
return record ? this.toDomainEvent(record) : null;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Count events by status
|
|
137
|
+
*/
|
|
138
|
+
async countByStatus(status) {
|
|
139
|
+
return this.prisma.outbox_event.count({
|
|
140
|
+
where: { status },
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
exports.OutboxService = OutboxService;
|
|
145
|
+
exports.OutboxService = OutboxService = __decorate([
|
|
146
|
+
(0, common_1.Injectable)(),
|
|
147
|
+
__metadata("design:paramtypes", [api_prisma_1.PrismaService])
|
|
148
|
+
], OutboxService);
|
|
149
|
+
//# sourceMappingURL=outbox.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.service.js","sourceRoot":"","sources":["../../../src/integration/services/outbox.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAoD;AACpD,2CAA4C;AAC5C,oCAA0D;AA+BnD,IAAM,aAAa,GAAnB,MAAM,aAAa;IACxB,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAE9C,aAAa,CAAC,MAAyB;QAC7C,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,SAAS,EAAE,MAAM,CAAC,UAAU;YAC5B,YAAY,EAAE,MAAM,CAAC,aAAa;YAClC,aAAa,EAAE,MAAM,CAAC,cAAc;YACpC,WAAW,EAAE,MAAM,CAAC,YAAY;YAChC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,YAAY,EAAE,MAAM,CAAC,aAAa;YAClC,SAAS,EAAE,MAAM,CAAC,UAAU;YAC5B,WAAW,EAAE,MAAM,CAAC,YAAY;YAChC,WAAW,EAAE,MAAM,CAAC,YAAY;YAChC,SAAS,EAAE,MAAM,CAAC,UAAU;YAC5B,SAAS,EAAE,MAAM,CAAC,UAAU;SAC7B,CAAC;IACJ,CAAC;IAEO,YAAY,CAAC,OAAwB;QAC3C,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAEO,gBAAgB,CACtB,aAKC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO;YACL,aAAa,EAAE,aAAa,CAAC,YAAY;YACzC,UAAU,EAAE,aAAa,CAAC,SAAS;YACnC,YAAY,EAAE,aAAa,CAAC,WAAW;YACvC,YAAY,EAAE,aAAa,CAAC,WAAW;SACxC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CACf,GAAyB,EACzB,iBAAgD;QAEhD,MAAM,MAAM,GAAG,iBAAiB,aAAjB,iBAAiB,cAAjB,iBAAiB,GAAI,IAAI,CAAC,MAAM,CAAC;QAEhD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YAC9C,IAAI,EAAE;gBACJ,UAAU,EAAE,GAAG,CAAC,SAAS;gBACzB,aAAa,EAAE,GAAG,CAAC,YAAY;gBAC/B,cAAc,EAAE,GAAG,CAAC,aAAa;gBACjC,YAAY,EAAE,GAAG,CAAC,WAAW;gBAC7B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,MAAM,EAAE,yBAAiB,CAAC,OAAO;gBACjC,YAAY,EAAE,IAAI,IAAI,EAAE;gBACxB,aAAa,EAAE,CAAC;aACjB;SACF,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CACf,KAAa,EACb,OAAe;QAEf,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;QAEzD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;YACtD,KAAK,EAAE;gBACL,EAAE,EAAE;oBACF,EAAE,MAAM,EAAE,yBAAiB,CAAC,OAAO,EAAE;oBACrC;wBACE,MAAM,EAAE,yBAAiB,CAAC,UAAU;wBACpC,YAAY,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE;qBACtC;iBACF;aACF;YACD,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;YAC9B,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC,CAAC;IAClF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAChB,OAAwB,EACxB,MAAyB,EACzB,aAKC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YACnD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;YACzC,IAAI,kBACF,MAAM,IACH,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CACxC;SACF,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAClB,OAAwB,EACxB,OAAe;QAEf,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,yBAAiB,CAAC,UAAU,EAAE;YAC9D,WAAW,EAAE,UAAU;SACxB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,OAAwB,EACxB,KAAc;QAEd,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC;YACvD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;SAC1C,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,YAAY,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC;QAE9D,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE;YAC9C,YAAY,EAAE,KAAK,CAAC,YAAY,GAAG,CAAC;YACpC,SAAS,EAAE,KAAK,IAAI,IAAI;SACzB,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAAwB;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC;YACvD,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE;SAC1C,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,MAA2B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,MAAyB;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;YACpC,KAAK,EAAE,EAAE,MAAM,EAAE;SAClB,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AA/KY,sCAAa;wBAAb,aAAa;IADzB,IAAA,mBAAU,GAAE;qCAE0B,0BAAa;GADvC,aAAa,CA+KzB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event status throughout the integration lifecycle
|
|
3
|
+
*/
|
|
4
|
+
export declare enum OutboxEventStatus {
|
|
5
|
+
PENDING = "pending",
|
|
6
|
+
PROCESSING = "processing",
|
|
7
|
+
PROCESSED = "processed",
|
|
8
|
+
FAILED = "failed",
|
|
9
|
+
DEAD_LETTER = "dead_letter"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Inbox event processing status per consumer
|
|
13
|
+
*/
|
|
14
|
+
export declare enum InboxEventStatus {
|
|
15
|
+
RECEIVED = "received",
|
|
16
|
+
PROCESSING = "processing",
|
|
17
|
+
PROCESSED = "processed",
|
|
18
|
+
FAILED = "failed",
|
|
19
|
+
SKIPPED = "skipped"
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Type of link between entities from different modules
|
|
23
|
+
*/
|
|
24
|
+
export declare enum LinkType {
|
|
25
|
+
REFERENCE = "reference",
|
|
26
|
+
CASCADE = "cascade",
|
|
27
|
+
AGGREGATE_ROOT = "aggregate_root"
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Domain event interface that is published and processed
|
|
31
|
+
*/
|
|
32
|
+
export interface DomainEvent {
|
|
33
|
+
eventName: string;
|
|
34
|
+
sourceModule: string;
|
|
35
|
+
aggregateType: string;
|
|
36
|
+
aggregateId: string;
|
|
37
|
+
payload: Record<string, any>;
|
|
38
|
+
timestamp: Date;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Outbox event record from database
|
|
42
|
+
*/
|
|
43
|
+
export interface OutboxEvent {
|
|
44
|
+
id: string;
|
|
45
|
+
eventName: string;
|
|
46
|
+
sourceModule: string;
|
|
47
|
+
aggregateType: string;
|
|
48
|
+
aggregateId: string;
|
|
49
|
+
payload: Record<string, any>;
|
|
50
|
+
status: OutboxEventStatus;
|
|
51
|
+
attemptCount: number;
|
|
52
|
+
lastError: string | null;
|
|
53
|
+
availableAt: Date;
|
|
54
|
+
processedAt: Date | null;
|
|
55
|
+
createdAt: Date;
|
|
56
|
+
updatedAt: Date;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Inbox event record from database for idempotency tracking
|
|
60
|
+
*/
|
|
61
|
+
export interface InboxEvent {
|
|
62
|
+
id: string;
|
|
63
|
+
outboxEventId: string;
|
|
64
|
+
consumerName: string;
|
|
65
|
+
status: InboxEventStatus;
|
|
66
|
+
attemptCount: number;
|
|
67
|
+
lastError: string | null;
|
|
68
|
+
processedAt: Date | null;
|
|
69
|
+
createdAt: Date;
|
|
70
|
+
updatedAt: Date;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Integration link between entities across modules
|
|
74
|
+
*/
|
|
75
|
+
export interface IntegrationLink {
|
|
76
|
+
id: string;
|
|
77
|
+
sourceModule: string;
|
|
78
|
+
sourceEntityType: string;
|
|
79
|
+
sourceEntityId: string;
|
|
80
|
+
targetModule: string;
|
|
81
|
+
targetEntityType: string;
|
|
82
|
+
targetEntityId: string;
|
|
83
|
+
linkType: LinkType;
|
|
84
|
+
metadata: Record<string, any> | null;
|
|
85
|
+
createdAt: Date;
|
|
86
|
+
updatedAt: Date;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=event.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.types.d.ts","sourceRoot":"","sources":["../../../src/integration/types/event.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,WAAW,gBAAgB;CAC5B;AAED;;GAEG;AACH,oBAAY,gBAAgB;IAC1B,QAAQ,aAAa;IACrB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,oBAAY,QAAQ;IAClB,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,cAAc,mBAAmB;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,CAAC;IAClB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB"}
|