@valentine-efagene/qshelter-common 2.0.65 → 2.0.67

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.
Files changed (36) hide show
  1. package/dist/generated/client/browser.d.ts +29 -0
  2. package/dist/generated/client/client.d.ts +29 -0
  3. package/dist/generated/client/commonInputTypes.d.ts +120 -0
  4. package/dist/generated/client/enums.d.ts +32 -0
  5. package/dist/generated/client/enums.js +28 -0
  6. package/dist/generated/client/internal/class.d.ts +55 -0
  7. package/dist/generated/client/internal/class.js +2 -2
  8. package/dist/generated/client/internal/prismaNamespace.d.ts +475 -1
  9. package/dist/generated/client/internal/prismaNamespace.js +113 -0
  10. package/dist/generated/client/internal/prismaNamespaceBrowser.d.ts +123 -0
  11. package/dist/generated/client/internal/prismaNamespaceBrowser.js +113 -0
  12. package/dist/generated/client/models/EventChannel.d.ts +1305 -0
  13. package/dist/generated/client/models/EventChannel.js +1 -0
  14. package/dist/generated/client/models/EventHandler.d.ts +1749 -0
  15. package/dist/generated/client/models/EventHandler.js +1 -0
  16. package/dist/generated/client/models/EventHandlerExecution.d.ts +1525 -0
  17. package/dist/generated/client/models/EventHandlerExecution.js +1 -0
  18. package/dist/generated/client/models/EventType.d.ts +1653 -0
  19. package/dist/generated/client/models/EventType.js +1 -0
  20. package/dist/generated/client/models/Tenant.d.ts +796 -0
  21. package/dist/generated/client/models/WorkflowEvent.d.ts +1654 -0
  22. package/dist/generated/client/models/WorkflowEvent.js +1 -0
  23. package/dist/generated/client/models/index.d.ts +5 -0
  24. package/dist/generated/client/models/index.js +5 -0
  25. package/dist/generated/client/models.d.ts +5 -0
  26. package/dist/src/events/event-config.service.d.ts +123 -0
  27. package/dist/src/events/event-config.service.js +416 -0
  28. package/dist/src/events/index.d.ts +3 -0
  29. package/dist/src/events/index.js +5 -0
  30. package/dist/src/events/workflow-event.service.d.ts +189 -0
  31. package/dist/src/events/workflow-event.service.js +588 -0
  32. package/dist/src/events/workflow-types.d.ts +288 -0
  33. package/dist/src/events/workflow-types.js +14 -0
  34. package/package.json +1 -1
  35. package/prisma/migrations/20260105151535_add_event_workflow_system/migration.sql +132 -0
  36. package/prisma/schema.prisma +271 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -15,6 +15,10 @@ export * from './DocumentationStepApproval';
15
15
  export * from './DocumentationStepDocument';
16
16
  export * from './DomainEvent';
17
17
  export * from './EmailPreference';
18
+ export * from './EventChannel';
19
+ export * from './EventHandler';
20
+ export * from './EventHandlerExecution';
21
+ export * from './EventType';
18
22
  export * from './OAuthState';
19
23
  export * from './OfferLetter';
20
24
  export * from './PasswordReset';
@@ -45,3 +49,4 @@ export * from './User';
45
49
  export * from './UserRole';
46
50
  export * from './UserSuspension';
47
51
  export * from './Wallet';
52
+ export * from './WorkflowEvent';
@@ -15,6 +15,10 @@ export * from './DocumentationStepApproval';
15
15
  export * from './DocumentationStepDocument';
16
16
  export * from './DomainEvent';
17
17
  export * from './EmailPreference';
18
+ export * from './EventChannel';
19
+ export * from './EventHandler';
20
+ export * from './EventHandlerExecution';
21
+ export * from './EventType';
18
22
  export * from './OAuthState';
19
23
  export * from './OfferLetter';
20
24
  export * from './PasswordReset';
@@ -45,3 +49,4 @@ export * from './User';
45
49
  export * from './UserRole';
46
50
  export * from './UserSuspension';
47
51
  export * from './Wallet';
52
+ export * from './WorkflowEvent';
@@ -44,5 +44,10 @@ export type * from './models/OfferLetter.js';
44
44
  export type * from './models/ContractTermination.js';
45
45
  export type * from './models/PaymentMethodChangeRequest.js';
46
46
  export type * from './models/DocumentRequirementRule.js';
47
+ export type * from './models/EventChannel.js';
48
+ export type * from './models/EventType.js';
49
+ export type * from './models/EventHandler.js';
50
+ export type * from './models/WorkflowEvent.js';
51
+ export type * from './models/EventHandlerExecution.js';
47
52
  export type * from './models/DomainEvent.js';
48
53
  export type * from './commonInputTypes.js';
@@ -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
+ }
@@ -1,3 +1,6 @@
1
1
  export * from './notification-enums';
2
2
  export * from './notification-event';
3
3
  export * from './event-publisher';
4
+ export * from './workflow-types';
5
+ export * from './event-config.service';
6
+ export * from './workflow-event.service';
@@ -1,3 +1,8 @@
1
+ // Notification events (legacy)
1
2
  export * from './notification-enums';
2
3
  export * from './notification-event';
3
4
  export * from './event-publisher';
5
+ // Event-driven workflow system
6
+ export * from './workflow-types';
7
+ export * from './event-config.service';
8
+ export * from './workflow-event.service';