@timothyw/pat-common 1.0.101 → 1.0.102
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/enums/module-type.d.ts +1 -0
- package/dist/enums/module-type.js +1 -0
- package/dist/types/api/account/update-user-types.d.ts +3 -3
- package/dist/types/api/auth/create-account-types.d.ts +2 -1
- package/dist/types/api/habits/create-habit-types.d.ts +2 -2
- package/dist/types/api/habits/update-habit-types.d.ts +2 -2
- package/dist/types/api/index.d.ts +1 -0
- package/dist/types/api/index.js +1 -0
- package/dist/types/api/notifications/create-notification-template-types.d.ts +93 -0
- package/dist/types/api/notifications/create-notification-template-types.js +31 -0
- package/dist/types/api/notifications/delete-notification-template-types.d.ts +14 -0
- package/dist/types/api/notifications/delete-notification-template-types.js +11 -0
- package/dist/types/api/notifications/get-notification-instances-types.d.ts +45 -0
- package/dist/types/api/notifications/get-notification-instances-types.js +19 -0
- package/dist/types/api/notifications/get-notification-templates-types.d.ts +23 -0
- package/dist/types/api/notifications/get-notification-templates-types.js +12 -0
- package/dist/types/api/notifications/index.d.ts +7 -0
- package/dist/types/api/notifications/index.js +23 -0
- package/dist/types/api/notifications/preview-notification-template-types.d.ts +58 -0
- package/dist/types/api/notifications/preview-notification-template-types.js +23 -0
- package/dist/types/api/notifications/sync-notification-template-types.d.ts +29 -0
- package/dist/types/api/notifications/sync-notification-template-types.js +14 -0
- package/dist/types/api/notifications/update-notification-template-types.d.ts +84 -0
- package/dist/types/api/notifications/update-notification-template-types.js +28 -0
- package/dist/types/api/people/create-person-note-types.d.ts +2 -2
- package/dist/types/id-types.d.ts +8 -0
- package/dist/types/id-types.js +3 -1
- package/dist/types/models/index.d.ts +3 -0
- package/dist/types/models/index.js +3 -0
- package/dist/types/models/notifiable.d.ts +42 -0
- package/dist/types/models/notifiable.js +2 -0
- package/dist/types/models/notification-instance-data.d.ts +128 -0
- package/dist/types/models/notification-instance-data.js +34 -0
- package/dist/types/models/notification-template-data.d.ts +202 -0
- package/dist/types/models/notification-template-data.js +38 -0
- package/dist/types/models/user-data.d.ts +2 -2
- package/dist/utils/serializing-utils.d.ts +5 -1
- package/dist/utils/serializing-utils.js +12 -0
- package/package.json +1 -1
- package/src/enums/module-type.ts +1 -0
- package/src/types/api/auth/create-account-types.ts +2 -1
- package/src/types/api/index.ts +1 -0
- package/src/types/api/notifications/create-notification-template-types.ts +39 -0
- package/src/types/api/notifications/delete-notification-template-types.ts +14 -0
- package/src/types/api/notifications/get-notification-instances-types.ts +29 -0
- package/src/types/api/notifications/get-notification-templates-types.ts +21 -0
- package/src/types/api/notifications/index.ts +7 -0
- package/src/types/api/notifications/preview-notification-template-types.ts +26 -0
- package/src/types/api/notifications/sync-notification-template-types.ts +23 -0
- package/src/types/api/notifications/update-notification-template-types.ts +36 -0
- package/src/types/id-types.ts +7 -1
- package/src/types/models/index.ts +3 -0
- package/src/types/models/notifiable.ts +52 -0
- package/src/types/models/notification-instance-data.ts +40 -0
- package/src/types/models/notification-template-data.ts +50 -0
- package/src/utils/serializing-utils.ts +18 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// Request schema - no body needed for DELETE
|
|
4
|
+
export const deleteNotificationTemplateRequestSchema = z.object({});
|
|
5
|
+
|
|
6
|
+
export type DeleteNotificationTemplateRequest = z.infer<typeof deleteNotificationTemplateRequestSchema>;
|
|
7
|
+
|
|
8
|
+
// Response schema
|
|
9
|
+
export const deleteNotificationTemplateResponseSchema = z.object({
|
|
10
|
+
success: z.boolean(),
|
|
11
|
+
error: z.string().optional()
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type DeleteNotificationTemplateResponse = z.infer<typeof deleteNotificationTemplateResponseSchema>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Serialized } from "../../../utils";
|
|
3
|
+
import { NotificationInstanceData } from "../../models/notification-instance-data";
|
|
4
|
+
|
|
5
|
+
// Request schema - query parameters
|
|
6
|
+
export const getNotificationInstancesRequestSchema = z.object({
|
|
7
|
+
status: z.string().optional(), // filter by status
|
|
8
|
+
templateId: z.string().optional(), // filter by template
|
|
9
|
+
entityId: z.string().optional(), // filter by entity
|
|
10
|
+
limit: z.number().optional(), // pagination
|
|
11
|
+
offset: z.number().optional() // pagination
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export type GetNotificationInstancesRequest = z.infer<typeof getNotificationInstancesRequestSchema>;
|
|
15
|
+
|
|
16
|
+
// Response schema
|
|
17
|
+
export const getNotificationInstancesResponseSchema = z.object({
|
|
18
|
+
success: z.boolean(),
|
|
19
|
+
instances: z.array(z.any()).optional(), // Will be Serialized<NotificationInstanceData>[]
|
|
20
|
+
total: z.number().optional(),
|
|
21
|
+
error: z.string().optional()
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export type GetNotificationInstancesResponse = {
|
|
25
|
+
success: boolean;
|
|
26
|
+
instances?: Serialized<NotificationInstanceData>[];
|
|
27
|
+
total?: number;
|
|
28
|
+
error?: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Serialized } from "../../../utils";
|
|
3
|
+
import { NotificationTemplateData } from "../../models/notification-template-data";
|
|
4
|
+
|
|
5
|
+
// Request schema - no body needed for GET
|
|
6
|
+
export const getNotificationTemplatesRequestSchema = z.object({});
|
|
7
|
+
|
|
8
|
+
export type GetNotificationTemplatesRequest = z.infer<typeof getNotificationTemplatesRequestSchema>;
|
|
9
|
+
|
|
10
|
+
// Response schema
|
|
11
|
+
export const getNotificationTemplatesResponseSchema = z.object({
|
|
12
|
+
success: z.boolean(),
|
|
13
|
+
templates: z.array(z.any()).optional(), // Will be Serialized<NotificationTemplateData>[]
|
|
14
|
+
error: z.string().optional()
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type GetNotificationTemplatesResponse = {
|
|
18
|
+
success: boolean;
|
|
19
|
+
templates?: Serialized<NotificationTemplateData>[];
|
|
20
|
+
error?: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './get-notification-templates-types';
|
|
2
|
+
export * from './create-notification-template-types';
|
|
3
|
+
export * from './update-notification-template-types';
|
|
4
|
+
export * from './delete-notification-template-types';
|
|
5
|
+
export * from './get-notification-instances-types';
|
|
6
|
+
export * from './preview-notification-template-types';
|
|
7
|
+
export * from './sync-notification-template-types';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// Request schema
|
|
4
|
+
export const previewNotificationTemplateRequestSchema = z.object({
|
|
5
|
+
templateTitle: z.string(),
|
|
6
|
+
templateBody: z.string(),
|
|
7
|
+
entityType: z.string(),
|
|
8
|
+
entityId: z.string(),
|
|
9
|
+
variables: z.record(z.any()).optional()
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type PreviewNotificationTemplateRequest = z.infer<typeof previewNotificationTemplateRequestSchema>;
|
|
13
|
+
|
|
14
|
+
// Response schema
|
|
15
|
+
export const previewNotificationTemplateResponseSchema = z.object({
|
|
16
|
+
success: z.boolean(),
|
|
17
|
+
preview: z.object({
|
|
18
|
+
title: z.string(),
|
|
19
|
+
body: z.string(),
|
|
20
|
+
variables: z.record(z.any())
|
|
21
|
+
}).optional(),
|
|
22
|
+
missingVariables: z.array(z.string()).optional(),
|
|
23
|
+
error: z.string().optional()
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type PreviewNotificationTemplateResponse = z.infer<typeof previewNotificationTemplateResponseSchema>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Serialized } from "../../../utils";
|
|
3
|
+
import { NotificationTemplateData } from "../../models/notification-template-data";
|
|
4
|
+
|
|
5
|
+
// Request schema
|
|
6
|
+
export const syncNotificationTemplateRequestSchema = z.object({
|
|
7
|
+
sync: z.boolean() // true to sync with parent, false to unsync
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
export type SyncNotificationTemplateRequest = z.infer<typeof syncNotificationTemplateRequestSchema>;
|
|
11
|
+
|
|
12
|
+
// Response schema
|
|
13
|
+
export const syncNotificationTemplateResponseSchema = z.object({
|
|
14
|
+
success: z.boolean(),
|
|
15
|
+
template: z.any().optional(), // Will be Serialized<NotificationTemplateData>
|
|
16
|
+
error: z.string().optional()
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export type SyncNotificationTemplateResponse = {
|
|
20
|
+
success: boolean;
|
|
21
|
+
template?: Serialized<NotificationTemplateData>;
|
|
22
|
+
error?: string;
|
|
23
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { Serialized } from "../../../utils";
|
|
3
|
+
import { NotificationTemplateData, notificationEntityTypeSchema, notificationTriggerTypeSchema } from "../../models/notification-template-data";
|
|
4
|
+
|
|
5
|
+
// Request schema
|
|
6
|
+
export const updateNotificationTemplateRequestSchema = z.object({
|
|
7
|
+
name: z.string().min(1).max(100).optional(),
|
|
8
|
+
description: z.string().max(500).optional(),
|
|
9
|
+
trigger: z.object({
|
|
10
|
+
type: notificationTriggerTypeSchema,
|
|
11
|
+
conditions: z.record(z.any()),
|
|
12
|
+
timing: z.record(z.any())
|
|
13
|
+
}).optional(),
|
|
14
|
+
content: z.object({
|
|
15
|
+
title: z.string().min(1).max(200),
|
|
16
|
+
body: z.string().min(1).max(1000),
|
|
17
|
+
variables: z.record(z.string()).optional()
|
|
18
|
+
}).optional(),
|
|
19
|
+
active: z.boolean().optional(),
|
|
20
|
+
customized: z.boolean().optional()
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type UpdateNotificationTemplateRequest = z.infer<typeof updateNotificationTemplateRequestSchema>;
|
|
24
|
+
|
|
25
|
+
// Response schema
|
|
26
|
+
export const updateNotificationTemplateResponseSchema = z.object({
|
|
27
|
+
success: z.boolean(),
|
|
28
|
+
template: z.any().optional(), // Will be Serialized<NotificationTemplateData>
|
|
29
|
+
error: z.string().optional()
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export type UpdateNotificationTemplateResponse = {
|
|
33
|
+
success: boolean;
|
|
34
|
+
template?: Serialized<NotificationTemplateData>;
|
|
35
|
+
error?: string;
|
|
36
|
+
};
|
package/src/types/id-types.ts
CHANGED
|
@@ -28,4 +28,10 @@ export const habitIdSchema = z.string().transform((val): TaskListId => val as Ta
|
|
|
28
28
|
export type HabitId = string & { readonly __brand: "HabitId" };
|
|
29
29
|
|
|
30
30
|
export const habitEntryIdSchema = z.string().transform((val): TaskListId => val as TaskListId);
|
|
31
|
-
export type HabitEntryId = string & { readonly __brand: "HabitEntryId" };
|
|
31
|
+
export type HabitEntryId = string & { readonly __brand: "HabitEntryId" };
|
|
32
|
+
|
|
33
|
+
export const notificationTemplateIdSchema = z.string().transform((val): NotificationTemplateId => val as NotificationTemplateId);
|
|
34
|
+
export type NotificationTemplateId = string & { readonly __brand: "NotificationTemplateId" };
|
|
35
|
+
|
|
36
|
+
export const notificationInstanceIdSchema = z.string().transform((val): NotificationInstanceId => val as NotificationInstanceId);
|
|
37
|
+
export type NotificationInstanceId = string & { readonly __brand: "NotificationInstanceId" };
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from './auth-data';
|
|
2
2
|
export * from './habit-data';
|
|
3
3
|
export * from './item-data';
|
|
4
|
+
export * from './notification-template-data';
|
|
5
|
+
export * from './notification-instance-data';
|
|
6
|
+
export * from './notifiable';
|
|
4
7
|
export * from './person-data';
|
|
5
8
|
export * from './program-config';
|
|
6
9
|
export * from './task-data';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NotificationTemplateData, NotificationEntityType } from "./notification-template-data";
|
|
2
|
+
|
|
3
|
+
export interface NotificationContext<T = any> {
|
|
4
|
+
entityId: string;
|
|
5
|
+
entityType: NotificationEntityType;
|
|
6
|
+
entityData: T;
|
|
7
|
+
userId: string;
|
|
8
|
+
// Additional context for template variable replacement
|
|
9
|
+
variables: Record<string, any>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface INotifiable<T = any> {
|
|
13
|
+
/**
|
|
14
|
+
* Get the ID of this notifiable entity
|
|
15
|
+
*/
|
|
16
|
+
getId(): string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get the entity type for notification purposes
|
|
20
|
+
*/
|
|
21
|
+
getNotificationEntityType(): NotificationEntityType;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get context data for notification template variables
|
|
25
|
+
*/
|
|
26
|
+
getNotificationContext(): NotificationContext<T>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get inherited notification templates from parent entities
|
|
30
|
+
*/
|
|
31
|
+
getInheritedNotificationTemplates(): Promise<NotificationTemplateData[]>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get custom notification templates specific to this entity
|
|
35
|
+
*/
|
|
36
|
+
getCustomNotificationTemplates(): Promise<NotificationTemplateData[]>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get all effective notification templates (inherited + custom)
|
|
40
|
+
*/
|
|
41
|
+
getAllNotificationTemplates(): Promise<NotificationTemplateData[]>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Register notification triggers when entity is created/updated
|
|
45
|
+
*/
|
|
46
|
+
registerNotificationTriggers(): Promise<void>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Remove notification triggers when entity is deleted
|
|
50
|
+
*/
|
|
51
|
+
removeNotificationTriggers(): Promise<void>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotificationInstanceId, NotificationTemplateId, UserId } from "../id-types";
|
|
3
|
+
|
|
4
|
+
export const notificationStatusSchema = z.enum(['scheduled', 'sent', 'failed', 'cancelled']);
|
|
5
|
+
export type NotificationStatus = z.infer<typeof notificationStatusSchema>;
|
|
6
|
+
|
|
7
|
+
export const notificationInstanceDataSchema = z.object({
|
|
8
|
+
_id: z.string().transform((val): NotificationInstanceId => val as NotificationInstanceId),
|
|
9
|
+
templateId: z.string().transform((val): NotificationTemplateId => val as NotificationTemplateId),
|
|
10
|
+
userId: z.string().transform((val): UserId => val as UserId),
|
|
11
|
+
entityId: z.string(), // ID of the specific entity this notification is for
|
|
12
|
+
scheduledFor: z.date(),
|
|
13
|
+
status: notificationStatusSchema,
|
|
14
|
+
sentAt: z.date().optional(),
|
|
15
|
+
content: z.object({
|
|
16
|
+
title: z.string(),
|
|
17
|
+
body: z.string(),
|
|
18
|
+
data: z.record(z.any()).optional() // additional data for the notification
|
|
19
|
+
}),
|
|
20
|
+
redisId: z.string(), // link to Redis scheduled notification for coordination
|
|
21
|
+
error: z.string().optional(), // error message if status is 'failed'
|
|
22
|
+
createdAt: z.date(),
|
|
23
|
+
updatedAt: z.date()
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type NotificationInstanceData = z.infer<typeof notificationInstanceDataSchema>;
|
|
27
|
+
|
|
28
|
+
// Helper type for creating new instances (without _id, dates, status)
|
|
29
|
+
export const createNotificationInstanceSchema = notificationInstanceDataSchema.omit({
|
|
30
|
+
_id: true,
|
|
31
|
+
status: true,
|
|
32
|
+
sentAt: true,
|
|
33
|
+
error: true,
|
|
34
|
+
createdAt: true,
|
|
35
|
+
updatedAt: true
|
|
36
|
+
}).extend({
|
|
37
|
+
status: notificationStatusSchema.default('scheduled')
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export type CreateNotificationInstanceData = z.infer<typeof createNotificationInstanceSchema>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { NotificationTemplateId, UserId } from "../id-types";
|
|
3
|
+
|
|
4
|
+
export const notificationEntityTypeSchema = z.enum(['agenda', 'tasks', 'habits', 'agenda_item', 'task_list', 'task', 'habit']);
|
|
5
|
+
export type NotificationEntityType = z.infer<typeof notificationEntityTypeSchema>;
|
|
6
|
+
|
|
7
|
+
export const notificationTriggerTypeSchema = z.enum(['time_based', 'event_based', 'recurring']);
|
|
8
|
+
export type NotificationTriggerType = z.infer<typeof notificationTriggerTypeSchema>;
|
|
9
|
+
|
|
10
|
+
export const notificationTriggerSchema = z.object({
|
|
11
|
+
type: notificationTriggerTypeSchema,
|
|
12
|
+
conditions: z.record(z.any()), // flexible conditions object
|
|
13
|
+
timing: z.record(z.any()) // timing configuration like "5 minutes before due"
|
|
14
|
+
});
|
|
15
|
+
export type NotificationTrigger = z.infer<typeof notificationTriggerSchema>;
|
|
16
|
+
|
|
17
|
+
export const notificationContentSchema = z.object({
|
|
18
|
+
title: z.string(),
|
|
19
|
+
body: z.string(),
|
|
20
|
+
// Support for template variables like {{entity.name}}
|
|
21
|
+
variables: z.record(z.string()).optional()
|
|
22
|
+
});
|
|
23
|
+
export type NotificationContent = z.infer<typeof notificationContentSchema>;
|
|
24
|
+
|
|
25
|
+
export const notificationTemplateDataSchema = z.object({
|
|
26
|
+
_id: z.string().transform((val): NotificationTemplateId => val as NotificationTemplateId),
|
|
27
|
+
userId: z.string().transform((val): UserId => val as UserId),
|
|
28
|
+
entityType: notificationEntityTypeSchema,
|
|
29
|
+
entityId: z.string().optional(), // null/undefined for panel-level templates
|
|
30
|
+
name: z.string(),
|
|
31
|
+
description: z.string().optional(),
|
|
32
|
+
trigger: notificationTriggerSchema,
|
|
33
|
+
content: notificationContentSchema,
|
|
34
|
+
active: z.boolean().default(true),
|
|
35
|
+
inheritedFrom: z.string().transform((val): NotificationTemplateId => val as NotificationTemplateId).optional(),
|
|
36
|
+
customized: z.boolean().default(false), // true if user modified inherited template
|
|
37
|
+
createdAt: z.date(),
|
|
38
|
+
updatedAt: z.date()
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export type NotificationTemplateData = z.infer<typeof notificationTemplateDataSchema>;
|
|
42
|
+
|
|
43
|
+
// Helper type for creating new templates (without _id, dates)
|
|
44
|
+
export const createNotificationTemplateSchema = notificationTemplateDataSchema.omit({
|
|
45
|
+
_id: true,
|
|
46
|
+
createdAt: true,
|
|
47
|
+
updatedAt: true
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export type CreateNotificationTemplateData = z.infer<typeof createNotificationTemplateSchema>;
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
ItemData, Person,
|
|
6
6
|
PersonData,
|
|
7
7
|
PersonNoteData,
|
|
8
|
+
NotificationTemplateData,
|
|
9
|
+
NotificationInstanceData,
|
|
8
10
|
TaskData, TaskListData,
|
|
9
11
|
ThoughtData,
|
|
10
12
|
UserData
|
|
@@ -126,6 +128,22 @@ export class Serializer {
|
|
|
126
128
|
static deserializeUserData(data: Serialized<UserData>): UserData {
|
|
127
129
|
return this.deserialize(data) as unknown as UserData;
|
|
128
130
|
}
|
|
131
|
+
|
|
132
|
+
static serializeNotificationTemplateData(data: NotificationTemplateData): Serialized<NotificationTemplateData> {
|
|
133
|
+
return this.serialize(data);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static deserializeNotificationTemplateData(data: Serialized<NotificationTemplateData>): NotificationTemplateData {
|
|
137
|
+
return this.deserialize(data) as unknown as NotificationTemplateData;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static serializeNotificationInstanceData(data: NotificationInstanceData): Serialized<NotificationInstanceData> {
|
|
141
|
+
return this.serialize(data);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static deserializeNotificationInstanceData(data: Serialized<NotificationInstanceData>): NotificationInstanceData {
|
|
145
|
+
return this.deserialize(data) as unknown as NotificationInstanceData;
|
|
146
|
+
}
|
|
129
147
|
}
|
|
130
148
|
|
|
131
149
|
function serializeRecursive(obj: any): any {
|