@tstdl/base 0.93.123 → 0.93.125

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 (27) hide show
  1. package/document-management/server/drizzle/{0000_silly_chimera.sql → 0000_complex_black_bird.sql} +1 -1
  2. package/document-management/server/drizzle/meta/0000_snapshot.json +3 -3
  3. package/document-management/server/drizzle/meta/_journal.json +2 -2
  4. package/notification/api/notification.api.d.ts +26 -6
  5. package/notification/api/notification.api.js +15 -4
  6. package/notification/client/notification-client.d.ts +6 -0
  7. package/notification/client/notification-client.js +13 -3
  8. package/notification/models/in-app-notification.model.d.ts +9 -3
  9. package/notification/models/in-app-notification.model.js +32 -11
  10. package/notification/models/notification-log.model.js +2 -3
  11. package/notification/server/api/notification.api-controller.d.ts +1 -0
  12. package/notification/server/api/notification.api-controller.js +7 -1
  13. package/notification/server/drizzle/{0000_oval_rage.sql → 0000_wise_pyro.sql} +22 -4
  14. package/notification/server/drizzle/meta/0000_snapshot.json +249 -37
  15. package/notification/server/drizzle/meta/_journal.json +2 -2
  16. package/notification/server/module.d.ts +5 -0
  17. package/notification/server/module.js +6 -1
  18. package/notification/server/providers/in-app-channel-provider.js +1 -0
  19. package/notification/server/schemas.d.ts +3 -2
  20. package/notification/server/schemas.js +3 -2
  21. package/notification/server/services/notification.service.d.ts +11 -6
  22. package/notification/server/services/notification.service.js +138 -42
  23. package/notification/tests/notification-api.test.js +8 -1
  24. package/notification/tests/notification-flow.test.js +41 -4
  25. package/orm/server/drizzle/schema-converter.js +5 -3
  26. package/orm/tests/schema-converter.test.js +1 -0
  27. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
- "id": "90cd6144-d455-4a13-8148-ca119f8bfe79",
2
+ "id": "23b5cedb-d56a-4f37-b838-fc9874b72ce3",
3
3
  "prevId": "00000000-0000-0000-0000-000000000000",
4
4
  "version": "7",
5
5
  "dialect": "postgresql",
@@ -33,6 +33,12 @@
33
33
  "primaryKey": false,
34
34
  "notNull": true
35
35
  },
36
+ "timestamp": {
37
+ "name": "timestamp",
38
+ "type": "timestamp with time zone",
39
+ "primaryKey": false,
40
+ "notNull": true
41
+ },
36
42
  "read_timestamp": {
37
43
  "name": "read_timestamp",
38
44
  "type": "timestamp with time zone",
@@ -47,8 +53,23 @@
47
53
  }
48
54
  },
