@voyantjs/notifications 0.6.2 → 0.6.5
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/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/routes.d.ts +2 -2
- package/dist/schema.d.ts +3 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -0
- package/dist/service-reminders.d.ts +28 -1
- package/dist/service-reminders.d.ts.map +1 -1
- package/dist/service-reminders.js +452 -74
- package/dist/service-shared.d.ts +6 -0
- package/dist/service-shared.d.ts.map +1 -1
- package/dist/service-templates.d.ts +2 -2
- package/dist/task-runtime.d.ts +8 -0
- package/dist/task-runtime.d.ts.map +1 -1
- package/dist/task-runtime.js +2 -0
- package/dist/tasks/deliver-reminder.d.ts +9 -0
- package/dist/tasks/deliver-reminder.d.ts.map +1 -0
- package/dist/tasks/deliver-reminder.js +12 -0
- package/dist/tasks/index.d.ts +1 -0
- package/dist/tasks/index.d.ts.map +1 -1
- package/dist/tasks/index.js +1 -0
- package/dist/tasks/send-due-reminders.d.ts +2 -1
- package/dist/tasks/send-due-reminders.d.ts.map +1 -1
- package/dist/tasks/send-due-reminders.js +26 -2
- package/dist/validation.d.ts +4 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +1 -0
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -16,9 +16,9 @@ export type { NotificationService } from "./service.js";
|
|
|
16
16
|
export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, renderNotificationTemplate, } from "./service.js";
|
|
17
17
|
export type { BookingDocumentAttachmentResolver, BookingDocumentsSentEvent, SendBookingDocumentsRuntimeOptions, } from "./service-booking-documents.js";
|
|
18
18
|
export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
|
|
19
|
-
export type { NotificationTaskEnv, NotificationTaskRuntime, NotificationTaskRuntimeOptions, } from "./task-runtime.js";
|
|
19
|
+
export type { NotificationTaskEnv, NotificationTaskRuntime, NotificationTaskRuntimeOptions, ReminderDeliveryJob, } from "./task-runtime.js";
|
|
20
20
|
export { buildNotificationTaskRuntime } from "./task-runtime.js";
|
|
21
|
-
export { sendDueNotificationReminders } from "./tasks/index.js";
|
|
21
|
+
export { deliverQueuedNotificationReminder, sendDueNotificationReminders } from "./tasks/index.js";
|
|
22
22
|
export type { NotificationAttachment, NotificationChannel, NotificationPayload, NotificationProvider, NotificationResult, } from "./types.js";
|
|
23
23
|
export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
|
|
24
24
|
export declare function createNotificationsHonoModule(options?: NotificationsRoutesOptions): HonoModule;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAIL,KAAK,0BAA0B,EAChC,MAAM,aAAa,CAAA;AAGpB,YAAY,EAAE,kCAAkC,EAAE,MAAM,0BAA0B,CAAA;AAClF,OAAO,EACL,kCAAkC,EAClC,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,yCAAyC,GAC1C,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,uBAAuB,EACvB,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,8BAA8B,EAC9B,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,mBAAmB,EACnB,0BAA0B,EAC1B,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,EACL,sCAAsC,EACtC,yBAAyB,EACzB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iCAAiC,EACjC,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAA;AACpF,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,8BAA8B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { notificationChannelEnum, notificationDeliveries, notificationDeliverySt
|
|
|
9
9
|
export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, renderNotificationTemplate, } from "./service.js";
|
|
10
10
|
export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
|
|
11
11
|
export { buildNotificationTaskRuntime } from "./task-runtime.js";
|
|
12
|
-
export { sendDueNotificationReminders } from "./tasks/index.js";
|
|
12
|
+
export { deliverQueuedNotificationReminder, sendDueNotificationReminders } from "./tasks/index.js";
|
|
13
13
|
export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
|
|
14
14
|
export function createNotificationsHonoModule(options) {
|
|
15
15
|
const module = {
|
package/dist/routes.d.ts
CHANGED
|
@@ -430,7 +430,7 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
|
|
|
430
430
|
targetType: "invoice" | "booking_payment_schedule";
|
|
431
431
|
targetId: string;
|
|
432
432
|
dedupeKey: string;
|
|
433
|
-
status: "failed" | "sent" | "processing" | "skipped";
|
|
433
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
434
434
|
recipient: string | null;
|
|
435
435
|
scheduledFor: string;
|
|
436
436
|
processedAt: string;
|
|
@@ -507,7 +507,7 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
|
|
|
507
507
|
targetType: "invoice" | "booking_payment_schedule";
|
|
508
508
|
targetId: string;
|
|
509
509
|
dedupeKey: string;
|
|
510
|
-
status: "failed" | "sent" | "processing" | "skipped";
|
|
510
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
511
511
|
recipient: string | null;
|
|
512
512
|
scheduledFor: string;
|
|
513
513
|
processedAt: string;
|
package/dist/schema.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const notificationDeliveryStatusEnum: import("drizzle-orm/pg-core
|
|
|
6
6
|
export declare const notificationTargetTypeEnum: import("drizzle-orm/pg-core").PgEnum<["booking", "booking_payment_schedule", "booking_guarantee", "invoice", "payment_session", "person", "organization", "other"]>;
|
|
7
7
|
export declare const notificationReminderStatusEnum: import("drizzle-orm/pg-core").PgEnum<["draft", "active", "archived"]>;
|
|
8
8
|
export declare const notificationReminderTargetTypeEnum: import("drizzle-orm/pg-core").PgEnum<["booking_payment_schedule", "invoice"]>;
|
|
9
|
-
export declare const notificationReminderRunStatusEnum: import("drizzle-orm/pg-core").PgEnum<["processing", "sent", "skipped", "failed"]>;
|
|
9
|
+
export declare const notificationReminderRunStatusEnum: import("drizzle-orm/pg-core").PgEnum<["queued", "processing", "sent", "skipped", "failed"]>;
|
|
10
10
|
export declare const notificationTemplates: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
11
11
|
name: "notification_templates";
|
|
12
12
|
schema: undefined;
|
|
@@ -1156,14 +1156,14 @@ export declare const notificationReminderRuns: import("drizzle-orm/pg-core").PgT
|
|
|
1156
1156
|
tableName: "notification_reminder_runs";
|
|
1157
1157
|
dataType: "string";
|
|
1158
1158
|
columnType: "PgEnumColumn";
|
|
1159
|
-
data: "failed" | "sent" | "processing" | "skipped";
|
|
1159
|
+
data: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
1160
1160
|
driverParam: string;
|
|
1161
1161
|
notNull: true;
|
|
1162
1162
|
hasDefault: false;
|
|
1163
1163
|
isPrimaryKey: false;
|
|
1164
1164
|
isAutoincrement: false;
|
|
1165
1165
|
hasRuntimeDefault: false;
|
|
1166
|
-
enumValues: ["processing", "sent", "skipped", "failed"];
|
|
1166
|
+
enumValues: ["queued", "processing", "sent", "skipped", "failed"];
|
|
1167
1167
|
baseColumn: never;
|
|
1168
1168
|
identity: undefined;
|
|
1169
1169
|
generated: undefined;
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAcvD,eAAO,MAAM,uBAAuB,wDAAmD,CAAA;AAEvF,eAAO,MAAM,8BAA8B,uEAIzC,CAAA;AAEF,eAAO,MAAM,8BAA8B,kFAKzC,CAAA;AAEF,eAAO,MAAM,0BAA0B,qKASrC,CAAA;AAEF,eAAO,MAAM,8BAA8B,uEAIzC,CAAA;AAEF,eAAO,MAAM,kCAAkC,+EAG7C,CAAA;AAEF,eAAO,MAAM,iCAAiC,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.js
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
-
import type { NotificationService, ReminderSweepResult, RunDueRemindersInput } from "./service-shared.js";
|
|
2
|
+
import type { NotificationService, ReminderQueueResult, ReminderSweepResult, RunDueRemindersInput } from "./service-shared.js";
|
|
3
|
+
type ReminderDeliveryEnqueuer = (input: {
|
|
4
|
+
reminderRunId: string;
|
|
5
|
+
}) => Promise<void>;
|
|
6
|
+
export declare function queueDueReminders(db: PostgresJsDatabase, input: RunDueRemindersInput | undefined, enqueueDelivery: ReminderDeliveryEnqueuer): Promise<ReminderQueueResult>;
|
|
7
|
+
export declare function deliverReminderRun(db: PostgresJsDatabase, dispatcher: NotificationService, input: {
|
|
8
|
+
reminderRunId: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
reminderRuleId: string;
|
|
12
|
+
targetType: "invoice" | "booking_payment_schedule";
|
|
13
|
+
targetId: string;
|
|
14
|
+
dedupeKey: string;
|
|
15
|
+
bookingId: string | null;
|
|
16
|
+
personId: string | null;
|
|
17
|
+
organizationId: string | null;
|
|
18
|
+
paymentSessionId: string | null;
|
|
19
|
+
notificationDeliveryId: string | null;
|
|
20
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
21
|
+
recipient: string | null;
|
|
22
|
+
scheduledFor: Date;
|
|
23
|
+
processedAt: Date;
|
|
24
|
+
errorMessage: string | null;
|
|
25
|
+
metadata: Record<string, unknown> | null;
|
|
26
|
+
createdAt: Date;
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
} | null>;
|
|
3
29
|
export declare function runDueReminders(db: PostgresJsDatabase, dispatcher: NotificationService, input?: RunDueRemindersInput): Promise<ReminderSweepResult>;
|
|
30
|
+
export {};
|
|
4
31
|
//# sourceMappingURL=service-reminders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-reminders.d.ts","sourceRoot":"","sources":["../src/service-reminders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAGV,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"service-reminders.d.ts","sourceRoot":"","sources":["../src/service-reminders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAGV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAU5B,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAgxBnF,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,oBAAoB,YAAK,EAChC,eAAe,EAAE,wBAAwB,gCAoF1C;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;UAkDjC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,GAAE,oBAAyB,gCA4EjC"}
|
|
@@ -4,6 +4,245 @@ import { and, desc, eq, gt, or } from "drizzle-orm";
|
|
|
4
4
|
import { notificationReminderRules, notificationReminderRuns } from "./schema.js";
|
|
5
5
|
import { sendInvoiceNotification, sendNotification } from "./service-deliveries.js";
|
|
6
6
|
import { addUtcDays, buildReminderDedupeKey, resolveReminderRecipient, startOfUtcDay, toDateString, toTimestamp, } from "./service-shared.js";
|
|
7
|
+
function buildReminderSweepSummary() {
|
|
8
|
+
return {
|
|
9
|
+
processed: 0,
|
|
10
|
+
sent: 0,
|
|
11
|
+
skipped: 0,
|
|
12
|
+
failed: 0,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function buildReminderQueueSummary() {
|
|
16
|
+
return {
|
|
17
|
+
processed: 0,
|
|
18
|
+
queued: 0,
|
|
19
|
+
skipped: 0,
|
|
20
|
+
failed: 0,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function isRetryableReminderRun(run) {
|
|
24
|
+
return run?.status === "failed";
|
|
25
|
+
}
|
|
26
|
+
async function getReminderRuleById(db, reminderRuleId) {
|
|
27
|
+
const [rule] = await db
|
|
28
|
+
.select()
|
|
29
|
+
.from(notificationReminderRules)
|
|
30
|
+
.where(eq(notificationReminderRules.id, reminderRuleId))
|
|
31
|
+
.limit(1);
|
|
32
|
+
return rule ?? null;
|
|
33
|
+
}
|
|
34
|
+
async function getReminderRunById(db, reminderRunId) {
|
|
35
|
+
const [run] = await db
|
|
36
|
+
.select()
|
|
37
|
+
.from(notificationReminderRuns)
|
|
38
|
+
.where(eq(notificationReminderRuns.id, reminderRunId))
|
|
39
|
+
.limit(1);
|
|
40
|
+
return run ?? null;
|
|
41
|
+
}
|
|
42
|
+
async function markReminderRunQueued(db, reminderRunId, now, recipient) {
|
|
43
|
+
const [run] = await db
|
|
44
|
+
.update(notificationReminderRuns)
|
|
45
|
+
.set({
|
|
46
|
+
status: "queued",
|
|
47
|
+
errorMessage: null,
|
|
48
|
+
recipient: recipient ?? undefined,
|
|
49
|
+
processedAt: now,
|
|
50
|
+
updatedAt: now,
|
|
51
|
+
})
|
|
52
|
+
.where(eq(notificationReminderRuns.id, reminderRunId))
|
|
53
|
+
.returning();
|
|
54
|
+
return run ?? null;
|
|
55
|
+
}
|
|
56
|
+
async function markReminderRunSkipped(db, reminderRunId, now, errorMessage) {
|
|
57
|
+
const [run] = await db
|
|
58
|
+
.update(notificationReminderRuns)
|
|
59
|
+
.set({
|
|
60
|
+
status: "skipped",
|
|
61
|
+
errorMessage,
|
|
62
|
+
processedAt: now,
|
|
63
|
+
updatedAt: now,
|
|
64
|
+
})
|
|
65
|
+
.where(eq(notificationReminderRuns.id, reminderRunId))
|
|
66
|
+
.returning();
|
|
67
|
+
return run ?? null;
|
|
68
|
+
}
|
|
69
|
+
async function markReminderRunFailed(db, reminderRunId, now, errorMessage) {
|
|
70
|
+
const [run] = await db
|
|
71
|
+
.update(notificationReminderRuns)
|
|
72
|
+
.set({
|
|
73
|
+
status: "failed",
|
|
74
|
+
errorMessage,
|
|
75
|
+
processedAt: now,
|
|
76
|
+
updatedAt: now,
|
|
77
|
+
})
|
|
78
|
+
.where(eq(notificationReminderRuns.id, reminderRunId))
|
|
79
|
+
.returning();
|
|
80
|
+
return run ?? null;
|
|
81
|
+
}
|
|
82
|
+
async function markReminderRunSent(db, reminderRunId, now, notificationDeliveryId) {
|
|
83
|
+
const [run] = await db
|
|
84
|
+
.update(notificationReminderRuns)
|
|
85
|
+
.set({
|
|
86
|
+
notificationDeliveryId,
|
|
87
|
+
status: "sent",
|
|
88
|
+
processedAt: now,
|
|
89
|
+
updatedAt: now,
|
|
90
|
+
errorMessage: null,
|
|
91
|
+
})
|
|
92
|
+
.where(eq(notificationReminderRuns.id, reminderRunId))
|
|
93
|
+
.returning();
|
|
94
|
+
return run ?? null;
|
|
95
|
+
}
|
|
96
|
+
async function enqueueReminderRun(db, enqueueDelivery, run, now) {
|
|
97
|
+
const queuedRun = await markReminderRunQueued(db, run.id, now, run.recipient);
|
|
98
|
+
if (!queuedRun) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
await enqueueDelivery({ reminderRunId: queuedRun.id });
|
|
103
|
+
return queuedRun;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const message = error instanceof Error ? error.message : "Failed to enqueue reminder delivery";
|
|
107
|
+
return markReminderRunFailed(db, queuedRun.id, new Date(), message);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async function queueBookingPaymentScheduleReminder(db, enqueueDelivery, rule, schedule, now) {
|
|
111
|
+
const runDate = toDateString(startOfUtcDay(now));
|
|
112
|
+
const dedupeKey = buildReminderDedupeKey(rule.id, schedule.id, runDate);
|
|
113
|
+
const [existingRun] = await db
|
|
114
|
+
.select()
|
|
115
|
+
.from(notificationReminderRuns)
|
|
116
|
+
.where(eq(notificationReminderRuns.dedupeKey, dedupeKey))
|
|
117
|
+
.limit(1);
|
|
118
|
+
if (existingRun && !isRetryableReminderRun(existingRun)) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const [booking] = await db
|
|
122
|
+
.select()
|
|
123
|
+
.from(bookings)
|
|
124
|
+
.where(eq(bookings.id, schedule.bookingId))
|
|
125
|
+
.limit(1);
|
|
126
|
+
const reminderRun = existingRun && isRetryableReminderRun(existingRun)
|
|
127
|
+
? existingRun
|
|
128
|
+
: ((await db
|
|
129
|
+
.insert(notificationReminderRuns)
|
|
130
|
+
.values({
|
|
131
|
+
reminderRuleId: rule.id,
|
|
132
|
+
targetType: "booking_payment_schedule",
|
|
133
|
+
targetId: schedule.id,
|
|
134
|
+
dedupeKey,
|
|
135
|
+
bookingId: schedule.bookingId,
|
|
136
|
+
personId: booking?.personId ?? null,
|
|
137
|
+
organizationId: booking?.organizationId ?? null,
|
|
138
|
+
paymentSessionId: null,
|
|
139
|
+
notificationDeliveryId: null,
|
|
140
|
+
status: "queued",
|
|
141
|
+
recipient: null,
|
|
142
|
+
scheduledFor: now,
|
|
143
|
+
processedAt: now,
|
|
144
|
+
errorMessage: null,
|
|
145
|
+
metadata: {
|
|
146
|
+
dueDate: schedule.dueDate,
|
|
147
|
+
relativeDaysFromDueDate: rule.relativeDaysFromDueDate,
|
|
148
|
+
bookingNumber: booking?.bookingNumber ?? null,
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
.onConflictDoNothing({ target: notificationReminderRuns.dedupeKey })
|
|
152
|
+
.returning())[0] ?? null);
|
|
153
|
+
if (!reminderRun) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
if (!booking) {
|
|
157
|
+
return markReminderRunSkipped(db, reminderRun.id, now, "Booking not found for payment schedule");
|
|
158
|
+
}
|
|
159
|
+
const participants = await db
|
|
160
|
+
.select({
|
|
161
|
+
id: bookingParticipants.id,
|
|
162
|
+
firstName: bookingParticipants.firstName,
|
|
163
|
+
lastName: bookingParticipants.lastName,
|
|
164
|
+
email: bookingParticipants.email,
|
|
165
|
+
participantType: bookingParticipants.participantType,
|
|
166
|
+
isPrimary: bookingParticipants.isPrimary,
|
|
167
|
+
})
|
|
168
|
+
.from(bookingParticipants)
|
|
169
|
+
.where(eq(bookingParticipants.bookingId, booking.id))
|
|
170
|
+
.orderBy(desc(bookingParticipants.isPrimary), bookingParticipants.createdAt);
|
|
171
|
+
const recipient = resolveReminderRecipient(participants);
|
|
172
|
+
if (!recipient?.email) {
|
|
173
|
+
return markReminderRunSkipped(db, reminderRun.id, now, "No participant email available for booking payment reminder");
|
|
174
|
+
}
|
|
175
|
+
return enqueueReminderRun(db, enqueueDelivery, { ...reminderRun, recipient: recipient.email }, now);
|
|
176
|
+
}
|
|
177
|
+
async function queueInvoiceReminder(db, enqueueDelivery, rule, invoice, now) {
|
|
178
|
+
const runDate = toDateString(startOfUtcDay(now));
|
|
179
|
+
const dedupeKey = buildReminderDedupeKey(rule.id, invoice.id, runDate);
|
|
180
|
+
const [existingRun] = await db
|
|
181
|
+
.select()
|
|
182
|
+
.from(notificationReminderRuns)
|
|
183
|
+
.where(eq(notificationReminderRuns.dedupeKey, dedupeKey))
|
|
184
|
+
.limit(1);
|
|
185
|
+
if (existingRun && !isRetryableReminderRun(existingRun)) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
const [booking] = await db
|
|
189
|
+
.select()
|
|
190
|
+
.from(bookings)
|
|
191
|
+
.where(eq(bookings.id, invoice.bookingId))
|
|
192
|
+
.limit(1);
|
|
193
|
+
const reminderRun = existingRun && isRetryableReminderRun(existingRun)
|
|
194
|
+
? existingRun
|
|
195
|
+
: ((await db
|
|
196
|
+
.insert(notificationReminderRuns)
|
|
197
|
+
.values({
|
|
198
|
+
reminderRuleId: rule.id,
|
|
199
|
+
targetType: "invoice",
|
|
200
|
+
targetId: invoice.id,
|
|
201
|
+
dedupeKey,
|
|
202
|
+
bookingId: invoice.bookingId,
|
|
203
|
+
personId: invoice.personId ?? booking?.personId ?? null,
|
|
204
|
+
organizationId: invoice.organizationId ?? booking?.organizationId ?? null,
|
|
205
|
+
paymentSessionId: null,
|
|
206
|
+
notificationDeliveryId: null,
|
|
207
|
+
status: "queued",
|
|
208
|
+
recipient: null,
|
|
209
|
+
scheduledFor: now,
|
|
210
|
+
processedAt: now,
|
|
211
|
+
errorMessage: null,
|
|
212
|
+
metadata: {
|
|
213
|
+
dueDate: invoice.dueDate,
|
|
214
|
+
relativeDaysFromDueDate: rule.relativeDaysFromDueDate,
|
|
215
|
+
bookingNumber: booking?.bookingNumber ?? null,
|
|
216
|
+
invoiceNumber: invoice.invoiceNumber,
|
|
217
|
+
invoiceType: invoice.invoiceType,
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
.onConflictDoNothing({ target: notificationReminderRuns.dedupeKey })
|
|
221
|
+
.returning())[0] ?? null);
|
|
222
|
+
if (!reminderRun) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
if (!booking) {
|
|
226
|
+
return markReminderRunSkipped(db, reminderRun.id, now, "Booking not found for invoice reminder");
|
|
227
|
+
}
|
|
228
|
+
const participants = await db
|
|
229
|
+
.select({
|
|
230
|
+
id: bookingParticipants.id,
|
|
231
|
+
firstName: bookingParticipants.firstName,
|
|
232
|
+
lastName: bookingParticipants.lastName,
|
|
233
|
+
email: bookingParticipants.email,
|
|
234
|
+
participantType: bookingParticipants.participantType,
|
|
235
|
+
isPrimary: bookingParticipants.isPrimary,
|
|
236
|
+
})
|
|
237
|
+
.from(bookingParticipants)
|
|
238
|
+
.where(eq(bookingParticipants.bookingId, booking.id))
|
|
239
|
+
.orderBy(desc(bookingParticipants.isPrimary), bookingParticipants.createdAt);
|
|
240
|
+
const recipient = resolveReminderRecipient(participants);
|
|
241
|
+
if (!recipient?.email) {
|
|
242
|
+
return markReminderRunSkipped(db, reminderRun.id, now, "No participant email available for invoice reminder");
|
|
243
|
+
}
|
|
244
|
+
return enqueueReminderRun(db, enqueueDelivery, { ...reminderRun, recipient: recipient.email }, now);
|
|
245
|
+
}
|
|
7
246
|
async function sendBookingPaymentScheduleReminder(db, dispatcher, rule, schedule, now) {
|
|
8
247
|
const runDate = toDateString(startOfUtcDay(now));
|
|
9
248
|
const dedupeKey = buildReminderDedupeKey(rule.id, schedule.id, runDate);
|
|
@@ -88,17 +327,7 @@ async function sendBookingPaymentScheduleReminder(db, dispatcher, rule, schedule
|
|
|
88
327
|
return null;
|
|
89
328
|
}
|
|
90
329
|
if (!recipient?.email) {
|
|
91
|
-
|
|
92
|
-
.update(notificationReminderRuns)
|
|
93
|
-
.set({
|
|
94
|
-
status: "skipped",
|
|
95
|
-
errorMessage: "No participant email available for booking payment reminder",
|
|
96
|
-
processedAt: now,
|
|
97
|
-
updatedAt: now,
|
|
98
|
-
})
|
|
99
|
-
.where(eq(notificationReminderRuns.id, processingRun.id))
|
|
100
|
-
.returning();
|
|
101
|
-
return run ?? null;
|
|
330
|
+
return markReminderRunSkipped(db, processingRun.id, now, "No participant email available for booking payment reminder");
|
|
102
331
|
}
|
|
103
332
|
try {
|
|
104
333
|
const delivery = await sendNotification(db, dispatcher, {
|
|
@@ -148,32 +377,11 @@ async function sendBookingPaymentScheduleReminder(db, dispatcher, rule, schedule
|
|
|
148
377
|
},
|
|
149
378
|
scheduledFor: now.toISOString(),
|
|
150
379
|
});
|
|
151
|
-
|
|
152
|
-
.update(notificationReminderRuns)
|
|
153
|
-
.set({
|
|
154
|
-
notificationDeliveryId: delivery?.id ?? null,
|
|
155
|
-
status: "sent",
|
|
156
|
-
processedAt: new Date(),
|
|
157
|
-
updatedAt: new Date(),
|
|
158
|
-
errorMessage: null,
|
|
159
|
-
})
|
|
160
|
-
.where(eq(notificationReminderRuns.id, processingRun.id))
|
|
161
|
-
.returning();
|
|
162
|
-
return run ?? null;
|
|
380
|
+
return markReminderRunSent(db, processingRun.id, new Date(), delivery?.id ?? null);
|
|
163
381
|
}
|
|
164
382
|
catch (error) {
|
|
165
383
|
const message = error instanceof Error ? error.message : "Notification reminder failed";
|
|
166
|
-
|
|
167
|
-
.update(notificationReminderRuns)
|
|
168
|
-
.set({
|
|
169
|
-
status: "failed",
|
|
170
|
-
errorMessage: message,
|
|
171
|
-
processedAt: new Date(),
|
|
172
|
-
updatedAt: new Date(),
|
|
173
|
-
})
|
|
174
|
-
.where(eq(notificationReminderRuns.id, processingRun.id))
|
|
175
|
-
.returning();
|
|
176
|
-
return run ?? null;
|
|
384
|
+
return markReminderRunFailed(db, processingRun.id, new Date(), message);
|
|
177
385
|
}
|
|
178
386
|
}
|
|
179
387
|
async function sendInvoiceReminder(db, dispatcher, rule, invoice, now) {
|
|
@@ -264,17 +472,7 @@ async function sendInvoiceReminder(db, dispatcher, rule, invoice, now) {
|
|
|
264
472
|
return null;
|
|
265
473
|
}
|
|
266
474
|
if (!recipient?.email) {
|
|
267
|
-
|
|
268
|
-
.update(notificationReminderRuns)
|
|
269
|
-
.set({
|
|
270
|
-
status: "skipped",
|
|
271
|
-
errorMessage: "No participant email available for invoice reminder",
|
|
272
|
-
processedAt: now,
|
|
273
|
-
updatedAt: now,
|
|
274
|
-
})
|
|
275
|
-
.where(eq(notificationReminderRuns.id, processingRun.id))
|
|
276
|
-
.returning();
|
|
277
|
-
return run ?? null;
|
|
475
|
+
return markReminderRunSkipped(db, processingRun.id, now, "No participant email available for invoice reminder");
|
|
278
476
|
}
|
|
279
477
|
try {
|
|
280
478
|
const delivery = await sendInvoiceNotification(db, dispatcher, invoice.id, {
|
|
@@ -293,32 +491,217 @@ async function sendInvoiceReminder(db, dispatcher, rule, invoice, now) {
|
|
|
293
491
|
},
|
|
294
492
|
scheduledFor: now.toISOString(),
|
|
295
493
|
});
|
|
296
|
-
|
|
297
|
-
.update(notificationReminderRuns)
|
|
298
|
-
.set({
|
|
299
|
-
notificationDeliveryId: delivery?.id ?? null,
|
|
300
|
-
status: "sent",
|
|
301
|
-
processedAt: new Date(),
|
|
302
|
-
updatedAt: new Date(),
|
|
303
|
-
errorMessage: null,
|
|
304
|
-
})
|
|
305
|
-
.where(eq(notificationReminderRuns.id, processingRun.id))
|
|
306
|
-
.returning();
|
|
307
|
-
return run ?? null;
|
|
494
|
+
return markReminderRunSent(db, processingRun.id, new Date(), delivery?.id ?? null);
|
|
308
495
|
}
|
|
309
496
|
catch (error) {
|
|
310
497
|
const message = error instanceof Error ? error.message : "Invoice reminder failed";
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return run
|
|
498
|
+
return markReminderRunFailed(db, processingRun.id, new Date(), message);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
async function sendQueuedBookingPaymentScheduleReminder(db, dispatcher, run, rule, now) {
|
|
502
|
+
const [schedule] = await db
|
|
503
|
+
.select()
|
|
504
|
+
.from(bookingPaymentSchedules)
|
|
505
|
+
.where(eq(bookingPaymentSchedules.id, run.targetId))
|
|
506
|
+
.limit(1);
|
|
507
|
+
if (!schedule) {
|
|
508
|
+
return markReminderRunSkipped(db, run.id, now, "Booking payment schedule not found for reminder run");
|
|
509
|
+
}
|
|
510
|
+
const [booking] = await db
|
|
511
|
+
.select()
|
|
512
|
+
.from(bookings)
|
|
513
|
+
.where(eq(bookings.id, schedule.bookingId))
|
|
514
|
+
.limit(1);
|
|
515
|
+
if (!booking) {
|
|
516
|
+
return markReminderRunSkipped(db, run.id, now, "Booking not found for payment schedule");
|
|
517
|
+
}
|
|
518
|
+
const participants = await db
|
|
519
|
+
.select({
|
|
520
|
+
id: bookingParticipants.id,
|
|
521
|
+
firstName: bookingParticipants.firstName,
|
|
522
|
+
lastName: bookingParticipants.lastName,
|
|
523
|
+
email: bookingParticipants.email,
|
|
524
|
+
participantType: bookingParticipants.participantType,
|
|
525
|
+
isPrimary: bookingParticipants.isPrimary,
|
|
526
|
+
})
|
|
527
|
+
.from(bookingParticipants)
|
|
528
|
+
.where(eq(bookingParticipants.bookingId, booking.id))
|
|
529
|
+
.orderBy(desc(bookingParticipants.isPrimary), bookingParticipants.createdAt);
|
|
530
|
+
const fallbackRecipient = resolveReminderRecipient(participants);
|
|
531
|
+
const participant = participants.find((entry) => entry.email === run.recipient) ?? fallbackRecipient ?? null;
|
|
532
|
+
const recipientEmail = run.recipient ?? participant?.email ?? null;
|
|
533
|
+
if (!recipientEmail) {
|
|
534
|
+
return markReminderRunSkipped(db, run.id, now, "No participant email available for booking payment reminder");
|
|
535
|
+
}
|
|
536
|
+
try {
|
|
537
|
+
const delivery = await sendNotification(db, dispatcher, {
|
|
538
|
+
templateId: rule.templateId ?? null,
|
|
539
|
+
templateSlug: rule.templateSlug ?? null,
|
|
540
|
+
channel: rule.channel,
|
|
541
|
+
provider: rule.provider ?? null,
|
|
542
|
+
to: recipientEmail,
|
|
543
|
+
data: {
|
|
544
|
+
bookingId: booking.id,
|
|
545
|
+
bookingNumber: booking.bookingNumber,
|
|
546
|
+
dueDate: schedule.dueDate,
|
|
547
|
+
amountCents: schedule.amountCents,
|
|
548
|
+
currency: schedule.currency,
|
|
549
|
+
scheduleType: schedule.scheduleType,
|
|
550
|
+
reminderOffsetDays: rule.relativeDaysFromDueDate,
|
|
551
|
+
participant: participant
|
|
552
|
+
? {
|
|
553
|
+
firstName: participant.firstName,
|
|
554
|
+
lastName: participant.lastName,
|
|
555
|
+
email: recipientEmail,
|
|
556
|
+
}
|
|
557
|
+
: null,
|
|
558
|
+
booking: {
|
|
559
|
+
id: booking.id,
|
|
560
|
+
bookingNumber: booking.bookingNumber,
|
|
561
|
+
startDate: booking.startDate,
|
|
562
|
+
endDate: booking.endDate,
|
|
563
|
+
sellCurrency: booking.sellCurrency,
|
|
564
|
+
sellAmountCents: booking.sellAmountCents,
|
|
565
|
+
},
|
|
566
|
+
paymentSchedule: {
|
|
567
|
+
id: schedule.id,
|
|
568
|
+
dueDate: schedule.dueDate,
|
|
569
|
+
amountCents: schedule.amountCents,
|
|
570
|
+
currency: schedule.currency,
|
|
571
|
+
scheduleType: schedule.scheduleType,
|
|
572
|
+
status: schedule.status,
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
targetType: "booking_payment_schedule",
|
|
576
|
+
targetId: schedule.id,
|
|
577
|
+
bookingId: booking.id,
|
|
578
|
+
personId: booking.personId ?? null,
|
|
579
|
+
organizationId: booking.organizationId ?? null,
|
|
580
|
+
metadata: {
|
|
581
|
+
reminderRuleId: rule.id,
|
|
582
|
+
reminderRunId: run.id,
|
|
583
|
+
},
|
|
584
|
+
scheduledFor: run.scheduledFor.toISOString(),
|
|
585
|
+
});
|
|
586
|
+
return markReminderRunSent(db, run.id, new Date(), delivery?.id ?? null);
|
|
587
|
+
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
const message = error instanceof Error ? error.message : "Notification reminder failed";
|
|
590
|
+
return markReminderRunFailed(db, run.id, new Date(), message);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
async function sendQueuedInvoiceReminder(db, dispatcher, run, rule, now) {
|
|
594
|
+
const delivery = await sendInvoiceNotification(db, dispatcher, run.targetId, {
|
|
595
|
+
templateId: rule.templateId ?? null,
|
|
596
|
+
templateSlug: rule.templateSlug ?? null,
|
|
597
|
+
channel: rule.channel,
|
|
598
|
+
provider: rule.provider ?? null,
|
|
599
|
+
to: run.recipient ?? undefined,
|
|
600
|
+
data: {
|
|
601
|
+
reminderOffsetDays: rule.relativeDaysFromDueDate,
|
|
602
|
+
reminderRunId: run.id,
|
|
603
|
+
},
|
|
604
|
+
metadata: {
|
|
605
|
+
reminderRuleId: rule.id,
|
|
606
|
+
reminderRunId: run.id,
|
|
607
|
+
},
|
|
608
|
+
scheduledFor: run.scheduledFor.toISOString(),
|
|
609
|
+
});
|
|
610
|
+
if (!delivery) {
|
|
611
|
+
return markReminderRunSkipped(db, run.id, now, "Invoice not found for reminder run");
|
|
612
|
+
}
|
|
613
|
+
return markReminderRunSent(db, run.id, new Date(), delivery.id ?? null);
|
|
614
|
+
}
|
|
615
|
+
export async function queueDueReminders(db, input = {}, enqueueDelivery) {
|
|
616
|
+
const now = toTimestamp(input.now) ?? new Date();
|
|
617
|
+
const today = startOfUtcDay(now);
|
|
618
|
+
const activeRules = await db
|
|
619
|
+
.select()
|
|
620
|
+
.from(notificationReminderRules)
|
|
621
|
+
.where(eq(notificationReminderRules.status, "active"))
|
|
622
|
+
.orderBy(notificationReminderRules.createdAt);
|
|
623
|
+
const summary = buildReminderQueueSummary();
|
|
624
|
+
for (const rule of activeRules) {
|
|
625
|
+
const matchingDueDate = toDateString(addUtcDays(today, -rule.relativeDaysFromDueDate));
|
|
626
|
+
if (rule.targetType === "booking_payment_schedule") {
|
|
627
|
+
const schedules = await db
|
|
628
|
+
.select()
|
|
629
|
+
.from(bookingPaymentSchedules)
|
|
630
|
+
.where(and(eq(bookingPaymentSchedules.dueDate, matchingDueDate), or(eq(bookingPaymentSchedules.status, "pending"), eq(bookingPaymentSchedules.status, "due"))))
|
|
631
|
+
.orderBy(bookingPaymentSchedules.createdAt);
|
|
632
|
+
for (const schedule of schedules) {
|
|
633
|
+
const run = await queueBookingPaymentScheduleReminder(db, enqueueDelivery, rule, schedule, now);
|
|
634
|
+
if (!run) {
|
|
635
|
+
continue;
|
|
636
|
+
}
|
|
637
|
+
summary.processed += 1;
|
|
638
|
+
if (run.status === "queued")
|
|
639
|
+
summary.queued += 1;
|
|
640
|
+
if (run.status === "skipped")
|
|
641
|
+
summary.skipped += 1;
|
|
642
|
+
if (run.status === "failed")
|
|
643
|
+
summary.failed += 1;
|
|
644
|
+
}
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
if (rule.targetType === "invoice") {
|
|
648
|
+
const dueInvoices = await db
|
|
649
|
+
.select()
|
|
650
|
+
.from(invoices)
|
|
651
|
+
.where(and(eq(invoices.dueDate, matchingDueDate), gt(invoices.balanceDueCents, 0), or(eq(invoices.invoiceType, "invoice"), eq(invoices.invoiceType, "proforma")), or(eq(invoices.status, "sent"), eq(invoices.status, "partially_paid"), eq(invoices.status, "overdue"))))
|
|
652
|
+
.orderBy(invoices.createdAt);
|
|
653
|
+
for (const invoice of dueInvoices) {
|
|
654
|
+
const run = await queueInvoiceReminder(db, enqueueDelivery, rule, invoice, now);
|
|
655
|
+
if (!run) {
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
summary.processed += 1;
|
|
659
|
+
if (run.status === "queued")
|
|
660
|
+
summary.queued += 1;
|
|
661
|
+
if (run.status === "skipped")
|
|
662
|
+
summary.skipped += 1;
|
|
663
|
+
if (run.status === "failed")
|
|
664
|
+
summary.failed += 1;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return summary;
|
|
669
|
+
}
|
|
670
|
+
export async function deliverReminderRun(db, dispatcher, input) {
|
|
671
|
+
const now = new Date();
|
|
672
|
+
const [claimedRun] = await db
|
|
673
|
+
.update(notificationReminderRuns)
|
|
674
|
+
.set({
|
|
675
|
+
status: "processing",
|
|
676
|
+
errorMessage: null,
|
|
677
|
+
processedAt: now,
|
|
678
|
+
updatedAt: now,
|
|
679
|
+
})
|
|
680
|
+
.where(and(eq(notificationReminderRuns.id, input.reminderRunId), or(eq(notificationReminderRuns.status, "queued"), eq(notificationReminderRuns.status, "failed"))))
|
|
681
|
+
.returning();
|
|
682
|
+
const run = claimedRun ?? (await getReminderRunById(db, input.reminderRunId));
|
|
683
|
+
if (!run) {
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
686
|
+
if (!claimedRun) {
|
|
687
|
+
return run;
|
|
688
|
+
}
|
|
689
|
+
const rule = await getReminderRuleById(db, run.reminderRuleId);
|
|
690
|
+
if (!rule) {
|
|
691
|
+
return markReminderRunFailed(db, run.id, new Date(), "Reminder rule not found");
|
|
692
|
+
}
|
|
693
|
+
try {
|
|
694
|
+
if (run.targetType === "booking_payment_schedule") {
|
|
695
|
+
return await sendQueuedBookingPaymentScheduleReminder(db, dispatcher, run, rule, now);
|
|
696
|
+
}
|
|
697
|
+
if (run.targetType === "invoice") {
|
|
698
|
+
return await sendQueuedInvoiceReminder(db, dispatcher, run, rule, now);
|
|
699
|
+
}
|
|
700
|
+
return markReminderRunSkipped(db, run.id, now, "Unsupported reminder target type");
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
const message = error instanceof Error ? error.message : "Reminder delivery failed";
|
|
704
|
+
return markReminderRunFailed(db, run.id, new Date(), message);
|
|
322
705
|
}
|
|
323
706
|
}
|
|
324
707
|
export async function runDueReminders(db, dispatcher, input = {}) {
|
|
@@ -329,12 +712,7 @@ export async function runDueReminders(db, dispatcher, input = {}) {
|
|
|
329
712
|
.from(notificationReminderRules)
|
|
330
713
|
.where(eq(notificationReminderRules.status, "active"))
|
|
331
714
|
.orderBy(notificationReminderRules.createdAt);
|
|
332
|
-
const summary =
|
|
333
|
-
processed: 0,
|
|
334
|
-
sent: 0,
|
|
335
|
-
skipped: 0,
|
|
336
|
-
failed: 0,
|
|
337
|
-
};
|
|
715
|
+
const summary = buildReminderSweepSummary();
|
|
338
716
|
for (const rule of activeRules) {
|
|
339
717
|
const matchingDueDate = toDateString(addUtcDays(today, -rule.relativeDaysFromDueDate));
|
|
340
718
|
if (rule.targetType === "booking_payment_schedule") {
|
package/dist/service-shared.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export type ReminderSweepResult = {
|
|
|
26
26
|
skipped: number;
|
|
27
27
|
failed: number;
|
|
28
28
|
};
|
|
29
|
+
export type ReminderQueueResult = {
|
|
30
|
+
processed: number;
|
|
31
|
+
queued: number;
|
|
32
|
+
skipped: number;
|
|
33
|
+
failed: number;
|
|
34
|
+
};
|
|
29
35
|
export type NotificationReminderRuleRow = typeof notificationReminderRules.$inferSelect;
|
|
30
36
|
export type BookingPaymentScheduleRow = typeof bookingPaymentSchedules.$inferSelect;
|
|
31
37
|
export declare class NotificationError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-shared.d.ts","sourceRoot":"","sources":["../src/service-shared.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"service-shared.d.ts","sourceRoot":"","sources":["../src/service-shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -161,7 +161,7 @@ export declare function listReminderRuns(db: PostgresJsDatabase, query: Notifica
|
|
|
161
161
|
targetType: "invoice" | "booking_payment_schedule";
|
|
162
162
|
targetId: string;
|
|
163
163
|
dedupeKey: string;
|
|
164
|
-
status: "failed" | "sent" | "processing" | "skipped";
|
|
164
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
165
165
|
recipient: string | null;
|
|
166
166
|
scheduledFor: string;
|
|
167
167
|
processedAt: string;
|
|
@@ -212,7 +212,7 @@ export declare function getReminderRunById(db: PostgresJsDatabase, id: string):
|
|
|
212
212
|
targetType: "invoice" | "booking_payment_schedule";
|
|
213
213
|
targetId: string;
|
|
214
214
|
dedupeKey: string;
|
|
215
|
-
status: "failed" | "sent" | "processing" | "skipped";
|
|
215
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped";
|
|
216
216
|
recipient: string | null;
|
|
217
217
|
scheduledFor: string;
|
|
218
218
|
processedAt: string;
|
package/dist/task-runtime.d.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import type { ExecutionLockManager } from "@voyantjs/core";
|
|
1
2
|
import type { NotificationProvider } from "./types.js";
|
|
2
3
|
export type NotificationTaskEnv = {
|
|
3
4
|
RESEND_API_KEY?: unknown;
|
|
4
5
|
EMAIL_FROM?: unknown;
|
|
5
6
|
};
|
|
7
|
+
export type ReminderDeliveryJob = {
|
|
8
|
+
reminderRunId: string;
|
|
9
|
+
};
|
|
6
10
|
export type NotificationTaskRuntime = {
|
|
7
11
|
providers: ReadonlyArray<NotificationProvider>;
|
|
12
|
+
reminderSweepLockManager?: ExecutionLockManager;
|
|
13
|
+
enqueueReminderDelivery?: (job: ReminderDeliveryJob) => Promise<void>;
|
|
8
14
|
};
|
|
9
15
|
export type NotificationTaskRuntimeOptions = {
|
|
10
16
|
providers?: ReadonlyArray<NotificationProvider>;
|
|
17
|
+
reminderSweepLockManager?: ExecutionLockManager;
|
|
18
|
+
enqueueReminderDelivery?: (job: ReminderDeliveryJob) => Promise<void>;
|
|
11
19
|
resolveProviders?: (env: NotificationTaskEnv) => ReadonlyArray<NotificationProvider>;
|
|
12
20
|
};
|
|
13
21
|
export declare function buildNotificationTaskRuntime(env: NotificationTaskEnv, options?: NotificationTaskRuntimeOptions): NotificationTaskRuntime;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-runtime.d.ts","sourceRoot":"","sources":["../src/task-runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"task-runtime.d.ts","sourceRoot":"","sources":["../src/task-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAG1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEtD,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC9C,wBAAwB,CAAC,EAAE,oBAAoB,CAAA;IAC/C,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtE,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC3C,SAAS,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC/C,wBAAwB,CAAC,EAAE,oBAAoB,CAAA;IAC/C,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,aAAa,CAAC,oBAAoB,CAAC,CAAA;CACrF,CAAA;AAED,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,mBAAmB,EACxB,OAAO,GAAE,8BAAmC,GAC3C,uBAAuB,CASzB"}
|
package/dist/task-runtime.js
CHANGED
|
@@ -4,5 +4,7 @@ export function buildNotificationTaskRuntime(env, options = {}) {
|
|
|
4
4
|
providers: options.resolveProviders?.(env) ??
|
|
5
5
|
options.providers ??
|
|
6
6
|
createDefaultNotificationProviders(env),
|
|
7
|
+
reminderSweepLockManager: options.reminderSweepLockManager,
|
|
8
|
+
enqueueReminderDelivery: options.enqueueReminderDelivery,
|
|
7
9
|
};
|
|
8
10
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import { type NotificationTaskEnv, type NotificationTaskRuntimeOptions } from "../task-runtime.js";
|
|
3
|
+
export declare function deliverQueuedNotificationReminder(db: PostgresJsDatabase, env: NotificationTaskEnv, input: {
|
|
4
|
+
reminderRunId: string;
|
|
5
|
+
}, options?: NotificationTaskRuntimeOptions): Promise<{
|
|
6
|
+
reminderRunId: string;
|
|
7
|
+
status: "failed" | "sent" | "processing" | "queued" | "skipped" | null;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=deliver-reminder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliver-reminder.d.ts","sourceRoot":"","sources":["../../src/tasks/deliver-reminder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACpC,MAAM,oBAAoB,CAAA;AAE3B,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,kBAAkB,EACtB,GAAG,EAAE,mBAAmB,EACxB,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,EAChC,OAAO,GAAE,8BAAmC;;;GAU7C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createNotificationService } from "../service.js";
|
|
2
|
+
import { deliverReminderRun } from "../service-reminders.js";
|
|
3
|
+
import { buildNotificationTaskRuntime, } from "../task-runtime.js";
|
|
4
|
+
export async function deliverQueuedNotificationReminder(db, env, input, options = {}) {
|
|
5
|
+
const runtime = buildNotificationTaskRuntime(env, options);
|
|
6
|
+
const dispatcher = createNotificationService(runtime.providers);
|
|
7
|
+
const result = await deliverReminderRun(db, dispatcher, input);
|
|
8
|
+
return {
|
|
9
|
+
reminderRunId: input.reminderRunId,
|
|
10
|
+
status: result?.status ?? null,
|
|
11
|
+
};
|
|
12
|
+
}
|
package/dist/tasks/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/tasks/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import type { ReminderQueueResult, ReminderSweepResult } from "../service-shared.js";
|
|
2
3
|
import { type NotificationTaskEnv, type NotificationTaskRuntimeOptions } from "../task-runtime.js";
|
|
3
4
|
export declare function sendDueNotificationReminders(db: PostgresJsDatabase, env: NotificationTaskEnv, input?: {
|
|
4
5
|
now?: string | null;
|
|
5
|
-
}, options?: NotificationTaskRuntimeOptions): Promise<
|
|
6
|
+
}, options?: NotificationTaskRuntimeOptions): Promise<ReminderSweepResult | ReminderQueueResult>;
|
|
6
7
|
//# sourceMappingURL=send-due-reminders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-due-reminders.d.ts","sourceRoot":"","sources":["../../src/tasks/send-due-reminders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"send-due-reminders.d.ts","sourceRoot":"","sources":["../../src/tasks/send-due-reminders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACpF,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACpC,MAAM,oBAAoB,CAAA;AAE3B,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,kBAAkB,EACtB,GAAG,EAAE,mBAAmB,EACxB,KAAK,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,EACnC,OAAO,GAAE,8BAAmC,sDAqC7C"}
|
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
import { createNotificationService
|
|
1
|
+
import { createNotificationService } from "../service.js";
|
|
2
|
+
import { queueDueReminders, runDueReminders } from "../service-reminders.js";
|
|
2
3
|
import { buildNotificationTaskRuntime, } from "../task-runtime.js";
|
|
3
4
|
export async function sendDueNotificationReminders(db, env, input = {}, options = {}) {
|
|
4
5
|
const runtime = buildNotificationTaskRuntime(env, options);
|
|
5
6
|
const dispatcher = createNotificationService(runtime.providers);
|
|
6
|
-
|
|
7
|
+
const runSweep = () => runtime.enqueueReminderDelivery
|
|
8
|
+
? queueDueReminders(db, input, runtime.enqueueReminderDelivery)
|
|
9
|
+
: runDueReminders(db, dispatcher, input);
|
|
10
|
+
if (!runtime.reminderSweepLockManager) {
|
|
11
|
+
return runSweep();
|
|
12
|
+
}
|
|
13
|
+
const result = await runtime.reminderSweepLockManager.runExclusive("notifications:due-reminders", runSweep);
|
|
14
|
+
if (result.executed) {
|
|
15
|
+
return result.value;
|
|
16
|
+
}
|
|
17
|
+
if (!runtime.enqueueReminderDelivery) {
|
|
18
|
+
return {
|
|
19
|
+
processed: 0,
|
|
20
|
+
sent: 0,
|
|
21
|
+
skipped: 0,
|
|
22
|
+
failed: 0,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
processed: 0,
|
|
27
|
+
queued: 0,
|
|
28
|
+
skipped: 0,
|
|
29
|
+
failed: 0,
|
|
30
|
+
};
|
|
7
31
|
}
|
package/dist/validation.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export declare const notificationReminderRunStatusSchema: z.ZodEnum<{
|
|
|
37
37
|
failed: "failed";
|
|
38
38
|
sent: "sent";
|
|
39
39
|
processing: "processing";
|
|
40
|
+
queued: "queued";
|
|
40
41
|
skipped: "skipped";
|
|
41
42
|
}>;
|
|
42
43
|
export declare const notificationDocumentTypeSchema: z.ZodEnum<{
|
|
@@ -231,6 +232,7 @@ export declare const notificationReminderRunListQuerySchema: z.ZodObject<{
|
|
|
231
232
|
failed: "failed";
|
|
232
233
|
sent: "sent";
|
|
233
234
|
processing: "processing";
|
|
235
|
+
queued: "queued";
|
|
234
236
|
skipped: "skipped";
|
|
235
237
|
}>>;
|
|
236
238
|
}, z.core.$strip>;
|
|
@@ -297,6 +299,7 @@ export declare const notificationReminderRunRecordSchema: z.ZodObject<{
|
|
|
297
299
|
failed: "failed";
|
|
298
300
|
sent: "sent";
|
|
299
301
|
processing: "processing";
|
|
302
|
+
queued: "queued";
|
|
300
303
|
skipped: "skipped";
|
|
301
304
|
}>;
|
|
302
305
|
recipient: z.ZodNullable<z.ZodString>;
|
|
@@ -371,6 +374,7 @@ export declare const notificationReminderRunListResponseSchema: z.ZodObject<{
|
|
|
371
374
|
failed: "failed";
|
|
372
375
|
sent: "sent";
|
|
373
376
|
processing: "processing";
|
|
377
|
+
queued: "queued";
|
|
374
378
|
skipped: "skipped";
|
|
375
379
|
}>;
|
|
376
380
|
recipient: z.ZodNullable<z.ZodString>;
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,yBAAyB;;;EAA2B,CAAA;AACjE,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,gCAAgC;;;;;EAAqD,CAAA;AAClG,eAAO,MAAM,4BAA4B;;;;;;;;;EASvC,CAAA;AACF,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,oCAAoC;;;EAAkD,CAAA;AACnG,eAAO,MAAM,mCAAmC
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,yBAAyB;;;EAA2B,CAAA;AACjE,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,gCAAgC;;;;;EAAqD,CAAA;AAClG,eAAO,MAAM,4BAA4B;;;;;;;;;EASvC,CAAA;AACF,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,oCAAoC;;;EAAkD,CAAA;AACnG,eAAO,MAAM,mCAAmC;;;;;;EAM9C,CAAA;AACF,eAAO,MAAM,8BAA8B;;;;EAA8C,CAAA;AACzF,eAAO,MAAM,gCAAgC;;;EAA+B,CAAA;AAC5E,eAAO,MAAM,4BAA4B;;;;;;;;;;iBAYrC,CAAA;AAqBJ,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;iBAAiC,CAAA;AAC9E,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;iBAA2C,CAAA;AAExF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;iBAK9C,CAAA;AAEF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAY9C,CAAA;AAgBF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;iBAMhD,CAAA;AAED,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;iBAI7C,CAAA;AAEJ,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;iBAKlD,CAAA;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;iBAajD,CAAA;AAEF,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;iBAWnD,CAAA;AAEF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;iBAUvD,CAAA;AAEF,eAAO,MAAM,kCAAkC;;;;;;;;iBAQ7C,CAAA;AAEF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiB9C,CAAA;AAEF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKpD,CAAA;AAEF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAA;AAkBF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMhD,CAAA;AAED,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMzC,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BhC,CAAA;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmB1C,CAAA;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGtC,CAAA;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;iBAajD,CAAA;AAEF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOvD,CAAA"}
|
package/dist/validation.js
CHANGED
|
@@ -15,6 +15,7 @@ export const notificationTargetTypeSchema = z.enum([
|
|
|
15
15
|
export const notificationReminderStatusSchema = z.enum(["draft", "active", "archived"]);
|
|
16
16
|
export const notificationReminderTargetTypeSchema = z.enum(["booking_payment_schedule", "invoice"]);
|
|
17
17
|
export const notificationReminderRunStatusSchema = z.enum([
|
|
18
|
+
"queued",
|
|
18
19
|
"processing",
|
|
19
20
|
"sent",
|
|
20
21
|
"skipped",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voyantjs/notifications",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"license": "FSL-1.1-Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"drizzle-orm": "^0.45.2",
|
|
50
50
|
"hono": "^4.12.10",
|
|
51
51
|
"zod": "^4.3.6",
|
|
52
|
-
"@voyantjs/bookings": "0.6.
|
|
53
|
-
"@voyantjs/core": "0.6.
|
|
54
|
-
"@voyantjs/db": "0.6.
|
|
55
|
-
"@voyantjs/finance": "0.6.
|
|
56
|
-
"@voyantjs/hono": "0.6.
|
|
57
|
-
"@voyantjs/legal": "0.6.
|
|
52
|
+
"@voyantjs/bookings": "0.6.5",
|
|
53
|
+
"@voyantjs/core": "0.6.5",
|
|
54
|
+
"@voyantjs/db": "0.6.5",
|
|
55
|
+
"@voyantjs/finance": "0.6.5",
|
|
56
|
+
"@voyantjs/hono": "0.6.5",
|
|
57
|
+
"@voyantjs/legal": "0.6.5"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"typescript": "^6.0.2",
|