@voyant-travel/notifications 0.111.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +179 -0
  3. package/dist/index.d.ts +61 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +196 -0
  6. package/dist/liquid.d.ts +5 -0
  7. package/dist/liquid.d.ts.map +1 -0
  8. package/dist/liquid.js +156 -0
  9. package/dist/providers/local.d.ts +22 -0
  10. package/dist/providers/local.d.ts.map +1 -0
  11. package/dist/providers/local.js +23 -0
  12. package/dist/providers/voyant-cloud-email.d.ts +27 -0
  13. package/dist/providers/voyant-cloud-email.d.ts.map +1 -0
  14. package/dist/providers/voyant-cloud-email.js +73 -0
  15. package/dist/providers/voyant-cloud-sms.d.ts +26 -0
  16. package/dist/providers/voyant-cloud-sms.d.ts.map +1 -0
  17. package/dist/providers/voyant-cloud-sms.js +24 -0
  18. package/dist/routes.d.ts +1546 -0
  19. package/dist/routes.d.ts.map +1 -0
  20. package/dist/routes.js +337 -0
  21. package/dist/schema.d.ts +2119 -0
  22. package/dist/schema.d.ts.map +1 -0
  23. package/dist/schema.js +356 -0
  24. package/dist/service-booking-document-lifecycle.d.ts +99 -0
  25. package/dist/service-booking-document-lifecycle.d.ts.map +1 -0
  26. package/dist/service-booking-document-lifecycle.js +259 -0
  27. package/dist/service-booking-documents.d.ts +256 -0
  28. package/dist/service-booking-documents.d.ts.map +1 -0
  29. package/dist/service-booking-documents.js +323 -0
  30. package/dist/service-deliveries.d.ts +183 -0
  31. package/dist/service-deliveries.d.ts.map +1 -0
  32. package/dist/service-deliveries.js +413 -0
  33. package/dist/service-delivery-metadata.d.ts +42 -0
  34. package/dist/service-delivery-metadata.d.ts.map +1 -0
  35. package/dist/service-delivery-metadata.js +114 -0
  36. package/dist/service-reminder-authoring.d.ts +33 -0
  37. package/dist/service-reminder-authoring.d.ts.map +1 -0
  38. package/dist/service-reminder-authoring.js +247 -0
  39. package/dist/service-reminder-booking-context.d.ts +94 -0
  40. package/dist/service-reminder-booking-context.d.ts.map +1 -0
  41. package/dist/service-reminder-booking-context.js +164 -0
  42. package/dist/service-reminder-events.d.ts +33 -0
  43. package/dist/service-reminder-events.d.ts.map +1 -0
  44. package/dist/service-reminder-events.js +178 -0
  45. package/dist/service-reminder-run-state.d.ts +114 -0
  46. package/dist/service-reminder-run-state.d.ts.map +1 -0
  47. package/dist/service-reminder-run-state.js +100 -0
  48. package/dist/service-reminder-stage-runs.d.ts +6 -0
  49. package/dist/service-reminder-stage-runs.d.ts.map +1 -0
  50. package/dist/service-reminder-stage-runs.js +310 -0
  51. package/dist/service-reminders.d.ts +30 -0
  52. package/dist/service-reminders.d.ts.map +1 -0
  53. package/dist/service-reminders.js +189 -0
  54. package/dist/service-sequence-targets.d.ts +50 -0
  55. package/dist/service-sequence-targets.d.ts.map +1 -0
  56. package/dist/service-sequence-targets.js +136 -0
  57. package/dist/service-sequence.d.ts +68 -0
  58. package/dist/service-sequence.d.ts.map +1 -0
  59. package/dist/service-sequence.js +316 -0
  60. package/dist/service-shared.d.ts +107 -0
  61. package/dist/service-shared.d.ts.map +1 -0
  62. package/dist/service-shared.js +159 -0
  63. package/dist/service-stages.d.ts +23 -0
  64. package/dist/service-stages.d.ts.map +1 -0
  65. package/dist/service-stages.js +203 -0
  66. package/dist/service-template-data.d.ts +19 -0
  67. package/dist/service-template-data.d.ts.map +1 -0
  68. package/dist/service-template-data.js +278 -0
  69. package/dist/service-templates.d.ts +260 -0
  70. package/dist/service-templates.d.ts.map +1 -0
  71. package/dist/service-templates.js +293 -0
  72. package/dist/service.d.ts +273 -0
  73. package/dist/service.d.ts.map +1 -0
  74. package/dist/service.js +51 -0
  75. package/dist/task-runtime.d.ts +19 -0
  76. package/dist/task-runtime.d.ts.map +1 -0
  77. package/dist/task-runtime.js +11 -0
  78. package/dist/tasks/deliver-reminder.d.ts +9 -0
  79. package/dist/tasks/deliver-reminder.d.ts.map +1 -0
  80. package/dist/tasks/deliver-reminder.js +12 -0
  81. package/dist/tasks/index.d.ts +3 -0
  82. package/dist/tasks/index.d.ts.map +1 -0
  83. package/dist/tasks/index.js +2 -0
  84. package/dist/tasks/send-due-reminders.d.ts +7 -0
  85. package/dist/tasks/send-due-reminders.d.ts.map +1 -0
  86. package/dist/tasks/send-due-reminders.js +31 -0
  87. package/dist/template-authoring.d.ts +23 -0
  88. package/dist/template-authoring.d.ts.map +1 -0
  89. package/dist/template-authoring.js +386 -0
  90. package/dist/types.d.ts +82 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +1 -0
  93. package/dist/validation.d.ts +1093 -0
  94. package/dist/validation.d.ts.map +1 -0
  95. package/dist/validation.js +451 -0
  96. package/package.json +102 -0
