@thebookingkit/server 0.1.1
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/.turbo/turbo-build.log +6 -0
- package/.turbo/turbo-test.log +20 -0
- package/CHANGELOG.md +9 -0
- package/dist/__tests__/api.test.d.ts +2 -0
- package/dist/__tests__/api.test.d.ts.map +1 -0
- package/dist/__tests__/api.test.js +280 -0
- package/dist/__tests__/api.test.js.map +1 -0
- package/dist/__tests__/auth.test.d.ts +2 -0
- package/dist/__tests__/auth.test.d.ts.map +1 -0
- package/dist/__tests__/auth.test.js +78 -0
- package/dist/__tests__/auth.test.js.map +1 -0
- package/dist/__tests__/concurrent-booking.test.d.ts +2 -0
- package/dist/__tests__/concurrent-booking.test.d.ts.map +1 -0
- package/dist/__tests__/concurrent-booking.test.js +111 -0
- package/dist/__tests__/concurrent-booking.test.js.map +1 -0
- package/dist/__tests__/multi-tenancy.test.d.ts +2 -0
- package/dist/__tests__/multi-tenancy.test.d.ts.map +1 -0
- package/dist/__tests__/multi-tenancy.test.js +196 -0
- package/dist/__tests__/multi-tenancy.test.js.map +1 -0
- package/dist/__tests__/serialization-retry.test.d.ts +2 -0
- package/dist/__tests__/serialization-retry.test.d.ts.map +1 -0
- package/dist/__tests__/serialization-retry.test.js +53 -0
- package/dist/__tests__/serialization-retry.test.js.map +1 -0
- package/dist/__tests__/webhooks.test.d.ts +2 -0
- package/dist/__tests__/webhooks.test.d.ts.map +1 -0
- package/dist/__tests__/webhooks.test.js +286 -0
- package/dist/__tests__/webhooks.test.js.map +1 -0
- package/dist/__tests__/workflows.test.d.ts +2 -0
- package/dist/__tests__/workflows.test.d.ts.map +1 -0
- package/dist/__tests__/workflows.test.js +299 -0
- package/dist/__tests__/workflows.test.js.map +1 -0
- package/dist/adapters/calendar-adapter.d.ts +47 -0
- package/dist/adapters/calendar-adapter.d.ts.map +1 -0
- package/dist/adapters/calendar-adapter.js +2 -0
- package/dist/adapters/calendar-adapter.js.map +1 -0
- package/dist/adapters/email-adapter.d.ts +65 -0
- package/dist/adapters/email-adapter.d.ts.map +1 -0
- package/dist/adapters/email-adapter.js +40 -0
- package/dist/adapters/email-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +9 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +3 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/job-adapter.d.ts +26 -0
- package/dist/adapters/job-adapter.d.ts.map +1 -0
- package/dist/adapters/job-adapter.js +13 -0
- package/dist/adapters/job-adapter.js.map +1 -0
- package/dist/adapters/payment-adapter.d.ts +106 -0
- package/dist/adapters/payment-adapter.d.ts.map +1 -0
- package/dist/adapters/payment-adapter.js +8 -0
- package/dist/adapters/payment-adapter.js.map +1 -0
- package/dist/adapters/sms-adapter.d.ts +33 -0
- package/dist/adapters/sms-adapter.d.ts.map +1 -0
- package/dist/adapters/sms-adapter.js +8 -0
- package/dist/adapters/sms-adapter.js.map +1 -0
- package/dist/adapters/storage-adapter.d.ts +12 -0
- package/dist/adapters/storage-adapter.d.ts.map +1 -0
- package/dist/adapters/storage-adapter.js +2 -0
- package/dist/adapters/storage-adapter.js.map +1 -0
- package/dist/api.d.ts +223 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +271 -0
- package/dist/api.js.map +1 -0
- package/dist/auth.d.ts +71 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +81 -0
- package/dist/auth.js.map +1 -0
- package/dist/booking-tokens.d.ts +23 -0
- package/dist/booking-tokens.d.ts.map +1 -0
- package/dist/booking-tokens.js +52 -0
- package/dist/booking-tokens.js.map +1 -0
- package/dist/email-templates.d.ts +36 -0
- package/dist/email-templates.d.ts.map +1 -0
- package/dist/email-templates.js +112 -0
- package/dist/email-templates.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/multi-tenancy.d.ts +132 -0
- package/dist/multi-tenancy.d.ts.map +1 -0
- package/dist/multi-tenancy.js +188 -0
- package/dist/multi-tenancy.js.map +1 -0
- package/dist/notification-jobs.d.ts +143 -0
- package/dist/notification-jobs.d.ts.map +1 -0
- package/dist/notification-jobs.js +278 -0
- package/dist/notification-jobs.js.map +1 -0
- package/dist/serialization-retry.d.ts +28 -0
- package/dist/serialization-retry.d.ts.map +1 -0
- package/dist/serialization-retry.js +71 -0
- package/dist/serialization-retry.js.map +1 -0
- package/dist/webhooks.d.ts +164 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +228 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/workflows.d.ts +169 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +251 -0
- package/dist/workflows.js.map +1 -0
- package/package.json +32 -0
- package/src/__tests__/api.test.ts +354 -0
- package/src/__tests__/auth.test.ts +111 -0
- package/src/__tests__/concurrent-booking.test.ts +170 -0
- package/src/__tests__/multi-tenancy.test.ts +267 -0
- package/src/__tests__/serialization-retry.test.ts +76 -0
- package/src/__tests__/webhooks.test.ts +412 -0
- package/src/__tests__/workflows.test.ts +422 -0
- package/src/adapters/calendar-adapter.ts +49 -0
- package/src/adapters/email-adapter.ts +108 -0
- package/src/adapters/index.ts +36 -0
- package/src/adapters/job-adapter.ts +26 -0
- package/src/adapters/payment-adapter.ts +118 -0
- package/src/adapters/sms-adapter.ts +35 -0
- package/src/adapters/storage-adapter.ts +11 -0
- package/src/api.ts +446 -0
- package/src/auth.ts +146 -0
- package/src/booking-tokens.ts +61 -0
- package/src/email-templates.ts +140 -0
- package/src/index.ts +192 -0
- package/src/multi-tenancy.ts +301 -0
- package/src/notification-jobs.ts +428 -0
- package/src/serialization-retry.ts +94 -0
- package/src/webhooks.ts +378 -0
- package/src/workflows.ts +441 -0
- package/tsconfig.json +9 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpolate template variables into a template string.
|
|
3
|
+
* Variables use the format `{variableName}`.
|
|
4
|
+
*/
|
|
5
|
+
export function interpolateTemplate(template, vars) {
|
|
6
|
+
return template.replace(/\{(\w+)\}/g, (match, key) => {
|
|
7
|
+
const value = vars[key];
|
|
8
|
+
return value ?? match;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/** Default booking confirmation email template (HTML) */
|
|
12
|
+
export const CONFIRMATION_EMAIL_HTML = `
|
|
13
|
+
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
14
|
+
<h2>Booking Confirmed</h2>
|
|
15
|
+
<p>Hi {customerName},</p>
|
|
16
|
+
<p>Your booking has been confirmed. Here are the details:</p>
|
|
17
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
18
|
+
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
19
|
+
<tr><td style="padding: 8px; font-weight: bold;">Provider</td><td style="padding: 8px;">{providerName}</td></tr>
|
|
20
|
+
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
21
|
+
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
22
|
+
<tr><td style="padding: 8px; font-weight: bold;">Duration</td><td style="padding: 8px;">{duration}</td></tr>
|
|
23
|
+
</table>
|
|
24
|
+
<p style="margin-top: 20px;">
|
|
25
|
+
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
26
|
+
Manage Booking
|
|
27
|
+
</a>
|
|
28
|
+
</p>
|
|
29
|
+
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
30
|
+
<a href="{unsubscribeUrl}">Unsubscribe</a> from booking notifications.
|
|
31
|
+
</p>
|
|
32
|
+
</div>
|
|
33
|
+
`.trim();
|
|
34
|
+
/** Default booking confirmation email (plain text) */
|
|
35
|
+
export const CONFIRMATION_EMAIL_TEXT = `
|
|
36
|
+
Booking Confirmed
|
|
37
|
+
|
|
38
|
+
Hi {customerName},
|
|
39
|
+
|
|
40
|
+
Your booking has been confirmed:
|
|
41
|
+
|
|
42
|
+
Service: {eventTitle}
|
|
43
|
+
Provider: {providerName}
|
|
44
|
+
Date: {date}
|
|
45
|
+
Time: {time} ({timezone})
|
|
46
|
+
Duration: {duration}
|
|
47
|
+
|
|
48
|
+
Manage your booking: {managementUrl}
|
|
49
|
+
|
|
50
|
+
To unsubscribe: {unsubscribeUrl}
|
|
51
|
+
`.trim();
|
|
52
|
+
/** Default reminder email template */
|
|
53
|
+
export const REMINDER_EMAIL_HTML = `
|
|
54
|
+
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
55
|
+
<h2>Appointment Reminder</h2>
|
|
56
|
+
<p>Hi {customerName},</p>
|
|
57
|
+
<p>This is a reminder about your upcoming appointment:</p>
|
|
58
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
59
|
+
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
60
|
+
<tr><td style="padding: 8px; font-weight: bold;">Provider</td><td style="padding: 8px;">{providerName}</td></tr>
|
|
61
|
+
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
62
|
+
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
63
|
+
</table>
|
|
64
|
+
<p style="margin-top: 20px;">
|
|
65
|
+
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
66
|
+
Manage Booking
|
|
67
|
+
</a>
|
|
68
|
+
</p>
|
|
69
|
+
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
70
|
+
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
71
|
+
</p>
|
|
72
|
+
</div>
|
|
73
|
+
`.trim();
|
|
74
|
+
/** Default cancellation email template */
|
|
75
|
+
export const CANCELLATION_EMAIL_HTML = `
|
|
76
|
+
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
77
|
+
<h2>Booking Cancelled</h2>
|
|
78
|
+
<p>Hi {customerName},</p>
|
|
79
|
+
<p>Your booking has been cancelled:</p>
|
|
80
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
81
|
+
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
82
|
+
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
83
|
+
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
84
|
+
</table>
|
|
85
|
+
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
86
|
+
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
87
|
+
</p>
|
|
88
|
+
</div>
|
|
89
|
+
`.trim();
|
|
90
|
+
/** Default reschedule email template */
|
|
91
|
+
export const RESCHEDULE_EMAIL_HTML = `
|
|
92
|
+
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
93
|
+
<h2>Booking Rescheduled</h2>
|
|
94
|
+
<p>Hi {customerName},</p>
|
|
95
|
+
<p>Your booking has been rescheduled:</p>
|
|
96
|
+
<table style="width: 100%; border-collapse: collapse;">
|
|
97
|
+
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
98
|
+
<tr><td style="padding: 8px; font-weight: bold;">Previous</td><td style="padding: 8px;">{oldDate} at {oldTime}</td></tr>
|
|
99
|
+
<tr><td style="padding: 8px; font-weight: bold;">New Date</td><td style="padding: 8px;">{newDate}</td></tr>
|
|
100
|
+
<tr><td style="padding: 8px; font-weight: bold;">New Time</td><td style="padding: 8px;">{newTime} ({timezone})</td></tr>
|
|
101
|
+
</table>
|
|
102
|
+
<p style="margin-top: 20px;">
|
|
103
|
+
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
104
|
+
Manage Booking
|
|
105
|
+
</a>
|
|
106
|
+
</p>
|
|
107
|
+
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
108
|
+
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
109
|
+
</p>
|
|
110
|
+
</div>
|
|
111
|
+
`.trim();
|
|
112
|
+
//# sourceMappingURL=email-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-templates.js","sourceRoot":"","sources":["../src/email-templates.ts"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,IAAuB;IAEvB,OAAO,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACnD,MAAM,KAAK,GAAI,IAAsD,CAAC,GAAG,CAAC,CAAC;QAC3E,OAAO,KAAK,IAAI,KAAK,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBtC,CAAC,IAAI,EAAE,CAAC;AAET,sDAAsD;AACtD,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;CAgBtC,CAAC,IAAI,EAAE,CAAC;AAET,sCAAsC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;CAoBlC,CAAC,IAAI,EAAE,CAAC;AAET,0CAA0C;AAC1C,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;CActC,CAAC,IAAI,EAAE,CAAC;AAET,wCAAwC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;CAoBpC,CAAC,IAAI,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { BookingConflictError, SerializationRetryExhaustedError, UnauthorizedError, ForbiddenError, } from "@thebookingkit/core";
|
|
2
|
+
export { withSerializableRetry, type SerializableRetryOptions, } from "./serialization-retry.js";
|
|
3
|
+
export { withAuth, assertProviderOwnership, assertCustomerAccess, type AuthUser, type AuthSession, type AuthAdapter, type AuthenticatedRequest, type WithAuthOptions, } from "./auth.js";
|
|
4
|
+
export type { EmailAdapter, SendEmailOptions, EmailResult, EmailDeliveryStatus, EmailAttachment, CalendarAdapter, CalendarEventOptions, CalendarEventResult, CalendarConflict, JobAdapter, StorageAdapter, SmsAdapter, SendSmsOptions, SmsResult, PaymentAdapter, CreatePaymentIntentOptions, CreatePaymentIntentResult, CreateSetupIntentOptions, CreateSetupIntentResult, CaptureResult, RefundResult, } from "./adapters/index.js";
|
|
5
|
+
export { generateICSAttachment, JOB_NAMES } from "./adapters/index.js";
|
|
6
|
+
export { generateBookingToken, verifyBookingToken, } from "./booking-tokens.js";
|
|
7
|
+
export { sendConfirmationEmail, sendReminderEmail, sendCancellationEmail, sendRescheduleEmail, scheduleAutoReject, syncBookingToCalendar, deleteBookingFromCalendar, formatDateTimeForEmail, formatDurationForEmail, type NotificationBookingData, type ConfirmationEmailPayload, type ReminderEmailPayload, type CancellationEmailPayload, type RescheduleEmailPayload, type CalendarSyncPayload, type CalendarDeletePayload, type AutoRejectPendingPayload, } from "./notification-jobs.js";
|
|
8
|
+
export { interpolateTemplate, CONFIRMATION_EMAIL_HTML, CONFIRMATION_EMAIL_TEXT, REMINDER_EMAIL_HTML, CANCELLATION_EMAIL_HTML, RESCHEDULE_EMAIL_HTML, type EmailTemplateVars, } from "./email-templates.js";
|
|
9
|
+
export { resolveTemplateVariables, evaluateConditions, validateWorkflow, matchWorkflows, DEFAULT_TEMPLATES, TEMPLATE_VARIABLES, WorkflowValidationError, type WorkflowTrigger, type WorkflowActionType, type ConditionOperator, type WorkflowCondition, type EmailActionConfig, type SmsActionConfig, type WebhookActionConfig, type StatusUpdateActionConfig, type CalendarEventActionConfig, type WorkflowAction, type WorkflowDefinition, type WorkflowContext, type WorkflowLogEntry, } from "./workflows.js";
|
|
10
|
+
export { signWebhookPayload, verifyWebhookSignature, createWebhookEnvelope, resolvePayloadTemplate, matchWebhookSubscriptions, getRetryDelay, isSuccessResponse, validateWebhookSubscription, WebhookValidationError, DEFAULT_RETRY_CONFIG, WEBHOOK_TRIGGERS, SIGNATURE_HEADER, TIMESTAMP_HEADER, DEFAULT_TOLERANCE_SECONDS, type WebhookTrigger, type WebhookAttendee, type WebhookPayload, type WebhookEnvelope, type WebhookSubscription, type WebhookDeliveryResult, type WebhookRetryConfig, type WebhookVerificationResult, } from "./webhooks.js";
|
|
11
|
+
export { createErrorResponse, createSuccessResponse, createPaginatedResponse, generateApiKey, hashApiKey, verifyApiKey, hasScope, isKeyExpired, checkRateLimit, encodeCursor, decodeCursor, validateSlotQueryParams, parseSortParam, API_ERROR_CODES, type ApiError, type ApiErrorResponse, type ApiSuccessResponse, type ApiMeta, type PaginatedResponse, type ApiErrorCode, type ApiKeyRecord, type ApiKeyScope, type GeneratedApiKey, type RateLimitState, type RateLimitResult, type ValidationDetail, type ValidationResult, } from "./api.js";
|
|
12
|
+
export { resolveEffectiveSettings, getRolePermissions, roleHasPermission, assertOrgPermission, assertTenantScope, buildOrgBookingUrl, parseOrgBookingPath, TenantAuthorizationError, GLOBAL_DEFAULTS, type OrgRole, type OrgMember, type OrgBranding, type OrgSettings, type ProviderSettings, type EventTypeSettings, type GlobalDefaults, type ResolvedSettings, type OrgPermission, } from "./multi-tenancy.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Re-export core errors used by server modules
|
|
2
|
+
export { BookingConflictError, SerializationRetryExhaustedError, UnauthorizedError, ForbiddenError, } from "@thebookingkit/core";
|
|
3
|
+
// Serialization retry utility
|
|
4
|
+
export { withSerializableRetry, } from "./serialization-retry.js";
|
|
5
|
+
// Auth middleware & adapters
|
|
6
|
+
export { withAuth, assertProviderOwnership, assertCustomerAccess, } from "./auth.js";
|
|
7
|
+
export { generateICSAttachment, JOB_NAMES } from "./adapters/index.js";
|
|
8
|
+
// Booking Tokens
|
|
9
|
+
export { generateBookingToken, verifyBookingToken, } from "./booking-tokens.js";
|
|
10
|
+
// Notification Jobs
|
|
11
|
+
export { sendConfirmationEmail, sendReminderEmail, sendCancellationEmail, sendRescheduleEmail, scheduleAutoReject, syncBookingToCalendar, deleteBookingFromCalendar, formatDateTimeForEmail, formatDurationForEmail, } from "./notification-jobs.js";
|
|
12
|
+
// Email Templates
|
|
13
|
+
export { interpolateTemplate, CONFIRMATION_EMAIL_HTML, CONFIRMATION_EMAIL_TEXT, REMINDER_EMAIL_HTML, CANCELLATION_EMAIL_HTML, RESCHEDULE_EMAIL_HTML, } from "./email-templates.js";
|
|
14
|
+
// Workflows
|
|
15
|
+
export { resolveTemplateVariables, evaluateConditions, validateWorkflow, matchWorkflows, DEFAULT_TEMPLATES, TEMPLATE_VARIABLES, WorkflowValidationError, } from "./workflows.js";
|
|
16
|
+
// Webhooks
|
|
17
|
+
export { signWebhookPayload, verifyWebhookSignature, createWebhookEnvelope, resolvePayloadTemplate, matchWebhookSubscriptions, getRetryDelay, isSuccessResponse, validateWebhookSubscription, WebhookValidationError, DEFAULT_RETRY_CONFIG, WEBHOOK_TRIGGERS, SIGNATURE_HEADER, TIMESTAMP_HEADER, DEFAULT_TOLERANCE_SECONDS, } from "./webhooks.js";
|
|
18
|
+
// REST API Utilities
|
|
19
|
+
export { createErrorResponse, createSuccessResponse, createPaginatedResponse, generateApiKey, hashApiKey, verifyApiKey, hasScope, isKeyExpired, checkRateLimit, encodeCursor, decodeCursor, validateSlotQueryParams, parseSortParam, API_ERROR_CODES, } from "./api.js";
|
|
20
|
+
// Multi-Tenancy
|
|
21
|
+
export { resolveEffectiveSettings, getRolePermissions, roleHasPermission, assertOrgPermission, assertTenantScope, buildOrgBookingUrl, parseOrgBookingPath, TenantAuthorizationError, GLOBAL_DEFAULTS, } from "./multi-tenancy.js";
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,EACL,oBAAoB,EACpB,gCAAgC,EAChC,iBAAiB,EACjB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,8BAA8B;AAC9B,OAAO,EACL,qBAAqB,GAEtB,MAAM,0BAA0B,CAAC;AAElC,6BAA6B;AAC7B,OAAO,EACL,QAAQ,EACR,uBAAuB,EACvB,oBAAoB,GAMrB,MAAM,WAAW,CAAC;AA0BnB,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEvE,iBAAiB;AACjB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAE7B,oBAAoB;AACpB,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GASvB,MAAM,wBAAwB,CAAC;AAEhC,kBAAkB;AAClB,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,GAEtB,MAAM,sBAAsB,CAAC;AAE9B,YAAY;AACZ,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,GAcxB,MAAM,gBAAgB,CAAC;AAExB,WAAW;AACX,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,aAAa,EACb,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,GAS1B,MAAM,eAAe,CAAC;AAEvB,qBAAqB;AACrB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,EACvB,cAAc,EACd,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,uBAAuB,EACvB,cAAc,EACd,eAAe,GAchB,MAAM,UAAU,CAAC;AAElB,gBAAgB;AAChB,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,GAUhB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-tenancy utilities for organization-scoped deployments.
|
|
3
|
+
*
|
|
4
|
+
* Provides organization settings resolution, cascading defaults,
|
|
5
|
+
* role-based access control, and tenant authorization helpers.
|
|
6
|
+
*/
|
|
7
|
+
/** Organization member role */
|
|
8
|
+
export type OrgRole = "owner" | "admin" | "member";
|
|
9
|
+
/** Organization member */
|
|
10
|
+
export interface OrgMember {
|
|
11
|
+
userId: string;
|
|
12
|
+
organizationId: string;
|
|
13
|
+
role: OrgRole;
|
|
14
|
+
}
|
|
15
|
+
/** Organization branding */
|
|
16
|
+
export interface OrgBranding {
|
|
17
|
+
logoUrl?: string;
|
|
18
|
+
primaryColor?: string;
|
|
19
|
+
accentColor?: string;
|
|
20
|
+
fontFamily?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Organization-level settings */
|
|
23
|
+
export interface OrgSettings {
|
|
24
|
+
defaultTimezone?: string;
|
|
25
|
+
defaultCurrency?: string;
|
|
26
|
+
branding?: OrgBranding;
|
|
27
|
+
defaultBufferMinutes?: number;
|
|
28
|
+
defaultBookingLimits?: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
/** Provider-level settings that can override org defaults */
|
|
31
|
+
export interface ProviderSettings {
|
|
32
|
+
timezone?: string;
|
|
33
|
+
currency?: string;
|
|
34
|
+
branding?: Partial<OrgBranding>;
|
|
35
|
+
bufferMinutes?: number;
|
|
36
|
+
bookingLimits?: Record<string, unknown>;
|
|
37
|
+
}
|
|
38
|
+
/** Event type settings that can override provider defaults */
|
|
39
|
+
export interface EventTypeSettings {
|
|
40
|
+
timezone?: string;
|
|
41
|
+
currency?: string;
|
|
42
|
+
bufferBefore?: number;
|
|
43
|
+
bufferAfter?: number;
|
|
44
|
+
bookingLimits?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
/** Global SlotKit defaults */
|
|
47
|
+
export interface GlobalDefaults {
|
|
48
|
+
timezone: string;
|
|
49
|
+
currency: string;
|
|
50
|
+
bufferMinutes: number;
|
|
51
|
+
}
|
|
52
|
+
/** Resolved effective settings after cascading resolution */
|
|
53
|
+
export interface ResolvedSettings {
|
|
54
|
+
timezone: string;
|
|
55
|
+
currency: string;
|
|
56
|
+
bufferMinutes: number;
|
|
57
|
+
branding: OrgBranding;
|
|
58
|
+
bookingLimits: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
/** Permissions available in the system */
|
|
61
|
+
export type OrgPermission = "manage:members" | "manage:teams" | "manage:event-types" | "view:all-bookings" | "view:own-bookings" | "manage:own-availability" | "view:analytics" | "manage:organization";
|
|
62
|
+
/** Error thrown for multi-tenancy authorization violations */
|
|
63
|
+
export declare class TenantAuthorizationError extends Error {
|
|
64
|
+
constructor(message: string);
|
|
65
|
+
}
|
|
66
|
+
/** System-wide defaults used as the base for cascading resolution */
|
|
67
|
+
export declare const GLOBAL_DEFAULTS: GlobalDefaults;
|
|
68
|
+
/**
|
|
69
|
+
* Resolve effective settings via the cascade:
|
|
70
|
+
* `event_type > provider > organization > global defaults`
|
|
71
|
+
*
|
|
72
|
+
* @param orgSettings - Organization-level settings
|
|
73
|
+
* @param providerSettings - Provider-level settings (overrides org)
|
|
74
|
+
* @param eventTypeSettings - Event type settings (overrides provider)
|
|
75
|
+
* @returns Fully resolved effective settings
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveEffectiveSettings(orgSettings?: OrgSettings | null, providerSettings?: ProviderSettings | null, eventTypeSettings?: EventTypeSettings | null): ResolvedSettings;
|
|
78
|
+
/**
|
|
79
|
+
* Get all permissions granted to a role.
|
|
80
|
+
*
|
|
81
|
+
* @param role - The organization role
|
|
82
|
+
* @returns Array of permissions
|
|
83
|
+
*/
|
|
84
|
+
export declare function getRolePermissions(role: OrgRole): OrgPermission[];
|
|
85
|
+
/**
|
|
86
|
+
* Check if a role has a specific permission.
|
|
87
|
+
*
|
|
88
|
+
* @param role - The organization role
|
|
89
|
+
* @param permission - The permission to check
|
|
90
|
+
* @returns Whether the role has the permission
|
|
91
|
+
*/
|
|
92
|
+
export declare function roleHasPermission(role: OrgRole, permission: OrgPermission): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Assert that an org member has a required permission.
|
|
95
|
+
*
|
|
96
|
+
* @param member - The org member
|
|
97
|
+
* @param permission - The required permission
|
|
98
|
+
* @throws {TenantAuthorizationError} If the member lacks the permission
|
|
99
|
+
*/
|
|
100
|
+
export declare function assertOrgPermission(member: OrgMember, permission: OrgPermission): void;
|
|
101
|
+
/**
|
|
102
|
+
* Validate that a resource belongs to the expected organization.
|
|
103
|
+
*
|
|
104
|
+
* @param resourceOrgId - Organization ID on the resource
|
|
105
|
+
* @param expectedOrgId - The org ID from the authenticated context
|
|
106
|
+
* @throws {TenantAuthorizationError} If there is a tenant mismatch
|
|
107
|
+
*/
|
|
108
|
+
export declare function assertTenantScope(resourceOrgId: string | null | undefined, expectedOrgId: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Generate the public booking URL for an organization's provider/event type.
|
|
111
|
+
*
|
|
112
|
+
* @param orgSlug - Organization slug
|
|
113
|
+
* @param providerSlug - Provider slug or ID
|
|
114
|
+
* @param eventTypeSlug - Event type slug
|
|
115
|
+
* @param baseUrl - Base URL of the application
|
|
116
|
+
* @returns Full booking URL
|
|
117
|
+
*/
|
|
118
|
+
export declare function buildOrgBookingUrl(orgSlug: string, providerSlug: string, eventTypeSlug: string, baseUrl: string): string;
|
|
119
|
+
/**
|
|
120
|
+
* Parse an organization slug from a booking URL path.
|
|
121
|
+
*
|
|
122
|
+
* Expected format: `/{orgSlug}/{providerSlug}/{eventTypeSlug}`
|
|
123
|
+
*
|
|
124
|
+
* @param pathname - URL pathname
|
|
125
|
+
* @returns Parsed segments, or null if format is invalid
|
|
126
|
+
*/
|
|
127
|
+
export declare function parseOrgBookingPath(pathname: string): {
|
|
128
|
+
orgSlug: string;
|
|
129
|
+
providerSlug: string;
|
|
130
|
+
eventTypeSlug: string;
|
|
131
|
+
} | null;
|
|
132
|
+
//# sourceMappingURL=multi-tenancy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-tenancy.d.ts","sourceRoot":"","sources":["../src/multi-tenancy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-tenancy utilities for organization-scoped deployments.
|
|
3
|
+
*
|
|
4
|
+
* Provides organization settings resolution, cascading defaults,
|
|
5
|
+
* role-based access control, and tenant authorization helpers.
|
|
6
|
+
*/
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Errors
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** Error thrown for multi-tenancy authorization violations */
|
|
11
|
+
export class TenantAuthorizationError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "TenantAuthorizationError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Global Defaults
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/** System-wide defaults used as the base for cascading resolution */
|
|
21
|
+
export const GLOBAL_DEFAULTS = {
|
|
22
|
+
timezone: "UTC",
|
|
23
|
+
currency: "USD",
|
|
24
|
+
bufferMinutes: 0,
|
|
25
|
+
};
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Settings Resolution
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Resolve effective settings via the cascade:
|
|
31
|
+
* `event_type > provider > organization > global defaults`
|
|
32
|
+
*
|
|
33
|
+
* @param orgSettings - Organization-level settings
|
|
34
|
+
* @param providerSettings - Provider-level settings (overrides org)
|
|
35
|
+
* @param eventTypeSettings - Event type settings (overrides provider)
|
|
36
|
+
* @returns Fully resolved effective settings
|
|
37
|
+
*/
|
|
38
|
+
export function resolveEffectiveSettings(orgSettings, providerSettings, eventTypeSettings) {
|
|
39
|
+
// Start with global defaults
|
|
40
|
+
let timezone = GLOBAL_DEFAULTS.timezone;
|
|
41
|
+
let currency = GLOBAL_DEFAULTS.currency;
|
|
42
|
+
let bufferMinutes = GLOBAL_DEFAULTS.bufferMinutes;
|
|
43
|
+
let branding = {};
|
|
44
|
+
let bookingLimits = {};
|
|
45
|
+
// Apply org settings
|
|
46
|
+
if (orgSettings) {
|
|
47
|
+
if (orgSettings.defaultTimezone)
|
|
48
|
+
timezone = orgSettings.defaultTimezone;
|
|
49
|
+
if (orgSettings.defaultCurrency)
|
|
50
|
+
currency = orgSettings.defaultCurrency;
|
|
51
|
+
if (orgSettings.defaultBufferMinutes !== undefined)
|
|
52
|
+
bufferMinutes = orgSettings.defaultBufferMinutes;
|
|
53
|
+
if (orgSettings.branding)
|
|
54
|
+
branding = { ...branding, ...orgSettings.branding };
|
|
55
|
+
if (orgSettings.defaultBookingLimits)
|
|
56
|
+
bookingLimits = { ...orgSettings.defaultBookingLimits };
|
|
57
|
+
}
|
|
58
|
+
// Apply provider settings (override org)
|
|
59
|
+
if (providerSettings) {
|
|
60
|
+
if (providerSettings.timezone)
|
|
61
|
+
timezone = providerSettings.timezone;
|
|
62
|
+
if (providerSettings.currency)
|
|
63
|
+
currency = providerSettings.currency;
|
|
64
|
+
if (providerSettings.bufferMinutes !== undefined)
|
|
65
|
+
bufferMinutes = providerSettings.bufferMinutes;
|
|
66
|
+
if (providerSettings.branding)
|
|
67
|
+
branding = { ...branding, ...providerSettings.branding };
|
|
68
|
+
if (providerSettings.bookingLimits)
|
|
69
|
+
bookingLimits = { ...bookingLimits, ...providerSettings.bookingLimits };
|
|
70
|
+
}
|
|
71
|
+
// Apply event type settings (override provider)
|
|
72
|
+
if (eventTypeSettings) {
|
|
73
|
+
if (eventTypeSettings.timezone)
|
|
74
|
+
timezone = eventTypeSettings.timezone;
|
|
75
|
+
if (eventTypeSettings.currency)
|
|
76
|
+
currency = eventTypeSettings.currency;
|
|
77
|
+
if (eventTypeSettings.bufferBefore !== undefined)
|
|
78
|
+
bufferMinutes = eventTypeSettings.bufferBefore;
|
|
79
|
+
if (eventTypeSettings.bookingLimits)
|
|
80
|
+
bookingLimits = { ...bookingLimits, ...eventTypeSettings.bookingLimits };
|
|
81
|
+
}
|
|
82
|
+
return { timezone, currency, bufferMinutes, branding, bookingLimits };
|
|
83
|
+
}
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// Role-Based Access Control
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
/** Permissions granted to each role */
|
|
88
|
+
const ROLE_PERMISSIONS = {
|
|
89
|
+
owner: [
|
|
90
|
+
"manage:members",
|
|
91
|
+
"manage:teams",
|
|
92
|
+
"manage:event-types",
|
|
93
|
+
"view:all-bookings",
|
|
94
|
+
"view:own-bookings",
|
|
95
|
+
"manage:own-availability",
|
|
96
|
+
"view:analytics",
|
|
97
|
+
"manage:organization",
|
|
98
|
+
],
|
|
99
|
+
admin: [
|
|
100
|
+
"manage:teams",
|
|
101
|
+
"manage:event-types",
|
|
102
|
+
"view:all-bookings",
|
|
103
|
+
"view:own-bookings",
|
|
104
|
+
"manage:own-availability",
|
|
105
|
+
"view:analytics",
|
|
106
|
+
],
|
|
107
|
+
member: [
|
|
108
|
+
"view:own-bookings",
|
|
109
|
+
"manage:own-availability",
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Get all permissions granted to a role.
|
|
114
|
+
*
|
|
115
|
+
* @param role - The organization role
|
|
116
|
+
* @returns Array of permissions
|
|
117
|
+
*/
|
|
118
|
+
export function getRolePermissions(role) {
|
|
119
|
+
return ROLE_PERMISSIONS[role] ?? [];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check if a role has a specific permission.
|
|
123
|
+
*
|
|
124
|
+
* @param role - The organization role
|
|
125
|
+
* @param permission - The permission to check
|
|
126
|
+
* @returns Whether the role has the permission
|
|
127
|
+
*/
|
|
128
|
+
export function roleHasPermission(role, permission) {
|
|
129
|
+
return getRolePermissions(role).includes(permission);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Assert that an org member has a required permission.
|
|
133
|
+
*
|
|
134
|
+
* @param member - The org member
|
|
135
|
+
* @param permission - The required permission
|
|
136
|
+
* @throws {TenantAuthorizationError} If the member lacks the permission
|
|
137
|
+
*/
|
|
138
|
+
export function assertOrgPermission(member, permission) {
|
|
139
|
+
if (!roleHasPermission(member.role, permission)) {
|
|
140
|
+
throw new TenantAuthorizationError(`Role "${member.role}" does not have permission: "${permission}"`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// ---------------------------------------------------------------------------
|
|
144
|
+
// Tenant Scoping
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
/**
|
|
147
|
+
* Validate that a resource belongs to the expected organization.
|
|
148
|
+
*
|
|
149
|
+
* @param resourceOrgId - Organization ID on the resource
|
|
150
|
+
* @param expectedOrgId - The org ID from the authenticated context
|
|
151
|
+
* @throws {TenantAuthorizationError} If there is a tenant mismatch
|
|
152
|
+
*/
|
|
153
|
+
export function assertTenantScope(resourceOrgId, expectedOrgId) {
|
|
154
|
+
if (resourceOrgId && resourceOrgId !== expectedOrgId) {
|
|
155
|
+
throw new TenantAuthorizationError("Resource does not belong to the current organization");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Generate the public booking URL for an organization's provider/event type.
|
|
160
|
+
*
|
|
161
|
+
* @param orgSlug - Organization slug
|
|
162
|
+
* @param providerSlug - Provider slug or ID
|
|
163
|
+
* @param eventTypeSlug - Event type slug
|
|
164
|
+
* @param baseUrl - Base URL of the application
|
|
165
|
+
* @returns Full booking URL
|
|
166
|
+
*/
|
|
167
|
+
export function buildOrgBookingUrl(orgSlug, providerSlug, eventTypeSlug, baseUrl) {
|
|
168
|
+
return `${baseUrl}/${orgSlug}/${providerSlug}/${eventTypeSlug}`;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Parse an organization slug from a booking URL path.
|
|
172
|
+
*
|
|
173
|
+
* Expected format: `/{orgSlug}/{providerSlug}/{eventTypeSlug}`
|
|
174
|
+
*
|
|
175
|
+
* @param pathname - URL pathname
|
|
176
|
+
* @returns Parsed segments, or null if format is invalid
|
|
177
|
+
*/
|
|
178
|
+
export function parseOrgBookingPath(pathname) {
|
|
179
|
+
const match = pathname.match(/^\/([^/]+)\/([^/]+)\/([^/]+)$/);
|
|
180
|
+
if (!match)
|
|
181
|
+
return null;
|
|
182
|
+
return {
|
|
183
|
+
orgSlug: match[1],
|
|
184
|
+
providerSlug: match[2],
|
|
185
|
+
eventTypeSlug: match[3],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
//# sourceMappingURL=multi-tenancy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-tenancy.js","sourceRoot":"","sources":["../src/multi-tenancy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notification job payload types and helper functions for E-06.
|
|
3
|
+
*
|
|
4
|
+
* These types are used by background job functions (Inngest, Trigger.dev, BullMQ, etc.)
|
|
5
|
+
* when sending booking notification emails and syncing calendar events.
|
|
6
|
+
*
|
|
7
|
+
* The actual job implementation lives in the consumer app (or a provided Inngest
|
|
8
|
+
* functions file), but the payload shapes and builder functions are framework-agnostic.
|
|
9
|
+
*/
|
|
10
|
+
import type { EmailAdapter, CalendarAdapter, JobAdapter } from "./adapters/index.js";
|
|
11
|
+
import { JOB_NAMES } from "./adapters/job-adapter.js";
|
|
12
|
+
/** Common booking data included in every notification payload */
|
|
13
|
+
export interface NotificationBookingData {
|
|
14
|
+
bookingId: string;
|
|
15
|
+
eventTitle: string;
|
|
16
|
+
providerName: string;
|
|
17
|
+
providerEmail: string;
|
|
18
|
+
customerName: string;
|
|
19
|
+
customerEmail: string;
|
|
20
|
+
/** ISO datetime strings */
|
|
21
|
+
startsAt: string;
|
|
22
|
+
endsAt: string;
|
|
23
|
+
timezone: string;
|
|
24
|
+
location?: string;
|
|
25
|
+
/** Signed management URL for the customer */
|
|
26
|
+
managementUrl?: string;
|
|
27
|
+
/** Unsubscribe URL */
|
|
28
|
+
unsubscribeUrl?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Payload for SEND_CONFIRMATION_EMAIL job */
|
|
31
|
+
export interface ConfirmationEmailPayload extends NotificationBookingData {
|
|
32
|
+
/** Whether to also send a notification to the provider */
|
|
33
|
+
notifyProvider?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Payload for SEND_REMINDER_EMAIL job */
|
|
36
|
+
export interface ReminderEmailPayload extends NotificationBookingData {
|
|
37
|
+
/** How many hours before the appointment this reminder is for (e.g., 24 or 1) */
|
|
38
|
+
reminderHours: number;
|
|
39
|
+
}
|
|
40
|
+
/** Payload for SEND_CANCELLATION_EMAIL job */
|
|
41
|
+
export interface CancellationEmailPayload extends NotificationBookingData {
|
|
42
|
+
/** Who initiated the cancellation */
|
|
43
|
+
cancelledBy: "customer" | "provider" | "system";
|
|
44
|
+
/** Optional reason for cancellation */
|
|
45
|
+
reason?: string;
|
|
46
|
+
}
|
|
47
|
+
/** Payload for SEND_RESCHEDULE_EMAIL job */
|
|
48
|
+
export interface RescheduleEmailPayload extends NotificationBookingData {
|
|
49
|
+
/** Original booking datetime strings */
|
|
50
|
+
oldStartsAt: string;
|
|
51
|
+
oldEndsAt: string;
|
|
52
|
+
}
|
|
53
|
+
/** Payload for SYNC_CALENDAR_EVENT job */
|
|
54
|
+
export interface CalendarSyncPayload {
|
|
55
|
+
bookingId: string;
|
|
56
|
+
providerId: string;
|
|
57
|
+
/** External calendar event ID (for updates/deletes) */
|
|
58
|
+
externalEventId?: string;
|
|
59
|
+
eventTitle: string;
|
|
60
|
+
customerName: string;
|
|
61
|
+
customerEmail: string;
|
|
62
|
+
startsAt: string;
|
|
63
|
+
endsAt: string;
|
|
64
|
+
timezone: string;
|
|
65
|
+
location?: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
}
|
|
68
|
+
/** Payload for DELETE_CALENDAR_EVENT job */
|
|
69
|
+
export interface CalendarDeletePayload {
|
|
70
|
+
bookingId: string;
|
|
71
|
+
providerId: string;
|
|
72
|
+
externalEventId: string;
|
|
73
|
+
}
|
|
74
|
+
/** Payload for AUTO_REJECT_PENDING job */
|
|
75
|
+
export interface AutoRejectPendingPayload {
|
|
76
|
+
bookingId: string;
|
|
77
|
+
/** Actor to record in the booking_event */
|
|
78
|
+
actor?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format a UTC datetime string in a given timezone for email templates.
|
|
82
|
+
*
|
|
83
|
+
* @returns `{ date, time }` formatted for the email template variables
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatDateTimeForEmail(isoString: string, timezone: string): {
|
|
86
|
+
date: string;
|
|
87
|
+
time: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Calculate duration in human-readable form from start/end ISO strings.
|
|
91
|
+
*/
|
|
92
|
+
export declare function formatDurationForEmail(startsAt: string, endsAt: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Send a booking confirmation email to the customer (and optionally the provider).
|
|
95
|
+
*
|
|
96
|
+
* Call this from your Inngest/Trigger.dev/BullMQ job handler.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* // In your Inngest function:
|
|
101
|
+
* export const sendConfirmation = inngest.createFunction(
|
|
102
|
+
* { id: "send-confirmation-email" },
|
|
103
|
+
* { event: JOB_NAMES.SEND_CONFIRMATION_EMAIL },
|
|
104
|
+
* async ({ event }) => {
|
|
105
|
+
* await sendConfirmationEmail(event.data, emailAdapter);
|
|
106
|
+
* },
|
|
107
|
+
* );
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function sendConfirmationEmail(payload: ConfirmationEmailPayload, emailAdapter: EmailAdapter): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Send a reminder email to the customer before their appointment.
|
|
113
|
+
*/
|
|
114
|
+
export declare function sendReminderEmail(payload: ReminderEmailPayload, emailAdapter: EmailAdapter): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Send cancellation notification emails to customer and provider.
|
|
117
|
+
*/
|
|
118
|
+
export declare function sendCancellationEmail(payload: CancellationEmailPayload, emailAdapter: EmailAdapter): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Send reschedule notification emails to customer and provider.
|
|
121
|
+
*/
|
|
122
|
+
export declare function sendRescheduleEmail(payload: RescheduleEmailPayload, emailAdapter: EmailAdapter): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Schedule the auto-rejection of a pending booking using the job adapter.
|
|
125
|
+
*
|
|
126
|
+
* Call this immediately after creating a booking that requires confirmation.
|
|
127
|
+
*
|
|
128
|
+
* @param bookingId - ID of the pending booking
|
|
129
|
+
* @param deadline - Date at which to auto-reject (from `getAutoRejectDeadline`)
|
|
130
|
+
* @param jobs - Your `JobAdapter` instance
|
|
131
|
+
* @returns The scheduled job ID (store it if you need to cancel on manual confirm/reject)
|
|
132
|
+
*/
|
|
133
|
+
export declare function scheduleAutoReject(bookingId: string, deadline: Date, jobs: JobAdapter): Promise<string>;
|
|
134
|
+
/**
|
|
135
|
+
* Sync a confirmed booking to the provider's connected calendar.
|
|
136
|
+
*/
|
|
137
|
+
export declare function syncBookingToCalendar(payload: CalendarSyncPayload, calendarAdapter: CalendarAdapter): Promise<string | undefined>;
|
|
138
|
+
/**
|
|
139
|
+
* Delete a calendar event when a booking is cancelled.
|
|
140
|
+
*/
|
|
141
|
+
export declare function deleteBookingFromCalendar(externalEventId: string, calendarAdapter: CalendarAdapter): Promise<void>;
|
|
142
|
+
export { JOB_NAMES };
|
|
143
|
+
//# sourceMappingURL=notification-jobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification-jobs.d.ts","sourceRoot":"","sources":["../src/notification-jobs.ts"],"names":[],"mappings":"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"}
|