49
55
  "indexes": {
50
- "in_app_tenant_id_user_id_log_id_idx": {
51
- "name": "in_app_tenant_id_user_id_log_id_idx",
56
+ "in_app_timestamp_idx": {
57
+ "name": "in_app_timestamp_idx",
58
+ "columns": [
59
+ {
60
+ "expression": "timestamp",
61
+ "isExpression": false,
62
+ "asc": true,
63
+ "nulls": "last"
64
+ }
65
+ ],
66
+ "isUnique": false,
67
+ "concurrently": false,
68
+ "method": "brin",
69
+ "with": {}
70
+ },
71
+ "in_app_tenant_id_user_id_read_timestamp_partial_idx": {
72
+ "name": "in_app_tenant_id_user_id_read_timestamp_partial_idx",
52
73
  "columns": [
53
74
  {
54
75
  "expression": "tenant_id",
@@ -62,15 +83,82 @@
62
83
  "asc": true,
63
84
  "nulls": "last"
64
85
  },
86
+ {
87
+ "expression": "read_timestamp",
88
+ "isExpression": false,
89
+ "asc": true,
90
+ "nulls": "last"
91
+ }
92
+ ],
93
+ "isUnique": false,
94
+ "where": "\"notification\".\"in_app\".\"read_timestamp\" is not null",
95
+ "concurrently": false,
96
+ "method": "btree",
97
+ "with": {}
98
+ },
99
+ "in_app_tenant_id_user_id_timestamp_log_id_partial_idx": {
100
+ "name": "in_app_tenant_id_user_id_timestamp_log_id_partial_idx",
101
+ "columns": [
102
+ {
103
+ "expression": "tenant_id",
104
+ "isExpression": false,
105
+ "asc": true,
106
+ "nulls": "last"
107
+ },
108
+ {
109
+ "expression": "user_id",
110
+ "isExpression": false,
111
+ "asc": true,
112
+ "nulls": "last"
113
+ },
114
+ {
115
+ "expression": "timestamp",
116
+ "isExpression": false,
117
+ "asc": false,
118
+ "nulls": "last"
119
+ },
65
120
  {
66
121
  "expression": "log_id",
67
122
  "isExpression": false,
123
+ "asc": false,
124
+ "nulls": "last"
125
+ }
126
+ ],
127
+ "isUnique": false,
128
+ "where": "\"notification\".\"in_app\".\"read_timestamp\" is null",
129
+ "concurrently": false,
130
+ "method": "btree",
131
+ "with": {}
132
+ },
133
+ "in_app_tenant_id_user_id_timestamp_log_id_idx": {
134
+ "name": "in_app_tenant_id_user_id_timestamp_log_id_idx",
135
+ "columns": [
136
+ {
137
+ "expression": "tenant_id",
138
+ "isExpression": false,
68
139
  "asc": true,
69
140
  "nulls": "last"
141
+ },
142
+ {
143
+ "expression": "user_id",
144
+ "isExpression": false,
145
+ "asc": true,
146
+ "nulls": "last"
147
+ },
148
+ {
149
+ "expression": "timestamp",
150
+ "isExpression": false,
151
+ "asc": false,
152
+ "nulls": "last"
153
+ },
154
+ {
155
+ "expression": "log_id",
156
+ "isExpression": false,
157
+ "asc": false,
158
+ "nulls": "last"
70
159
  }
71
160
  ],
72
161
  "isUnique": false,
73
- "where": "\"notification\".\"in_app\".\"archive_timestamp\" is null",
74
162
  "concurrently": false,
75
163
  "method": "btree",
76
164
  "with": {}
@@ -121,6 +209,158 @@
121
209
  ]
122
210
  }
123
211
  },
