@voyantjs/notifications 0.6.2 → 0.6.3

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 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;
@@ -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,GAC/B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAC/D,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,oCAAoC,EACpC,gCAAgC,EAChC,4BAA4B,EAC5B,yBAAyB,EACzB,mCAAmC,EACnC,gCAAgC,EAChC,gCAAgC,EAChC,8BAA8B,EAC9B,uCAAuC,EACvC,4CAA4C,EAC5C,kCAAkC,EAClC,sCAAsC,EACtC,yCAAyC,EACzC,mCAAmC,EACnC,wCAAwC,EACxC,mCAAmC,EACnC,gCAAgC,EAChC,oCAAoC,EACpC,4BAA4B,EAC5B,mCAAmC,EACnC,gCAAgC,EAChC,qBAAqB,EACrB,4CAA4C,EAC5C,sCAAsC,EACtC,6BAA6B,EAC7B,sBAAsB,EACtB,oCAAoC,EACpC,oCAAoC,EACpC,gCAAgC,GACjC,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,6BAA6B,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,UAAU,CAe9F"}
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;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -33,6 +33,7 @@ export const notificationReminderTargetTypeEnum = pgEnum("notification_reminder_
33
33
  "invoice",
34
34
  ]);
35
35
  export const notificationReminderRunStatusEnum = pgEnum("notification_reminder_run_status", [
36
+ "queued",
36
37
  "processing",
37
38
  "sent",
38
39
  "skipped",
@@ -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;AAoW5B,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,GAAE,oBAAyB,gCAiFjC"}
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
- const [run] = await db
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
- const [run] = await db
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
- const [run] = await db
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
- const [run] = await db
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
- const [run] = await db
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
- const [run] = await db
312
- .update(notificationReminderRuns)
313
- .set({
314
- status: "failed",
315
- errorMessage: message,
316
- processedAt: new Date(),
317
- updatedAt: new Date(),
318
- })
319
- .where(eq(notificationReminderRuns.id, processingRun.id))
320
- .returning();
321
- return run ?? null;
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") {
@@ -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;
@@ -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":"AACA,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,uBAAuB,GAAG;IACpC,SAAS,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;CAC/C,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC3C,SAAS,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC/C,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,CAOzB"}
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"}
@@ -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
+ }
@@ -1,2 +1,3 @@
1
+ export { deliverQueuedNotificationReminder } from "./deliver-reminder.js";
1
2
  export { sendDueNotificationReminders } from "./send-due-reminders.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -1 +1,2 @@
1
+ export { deliverQueuedNotificationReminder } from "./deliver-reminder.js";
1
2
  export { sendDueNotificationReminders } from "./send-due-reminders.js";
@@ -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<import("../service-shared.js").ReminderSweepResult>;
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;AAEjE,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,+DAK7C"}
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, notificationsService } from "../service.js";
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
- return notificationsService.runDueReminders(db, dispatcher, input);
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
  }
@@ -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>;
@@ -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;;;;;EAK9C,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"}
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"}
@@ -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.2",
3
+ "version": "0.6.3",
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.2",
53
- "@voyantjs/core": "0.6.2",
54
- "@voyantjs/db": "0.6.2",
55
- "@voyantjs/finance": "0.6.2",
56
- "@voyantjs/hono": "0.6.2",
57
- "@voyantjs/legal": "0.6.2"
52
+ "@voyantjs/bookings": "0.6.3",
53
+ "@voyantjs/core": "0.6.3",
54
+ "@voyantjs/db": "0.6.3",
55
+ "@voyantjs/finance": "0.6.3",
56
+ "@voyantjs/hono": "0.6.3",
57
+ "@voyantjs/legal": "0.6.3"
58
58
  },
59
59
  "devDependencies": {
60
60
  "typescript": "^6.0.2",