@@ -0,0 +1,323 @@
1
+ import { bookings } from "@voyant-travel/bookings/schema";
2
+ import { invoiceRenditions, invoices } from "@voyant-travel/finance/schema";
3
+ import { contractAttachments, contracts } from "@voyant-travel/legal/contracts";
4
+ import { and, desc, eq, ne, or } from "drizzle-orm";
5
+ import { sendNotification } from "./service-deliveries.js";
6
+ import { listBookingNotificationItems, listBookingNotificationParticipants, resolveReminderRecipient, } from "./service-shared.js";
7
+ function getMetadataRecord(value) {
8
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
9
+ return null;
10
+ }
11
+ return value;
12
+ }
13
+ function getMetadataString(metadata, keys) {
14
+ if (!metadata) {
15
+ return null;
16
+ }
17
+ for (const key of keys) {
18
+ const value = metadata[key];
19
+ if (typeof value === "string" && value.length > 0) {
20
+ return value;
21
+ }
22
+ }
23
+ return null;
24
+ }
25
+ function createDefaultAttachmentFromDocument(document) {
26
+ if (!document.downloadUrl) {
27
+ return null;
28
+ }
29
+ return {
30
+ filename: document.name,
31
+ path: document.downloadUrl,
32
+ contentType: document.mimeType ?? undefined,
33
+ };
34
+ }
35
+ function buildDefaultDocumentMessage(booking, documents) {
36
+ const label = booking.bookingNumber || booking.id;
37
+ const listText = documents.map((document) => `- ${document.name}`).join("\n");
38
+ const listHtml = documents.map((document) => `<li>${document.name}</li>`).join("");
39
+ return {
40
+ subject: `Booking ${label} documents`,
41
+ text: `Your booking documents are attached.\n\nBooking: ${label}\n\n${listText}`,
42
+ html: `<p>Your booking documents are attached.</p><p><strong>Booking:</strong> ${label}</p><ul>${listHtml}</ul>`,
43
+ };
44
+ }
45
+ async function listLegalBookingDocuments(db, bookingId) {
46
+ const contractRows = await db
47
+ .select()
48
+ .from(contracts)
49
+ .where(and(eq(contracts.bookingId, bookingId), eq(contracts.scope, "customer"), ne(contracts.status, "void")))
50
+ .orderBy(desc(contracts.createdAt));
51
+ if (contractRows.length === 0) {
52
+ return [];
53
+ }
54
+ const attachmentRows = await db
55
+ .select()
56
+ .from(contractAttachments)
57
+ .where(and(eq(contractAttachments.kind, "document"), or(...contractRows.map((contract) => eq(contractAttachments.contractId, contract.id)))))
58
+ .orderBy(desc(contractAttachments.createdAt));
59
+ const bestAttachmentByContractId = new Map();
60
+ for (const attachment of attachmentRows) {
61
+ if (!bestAttachmentByContractId.has(attachment.contractId)) {
62
+ bestAttachmentByContractId.set(attachment.contractId, attachment);
63
+ }
64
+ }
65
+ return contractRows.flatMap((contract) => {
66
+ const attachment = bestAttachmentByContractId.get(contract.id);
67
+ if (!attachment) {
68
+ return [];
69
+ }
70
+ const metadata = getMetadataRecord(attachment.metadata);
71
+ return [
72
+ {
73
+ key: `legal:${attachment.id}`,
74
+ source: "legal",
75
+ documentType: "contract",
76
+ bookingId,
77
+ contractId: contract.id,
78
+ invoiceId: null,
79
+ attachmentId: attachment.id,
80
+ renditionId: null,
81
+ contractStatus: contract.status,
82
+ invoiceStatus: null,
83
+ name: attachment.name,
84
+ format: attachment.mimeType === "application/pdf" ? "pdf" : null,
85
+ mimeType: attachment.mimeType ?? null,
86
+ storageKey: attachment.storageKey ?? null,
87
+ downloadUrl: getMetadataString(metadata, ["url"]),
88
+ language: contract.language ?? null,
89
+ metadata,
90
+ createdAt: attachment.createdAt.toISOString(),
91
+ },
92
+ ];
93
+ });
94
+ }
95
+ function compareInvoiceRenditions(left, right) {
96
+ const formatRank = new Map([
97
+ ["pdf", 0],
98
+ ["html", 1],
99
+ ["json", 2],
100
+ ["xml", 3],
101
+ ]);
102
+ const leftRank = formatRank.get(left.format) ?? Number.MAX_SAFE_INTEGER;
103
+ const rightRank = formatRank.get(right.format) ?? Number.MAX_SAFE_INTEGER;
104
+ if (leftRank !== rightRank) {
105
+ return leftRank - rightRank;
106
+ }
107
+ return right.createdAt.getTime() - left.createdAt.getTime();
108
+ }
109
+ async function listFinanceBookingDocuments(db, bookingId) {
110
+ const invoiceRows = await db
111
+ .select()
112
+ .from(invoices)
113
+ .where(and(eq(invoices.bookingId, bookingId), ne(invoices.status, "void")))
114
+ .orderBy(desc(invoices.createdAt));
115
+ if (invoiceRows.length === 0) {
116
+ return [];
117
+ }
118
+ const renditionRows = await db
119
+ .select()
120
+ .from(invoiceRenditions)
121
+ .where(and(eq(invoiceRenditions.status, "ready"), or(...invoiceRows.map((invoice) => eq(invoiceRenditions.invoiceId, invoice.id)))))
122
+ .orderBy(desc(invoiceRenditions.createdAt));
123
+ const bestRenditionByInvoiceId = new Map();
124
+ for (const rendition of renditionRows) {
125
+ const existing = bestRenditionByInvoiceId.get(rendition.invoiceId);
126
+ if (!existing || compareInvoiceRenditions(rendition, existing) < 0) {
127
+ bestRenditionByInvoiceId.set(rendition.invoiceId, rendition);
128
+ }
129
+ }
130
+ return invoiceRows.flatMap((invoice) => {
131
+ const rendition = bestRenditionByInvoiceId.get(invoice.id);
132
+ if (!rendition) {
133
+ return [];
134
+ }
135
+ const metadata = getMetadataRecord(rendition.metadata);
136
+ const format = rendition.format;
137
+ const extension = format === "pdf" ? "pdf" : format;
138
+ return [
139
+ {
140
+ key: `finance:${rendition.id}`,
141
+ source: "finance",
142
+ documentType: invoice.invoiceType === "proforma" ? "proforma" : "invoice",
143
+ bookingId,
144
+ contractId: null,
145
+ invoiceId: invoice.id,
146
+ attachmentId: null,
147
+ renditionId: rendition.id,
148
+ contractStatus: null,
149
+ invoiceStatus: invoice.status,
150
+ name: `${invoice.invoiceNumber}.${extension}`,
151
+ format,
152
+ mimeType: format === "pdf"
153
+ ? "application/pdf"
154
+ : format === "html"
155
+ ? "text/html"
156
+ : format === "json"
157
+ ? "application/json"
158
+ : "application/xml",
159
+ storageKey: rendition.storageKey ?? null,
160
+ downloadUrl: getMetadataString(metadata, ["url"]),
161
+ language: rendition.language ?? invoice.language ?? null,
162
+ metadata,
163
+ createdAt: rendition.createdAt.toISOString(),
164
+ },
165
+ ];
166
+ });
167
+ }
168
+ export const bookingDocumentNotificationsService = {
169
+ async listBookingDocumentBundle(db, bookingId) {
170
+ const [booking] = await db.select().from(bookings).where(eq(bookings.id, bookingId)).limit(1);
171
+ if (!booking) {
172
+ return null;
173
+ }
174
+ const [legalDocuments, financeDocuments] = await Promise.all([
175
+ listLegalBookingDocuments(db, bookingId),
176
+ listFinanceBookingDocuments(db, bookingId),
177
+ ]);
178
+ return {
179
+ bookingId,
180
+ documents: [...legalDocuments, ...financeDocuments],
181
+ };
182
+ },
183
+ async sendBookingDocumentsNotification(db, dispatcher, bookingId, input, runtime = {}) {
184
+ const [booking] = await db.select().from(bookings).where(eq(bookings.id, bookingId)).limit(1);
185
+ if (!booking) {
186
+ return { status: "not_found" };
187
+ }
188
+ const bundle = await this.listBookingDocumentBundle(db, bookingId);
189
+ const requestedTypes = new Set(input.documentTypes ?? ["contract", "invoice", "proforma"]);
190
+ const documents = (bundle?.documents ?? []).filter((document) => requestedTypes.has(document.documentType));
191
+ if (documents.length === 0) {
192
+ return { status: "no_documents" };
193
+ }
194
+ const [participants, items] = await Promise.all([
195
+ listBookingNotificationParticipants(db, bookingId),
196
+ listBookingNotificationItems(db, bookingId),
197
+ ]);
198
+ const recipient = resolveReminderRecipient(booking, participants);
199
+ const to = input.to ?? recipient?.email ?? null;
200
+ if (!to) {
201
+ return { status: "no_recipient" };
202
+ }
203
+ const attachmentResolver = runtime.attachmentResolver ??
204
+ (async (document) => createDefaultAttachmentFromDocument(document));
205
+ const attachments = (await Promise.all(documents.map((document) => attachmentResolver(document)))).filter((attachment) => Boolean(attachment));
206
+ if (attachments.length === 0) {
207
+ return { status: "no_attachments" };
208
+ }
209
+ const defaults = buildDefaultDocumentMessage(booking, documents);
210
+ const delivery = await sendNotification(db, dispatcher, {
211
+ templateId: input.templateId ?? null,
212
+ templateSlug: input.templateSlug ?? null,
213
+ channel: "email",
214
+ provider: input.provider ?? null,
215
+ to,
216
+ from: input.from ?? null,
217
+ subject: input.subject ?? defaults.subject,
218
+ html: input.html ?? defaults.html,
219
+ text: input.text ?? defaults.text,
220
+ attachments,
221
+ data: {
222
+ booking: {
223
+ id: booking.id,
224
+ bookingNumber: booking.bookingNumber,
225
+ status: booking.status,
226
+ sellCurrency: booking.sellCurrency,
227
+ sellAmountCents: booking.sellAmountCents,
228
+ startDate: booking.startDate,
229
+ endDate: booking.endDate,
230
+ },
231
+ traveler: recipient
232
+ ? {
233
+ firstName: recipient.firstName,
234
+ lastName: recipient.lastName,
235
+ email: recipient.email,
236
+ participantType: recipient.participantType,
237
+ isPrimary: recipient.isPrimary,
238
+ }
239
+ : null,
240
+ travelers: participants,
241
+ documents,
242
+ items,
243
+ ...(input.data ?? {}),
244
+ },
245
+ targetType: "booking",
246
+ targetId: booking.id,
247
+ bookingId: booking.id,
248
+ personId: booking.personId ?? null,
249
+ organizationId: booking.organizationId ?? null,
250
+ metadata: {
251
+ bookingDocumentKeys: documents.map((document) => document.key),
252
+ ...(input.metadata ?? {}),
253
+ },
254
+ scheduledFor: input.scheduledFor ?? null,
255
+ });
256
+ if (!delivery) {
257
+ return { status: "send_failed" };
258
+ }
259
+ await runtime.eventBus?.emit("booking.documents.sent", {
260
+ bookingId: booking.id,
261
+ recipient: to,
262
+ deliveryId: delivery.id,
263
+ provider: delivery.provider ?? null,
264
+ documentKeys: documents.map((document) => document.key),
265
+ }, {
266
+ category: "domain",
267
+ source: "service",
268
+ });
269
+ return {
270
+ status: "sent",
271
+ bookingId: booking.id,
272
+ recipient: to,
273
+ documents,
274
+ delivery,
275
+ };
276
+ },
277
+ /**
278
+ * Confirm-and-dispatch — single orchestrated call for the operator flow
279
+ * that wants "list the booking's documents, then send them to the client"
280
+ * to be one action instead of two round-trips.
281
+ *
282
+ * With `sendNotification: false`, the caller gets the bundle back without
283
+ * attempting a send — useful for rendering a preview/checkbox list before
284
+ * the operator confirms. With `sendNotification: true`, the same send
285
+ * guards as `sendBookingDocumentsNotification` apply (no_documents,
286
+ * no_recipient, no_attachments, send_failed); the result keeps the bundle
287
+ * regardless so the UI always has something to show.
288
+ */
289
+ async confirmAndDispatchBooking(db, dispatcher, bookingId, input, runtime = {}) {
290
+ const bundle = await this.listBookingDocumentBundle(db, bookingId);
291
+ if (!bundle)
292
+ return { status: "not_found" };
293
+ const documents = bundle.documents;
294
+ const sendNotification = input.sendNotification ?? true;
295
+ if (!sendNotification) {
296
+ return {
297
+ status: "preview",
298
+ bookingId,
299
+ documents,
300
+ };
301
+ }
302
+ const result = await this.sendBookingDocumentsNotification(db, dispatcher, bookingId, input, runtime);
303
+ if (result.status === "not_found") {
304
+ return { status: "not_found" };
305
+ }
306
+ if (result.status !== "sent") {
307
+ return {
308
+ status: "skipped",
309
+ bookingId,
310
+ documents,
311
+ skipReason: result.status,
312
+ };
313
+ }
314
+ return {
315
+ status: "dispatched",
316
+ bookingId: result.bookingId,
317
+ documents: result.documents,
318
+ recipient: result.recipient,
319
+ delivery: result.delivery,
320
+ };
321
+ },
322
+ };
323
+ export { createDefaultAttachmentFromDocument as createDefaultBookingDocumentAttachment };
@@ -0,0 +1,183 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import type { NotificationDeliveryListQuery, NotificationService, SendInvoiceNotificationInput, SendNotificationInput, SendPaymentSessionNotificationInput } from "./service-shared.js";
3
+ export { resolveNotificationPaymentUrl } from "./service-delivery-metadata.js";
4
+ export declare function listDeliveries(db: PostgresJsDatabase, query: NotificationDeliveryListQuery): Promise<{
5
+ data: {
6
+ id: string;
7
+ templateId: string | null;
8
+ templateSlug: string | null;
9
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
10
+ targetId: string | null;
11
+ personId: string | null;
12
+ organizationId: string | null;
13
+ bookingId: string | null;
14
+ invoiceId: string | null;
15
+ paymentSessionId: string | null;
16
+ channel: "email" | "sms";
17
+ provider: string;
18
+ providerMessageId: string | null;
19
+ status: "pending" | "sent" | "failed" | "cancelled";
20
+ toAddress: string;
21
+ fromAddress: string | null;
22
+ subject: string | null;
23
+ htmlBody: string | null;
24
+ textBody: string | null;
25
+ payloadData: Record<string, unknown> | null;
26
+ metadata: Record<string, unknown> | null;
27
+ errorMessage: string | null;
28
+ scheduledFor: Date | null;
29
+ sentAt: Date | null;
30
+ failedAt: Date | null;
31
+ createdAt: Date;
32
+ updatedAt: Date;
33
+ }[];
34
+ total: number;
35
+ limit: number;
36
+ offset: number;
37
+ }>;
38
+ export declare function getDeliveryById(db: PostgresJsDatabase, id: string): Promise<{
39
+ id: string;
40
+ templateId: string | null;
41
+ templateSlug: string | null;
42
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
43
+ targetId: string | null;
44
+ personId: string | null;
45
+ organizationId: string | null;
46
+ bookingId: string | null;
47
+ invoiceId: string | null;
48
+ paymentSessionId: string | null;
49
+ channel: "email" | "sms";
50
+ provider: string;
51
+ providerMessageId: string | null;
52
+ status: "pending" | "sent" | "failed" | "cancelled";
53
+ toAddress: string;
54
+ fromAddress: string | null;
55
+ subject: string | null;
56
+ htmlBody: string | null;
57
+ textBody: string | null;
58
+ payloadData: Record<string, unknown> | null;
59
+ metadata: Record<string, unknown> | null;
60
+ errorMessage: string | null;
61
+ scheduledFor: Date | null;
62
+ sentAt: Date | null;
63
+ failedAt: Date | null;
64
+ createdAt: Date;
65
+ updatedAt: Date;
66
+ } | null>;
67
+ export declare function resendDelivery(db: PostgresJsDatabase, dispatcher: NotificationService, id: string): Promise<{
68
+ id: string;
69
+ templateId: string | null;
70
+ templateSlug: string | null;
71
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
72
+ targetId: string | null;
73
+ personId: string | null;
74
+ organizationId: string | null;
75
+ bookingId: string | null;
76
+ invoiceId: string | null;
77
+ paymentSessionId: string | null;
78
+ channel: "email" | "sms";
79
+ provider: string;
80
+ providerMessageId: string | null;
81
+ status: "pending" | "sent" | "failed" | "cancelled";
82
+ toAddress: string;
83
+ fromAddress: string | null;
84
+ subject: string | null;
85
+ htmlBody: string | null;
86
+ textBody: string | null;
87
+ payloadData: Record<string, unknown> | null;
88
+ metadata: Record<string, unknown> | null;
89
+ errorMessage: string | null;
90
+ scheduledFor: Date | null;
91
+ sentAt: Date | null;
92
+ failedAt: Date | null;
93
+ createdAt: Date;
94
+ updatedAt: Date;
95
+ } | null>;
96
+ export declare function sendNotification(db: PostgresJsDatabase, dispatcher: NotificationService, input: SendNotificationInput): Promise<{
97
+ id: string;
98
+ templateId: string | null;
99
+ templateSlug: string | null;
100
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
101
+ targetId: string | null;
102
+ personId: string | null;
103
+ organizationId: string | null;
104
+ bookingId: string | null;
105
+ invoiceId: string | null;
106
+ paymentSessionId: string | null;
107
+ channel: "email" | "sms";
108
+ provider: string;
109
+ providerMessageId: string | null;
110
+ status: "pending" | "sent" | "failed" | "cancelled";
111
+ toAddress: string;
112
+ fromAddress: string | null;
113
+ subject: string | null;
114
+ htmlBody: string | null;
115
+ textBody: string | null;
116
+ payloadData: Record<string, unknown> | null;
117
+ metadata: Record<string, unknown> | null;
118
+ errorMessage: string | null;
119
+ scheduledFor: Date | null;
120
+ sentAt: Date | null;
121
+ failedAt: Date | null;
122
+ createdAt: Date;
123
+ updatedAt: Date;
124
+ } | null>;
125
+ export declare function sendPaymentSessionNotification(db: PostgresJsDatabase, dispatcher: NotificationService, sessionId: string, input: SendPaymentSessionNotificationInput): Promise<{
126
+ id: string;
127
+ templateId: string | null;
128
+ templateSlug: string | null;
129
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
130
+ targetId: string | null;
131
+ personId: string | null;
132
+ organizationId: string | null;
133
+ bookingId: string | null;
134
+ invoiceId: string | null;
135
+ paymentSessionId: string | null;
136
+ channel: "email" | "sms";
137
+ provider: string;
138
+ providerMessageId: string | null;
139
+ status: "pending" | "sent" | "failed" | "cancelled";
140
+ toAddress: string;
141
+ fromAddress: string | null;
142
+ subject: string | null;
143
+ htmlBody: string | null;
144
+ textBody: string | null;
145
+ payloadData: Record<string, unknown> | null;
146
+ metadata: Record<string, unknown> | null;
147
+ errorMessage: string | null;
148
+ scheduledFor: Date | null;
149
+ sentAt: Date | null;
150
+ failedAt: Date | null;
151
+ createdAt: Date;
152
+ updatedAt: Date;
153
+ } | null>;
154
+ export declare function sendInvoiceNotification(db: PostgresJsDatabase, dispatcher: NotificationService, invoiceId: string, input: SendInvoiceNotificationInput): Promise<{
155
+ id: string;
156
+ templateId: string | null;
157
+ templateSlug: string | null;
158
+ targetType: "invoice" | "booking" | "booking_payment_schedule" | "booking_guarantee" | "payment_session" | "person" | "organization" | "other";
159
+ targetId: string | null;
160
+ personId: string | null;
161
+ organizationId: string | null;
162
+ bookingId: string | null;
163
+ invoiceId: string | null;
164
+ paymentSessionId: string | null;
165
+ channel: "email" | "sms";
166
+ provider: string;
167
+ providerMessageId: string | null;
168
+ status: "pending" | "sent" | "failed" | "cancelled";
169
+ toAddress: string;
170
+ fromAddress: string | null;
171
+ subject: string | null;
172
+ htmlBody: string | null;
173
+ textBody: string | null;
174
+ payloadData: Record<string, unknown> | null;
175
+ metadata: Record<string, unknown> | null;
176
+ errorMessage: string | null;
177
+ scheduledFor: Date | null;
178
+ sentAt: Date | null;
179
+ failedAt: Date | null;
180
+ createdAt: Date;
181
+ updatedAt: Date;
182
+ } | null>;
183
+ //# sourceMappingURL=service-deliveries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-deliveries.d.ts","sourceRoot":"","sources":["../src/service-deliveries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAUjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,mBAAmB,EACnB,4BAA4B,EAC5B,qBAAqB,EACrB,mCAAmC,EACpC,MAAM,qBAAqB,CAAA;AAc5B,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAE9E,wBAAsB,cAAc,CAAC,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgChG;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOvE;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAgCX;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuI7B;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA2G3C;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAyGpC"}