212
+ "uniqueConstraints": {
213
+ "in_app_tenant_id_user_id_log_id_unique": {
214
+ "name": "in_app_tenant_id_user_id_log_id_unique",
215
+ "nullsNotDistinct": false,
216
+ "columns": [
217
+ "tenant_id",
218
+ "user_id",
219
+ "log_id"
220
+ ]
221
+ }
222
+ },
223
+ "policies": {},
224
+ "checkConstraints": {},
225
+ "isRLSEnabled": false
226
+ },
227
+ "notification.in_app_archive": {
228
+ "name": "in_app_archive",
229
+ "schema": "notification",
230
+ "columns": {
231
+ "id": {
232
+ "name": "id",
233
+ "type": "uuid",
234
+ "primaryKey": false,
235
+ "notNull": true,
236
+ "default": "gen_random_uuid()"
237
+ },
238
+ "tenant_id": {
239
+ "name": "tenant_id",
240
+ "type": "uuid",
241
+ "primaryKey": false,
242
+ "notNull": true
243
+ },
244
+ "user_id": {
245
+ "name": "user_id",
246
+ "type": "uuid",
247
+ "primaryKey": false,
248
+ "notNull": true
249
+ },
250
+ "log_id": {
251
+ "name": "log_id",
252
+ "type": "uuid",
253
+ "primaryKey": false,
254
+ "notNull": true
255
+ },
256
+ "timestamp": {
257
+ "name": "timestamp",
258
+ "type": "timestamp with time zone",
259
+ "primaryKey": false,
260
+ "notNull": true
261
+ },
262
+ "read_timestamp": {
263
+ "name": "read_timestamp",
264
+ "type": "timestamp with time zone",
265
+ "primaryKey": false,
266
+ "notNull": false
267
+ },
268
+ "archive_timestamp": {
269
+ "name": "archive_timestamp",
270
+ "type": "timestamp with time zone",
271
+ "primaryKey": false,
272
+ "notNull": false
273
+ }
274
+ },
275
+ "indexes": {
276
+ "in_app_archive_tenant_id_user_id_archive_timestamp_idx": {
277
+ "name": "in_app_archive_tenant_id_user_id_archive_timestamp_idx",
278
+ "columns": [
279
+ {
280
+ "expression": "tenant_id",
281
+ "isExpression": false,
282
+ "asc": true,
283
+ "nulls": "last"
284
+ },
285
+ {
286
+ "expression": "user_id",
287
+ "isExpression": false,
288
+ "asc": true,
289
+ "nulls": "last"
290
+ },
291
+ {
292
+ "expression": "archive_timestamp",
293
+ "isExpression": false,
294
+ "asc": false,
295
+ "nulls": "last"
296
+ }
297
+ ],
298
+ "isUnique": false,
299
+ "concurrently": false,
300
+ "method": "btree",
301
+ "with": {}
302
+ },
303
+ "in_app_archive_tenant_id_user_id_timestamp_log_id_idx": {
304
+ "name": "in_app_archive_tenant_id_user_id_timestamp_log_id_idx",
305
+ "columns": [
306
+ {
307
+ "expression": "tenant_id",
308
+ "isExpression": false,
309
+ "asc": true,
310
+ "nulls": "last"
311
+ },
312
+ {
313
+ "expression": "user_id",
314
+ "isExpression": false,
315
+ "asc": true,
316
+ "nulls": "last"
317
+ },
318
+ {
319
+ "expression": "timestamp",
320
+ "isExpression": false,
321
+ "asc": false,
322
+ "nulls": "last"
323
+ },
324
+ {
325
+ "expression": "log_id",
326
+ "isExpression": false,
327
+ "asc": false,
328
+ "nulls": "last"
329
+ }
330
+ ],
331
+ "isUnique": false,
332
+ "concurrently": false,
333
+ "method": "btree",
334
+ "with": {}
335
+ }
336
+ },
337
+ "foreignKeys": {
338
+ "in_app_archive_id_user_fkey": {
339
+ "name": "in_app_archive_id_user_fkey",
340
+ "tableFrom": "in_app_archive",
341
+ "tableTo": "user",
342
+ "schemaTo": "authentication",
343
+ "columnsFrom": [
344
+ "tenant_id",
345
+ "user_id"
346
+ ],
347
+ "columnsTo": [
348
+ "tenant_id",
349
+ "id"
350
+ ],
351
+ "onDelete": "no action",
352
+ "onUpdate": "no action"
353
+ }
354
+ },
355
+ "compositePrimaryKeys": {
356
+ "in_app_archive_tenant_id_id_pk": {
357
+ "name": "in_app_archive_tenant_id_id_pk",
358
+ "columns": [
359
+ "tenant_id",
360
+ "id"
361
+ ]
362
+ }
363
+ },
124
364
  "uniqueConstraints": {},
125
365
  "policies": {},
126
366
  "checkConstraints": {},
@@ -194,35 +434,7 @@
194
434
  "notNull": false
195
435
  }
196
436
  },
197
- "indexes": {
198
- "log_tenant_id_user_id_timestamp_idx": {
199
- "name": "log_tenant_id_user_id_timestamp_idx",
200
- "columns": [
201
- {
202
- "expression": "tenant_id",
203
- "isExpression": false,
204
- "asc": true,
205
- "nulls": "last"
206
- },
207
- {
208
- "expression": "user_id",
209
- "isExpression": false,
210
- "asc": true,
211
- "nulls": "last"
212
- },
213
- {
214
- "expression": "timestamp",
215
- "isExpression": false,
216
- "asc": true,
217
- "nulls": "last"
218
- }
219
- ],
220
- "isUnique": false,
221
- "concurrently": false,
222
- "method": "btree",
223
- "with": {}
224
- }
225
- },
437
+ "indexes": {},
226
438
  "foreignKeys": {
227
439
  "log_type_type_key_fk": {
228
440
  "name": "log_type_type_key_fk",
@@ -281,13 +493,13 @@
281
493
  }
282
494
  },
283
495
  "uniqueConstraints": {
284
- "log_tenant_id_id_user_id_unique": {
285
- "name": "log_tenant_id_id_user_id_unique",
496
+ "log_tenant_id_user_id_id_unique": {
497
+ "name": "log_tenant_id_user_id_id_unique",
286
498
  "nullsNotDistinct": false,
287
499
  "columns": [
288
500
  "tenant_id",
289
- "id",
290
- "user_id"
501
+ "user_id",
502
+ "id"
291
503
  ]
292
504
  }
293
505
  },
@@ -5,8 +5,8 @@
5
5
  {
6
6
  "idx": 0,
7
7
  "version": "7",
8
- "when": 1770233636064,
9
- "tag": "0000_oval_rage",
8
+ "when": 1770754328787,
9
+ "tag": "0000_wise_pyro",
10
10
  "breakpoints": true
11
11
  }
12
12
  ]
