@campfire-interactive/platform-events 0.2.0 → 0.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/consumer.d.ts +12 -0
- package/dist/consumer.js +23 -0
- package/dist/envelope.d.ts +14 -14
- package/dist/envelope.js +1 -0
- package/dist/events/ai-hub.d.ts +40 -0
- package/dist/events/ai-hub.js +22 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +7 -1
- package/dist/publisher.d.ts +8 -0
- package/dist/publisher.js +50 -0
- package/package.json +30 -30
package/dist/consumer.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Envelope } from './envelope';
|
|
2
2
|
import { MasterDataEventType, MasterDataPayload } from './events/master-data';
|
|
3
|
+
import { AiHubEventType, AiHubPayload } from './events/ai-hub';
|
|
3
4
|
/**
|
|
4
5
|
* Consumer-side helpers (ADR §10: consumers need the types as much as
|
|
5
6
|
* producers). The eventId dedup helper and replay-drop default land in
|
|
@@ -17,3 +18,14 @@ export declare function isMasterDataEventType(type: string): type is MasterDataE
|
|
|
17
18
|
* both envelope and payload and narrows the payload type on `type`.
|
|
18
19
|
*/
|
|
19
20
|
export declare function parseMasterDataEvent(detail: unknown): MasterDataEvent;
|
|
21
|
+
export interface AiHubEvent<T extends AiHubEventType = AiHubEventType> {
|
|
22
|
+
type: T;
|
|
23
|
+
envelope: Envelope<AiHubPayload<T>>;
|
|
24
|
+
}
|
|
25
|
+
export declare function isAiHubEventType(type: string): type is AiHubEventType;
|
|
26
|
+
/**
|
|
27
|
+
* Parse a message known to come from the ai-hub catalog; validates both
|
|
28
|
+
* envelope and payload and narrows the payload type on `type`. This is what
|
|
29
|
+
* forecast (the consumer) uses on its `forecast-events` queue.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseAiHubEvent(detail: unknown): AiHubEvent;
|
package/dist/consumer.js
CHANGED
|
@@ -3,8 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.parseEnvelope = parseEnvelope;
|
|
4
4
|
exports.isMasterDataEventType = isMasterDataEventType;
|
|
5
5
|
exports.parseMasterDataEvent = parseMasterDataEvent;
|
|
6
|
+
exports.isAiHubEventType = isAiHubEventType;
|
|
7
|
+
exports.parseAiHubEvent = parseAiHubEvent;
|
|
6
8
|
const envelope_1 = require("./envelope");
|
|
7
9
|
const master_data_1 = require("./events/master-data");
|
|
10
|
+
const ai_hub_1 = require("./events/ai-hub");
|
|
8
11
|
/**
|
|
9
12
|
* Consumer-side helpers (ADR §10: consumers need the types as much as
|
|
10
13
|
* producers). The eventId dedup helper and replay-drop default land in
|
|
@@ -34,3 +37,23 @@ function parseMasterDataEvent(detail) {
|
|
|
34
37
|
envelope: { ...envelope, payload },
|
|
35
38
|
};
|
|
36
39
|
}
|
|
40
|
+
function isAiHubEventType(type) {
|
|
41
|
+
return type in ai_hub_1.aiHubEvents;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse a message known to come from the ai-hub catalog; validates both
|
|
45
|
+
* envelope and payload and narrows the payload type on `type`. This is what
|
|
46
|
+
* forecast (the consumer) uses on its `forecast-events` queue.
|
|
47
|
+
*/
|
|
48
|
+
function parseAiHubEvent(detail) {
|
|
49
|
+
const envelope = parseEnvelope(detail);
|
|
50
|
+
if (!isAiHubEventType(envelope.type)) {
|
|
51
|
+
throw new Error(`platform-events: '${envelope.type}' is not a catalogued ai-hub event`);
|
|
52
|
+
}
|
|
53
|
+
const def = ai_hub_1.aiHubEvents[envelope.type];
|
|
54
|
+
const payload = def.payload.parse(envelope.payload);
|
|
55
|
+
return {
|
|
56
|
+
type: envelope.type,
|
|
57
|
+
envelope: { ...envelope, payload },
|
|
58
|
+
};
|
|
59
|
+
}
|
package/dist/envelope.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ import { z } from 'zod';
|
|
|
14
14
|
* union — hyphenated `master-data`, settled at ratification (plan
|
|
15
15
|
* decision 3; the ADR uses this spelling).
|
|
16
16
|
*/
|
|
17
|
-
export declare const PRODUCERS: readonly ["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"];
|
|
18
|
-
export declare const producerSchema: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>;
|
|
17
|
+
export declare const PRODUCERS: readonly ["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"];
|
|
18
|
+
export declare const producerSchema: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>;
|
|
19
19
|
export type Producer = z.infer<typeof producerSchema>;
|
|
20
20
|
export declare const ENVELOPE_SCHEMA_VERSION: 2;
|
|
21
21
|
/** Envelope with an unvalidated payload — use `envelopeFor(schema)` when the payload shape is known. */
|
|
@@ -25,7 +25,7 @@ export declare const envelopeSchema: z.ZodObject<{
|
|
|
25
25
|
eventId: z.ZodString;
|
|
26
26
|
/** ISO-8601 instant the state change committed at the producer */
|
|
27
27
|
occurredAt: z.ZodString;
|
|
28
|
-
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>;
|
|
28
|
+
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>;
|
|
29
29
|
/** = EventBridge detail-type, `<entity>.<action>` (or `<verb>.<noun>` for commands) */
|
|
30
30
|
type: z.ZodString;
|
|
31
31
|
entityType: z.ZodString;
|
|
@@ -43,7 +43,7 @@ export declare const envelopeSchema: z.ZodObject<{
|
|
|
43
43
|
/** acting user, when the change was user-initiated */
|
|
44
44
|
userId: z.ZodOptional<z.ZodString>;
|
|
45
45
|
/** commands only: the app whose inbox this is routed to */
|
|
46
|
-
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>>;
|
|
46
|
+
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>>;
|
|
47
47
|
/** commands only: async request/reply correlation */
|
|
48
48
|
correlationId: z.ZodOptional<z.ZodString>;
|
|
49
49
|
/** commands only: sender's inbox identifier for the reply */
|
|
@@ -65,14 +65,14 @@ export declare const envelopeSchema: z.ZodObject<{
|
|
|
65
65
|
schemaVersion: 2;
|
|
66
66
|
eventId: string;
|
|
67
67
|
occurredAt: string;
|
|
68
|
-
producer: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications";
|
|
68
|
+
producer: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | "ai-hub";
|
|
69
69
|
entityType: string;
|
|
70
70
|
entityId: string;
|
|
71
71
|
tenantId: string | null;
|
|
72
72
|
traceId: string;
|
|
73
73
|
entityVersion?: number | undefined;
|
|
74
74
|
userId?: string | undefined;
|
|
75
|
-
recipient?: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | undefined;
|
|
75
|
+
recipient?: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | "ai-hub" | undefined;
|
|
76
76
|
correlationId?: string | undefined;
|
|
77
77
|
replyTo?: string | undefined;
|
|
78
78
|
sagaId?: string | undefined;
|
|
@@ -85,14 +85,14 @@ export declare const envelopeSchema: z.ZodObject<{
|
|
|
85
85
|
schemaVersion: 2;
|
|
86
86
|
eventId: string;
|
|
87
87
|
occurredAt: string;
|
|
88
|
-
producer: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications";
|
|
88
|
+
producer: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | "ai-hub";
|
|
89
89
|
entityType: string;
|
|
90
90
|
entityId: string;
|
|
91
91
|
tenantId: string | null;
|
|
92
92
|
traceId: string;
|
|
93
93
|
entityVersion?: number | undefined;
|
|
94
94
|
userId?: string | undefined;
|
|
95
|
-
recipient?: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | undefined;
|
|
95
|
+
recipient?: "master-data" | "cpq" | "omsf" | "pim" | "erfq" | "forecast" | "identity" | "notifications" | "ai-hub" | undefined;
|
|
96
96
|
correlationId?: string | undefined;
|
|
97
97
|
replyTo?: string | undefined;
|
|
98
98
|
sagaId?: string | undefined;
|
|
@@ -111,7 +111,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
111
111
|
eventId: z.ZodString;
|
|
112
112
|
/** ISO-8601 instant the state change committed at the producer */
|
|
113
113
|
occurredAt: z.ZodString;
|
|
114
|
-
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>;
|
|
114
|
+
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>;
|
|
115
115
|
/** = EventBridge detail-type, `<entity>.<action>` (or `<verb>.<noun>` for commands) */
|
|
116
116
|
type: z.ZodString;
|
|
117
117
|
entityType: z.ZodString;
|
|
@@ -129,7 +129,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
129
129
|
/** acting user, when the change was user-initiated */
|
|
130
130
|
userId: z.ZodOptional<z.ZodString>;
|
|
131
131
|
/** commands only: the app whose inbox this is routed to */
|
|
132
|
-
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>>;
|
|
132
|
+
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>>;
|
|
133
133
|
/** commands only: async request/reply correlation */
|
|
134
134
|
correlationId: z.ZodOptional<z.ZodString>;
|
|
135
135
|
/** commands only: sender's inbox identifier for the reply */
|
|
@@ -152,7 +152,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
152
152
|
eventId: z.ZodString;
|
|
153
153
|
/** ISO-8601 instant the state change committed at the producer */
|
|
154
154
|
occurredAt: z.ZodString;
|
|
155
|
-
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>;
|
|
155
|
+
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>;
|
|
156
156
|
/** = EventBridge detail-type, `<entity>.<action>` (or `<verb>.<noun>` for commands) */
|
|
157
157
|
type: z.ZodString;
|
|
158
158
|
entityType: z.ZodString;
|
|
@@ -170,7 +170,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
170
170
|
/** acting user, when the change was user-initiated */
|
|
171
171
|
userId: z.ZodOptional<z.ZodString>;
|
|
172
172
|
/** commands only: the app whose inbox this is routed to */
|
|
173
|
-
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>>;
|
|
173
|
+
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>>;
|
|
174
174
|
/** commands only: async request/reply correlation */
|
|
175
175
|
correlationId: z.ZodOptional<z.ZodString>;
|
|
176
176
|
/** commands only: sender's inbox identifier for the reply */
|
|
@@ -193,7 +193,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
193
193
|
eventId: z.ZodString;
|
|
194
194
|
/** ISO-8601 instant the state change committed at the producer */
|
|
195
195
|
occurredAt: z.ZodString;
|
|
196
|
-
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>;
|
|
196
|
+
producer: z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>;
|
|
197
197
|
/** = EventBridge detail-type, `<entity>.<action>` (or `<verb>.<noun>` for commands) */
|
|
198
198
|
type: z.ZodString;
|
|
199
199
|
entityType: z.ZodString;
|
|
@@ -211,7 +211,7 @@ export declare function envelopeFor<TSchema extends z.ZodTypeAny>(payload: TSche
|
|
|
211
211
|
/** acting user, when the change was user-initiated */
|
|
212
212
|
userId: z.ZodOptional<z.ZodString>;
|
|
213
213
|
/** commands only: the app whose inbox this is routed to */
|
|
214
|
-
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications"]>>;
|
|
214
|
+
recipient: z.ZodOptional<z.ZodEnum<["master-data", "cpq", "omsf", "pim", "erfq", "forecast", "identity", "notifications", "ai-hub"]>>;
|
|
215
215
|
/** commands only: async request/reply correlation */
|
|
216
216
|
correlationId: z.ZodOptional<z.ZodString>;
|
|
217
217
|
/** commands only: sender's inbox identifier for the reply */
|
package/dist/envelope.js
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* ai-hub event catalog — owned by the cfi-ai-hub team (ADR §10).
|
|
4
|
+
*
|
|
5
|
+
* The AI-hub runs long forecast batches for the forecast (Volume Intelligence)
|
|
6
|
+
* app. It emits `forecast.run_completed` when a batch job finishes, so forecast
|
|
7
|
+
* reacts to a durable bus event instead of the lossy `callback_url` + 60s poll
|
|
8
|
+
* it uses today. See
|
|
9
|
+
* `cfi-ai-hub/docs/plans/2026-06-30-publish-forecast-completion-events.md`.
|
|
10
|
+
*
|
|
11
|
+
* MINIMAL trigger payload (meta ADR 2026-06-30 §2): it carries only the job
|
|
12
|
+
* identity + outcome. forecast re-reads the full result via its existing
|
|
13
|
+
* `GET /forecast/jobs/{progressId}` — the forecast timeline never travels on
|
|
14
|
+
* the bus (it exceeds the 256 KB transport limit and needs no claim-check this
|
|
15
|
+
* way).
|
|
16
|
+
*/
|
|
17
|
+
export interface AiHubEventDef<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
18
|
+
entityType: string;
|
|
19
|
+
/** payload field holding the affected entity's id */
|
|
20
|
+
entityIdField: string;
|
|
21
|
+
/** false → platform-global event; envelope tenantId must be null */
|
|
22
|
+
tenantScoped: boolean;
|
|
23
|
+
payload: TSchema;
|
|
24
|
+
}
|
|
25
|
+
export declare const aiHubEvents: {
|
|
26
|
+
readonly 'forecast.run_completed': AiHubEventDef<z.ZodObject<{
|
|
27
|
+
/** the hub batch job id forecast polls / re-reads the result by */
|
|
28
|
+
progressId: z.ZodString;
|
|
29
|
+
/** terminal outcome of the batch run */
|
|
30
|
+
status: z.ZodEnum<["done", "done_with_errors", "failed"]>;
|
|
31
|
+
}, "strip", z.ZodTypeAny, {
|
|
32
|
+
status: "done" | "done_with_errors" | "failed";
|
|
33
|
+
progressId: string;
|
|
34
|
+
}, {
|
|
35
|
+
status: "done" | "done_with_errors" | "failed";
|
|
36
|
+
progressId: string;
|
|
37
|
+
}>>;
|
|
38
|
+
};
|
|
39
|
+
export type AiHubEventType = keyof typeof aiHubEvents;
|
|
40
|
+
export type AiHubPayload<T extends AiHubEventType> = z.infer<(typeof aiHubEvents)[T]['payload']>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.aiHubEvents = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
function defineEvent(def) {
|
|
6
|
+
return def;
|
|
7
|
+
}
|
|
8
|
+
exports.aiHubEvents = {
|
|
9
|
+
'forecast.run_completed': defineEvent({
|
|
10
|
+
entityType: 'forecast_run',
|
|
11
|
+
entityIdField: 'progressId',
|
|
12
|
+
tenantScoped: true,
|
|
13
|
+
payload: zod_1.z.object({
|
|
14
|
+
/** the hub batch job id forecast polls / re-reads the result by */
|
|
15
|
+
progressId: zod_1.z.string(),
|
|
16
|
+
/** terminal outcome of the batch run */
|
|
17
|
+
status: zod_1.z.enum(['done', 'done_with_errors', 'failed']),
|
|
18
|
+
}),
|
|
19
|
+
// Ordering is carried by the standard envelope field `entityVersion`
|
|
20
|
+
// (§5), supplied via the publish context — not duplicated in the payload.
|
|
21
|
+
}),
|
|
22
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,10 +4,12 @@ export { masterDataEvents } from './events/master-data';
|
|
|
4
4
|
export type { EventDef, MasterDataEventType, MasterDataPayload } from './events/master-data';
|
|
5
5
|
export { notificationEvents } from './events/notifications';
|
|
6
6
|
export type { NotificationEventDef, NotificationEventType, NotificationPayload, } from './events/notifications';
|
|
7
|
-
export {
|
|
7
|
+
export { aiHubEvents } from './events/ai-hub';
|
|
8
|
+
export type { AiHubEventDef, AiHubEventType, AiHubPayload } from './events/ai-hub';
|
|
9
|
+
export { buildAiHubEnvelope, buildMasterDataEnvelope, buildNotificationEnvelope, configurePublisher, publishAiHubEvent, publishMasterDataEvent, publishNotificationEvent, sendCommand, } from './publisher';
|
|
8
10
|
export type { NotificationPublishContext, PublishContext, PublisherConfig, SendCommandContext, } from './publisher';
|
|
9
|
-
export { isMasterDataEventType, parseEnvelope, parseMasterDataEvent } from './consumer';
|
|
10
|
-
export type { MasterDataEvent } from './consumer';
|
|
11
|
+
export { isAiHubEventType, isMasterDataEventType, parseAiHubEvent, parseEnvelope, parseMasterDataEvent } from './consumer';
|
|
12
|
+
export type { AiHubEvent, MasterDataEvent } from './consumer';
|
|
11
13
|
export { DynamoDbDedupStore, isReplay, withIdempotency } from './dedup';
|
|
12
14
|
export type { DedupStore, DynamoDbDedupStoreOptions, HandleResult, WithIdempotencyOptions } from './dedup';
|
|
13
15
|
export { relayOutbox, toOutboxRecord } from './outbox';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.startSaga = exports.publishCompensation = exports.childContext = exports.toOutboxRecord = exports.relayOutbox = exports.withIdempotency = exports.isReplay = exports.DynamoDbDedupStore = exports.parseMasterDataEvent = exports.parseEnvelope = exports.isMasterDataEventType = exports.sendCommand = exports.publishNotificationEvent = exports.publishMasterDataEvent = exports.configurePublisher = exports.buildNotificationEnvelope = exports.buildMasterDataEnvelope = exports.notificationEvents = exports.masterDataEvents = exports.producerSchema = exports.envelopeSchema = exports.envelopeFor = exports.PRODUCERS = exports.ENVELOPE_SCHEMA_VERSION = void 0;
|
|
3
|
+
exports.startSaga = exports.publishCompensation = exports.childContext = exports.toOutboxRecord = exports.relayOutbox = exports.withIdempotency = exports.isReplay = exports.DynamoDbDedupStore = exports.parseMasterDataEvent = exports.parseEnvelope = exports.parseAiHubEvent = exports.isMasterDataEventType = exports.isAiHubEventType = exports.sendCommand = exports.publishNotificationEvent = exports.publishMasterDataEvent = exports.publishAiHubEvent = exports.configurePublisher = exports.buildNotificationEnvelope = exports.buildMasterDataEnvelope = exports.buildAiHubEnvelope = exports.aiHubEvents = exports.notificationEvents = exports.masterDataEvents = exports.producerSchema = exports.envelopeSchema = exports.envelopeFor = exports.PRODUCERS = exports.ENVELOPE_SCHEMA_VERSION = void 0;
|
|
4
4
|
var envelope_1 = require("./envelope");
|
|
5
5
|
Object.defineProperty(exports, "ENVELOPE_SCHEMA_VERSION", { enumerable: true, get: function () { return envelope_1.ENVELOPE_SCHEMA_VERSION; } });
|
|
6
6
|
Object.defineProperty(exports, "PRODUCERS", { enumerable: true, get: function () { return envelope_1.PRODUCERS; } });
|
|
@@ -11,15 +11,21 @@ var master_data_1 = require("./events/master-data");
|
|
|
11
11
|
Object.defineProperty(exports, "masterDataEvents", { enumerable: true, get: function () { return master_data_1.masterDataEvents; } });
|
|
12
12
|
var notifications_1 = require("./events/notifications");
|
|
13
13
|
Object.defineProperty(exports, "notificationEvents", { enumerable: true, get: function () { return notifications_1.notificationEvents; } });
|
|
14
|
+
var ai_hub_1 = require("./events/ai-hub");
|
|
15
|
+
Object.defineProperty(exports, "aiHubEvents", { enumerable: true, get: function () { return ai_hub_1.aiHubEvents; } });
|
|
14
16
|
var publisher_1 = require("./publisher");
|
|
17
|
+
Object.defineProperty(exports, "buildAiHubEnvelope", { enumerable: true, get: function () { return publisher_1.buildAiHubEnvelope; } });
|
|
15
18
|
Object.defineProperty(exports, "buildMasterDataEnvelope", { enumerable: true, get: function () { return publisher_1.buildMasterDataEnvelope; } });
|
|
16
19
|
Object.defineProperty(exports, "buildNotificationEnvelope", { enumerable: true, get: function () { return publisher_1.buildNotificationEnvelope; } });
|
|
17
20
|
Object.defineProperty(exports, "configurePublisher", { enumerable: true, get: function () { return publisher_1.configurePublisher; } });
|
|
21
|
+
Object.defineProperty(exports, "publishAiHubEvent", { enumerable: true, get: function () { return publisher_1.publishAiHubEvent; } });
|
|
18
22
|
Object.defineProperty(exports, "publishMasterDataEvent", { enumerable: true, get: function () { return publisher_1.publishMasterDataEvent; } });
|
|
19
23
|
Object.defineProperty(exports, "publishNotificationEvent", { enumerable: true, get: function () { return publisher_1.publishNotificationEvent; } });
|
|
20
24
|
Object.defineProperty(exports, "sendCommand", { enumerable: true, get: function () { return publisher_1.sendCommand; } });
|
|
21
25
|
var consumer_1 = require("./consumer");
|
|
26
|
+
Object.defineProperty(exports, "isAiHubEventType", { enumerable: true, get: function () { return consumer_1.isAiHubEventType; } });
|
|
22
27
|
Object.defineProperty(exports, "isMasterDataEventType", { enumerable: true, get: function () { return consumer_1.isMasterDataEventType; } });
|
|
28
|
+
Object.defineProperty(exports, "parseAiHubEvent", { enumerable: true, get: function () { return consumer_1.parseAiHubEvent; } });
|
|
23
29
|
Object.defineProperty(exports, "parseEnvelope", { enumerable: true, get: function () { return consumer_1.parseEnvelope; } });
|
|
24
30
|
Object.defineProperty(exports, "parseMasterDataEvent", { enumerable: true, get: function () { return consumer_1.parseMasterDataEvent; } });
|
|
25
31
|
var dedup_1 = require("./dedup");
|
package/dist/publisher.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { EventBridgeClient } from '@aws-sdk/client-eventbridge';
|
|
|
2
2
|
import { Envelope, Producer } from './envelope';
|
|
3
3
|
import { MasterDataEventType, MasterDataPayload } from './events/master-data';
|
|
4
4
|
import { NotificationEventType, NotificationPayload } from './events/notifications';
|
|
5
|
+
import { AiHubEventType, AiHubPayload } from './events/ai-hub';
|
|
5
6
|
/**
|
|
6
7
|
* Publisher core. Mirrors the deployed master-data publisher's posture:
|
|
7
8
|
* fire-and-forget, console fallback when EVENT_BUS_NAME is unset, never
|
|
@@ -51,6 +52,13 @@ export declare function buildMasterDataEnvelope<T extends MasterDataEventType>(t
|
|
|
51
52
|
* logged, never thrown into the caller (until the outbox lands).
|
|
52
53
|
*/
|
|
53
54
|
export declare function publishMasterDataEvent<T extends MasterDataEventType>(type: T, payload: MasterDataPayload<T>, ctx: PublishContext): Promise<void>;
|
|
55
|
+
/** Build + validate the full envelope for a catalogued ai-hub event. */
|
|
56
|
+
export declare function buildAiHubEnvelope<T extends AiHubEventType>(type: T, payload: AiHubPayload<T>, ctx: PublishContext, producer?: Producer): Envelope<AiHubPayload<T>>;
|
|
57
|
+
/**
|
|
58
|
+
* Publish a catalogued ai-hub event. Fire-and-forget: failures are logged,
|
|
59
|
+
* never thrown into the caller (until the outbox lands — hub plan fast-follow).
|
|
60
|
+
*/
|
|
61
|
+
export declare function publishAiHubEvent<T extends AiHubEventType>(type: T, payload: AiHubPayload<T>, ctx: PublishContext): Promise<void>;
|
|
54
62
|
export interface NotificationPublishContext extends Omit<PublishContext, 'userId'> {
|
|
55
63
|
/** The RECIPIENT user (identity sub) — required: it is the routing key. */
|
|
56
64
|
userId: string;
|
package/dist/publisher.js
CHANGED
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.configurePublisher = configurePublisher;
|
|
4
4
|
exports.buildMasterDataEnvelope = buildMasterDataEnvelope;
|
|
5
5
|
exports.publishMasterDataEvent = publishMasterDataEvent;
|
|
6
|
+
exports.buildAiHubEnvelope = buildAiHubEnvelope;
|
|
7
|
+
exports.publishAiHubEvent = publishAiHubEvent;
|
|
6
8
|
exports.buildNotificationEnvelope = buildNotificationEnvelope;
|
|
7
9
|
exports.publishNotificationEvent = publishNotificationEvent;
|
|
8
10
|
exports.sendCommand = sendCommand;
|
|
@@ -11,6 +13,7 @@ const client_eventbridge_1 = require("@aws-sdk/client-eventbridge");
|
|
|
11
13
|
const envelope_1 = require("./envelope");
|
|
12
14
|
const master_data_1 = require("./events/master-data");
|
|
13
15
|
const notifications_1 = require("./events/notifications");
|
|
16
|
+
const ai_hub_1 = require("./events/ai-hub");
|
|
14
17
|
let config = {};
|
|
15
18
|
let client;
|
|
16
19
|
function configurePublisher(next) {
|
|
@@ -97,6 +100,53 @@ async function publishMasterDataEvent(type, payload, ctx) {
|
|
|
97
100
|
console.error(`[platform-events] publish failed for ${type}`, err);
|
|
98
101
|
}
|
|
99
102
|
}
|
|
103
|
+
/** Build + validate the full envelope for a catalogued ai-hub event. */
|
|
104
|
+
function buildAiHubEnvelope(type, payload, ctx, producer = 'ai-hub') {
|
|
105
|
+
const def = ai_hub_1.aiHubEvents[type];
|
|
106
|
+
const parsedPayload = def.payload.parse(payload);
|
|
107
|
+
if (def.tenantScoped && ctx.tenantId == null) {
|
|
108
|
+
throw new Error(`platform-events: ${type} is tenant-scoped but tenantId is null`);
|
|
109
|
+
}
|
|
110
|
+
if (!def.tenantScoped && ctx.tenantId != null) {
|
|
111
|
+
throw new Error(`platform-events: ${type} is platform-global but tenantId was provided`);
|
|
112
|
+
}
|
|
113
|
+
const entityId = parsedPayload[def.entityIdField];
|
|
114
|
+
if (typeof entityId !== 'string' || entityId.length === 0) {
|
|
115
|
+
throw new Error(`platform-events: ${type} payload is missing entity id field '${def.entityIdField}'`);
|
|
116
|
+
}
|
|
117
|
+
const envelope = {
|
|
118
|
+
schemaVersion: envelope_1.ENVELOPE_SCHEMA_VERSION,
|
|
119
|
+
eventId: ctx.eventId ?? (0, node_crypto_1.randomUUID)(),
|
|
120
|
+
occurredAt: ctx.occurredAt ?? new Date().toISOString(),
|
|
121
|
+
producer,
|
|
122
|
+
type,
|
|
123
|
+
entityType: def.entityType,
|
|
124
|
+
entityId,
|
|
125
|
+
entityVersion: ctx.entityVersion,
|
|
126
|
+
tenantId: ctx.tenantId,
|
|
127
|
+
userId: ctx.userId,
|
|
128
|
+
sagaId: ctx.sagaId,
|
|
129
|
+
causationId: ctx.causationId,
|
|
130
|
+
compensation: ctx.compensation,
|
|
131
|
+
traceId: ctx.traceId ?? (0, node_crypto_1.randomUUID)(),
|
|
132
|
+
payload: parsedPayload,
|
|
133
|
+
};
|
|
134
|
+
envelope_1.envelopeSchema.parse(envelope);
|
|
135
|
+
return envelope;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Publish a catalogued ai-hub event. Fire-and-forget: failures are logged,
|
|
139
|
+
* never thrown into the caller (until the outbox lands — hub plan fast-follow).
|
|
140
|
+
*/
|
|
141
|
+
async function publishAiHubEvent(type, payload, ctx) {
|
|
142
|
+
try {
|
|
143
|
+
const envelope = buildAiHubEnvelope(type, payload, ctx, resolveProducer());
|
|
144
|
+
await putOnBus(envelope, envelope.producer);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
console.error(`[platform-events] publish failed for ${type}`, err);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
100
150
|
/** Build + validate the envelope for a catalogued notification event. */
|
|
101
151
|
function buildNotificationEnvelope(type, payload, ctx, producer = 'notifications') {
|
|
102
152
|
const def = notifications_1.notificationEvents[type];
|
package/package.json
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@campfire-interactive/platform-events",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Publisher/consumer SDK for the platform-events bus: envelope v2, typed event schemas, publish helpers, sendCommand. 0.x during the Phase 2 dual-publish window; 1.0.0 at cutover (nextgen/docs/plans/2026-06-10-platform-async-messaging.md).",
|
|
5
|
-
"license": "UNLICENSED",
|
|
6
|
-
"publishConfig": {
|
|
7
|
-
"registry": "https://registry.npmjs.org",
|
|
8
|
-
"access": "public"
|
|
9
|
-
},
|
|
10
|
-
"main": "dist/index.js",
|
|
11
|
-
"types": "dist/index.d.ts",
|
|
12
|
-
"files": [
|
|
13
|
-
"dist"
|
|
14
|
-
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"build": "tsc -p tsconfig.build.json",
|
|
17
|
-
"test": "vitest run",
|
|
18
|
-
"typecheck": "tsc --noEmit"
|
|
19
|
-
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@aws-sdk/client-dynamodb": "^3.600.0",
|
|
22
|
-
"@aws-sdk/client-eventbridge": "^3.600.0",
|
|
23
|
-
"zod": "^3.23.0"
|
|
24
|
-
},
|
|
25
|
-
"devDependencies": {
|
|
26
|
-
"@types/node": "^20.14.0",
|
|
27
|
-
"typescript": "^5.5.0",
|
|
28
|
-
"vitest": "^2.0.0"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@campfire-interactive/platform-events",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Publisher/consumer SDK for the platform-events bus: envelope v2, typed event schemas, publish helpers, sendCommand. 0.x during the Phase 2 dual-publish window; 1.0.0 at cutover (nextgen/docs/plans/2026-06-10-platform-async-messaging.md).",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"registry": "https://registry.npmjs.org",
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc -p tsconfig.build.json",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"typecheck": "tsc --noEmit"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@aws-sdk/client-dynamodb": "^3.600.0",
|
|
22
|
+
"@aws-sdk/client-eventbridge": "^3.600.0",
|
|
23
|
+
"zod": "^3.23.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.14.0",
|
|
27
|
+
"typescript": "^5.5.0",
|
|
28
|
+
"vitest": "^2.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|