@valentine-efagene/qshelter-common 2.0.75 → 2.0.77
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/generated/client/browser.d.ts +5 -5
- package/dist/generated/client/client.d.ts +5 -5
- package/dist/generated/client/enums.d.ts +36 -0
- package/dist/generated/client/enums.js +33 -0
- package/dist/generated/client/internal/class.d.ts +11 -11
- package/dist/generated/client/internal/class.js +2 -2
- package/dist/generated/client/internal/prismaNamespace.d.ts +95 -95
- package/dist/generated/client/internal/prismaNamespace.js +25 -25
- package/dist/generated/client/internal/prismaNamespaceBrowser.d.ts +27 -27
- package/dist/generated/client/internal/prismaNamespaceBrowser.js +25 -25
- package/dist/generated/client/models/Contract.d.ts +155 -155
- package/dist/generated/client/models/index.d.ts +3 -0
- package/dist/generated/client/models/index.js +3 -0
- package/dist/generated/client/models.d.ts +1 -1
- package/dist/src/events/bus/event-bus.service.d.ts +84 -0
- package/dist/src/events/bus/event-bus.service.js +372 -0
- package/dist/src/events/bus/event-bus.types.d.ts +73 -0
- package/dist/src/events/bus/event-bus.types.js +22 -0
- package/dist/src/events/index.d.ts +5 -6
- package/dist/src/events/index.js +7 -8
- package/dist/src/events/notifications/event-publisher.d.ts +41 -0
- package/dist/src/events/notifications/event-publisher.js +111 -0
- package/dist/src/events/notifications/notification-enums.d.ts +46 -0
- package/dist/src/events/notifications/notification-enums.js +59 -0
- package/dist/src/events/notifications/notification-event.d.ts +76 -0
- package/dist/src/events/notifications/notification-event.js +1 -0
- package/dist/src/events/unified/unified-event.service.d.ts +157 -0
- package/dist/src/events/unified/unified-event.service.js +177 -0
- package/dist/src/events/workflow/event-config.service.d.ts +123 -0
- package/dist/src/events/workflow/event-config.service.js +416 -0
- package/dist/src/events/workflow/event-seeder.d.ts +80 -0
- package/dist/src/events/workflow/event-seeder.js +343 -0
- package/dist/src/events/workflow/workflow-event.service.d.ts +230 -0
- package/dist/src/events/workflow/workflow-event.service.js +682 -0
- package/dist/src/events/workflow/workflow-types.d.ts +364 -0
- package/dist/src/events/workflow/workflow-types.js +22 -0
- package/package.json +4 -1
- package/prisma/schema.prisma +123 -79
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Configuration Service
|
|
3
|
+
*
|
|
4
|
+
* Allows admins to configure event channels, types, and handlers.
|
|
5
|
+
* This is the "admin" side of the event system.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const configService = new EventConfigService(prisma);
|
|
10
|
+
*
|
|
11
|
+
* // Create a channel
|
|
12
|
+
* const channel = await configService.createChannel(tenantId, {
|
|
13
|
+
* code: 'CONTRACTS',
|
|
14
|
+
* name: 'Contract Events',
|
|
15
|
+
* description: 'Events related to contract lifecycle',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Create an event type
|
|
19
|
+
* const eventType = await configService.createEventType(tenantId, {
|
|
20
|
+
* channelId: channel.id,
|
|
21
|
+
* code: 'DOCUMENT_UPLOADED',
|
|
22
|
+
* name: 'Document Uploaded',
|
|
23
|
+
* description: 'Fired when a document is uploaded to a contract step',
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Create a webhook handler
|
|
27
|
+
* await configService.createHandler(tenantId, {
|
|
28
|
+
* eventTypeId: eventType.id,
|
|
29
|
+
* name: 'Notify CRM',
|
|
30
|
+
* handlerType: 'WEBHOOK',
|
|
31
|
+
* config: {
|
|
32
|
+
* type: 'WEBHOOK',
|
|
33
|
+
* url: 'https://crm.example.com/webhook',
|
|
34
|
+
* method: 'POST',
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
import { PrismaClient } from '../../../generated/client/client';
|
|
40
|
+
import type { CreateEventChannelInput, UpdateEventChannelInput, CreateEventTypeInput, UpdateEventTypeInput, CreateEventHandlerInput, UpdateEventHandlerInput, EventChannelWithTypes, EventTypeWithHandlers, EventHandlerWithType } from './workflow-types';
|
|
41
|
+
export declare class EventConfigService {
|
|
42
|
+
private prisma;
|
|
43
|
+
constructor(prisma: PrismaClient);
|
|
44
|
+
/**
|
|
45
|
+
* Create an event channel
|
|
46
|
+
*/
|
|
47
|
+
createChannel(tenantId: string, input: CreateEventChannelInput): Promise<EventChannelWithTypes>;
|
|
48
|
+
/**
|
|
49
|
+
* List all channels for a tenant
|
|
50
|
+
*/
|
|
51
|
+
listChannels(tenantId: string): Promise<EventChannelWithTypes[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Get a channel by ID
|
|
54
|
+
*/
|
|
55
|
+
getChannel(tenantId: string, channelId: string): Promise<EventChannelWithTypes | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Get a channel by code
|
|
58
|
+
*/
|
|
59
|
+
getChannelByCode(tenantId: string, code: string): Promise<EventChannelWithTypes | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Update a channel
|
|
62
|
+
*/
|
|
63
|
+
updateChannel(tenantId: string, channelId: string, input: UpdateEventChannelInput): Promise<EventChannelWithTypes>;
|
|
64
|
+
/**
|
|
65
|
+
* Delete a channel (cascades to event types and handlers)
|
|
66
|
+
*/
|
|
67
|
+
deleteChannel(tenantId: string, channelId: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Create an event type
|
|
70
|
+
*/
|
|
71
|
+
createEventType(tenantId: string, input: CreateEventTypeInput): Promise<EventTypeWithHandlers>;
|
|
72
|
+
/**
|
|
73
|
+
* List event types for a tenant, optionally filtered by channel
|
|
74
|
+
*/
|
|
75
|
+
listEventTypes(tenantId: string, channelId?: string): Promise<EventTypeWithHandlers[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Get an event type by ID
|
|
78
|
+
*/
|
|
79
|
+
getEventType(tenantId: string, eventTypeId: string): Promise<EventTypeWithHandlers | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Get an event type by code
|
|
82
|
+
*/
|
|
83
|
+
getEventTypeByCode(tenantId: string, code: string): Promise<EventTypeWithHandlers | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Update an event type
|
|
86
|
+
*/
|
|
87
|
+
updateEventType(tenantId: string, eventTypeId: string, input: UpdateEventTypeInput): Promise<EventTypeWithHandlers>;
|
|
88
|
+
/**
|
|
89
|
+
* Delete an event type (cascades to handlers)
|
|
90
|
+
*/
|
|
91
|
+
deleteEventType(tenantId: string, eventTypeId: string): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Create an event handler
|
|
94
|
+
*/
|
|
95
|
+
createHandler(tenantId: string, input: CreateEventHandlerInput): Promise<EventHandlerWithType>;
|
|
96
|
+
/**
|
|
97
|
+
* List handlers for an event type
|
|
98
|
+
*/
|
|
99
|
+
listHandlers(tenantId: string, eventTypeId?: string): Promise<EventHandlerWithType[]>;
|
|
100
|
+
/**
|
|
101
|
+
* Get a handler by ID
|
|
102
|
+
*/
|
|
103
|
+
getHandler(tenantId: string, handlerId: string): Promise<EventHandlerWithType | null>;
|
|
104
|
+
/**
|
|
105
|
+
* Update a handler
|
|
106
|
+
*/
|
|
107
|
+
updateHandler(tenantId: string, handlerId: string, input: UpdateEventHandlerInput): Promise<EventHandlerWithType>;
|
|
108
|
+
/**
|
|
109
|
+
* Delete a handler
|
|
110
|
+
*/
|
|
111
|
+
deleteHandler(tenantId: string, handlerId: string): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Enable or disable a handler
|
|
114
|
+
*/
|
|
115
|
+
setHandlerEnabled(tenantId: string, handlerId: string, enabled: boolean): Promise<void>;
|
|
116
|
+
private mapChannel;
|
|
117
|
+
private mapEventType;
|
|
118
|
+
private mapHandler;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create an event config service instance
|
|
122
|
+
*/
|
|
123
|
+
export declare function createEventConfigService(prisma: PrismaClient): EventConfigService;
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Configuration Service
|
|
3
|
+
*
|
|
4
|
+
* Allows admins to configure event channels, types, and handlers.
|
|
5
|
+
* This is the "admin" side of the event system.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const configService = new EventConfigService(prisma);
|
|
10
|
+
*
|
|
11
|
+
* // Create a channel
|
|
12
|
+
* const channel = await configService.createChannel(tenantId, {
|
|
13
|
+
* code: 'CONTRACTS',
|
|
14
|
+
* name: 'Contract Events',
|
|
15
|
+
* description: 'Events related to contract lifecycle',
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Create an event type
|
|
19
|
+
* const eventType = await configService.createEventType(tenantId, {
|
|
20
|
+
* channelId: channel.id,
|
|
21
|
+
* code: 'DOCUMENT_UPLOADED',
|
|
22
|
+
* name: 'Document Uploaded',
|
|
23
|
+
* description: 'Fired when a document is uploaded to a contract step',
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Create a webhook handler
|
|
27
|
+
* await configService.createHandler(tenantId, {
|
|
28
|
+
* eventTypeId: eventType.id,
|
|
29
|
+
* name: 'Notify CRM',
|
|
30
|
+
* handlerType: 'WEBHOOK',
|
|
31
|
+
* config: {
|
|
32
|
+
* type: 'WEBHOOK',
|
|
33
|
+
* url: 'https://crm.example.com/webhook',
|
|
34
|
+
* method: 'POST',
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class EventConfigService {
|
|
40
|
+
prisma;
|
|
41
|
+
constructor(prisma) {
|
|
42
|
+
this.prisma = prisma;
|
|
43
|
+
}
|
|
44
|
+
// ==========================================
|
|
45
|
+
// EVENT CHANNELS
|
|
46
|
+
// ==========================================
|
|
47
|
+
/**
|
|
48
|
+
* Create an event channel
|
|
49
|
+
*/
|
|
50
|
+
async createChannel(tenantId, input) {
|
|
51
|
+
const channel = await this.prisma.eventChannel.create({
|
|
52
|
+
data: {
|
|
53
|
+
tenantId,
|
|
54
|
+
code: input.code.toUpperCase().replace(/\s+/g, '_'),
|
|
55
|
+
name: input.name,
|
|
56
|
+
description: input.description,
|
|
57
|
+
enabled: input.enabled ?? true,
|
|
58
|
+
},
|
|
59
|
+
include: {
|
|
60
|
+
eventTypes: {
|
|
61
|
+
select: { id: true, code: true, name: true, enabled: true },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return this.mapChannel(channel);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* List all channels for a tenant
|
|
69
|
+
*/
|
|
70
|
+
async listChannels(tenantId) {
|
|
71
|
+
const channels = await this.prisma.eventChannel.findMany({
|
|
72
|
+
where: { tenantId },
|
|
73
|
+
include: {
|
|
74
|
+
eventTypes: {
|
|
75
|
+
select: { id: true, code: true, name: true, enabled: true },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
orderBy: { name: 'asc' },
|
|
79
|
+
});
|
|
80
|
+
return channels.map(this.mapChannel);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get a channel by ID
|
|
84
|
+
*/
|
|
85
|
+
async getChannel(tenantId, channelId) {
|
|
86
|
+
const channel = await this.prisma.eventChannel.findFirst({
|
|
87
|
+
where: { id: channelId, tenantId },
|
|
88
|
+
include: {
|
|
89
|
+
eventTypes: {
|
|
90
|
+
select: { id: true, code: true, name: true, enabled: true },
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
return channel ? this.mapChannel(channel) : null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get a channel by code
|
|
98
|
+
*/
|
|
99
|
+
async getChannelByCode(tenantId, code) {
|
|
100
|
+
const channel = await this.prisma.eventChannel.findFirst({
|
|
101
|
+
where: { tenantId, code: code.toUpperCase() },
|
|
102
|
+
include: {
|
|
103
|
+
eventTypes: {
|
|
104
|
+
select: { id: true, code: true, name: true, enabled: true },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return channel ? this.mapChannel(channel) : null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Update a channel
|
|
112
|
+
*/
|
|
113
|
+
async updateChannel(tenantId, channelId, input) {
|
|
114
|
+
const channel = await this.prisma.eventChannel.update({
|
|
115
|
+
where: { id: channelId, tenantId },
|
|
116
|
+
data: {
|
|
117
|
+
...(input.name !== undefined && { name: input.name }),
|
|
118
|
+
...(input.description !== undefined && { description: input.description }),
|
|
119
|
+
...(input.enabled !== undefined && { enabled: input.enabled }),
|
|
120
|
+
},
|
|
121
|
+
include: {
|
|
122
|
+
eventTypes: {
|
|
123
|
+
select: { id: true, code: true, name: true, enabled: true },
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
return this.mapChannel(channel);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Delete a channel (cascades to event types and handlers)
|
|
131
|
+
*/
|
|
132
|
+
async deleteChannel(tenantId, channelId) {
|
|
133
|
+
await this.prisma.eventChannel.delete({
|
|
134
|
+
where: { id: channelId, tenantId },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// ==========================================
|
|
138
|
+
// EVENT TYPES
|
|
139
|
+
// ==========================================
|
|
140
|
+
/**
|
|
141
|
+
* Create an event type
|
|
142
|
+
*/
|
|
143
|
+
async createEventType(tenantId, input) {
|
|
144
|
+
const eventType = await this.prisma.eventType.create({
|
|
145
|
+
data: {
|
|
146
|
+
tenantId,
|
|
147
|
+
channelId: input.channelId,
|
|
148
|
+
code: input.code.toUpperCase().replace(/\s+/g, '_'),
|
|
149
|
+
name: input.name,
|
|
150
|
+
description: input.description,
|
|
151
|
+
payloadSchema: input.payloadSchema,
|
|
152
|
+
enabled: input.enabled ?? true,
|
|
153
|
+
},
|
|
154
|
+
include: {
|
|
155
|
+
channel: { select: { code: true, name: true } },
|
|
156
|
+
handlers: {
|
|
157
|
+
select: { id: true, name: true, handlerType: true, enabled: true },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
return this.mapEventType(eventType);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* List event types for a tenant, optionally filtered by channel
|
|
165
|
+
*/
|
|
166
|
+
async listEventTypes(tenantId, channelId) {
|
|
167
|
+
const eventTypes = await this.prisma.eventType.findMany({
|
|
168
|
+
where: {
|
|
169
|
+
tenantId,
|
|
170
|
+
...(channelId && { channelId }),
|
|
171
|
+
},
|
|
172
|
+
include: {
|
|
173
|
+
channel: { select: { code: true, name: true } },
|
|
174
|
+
handlers: {
|
|
175
|
+
select: { id: true, name: true, handlerType: true, enabled: true },
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
orderBy: { code: 'asc' },
|
|
179
|
+
});
|
|
180
|
+
return eventTypes.map(this.mapEventType);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get an event type by ID
|
|
184
|
+
*/
|
|
185
|
+
async getEventType(tenantId, eventTypeId) {
|
|
186
|
+
const eventType = await this.prisma.eventType.findFirst({
|
|
187
|
+
where: { id: eventTypeId, tenantId },
|
|
188
|
+
include: {
|
|
189
|
+
channel: { select: { code: true, name: true } },
|
|
190
|
+
handlers: {
|
|
191
|
+
select: { id: true, name: true, handlerType: true, enabled: true },
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
return eventType ? this.mapEventType(eventType) : null;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Get an event type by code
|
|
199
|
+
*/
|
|
200
|
+
async getEventTypeByCode(tenantId, code) {
|
|
201
|
+
const eventType = await this.prisma.eventType.findFirst({
|
|
202
|
+
where: { tenantId, code: code.toUpperCase() },
|
|
203
|
+
include: {
|
|
204
|
+
channel: { select: { code: true, name: true } },
|
|
205
|
+
handlers: {
|
|
206
|
+
select: { id: true, name: true, handlerType: true, enabled: true },
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
return eventType ? this.mapEventType(eventType) : null;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Update an event type
|
|
214
|
+
*/
|
|
215
|
+
async updateEventType(tenantId, eventTypeId, input) {
|
|
216
|
+
const eventType = await this.prisma.eventType.update({
|
|
217
|
+
where: { id: eventTypeId, tenantId },
|
|
218
|
+
data: {
|
|
219
|
+
...(input.name !== undefined && { name: input.name }),
|
|
220
|
+
...(input.description !== undefined && { description: input.description }),
|
|
221
|
+
...(input.payloadSchema !== undefined && { payloadSchema: input.payloadSchema }),
|
|
222
|
+
...(input.enabled !== undefined && { enabled: input.enabled }),
|
|
223
|
+
},
|
|
224
|
+
include: {
|
|
225
|
+
channel: { select: { code: true, name: true } },
|
|
226
|
+
handlers: {
|
|
227
|
+
select: { id: true, name: true, handlerType: true, enabled: true },
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
return this.mapEventType(eventType);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Delete an event type (cascades to handlers)
|
|
235
|
+
*/
|
|
236
|
+
async deleteEventType(tenantId, eventTypeId) {
|
|
237
|
+
await this.prisma.eventType.delete({
|
|
238
|
+
where: { id: eventTypeId, tenantId },
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
// ==========================================
|
|
242
|
+
// EVENT HANDLERS
|
|
243
|
+
// ==========================================
|
|
244
|
+
/**
|
|
245
|
+
* Create an event handler
|
|
246
|
+
*/
|
|
247
|
+
async createHandler(tenantId, input) {
|
|
248
|
+
const handler = await this.prisma.eventHandler.create({
|
|
249
|
+
data: {
|
|
250
|
+
tenantId,
|
|
251
|
+
eventTypeId: input.eventTypeId,
|
|
252
|
+
name: input.name,
|
|
253
|
+
description: input.description,
|
|
254
|
+
handlerType: input.handlerType,
|
|
255
|
+
config: input.config,
|
|
256
|
+
priority: input.priority ?? 100,
|
|
257
|
+
enabled: input.enabled ?? true,
|
|
258
|
+
maxRetries: input.maxRetries ?? 3,
|
|
259
|
+
retryDelayMs: input.retryDelayMs ?? 1000,
|
|
260
|
+
filterCondition: input.filterCondition,
|
|
261
|
+
},
|
|
262
|
+
include: {
|
|
263
|
+
eventType: {
|
|
264
|
+
select: {
|
|
265
|
+
code: true,
|
|
266
|
+
name: true,
|
|
267
|
+
channel: { select: { code: true, name: true } },
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
return this.mapHandler(handler);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* List handlers for an event type
|
|
276
|
+
*/
|
|
277
|
+
async listHandlers(tenantId, eventTypeId) {
|
|
278
|
+
const handlers = await this.prisma.eventHandler.findMany({
|
|
279
|
+
where: {
|
|
280
|
+
tenantId,
|
|
281
|
+
...(eventTypeId && { eventTypeId }),
|
|
282
|
+
},
|
|
283
|
+
include: {
|
|
284
|
+
eventType: {
|
|
285
|
+
select: {
|
|
286
|
+
code: true,
|
|
287
|
+
name: true,
|
|
288
|
+
channel: { select: { code: true, name: true } },
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
orderBy: [{ eventTypeId: 'asc' }, { priority: 'asc' }],
|
|
293
|
+
});
|
|
294
|
+
return handlers.map(this.mapHandler);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get a handler by ID
|
|
298
|
+
*/
|
|
299
|
+
async getHandler(tenantId, handlerId) {
|
|
300
|
+
const handler = await this.prisma.eventHandler.findFirst({
|
|
301
|
+
where: { id: handlerId, tenantId },
|
|
302
|
+
include: {
|
|
303
|
+
eventType: {
|
|
304
|
+
select: {
|
|
305
|
+
code: true,
|
|
306
|
+
name: true,
|
|
307
|
+
channel: { select: { code: true, name: true } },
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
return handler ? this.mapHandler(handler) : null;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Update a handler
|
|
316
|
+
*/
|
|
317
|
+
async updateHandler(tenantId, handlerId, input) {
|
|
318
|
+
const handler = await this.prisma.eventHandler.update({
|
|
319
|
+
where: { id: handlerId, tenantId },
|
|
320
|
+
data: {
|
|
321
|
+
...(input.name !== undefined && { name: input.name }),
|
|
322
|
+
...(input.description !== undefined && { description: input.description }),
|
|
323
|
+
...(input.config !== undefined && { config: input.config }),
|
|
324
|
+
...(input.priority !== undefined && { priority: input.priority }),
|
|
325
|
+
...(input.enabled !== undefined && { enabled: input.enabled }),
|
|
326
|
+
...(input.maxRetries !== undefined && { maxRetries: input.maxRetries }),
|
|
327
|
+
...(input.retryDelayMs !== undefined && { retryDelayMs: input.retryDelayMs }),
|
|
328
|
+
...(input.filterCondition !== undefined && { filterCondition: input.filterCondition }),
|
|
329
|
+
},
|
|
330
|
+
include: {
|
|
331
|
+
eventType: {
|
|
332
|
+
select: {
|
|
333
|
+
code: true,
|
|
334
|
+
name: true,
|
|
335
|
+
channel: { select: { code: true, name: true } },
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
return this.mapHandler(handler);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Delete a handler
|
|
344
|
+
*/
|
|
345
|
+
async deleteHandler(tenantId, handlerId) {
|
|
346
|
+
await this.prisma.eventHandler.delete({
|
|
347
|
+
where: { id: handlerId, tenantId },
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Enable or disable a handler
|
|
352
|
+
*/
|
|
353
|
+
async setHandlerEnabled(tenantId, handlerId, enabled) {
|
|
354
|
+
await this.prisma.eventHandler.update({
|
|
355
|
+
where: { id: handlerId, tenantId },
|
|
356
|
+
data: { enabled },
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// ==========================================
|
|
360
|
+
// HELPER METHODS
|
|
361
|
+
// ==========================================
|
|
362
|
+
mapChannel(channel) {
|
|
363
|
+
return {
|
|
364
|
+
id: channel.id,
|
|
365
|
+
tenantId: channel.tenantId,
|
|
366
|
+
code: channel.code,
|
|
367
|
+
name: channel.name,
|
|
368
|
+
description: channel.description,
|
|
369
|
+
enabled: channel.enabled,
|
|
370
|
+
eventTypes: channel.eventTypes,
|
|
371
|
+
createdAt: channel.createdAt,
|
|
372
|
+
updatedAt: channel.updatedAt,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
mapEventType(eventType) {
|
|
376
|
+
return {
|
|
377
|
+
id: eventType.id,
|
|
378
|
+
tenantId: eventType.tenantId,
|
|
379
|
+
channelId: eventType.channelId,
|
|
380
|
+
channel: eventType.channel,
|
|
381
|
+
code: eventType.code,
|
|
382
|
+
name: eventType.name,
|
|
383
|
+
description: eventType.description,
|
|
384
|
+
payloadSchema: eventType.payloadSchema,
|
|
385
|
+
enabled: eventType.enabled,
|
|
386
|
+
handlers: eventType.handlers,
|
|
387
|
+
createdAt: eventType.createdAt,
|
|
388
|
+
updatedAt: eventType.updatedAt,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
mapHandler(handler) {
|
|
392
|
+
return {
|
|
393
|
+
id: handler.id,
|
|
394
|
+
tenantId: handler.tenantId,
|
|
395
|
+
eventTypeId: handler.eventTypeId,
|
|
396
|
+
eventType: handler.eventType,
|
|
397
|
+
name: handler.name,
|
|
398
|
+
description: handler.description,
|
|
399
|
+
handlerType: handler.handlerType,
|
|
400
|
+
config: handler.config,
|
|
401
|
+
priority: handler.priority,
|
|
402
|
+
enabled: handler.enabled,
|
|
403
|
+
maxRetries: handler.maxRetries,
|
|
404
|
+
retryDelayMs: handler.retryDelayMs,
|
|
405
|
+
filterCondition: handler.filterCondition,
|
|
406
|
+
createdAt: handler.createdAt,
|
|
407
|
+
updatedAt: handler.updatedAt,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Create an event config service instance
|
|
413
|
+
*/
|
|
414
|
+
export function createEventConfigService(prisma) {
|
|
415
|
+
return new EventConfigService(prisma);
|
|
416
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Type Seeder
|
|
3
|
+
*
|
|
4
|
+
* Utilities for seeding EventChannel, EventType, and EventHandler records.
|
|
5
|
+
* This allows admins to configure event-driven workflows programmatically.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { seedContractEventTypes } from '@valentine-efagene/qshelter-common';
|
|
10
|
+
*
|
|
11
|
+
* await seedContractEventTypes(prisma, tenantId);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import { PrismaClient } from '../../../generated/client/client';
|
|
15
|
+
/**
|
|
16
|
+
* Event type definition for seeding
|
|
17
|
+
*/
|
|
18
|
+
export interface EventTypeDefinition {
|
|
19
|
+
code: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
channelCode: string;
|
|
23
|
+
payloadSchema?: any;
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Event channel definition for seeding
|
|
28
|
+
*/
|
|
29
|
+
export interface EventChannelDefinition {
|
|
30
|
+
code: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Event handler definition for seeding
|
|
37
|
+
*/
|
|
38
|
+
export interface EventHandlerDefinition {
|
|
39
|
+
eventTypeCode: string;
|
|
40
|
+
name: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
handlerType: 'SEND_EMAIL' | 'SEND_SMS' | 'SEND_PUSH' | 'CALL_WEBHOOK' | 'ADVANCE_WORKFLOW' | 'RUN_AUTOMATION';
|
|
43
|
+
config: any;
|
|
44
|
+
priority?: number;
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
maxRetries?: number;
|
|
47
|
+
retryDelayMs?: number;
|
|
48
|
+
filterCondition?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Seed event channels
|
|
52
|
+
*/
|
|
53
|
+
export declare function seedEventChannels(prisma: PrismaClient, tenantId: string, channels: EventChannelDefinition[]): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Seed event types
|
|
56
|
+
*/
|
|
57
|
+
export declare function seedEventTypes(prisma: PrismaClient, tenantId: string, eventTypes: EventTypeDefinition[]): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Seed event handlers
|
|
60
|
+
*/
|
|
61
|
+
export declare function seedEventHandlers(prisma: PrismaClient, tenantId: string, handlers: EventHandlerDefinition[]): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Contract event channels
|
|
64
|
+
*/
|
|
65
|
+
export declare const CONTRACT_CHANNELS: EventChannelDefinition[];
|
|
66
|
+
/**
|
|
67
|
+
* Contract event types
|
|
68
|
+
*/
|
|
69
|
+
export declare const CONTRACT_EVENT_TYPES: EventTypeDefinition[];
|
|
70
|
+
/**
|
|
71
|
+
* Seed all contract event types
|
|
72
|
+
*/
|
|
73
|
+
export declare function seedContractEventTypes(prisma: PrismaClient, tenantId: string): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Seed example email notification handlers
|
|
76
|
+
*
|
|
77
|
+
* Note: In production, admins would configure these via the UI.
|
|
78
|
+
* This is just an example for testing.
|
|
79
|
+
*/
|
|
80
|
+
export declare function seedExampleEmailHandlers(prisma: PrismaClient, tenantId: string): Promise<void>;
|