@@ -6,6 +6,11 @@ export declare class NotificationConfiguration {
6
6
  database?: DatabaseConfig;
7
7
  defaultChannels?: NotificationChannel[];
8
8
  ancillaryService?: InjectionToken<NotificationAncillaryService<any>>;
9
+ /**
10
+ * The duration in milliseconds after which notifications should be automatically archived.
11
+ * Defaults to 30 days.
12
+ */
13
+ autoArchiveAfter?: number;
9
14
  }
10
15
  export declare function configureNotification({ injector, ...config }: NotificationConfiguration & {
11
16
  injector?: Injector;
@@ -6,10 +6,15 @@ export class NotificationConfiguration {
6
6
  database;
7
7
  defaultChannels;
8
8
  ancillaryService;
9
+ /**
10
+ * The duration in milliseconds after which notifications should be automatically archived.
11
+ * Defaults to 30 days.
12
+ */
13
+ autoArchiveAfter;
9
14
  }
10
15
  export function configureNotification({ injector, ...config }) {
11
16
  const targetInjector = injector ?? Injector;
12
- targetInjector.register(NotificationConfiguration, { useValue: config });
17
+ targetInjector.register(NotificationConfiguration, { useValue: { autoArchiveAfter: 30 * 24 * 60 * 60 * 1000, ...config } });
13
18
  if (isDefined(config.ancillaryService)) {
14
19
  targetInjector.register(NotificationAncillaryService, { useToken: config.ancillaryService });
15
20
  }
@@ -19,6 +19,7 @@ let InAppChannelProvider = class InAppChannelProvider extends ChannelProvider {
19
19
  tenantId: notification.tenantId,
20
20
  userId: notification.userId,
21
21
  logId: notification.id,
22
+ timestamp: notification.timestamp,
22
23
  readTimestamp: null,
23
24
  archiveTimestamp: null,
24
25
  });
@@ -1,4 +1,4 @@
1
- import { InAppNotification, NotificationLogEntity, NotificationPreference, NotificationType, WebPushSubscription } from '../models/index.js';
1
+ import { InAppNotification, InAppNotificationArchive, NotificationLogEntity, NotificationPreference, NotificationType, WebPushSubscription } from '../models/index.js';
2
2
  export declare const notificationSchema: import("../../orm/server/index.js").DatabaseSchema<"notification">;
3
3
  export declare const notificationChannel: import("../../orm/enums.js").PgEnumFromEnumeration<{
4
4
  readonly InApp: "in-app";
@@ -19,7 +19,8 @@ export declare const notificationStatus: import("../../orm/enums.js").PgEnumFrom
19
19
  readonly Failed: "failed";
20
20
  }>;
21
21
  export declare const inAppNotification: import("../../orm/server/types.js").PgTableFromType<typeof InAppNotification, "notification">;
22
- export declare const notificationType: import("../../orm/server/types.js").PgTableFromType<typeof NotificationType, "notification">;
22
+ export declare const inAppNotificationArchive: import("../../orm/server/types.js").PgTableFromType<typeof InAppNotificationArchive, "notification">;
23
23
  export declare const notificationLog: import("../../orm/server/types.js").PgTableFromType<typeof NotificationLogEntity, "notification">;
24
24
  export declare const notificationPreference: import("../../orm/server/types.js").PgTableFromType<typeof NotificationPreference, "notification">;
25
+ export declare const notificationType: import("../../orm/server/types.js").PgTableFromType<typeof NotificationType, "notification">;
25
26
  export declare const webPushSubscription: import("../../orm/server/types.js").PgTableFromType<typeof WebPushSubscription, "notification">;
@@ -1,11 +1,12 @@
1
1
  import { databaseSchema } from '../../orm/server/index.js';
2
- import { InAppNotification, NotificationChannel, NotificationLogEntity, NotificationPreference, NotificationPriority, NotificationStatus, NotificationType, WebPushSubscription } from '../models/index.js';
2
+ import { InAppNotification, InAppNotificationArchive, NotificationChannel, NotificationLogEntity, NotificationPreference, NotificationPriority, NotificationStatus, NotificationType, WebPushSubscription } from '../models/index.js';
3
3
  export const notificationSchema = databaseSchema('notification');
4
4
  export const notificationChannel = notificationSchema.getEnum(NotificationChannel);
5
5
  export const notificationPriority = notificationSchema.getEnum(NotificationPriority);
6
6
  export const notificationStatus = notificationSchema.getEnum(NotificationStatus);
7
7
  export const inAppNotification = notificationSchema.getTable(InAppNotification);
8
- export const notificationType = notificationSchema.getTable(NotificationType);
8
+ export const inAppNotificationArchive = notificationSchema.getTable(InAppNotificationArchive);
9
9
  export const notificationLog = notificationSchema.getTable(NotificationLogEntity);
10
10
  export const notificationPreference = notificationSchema.getTable(NotificationPreference);
11
+ export const notificationType = notificationSchema.getTable(NotificationType);
11
12
  export const webPushSubscription = notificationSchema.getTable(WebPushSubscription);
@@ -1,7 +1,7 @@
1
- import { type NewEntity } from '../../../orm/index.js';
1
+ import { type NewEntity, type Query } from '../../../orm/index.js';
2
2
  import { Transactional, type Transaction } from '../../../orm/server/index.js';
3
3
  import type { TypedOmit } from '../../../types/types.js';
4
- import { NotificationChannel, NotificationPreference, type InAppNotificationView, type NotificationDefinitionMap, type NotificationLog } from '../../models/index.js';
4
+ import { NotificationChannel, NotificationLogEntity, NotificationPreference, type InAppNotificationView, type NotificationDefinitionMap, type NotificationLog } from '../../models/index.js';
5
5
  export type NewNotificationData<Definitions extends NotificationDefinitionMap = NotificationDefinitionMap> = TypedOmit<NewEntity<NotificationLog<Definitions>>, 'tenantId' | 'id' | 'userId' | 'timestamp' | 'status' | 'currentStep' | 'priority'> & Partial<Pick<NotificationLog<Definitions>, 'priority'>>;
6
6
  export declare class NotificationService<Definitions extends NotificationDefinitionMap = NotificationDefinitionMap> extends Transactional {
7
7
  #private;
@@ -11,22 +11,27 @@ export declare class NotificationService<Definitions extends NotificationDefinit
11
11
  listInApp(tenantId: string, userId: string, options?: {
12
12
  limit?: number;
13
13
  offset?: number;
14
- after?: string;
15
- includeArchived?: boolean;
14
+ after?: number | string;
16
15
  unreadOnly?: boolean;
17
16
  }): Promise<InAppNotificationView[]>;
17
+ listArchivedInApp(tenantId: string, userId: string, options?: {
18
+ limit?: number;
19
+ offset?: number;
20
+ after?: number | string;
21
+ }): Promise<InAppNotificationView[]>;
18
22
  markRead(tenantId: string, userId: string, id: string): Promise<void>;
19
23
  markAllRead(tenantId: string, userId: string): Promise<void>;
20
24
  archive(tenantId: string, userId: string, id: string): Promise<void>;
25
+ archiveByQuery(tenantId: string, query: Query<NotificationLogEntity>): Promise<void>;
21
26
  archiveAll(tenantId: string, userId: string): Promise<void>;
27
+ runAutoArchive(): Promise<void>;
22
28
  unreadCount(tenantId: string, userId: string): Promise<number>;
23
- getCatchupData(tenantId: string, userId: string, lastNotificationId: string): Promise<{
29
+ getCatchupData(tenantId: string, userId: string, stateTimestamp: number): Promise<{
24
30
  unreadCount: number;
25
31
  missedNotifications: InAppNotificationView[];
26
32
  readIds: string[];
27
33
  archiveIds: string[];
28
34
  }>;
29
- getTimestamp(tenantId: string, userId: string, inAppId: string): Promise<number>;
30
35
  getPreferences(tenantId: string, userId: string): Promise<NotificationPreference[]>;
31
36
  updatePreference(tenantId: string, userId: string, type: string, channel: NotificationChannel, enabled: boolean): Promise<void>;
32
37
  registerWebPush(tenantId: string, userId: string, endpoint: string, p256dh: Uint8Array<ArrayBuffer>, auth: Uint8Array<ArrayBuffer>): Promise<void>;