@voyant-travel/distribution 0.109.8

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 (168) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +42 -0
  3. package/dist/booking-extension.d.ts +168 -0
  4. package/dist/booking-extension.d.ts.map +1 -0
  5. package/dist/booking-extension.js +102 -0
  6. package/dist/channel-push/admin-routes.d.ts +31 -0
  7. package/dist/channel-push/admin-routes.d.ts.map +1 -0
  8. package/dist/channel-push/admin-routes.js +165 -0
  9. package/dist/channel-push/availability-push.d.ts +76 -0
  10. package/dist/channel-push/availability-push.d.ts.map +1 -0
  11. package/dist/channel-push/availability-push.js +236 -0
  12. package/dist/channel-push/booking-push-helpers.d.ts +36 -0
  13. package/dist/channel-push/booking-push-helpers.d.ts.map +1 -0
  14. package/dist/channel-push/booking-push-helpers.js +169 -0
  15. package/dist/channel-push/booking-push.d.ts +108 -0
  16. package/dist/channel-push/booking-push.d.ts.map +1 -0
  17. package/dist/channel-push/booking-push.js +335 -0
  18. package/dist/channel-push/boundary-sql.d.ts +23 -0
  19. package/dist/channel-push/boundary-sql.d.ts.map +1 -0
  20. package/dist/channel-push/boundary-sql.js +75 -0
  21. package/dist/channel-push/content-push.d.ts +60 -0
  22. package/dist/channel-push/content-push.d.ts.map +1 -0
  23. package/dist/channel-push/content-push.js +252 -0
  24. package/dist/channel-push/index.d.ts +15 -0
  25. package/dist/channel-push/index.d.ts.map +1 -0
  26. package/dist/channel-push/index.js +18 -0
  27. package/dist/channel-push/plugin.d.ts +18 -0
  28. package/dist/channel-push/plugin.d.ts.map +1 -0
  29. package/dist/channel-push/plugin.js +21 -0
  30. package/dist/channel-push/reconciler.d.ts +85 -0
  31. package/dist/channel-push/reconciler.d.ts.map +1 -0
  32. package/dist/channel-push/reconciler.js +179 -0
  33. package/dist/channel-push/subscriber.d.ts +40 -0
  34. package/dist/channel-push/subscriber.d.ts.map +1 -0
  35. package/dist/channel-push/subscriber.js +199 -0
  36. package/dist/channel-push/types.d.ts +43 -0
  37. package/dist/channel-push/types.d.ts.map +1 -0
  38. package/dist/channel-push/types.js +32 -0
  39. package/dist/channel-push/workflows.d.ts +56 -0
  40. package/dist/channel-push/workflows.d.ts.map +1 -0
  41. package/dist/channel-push/workflows.js +100 -0
  42. package/dist/external-refs/index.d.ts +11 -0
  43. package/dist/external-refs/index.d.ts.map +1 -0
  44. package/dist/external-refs/index.js +12 -0
  45. package/dist/external-refs/routes.d.ts +253 -0
  46. package/dist/external-refs/routes.d.ts.map +1 -0
  47. package/dist/external-refs/routes.js +52 -0
  48. package/dist/external-refs/schema.d.ts +251 -0
  49. package/dist/external-refs/schema.d.ts.map +1 -0
  50. package/dist/external-refs/schema.js +32 -0
  51. package/dist/external-refs/service.d.ts +82 -0
  52. package/dist/external-refs/service.d.ts.map +1 -0
  53. package/dist/external-refs/service.js +112 -0
  54. package/dist/external-refs/validation.d.ts +91 -0
  55. package/dist/external-refs/validation.d.ts.map +1 -0
  56. package/dist/external-refs/validation.js +40 -0
  57. package/dist/index.d.ts +21 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +20 -0
  60. package/dist/interface-types.d.ts +128 -0
  61. package/dist/interface-types.d.ts.map +1 -0
  62. package/dist/interface-types.js +1 -0
  63. package/dist/interface.d.ts +10 -0
  64. package/dist/interface.d.ts.map +1 -0
  65. package/dist/interface.js +286 -0
  66. package/dist/rate-limit.d.ts +69 -0
  67. package/dist/rate-limit.d.ts.map +1 -0
  68. package/dist/rate-limit.js +135 -0
  69. package/dist/routes/batch.d.ts +200 -0
  70. package/dist/routes/batch.d.ts.map +1 -0
  71. package/dist/routes/batch.js +52 -0
  72. package/dist/routes/env.d.ts +8 -0
  73. package/dist/routes/env.d.ts.map +1 -0
  74. package/dist/routes/env.js +1 -0
  75. package/dist/routes/inventory.d.ts +604 -0
  76. package/dist/routes/inventory.d.ts.map +1 -0
  77. package/dist/routes/inventory.js +138 -0
  78. package/dist/routes/settlements.d.ts +1649 -0
  79. package/dist/routes/settlements.d.ts.map +1 -0
  80. package/dist/routes/settlements.js +265 -0
  81. package/dist/routes.d.ts +3909 -0
  82. package/dist/routes.d.ts.map +1 -0
  83. package/dist/routes.js +323 -0
  84. package/dist/schema-automation.d.ts +680 -0
  85. package/dist/schema-automation.d.ts.map +1 -0
  86. package/dist/schema-automation.js +76 -0
  87. package/dist/schema-core.d.ts +1674 -0
  88. package/dist/schema-core.d.ts.map +1 -0
  89. package/dist/schema-core.js +227 -0
  90. package/dist/schema-finance.d.ts +1372 -0
  91. package/dist/schema-finance.d.ts.map +1 -0
  92. package/dist/schema-finance.js +153 -0
  93. package/dist/schema-inventory.d.ts +855 -0
  94. package/dist/schema-inventory.d.ts.map +1 -0
  95. package/dist/schema-inventory.js +102 -0
  96. package/dist/schema-push-intents.d.ts +387 -0
  97. package/dist/schema-push-intents.d.ts.map +1 -0
  98. package/dist/schema-push-intents.js +77 -0
  99. package/dist/schema-relations.d.ts +95 -0
  100. package/dist/schema-relations.d.ts.map +1 -0
  101. package/dist/schema-relations.js +196 -0
  102. package/dist/schema-shared.d.ts +24 -0
  103. package/dist/schema-shared.d.ts.map +1 -0
  104. package/dist/schema-shared.js +123 -0
  105. package/dist/schema.d.ts +9 -0
  106. package/dist/schema.d.ts.map +1 -0
  107. package/dist/schema.js +8 -0
  108. package/dist/service/channels.d.ts +167 -0
  109. package/dist/service/channels.d.ts.map +1 -0
  110. package/dist/service/channels.js +305 -0
  111. package/dist/service/commercial.d.ts +385 -0
  112. package/dist/service/commercial.d.ts.map +1 -0
  113. package/dist/service/commercial.js +248 -0
  114. package/dist/service/helpers.d.ts +10 -0
  115. package/dist/service/helpers.d.ts.map +1 -0
  116. package/dist/service/helpers.js +7 -0
  117. package/dist/service/inventory.d.ts +193 -0
  118. package/dist/service/inventory.d.ts.map +1 -0
  119. package/dist/service/inventory.js +154 -0
  120. package/dist/service/settlement-policies.d.ts +325 -0
  121. package/dist/service/settlement-policies.d.ts.map +1 -0
  122. package/dist/service/settlement-policies.js +272 -0
  123. package/dist/service/settlements.d.ts +357 -0
  124. package/dist/service/settlements.d.ts.map +1 -0
  125. package/dist/service/settlements.js +319 -0
  126. package/dist/service/types.d.ts +60 -0
  127. package/dist/service/types.d.ts.map +1 -0
  128. package/dist/service/types.js +1 -0
  129. package/dist/service.d.ts +1418 -0
  130. package/dist/service.d.ts.map +1 -0
  131. package/dist/service.js +17 -0
  132. package/dist/suppliers/index.d.ts +15 -0
  133. package/dist/suppliers/index.d.ts.map +1 -0
  134. package/dist/suppliers/index.js +23 -0
  135. package/dist/suppliers/routes.d.ts +1202 -0
  136. package/dist/suppliers/routes.d.ts.map +1 -0
  137. package/dist/suppliers/routes.js +290 -0
  138. package/dist/suppliers/schema.d.ts +1272 -0
  139. package/dist/suppliers/schema.d.ts.map +1 -0
  140. package/dist/suppliers/schema.js +219 -0
  141. package/dist/suppliers/service-aggregates.d.ts +23 -0
  142. package/dist/suppliers/service-aggregates.d.ts.map +1 -0
  143. package/dist/suppliers/service-aggregates.js +51 -0
  144. package/dist/suppliers/service-core.d.ts +89 -0
  145. package/dist/suppliers/service-core.d.ts.map +1 -0
  146. package/dist/suppliers/service-core.js +164 -0
  147. package/dist/suppliers/service-identity.d.ts +162 -0
  148. package/dist/suppliers/service-identity.d.ts.map +1 -0
  149. package/dist/suppliers/service-identity.js +101 -0
  150. package/dist/suppliers/service-operations.d.ts +1500 -0
  151. package/dist/suppliers/service-operations.d.ts.map +1 -0
  152. package/dist/suppliers/service-operations.js +157 -0
  153. package/dist/suppliers/service-shared.d.ts +45 -0
  154. package/dist/suppliers/service-shared.d.ts.map +1 -0
  155. package/dist/suppliers/service-shared.js +294 -0
  156. package/dist/suppliers/service.d.ts +41 -0
  157. package/dist/suppliers/service.d.ts.map +1 -0
  158. package/dist/suppliers/service.js +40 -0
  159. package/dist/suppliers/validation.d.ts +2 -0
  160. package/dist/suppliers/validation.d.ts.map +1 -0
  161. package/dist/suppliers/validation.js +1 -0
  162. package/dist/validation.d.ts +1371 -0
  163. package/dist/validation.d.ts.map +1 -0
  164. package/dist/validation.js +445 -0
  165. package/dist/webhook-deliveries.d.ts +86 -0
  166. package/dist/webhook-deliveries.d.ts.map +1 -0
  167. package/dist/webhook-deliveries.js +296 -0
  168. package/package.json +71 -0
@@ -0,0 +1,305 @@
1
+ import { identityService } from "@voyant-travel/identity/service";
2
+ import { and, eq, inArray, sql } from "drizzle-orm";
3
+ import { channelContactProjections, channels } from "../schema.js";
4
+ const channelEntityType = "channel";
5
+ const channelBaseIdentitySource = "distribution.base";
6
+ const channelPrimaryNamedContactSource = "distribution.primary_contact";
7
+ function emptyChannelHydratedFields() {
8
+ return {
9
+ website: null,
10
+ contactName: null,
11
+ contactEmail: null,
12
+ };
13
+ }
14
+ function normalizeWebsite(value) {
15
+ return value.trim().toLowerCase();
16
+ }
17
+ function isManagedBySource(metadata, source) {
18
+ return metadata?.managedBy === source;
19
+ }
20
+ function toNullableTrimmed(value) {
21
+ const trimmed = value?.trim();
22
+ return trimmed ? trimmed : null;
23
+ }
24
+ function toCreateChannelBaseValues(data) {
25
+ return {
26
+ name: data.name,
27
+ description: data.description,
28
+ kind: data.kind,
29
+ status: data.status,
30
+ metadata: data.metadata,
31
+ };
32
+ }
33
+ function toUpdateChannelBaseValues(data) {
34
+ return {
35
+ name: data.name,
36
+ description: data.description,
37
+ kind: data.kind,
38
+ status: data.status,
39
+ metadata: data.metadata,
40
+ };
41
+ }
42
+ async function ensureChannelExists(db, channelId) {
43
+ const [row] = await db
44
+ .select({ id: channels.id })
45
+ .from(channels)
46
+ .where(eq(channels.id, channelId))
47
+ .limit(1);
48
+ return row ?? null;
49
+ }
50
+ async function syncChannelIdentity(db, channelId, data) {
51
+ const [existingContactPoints, existingNamedContacts] = await Promise.all([
52
+ identityService.listContactPointsForEntity(db, channelEntityType, channelId),
53
+ identityService.listNamedContactsForEntity(db, channelEntityType, channelId),
54
+ ]);
55
+ const managedWebsiteContact = existingContactPoints.find((point) => point.kind === "website" &&
56
+ isManagedBySource(point.metadata, channelBaseIdentitySource));
57
+ const managedPrimaryContact = existingNamedContacts.find((contact) => isManagedBySource(contact.metadata, channelPrimaryNamedContactSource));
58
+ const website = toNullableTrimmed(data.website);
59
+ if (!website) {
60
+ if (managedWebsiteContact) {
61
+ await identityService.deleteContactPoint(db, managedWebsiteContact.id);
62
+ }
63
+ }
64
+ else {
65
+ const websitePayload = {
66
+ entityType: channelEntityType,
67
+ entityId: channelId,
68
+ kind: "website",
69
+ label: "website",
70
+ value: website,
71
+ normalizedValue: normalizeWebsite(website),
72
+ isPrimary: true,
73
+ metadata: {
74
+ managedBy: channelBaseIdentitySource,
75
+ },
76
+ };
77
+ if (managedWebsiteContact) {
78
+ await identityService.updateContactPoint(db, managedWebsiteContact.id, websitePayload);
79
+ }
80
+ else {
81
+ await identityService.createContactPoint(db, websitePayload);
82
+ }
83
+ }
84
+ const contactName = toNullableTrimmed(data.contactName);
85
+ const contactEmail = toNullableTrimmed(data.contactEmail);
86
+ const hasPrimaryContact = Boolean(contactName || contactEmail);
87
+ if (!hasPrimaryContact) {
88
+ if (managedPrimaryContact) {
89
+ await identityService.deleteNamedContact(db, managedPrimaryContact.id);
90
+ }
91
+ await rebuildChannelContactProjection(db, channelId);
92
+ return;
93
+ }
94
+ const namedContactPayload = {
95
+ entityType: channelEntityType,
96
+ entityId: channelId,
97
+ role: "primary",
98
+ name: contactName ?? contactEmail ?? "Primary contact",
99
+ email: contactEmail,
100
+ isPrimary: true,
101
+ metadata: {
102
+ managedBy: channelPrimaryNamedContactSource,
103
+ },
104
+ };
105
+ if (managedPrimaryContact) {
106
+ await identityService.updateNamedContact(db, managedPrimaryContact.id, namedContactPayload);
107
+ }
108
+ else {
109
+ await identityService.createNamedContact(db, namedContactPayload);
110
+ }
111
+ await rebuildChannelContactProjection(db, channelId);
112
+ }
113
+ async function deleteChannelIdentity(db, channelId) {
114
+ const [contactPoints, namedContacts] = await Promise.all([
115
+ identityService.listContactPointsForEntity(db, channelEntityType, channelId),
116
+ identityService.listNamedContactsForEntity(db, channelEntityType, channelId),
117
+ ]);
118
+ await Promise.all([
119
+ ...contactPoints.map((point) => identityService.deleteContactPoint(db, point.id)),
120
+ ...namedContacts.map((contact) => identityService.deleteNamedContact(db, contact.id)),
121
+ ]);
122
+ await rebuildChannelContactProjection(db, channelId);
123
+ }
124
+ async function rebuildChannelContactProjection(db, channelId) {
125
+ const [contactPoints, namedContacts] = await Promise.all([
126
+ identityService.listContactPointsForEntity(db, channelEntityType, channelId),
127
+ identityService.listNamedContactsForEntity(db, channelEntityType, channelId),
128
+ ]);
129
+ const primaryWebsite = contactPoints.find((point) => point.kind === "website" && point.isPrimary) ??
130
+ contactPoints.find((point) => point.kind === "website") ??
131
+ null;
132
+ const primaryContact = namedContacts.find((contact) => contact.isPrimary) ?? namedContacts[0] ?? null;
133
+ await db
134
+ .delete(channelContactProjections)
135
+ .where(eq(channelContactProjections.channelId, channelId));
136
+ if (!primaryWebsite && !primaryContact) {
137
+ return;
138
+ }
139
+ await db.insert(channelContactProjections).values({
140
+ channelId,
141
+ websiteContactPointId: primaryWebsite?.id ?? null,
142
+ primaryNamedContactId: primaryContact?.id ?? null,
143
+ website: primaryWebsite?.value ?? null,
144
+ contactName: primaryContact?.name ?? null,
145
+ contactEmail: primaryContact?.email ?? null,
146
+ });
147
+ }
148
+ async function hydrateChannels(db, rows) {
149
+ if (rows.length === 0) {
150
+ return rows.map((row) => ({ ...row, ...emptyChannelHydratedFields() }));
151
+ }
152
+ const ids = rows.map((row) => row.id);
153
+ const projections = await db
154
+ .select()
155
+ .from(channelContactProjections)
156
+ .where(inArray(channelContactProjections.channelId, ids));
157
+ const projectionMap = new Map(projections.map((projection) => [projection.channelId, projection]));
158
+ return rows.map((row) => {
159
+ const projection = projectionMap.get(row.id);
160
+ return {
161
+ ...row,
162
+ website: projection?.website ?? null,
163
+ contactName: projection?.contactName ?? null,
164
+ contactEmail: projection?.contactEmail ?? null,
165
+ };
166
+ });
167
+ }
168
+ export const channelServiceOperations = {
169
+ async listChannels(db, query) {
170
+ const conditions = [];
171
+ if (query.kind)
172
+ conditions.push(eq(channels.kind, query.kind));
173
+ if (query.status)
174
+ conditions.push(eq(channels.status, query.status));
175
+ const where = conditions.length ? and(...conditions) : undefined;
176
+ const [rows, countResult] = await Promise.all([
177
+ db
178
+ .select()
179
+ .from(channels)
180
+ .where(where)
181
+ .limit(query.limit)
182
+ .offset(query.offset)
183
+ .orderBy(channels.createdAt),
184
+ db.select({ count: sql `count(*)::int` }).from(channels).where(where),
185
+ ]);
186
+ return {
187
+ data: await hydrateChannels(db, rows),
188
+ total: countResult[0]?.count ?? 0,
189
+ limit: query.limit,
190
+ offset: query.offset,
191
+ };
192
+ },
193
+ async getChannelById(db, id) {
194
+ const [row] = await db.select().from(channels).where(eq(channels.id, id)).limit(1);
195
+ if (!row) {
196
+ return null;
197
+ }
198
+ const [hydrated] = await hydrateChannels(db, [row]);
199
+ return hydrated ?? null;
200
+ },
201
+ async createChannel(db, data) {
202
+ const [row] = await db.insert(channels).values(toCreateChannelBaseValues(data)).returning();
203
+ if (!row) {
204
+ throw new Error("Failed to create channel");
205
+ }
206
+ await syncChannelIdentity(db, row.id, data);
207
+ return channelServiceOperations.getChannelById(db, row.id);
208
+ },
209
+ async updateChannel(db, id, data) {
210
+ const existing = await channelServiceOperations.getChannelById(db, id);
211
+ if (!existing) {
212
+ return null;
213
+ }
214
+ await db
215
+ .update(channels)
216
+ .set({ ...toUpdateChannelBaseValues(data), updatedAt: new Date() })
217
+ .where(eq(channels.id, id));
218
+ await syncChannelIdentity(db, id, {
219
+ website: data.website === undefined ? existing.website : data.website,
220
+ contactName: data.contactName === undefined ? existing.contactName : data.contactName,
221
+ contactEmail: data.contactEmail === undefined ? existing.contactEmail : data.contactEmail,
222
+ });
223
+ return channelServiceOperations.getChannelById(db, id);
224
+ },
225
+ async deleteChannel(db, id) {
226
+ await deleteChannelIdentity(db, id);
227
+ const [row] = await db
228
+ .delete(channels)
229
+ .where(eq(channels.id, id))
230
+ .returning({ id: channels.id });
231
+ return row ?? null;
232
+ },
233
+ async listChannelContactPoints(db, channelId) {
234
+ const channel = await ensureChannelExists(db, channelId);
235
+ if (!channel)
236
+ return null;
237
+ return identityService.listContactPointsForEntity(db, channelEntityType, channelId);
238
+ },
239
+ async createChannelContactPoint(db, channelId, data) {
240
+ const channel = await ensureChannelExists(db, channelId);
241
+ if (!channel)
242
+ return null;
243
+ const row = await identityService.createContactPoint(db, {
244
+ ...data,
245
+ entityType: channelEntityType,
246
+ entityId: channelId,
247
+ });
248
+ await rebuildChannelContactProjection(db, channelId);
249
+ return row;
250
+ },
251
+ async updateChannelContactPoint(db, id, data) {
252
+ const existing = await identityService.getContactPointById(db, id);
253
+ if (!existing)
254
+ return null;
255
+ const row = await identityService.updateContactPoint(db, id, data);
256
+ if (row?.entityType === channelEntityType) {
257
+ await rebuildChannelContactProjection(db, row.entityId);
258
+ }
259
+ return row;
260
+ },
261
+ async deleteChannelContactPoint(db, id) {
262
+ const existing = await identityService.getContactPointById(db, id);
263
+ const row = await identityService.deleteContactPoint(db, id);
264
+ if (row && existing?.entityType === channelEntityType) {
265
+ await rebuildChannelContactProjection(db, existing.entityId);
266
+ }
267
+ return row;
268
+ },
269
+ async listChannelContacts(db, channelId) {
270
+ const channel = await ensureChannelExists(db, channelId);
271
+ if (!channel)
272
+ return null;
273
+ return identityService.listNamedContactsForEntity(db, channelEntityType, channelId);
274
+ },
275
+ async createChannelContact(db, channelId, data) {
276
+ const channel = await ensureChannelExists(db, channelId);
277
+ if (!channel)
278
+ return null;
279
+ const row = await identityService.createNamedContact(db, {
280
+ ...data,
281
+ entityType: channelEntityType,
282
+ entityId: channelId,
283
+ });
284
+ await rebuildChannelContactProjection(db, channelId);
285
+ return row;
286
+ },
287
+ async updateChannelContact(db, id, data) {
288
+ const existing = await identityService.getNamedContactById(db, id);
289
+ if (!existing)
290
+ return null;
291
+ const row = await identityService.updateNamedContact(db, id, data);
292
+ if (row?.entityType === channelEntityType) {
293
+ await rebuildChannelContactProjection(db, row.entityId);
294
+ }
295
+ return row;
296
+ },
297
+ async deleteChannelContact(db, id) {
298
+ const existing = await identityService.getNamedContactById(db, id);
299
+ const row = await identityService.deleteNamedContact(db, id);
300
+ if (row && existing?.entityType === channelEntityType) {
301
+ await rebuildChannelContactProjection(db, existing.entityId);
302
+ }
303
+ return row;
304
+ },
305
+ };
@@ -0,0 +1,385 @@
1
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
2
+ import type { ChannelBookingLinkListQuery, ChannelCommissionRuleListQuery, ChannelContractListQuery, ChannelProductMappingListQuery, ChannelWebhookEventListQuery, CreateChannelBookingLinkInput, CreateChannelCommissionRuleInput, CreateChannelContractInput, CreateChannelProductMappingInput, CreateChannelWebhookEventInput, UpdateChannelBookingLinkInput, UpdateChannelCommissionRuleInput, UpdateChannelContractInput, UpdateChannelProductMappingInput, UpdateChannelWebhookEventInput } from "./types.js";
3
+ export declare const commercialServiceOperations: {
4
+ listContracts(db: PostgresJsDatabase, query: ChannelContractListQuery): Promise<{
5
+ data: {
6
+ id: string;
7
+ channelId: string;
8
+ supplierId: string | null;
9
+ status: "active" | "draft" | "expired" | "terminated";
10
+ startsAt: string;
11
+ endsAt: string | null;
12
+ paymentOwner: "operator" | "channel" | "split";
13
+ cancellationOwner: "operator" | "channel" | "mixed";
14
+ settlementTerms: string | null;
15
+ notes: string | null;
16
+ rateLimitRps: number | null;
17
+ rateLimitBurst: number | null;
18
+ rateLimitPriorityGates: Record<string, number> | null;
19
+ policy: Record<string, unknown> | null;
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ }[];
23
+ total: number;
24
+ limit: number;
25
+ offset: number;
26
+ }>;
27
+ getContractById(db: PostgresJsDatabase, id: string): Promise<{
28
+ id: string;
29
+ channelId: string;
30
+ supplierId: string | null;
31
+ status: "active" | "draft" | "expired" | "terminated";
32
+ startsAt: string;
33
+ endsAt: string | null;
34
+ paymentOwner: "operator" | "channel" | "split";
35
+ cancellationOwner: "operator" | "channel" | "mixed";
36
+ settlementTerms: string | null;
37
+ notes: string | null;
38
+ rateLimitRps: number | null;
39
+ rateLimitBurst: number | null;
40
+ rateLimitPriorityGates: Record<string, number> | null;
41
+ policy: Record<string, unknown> | null;
42
+ createdAt: Date;
43
+ updatedAt: Date;
44
+ } | null>;
45
+ createContract(db: PostgresJsDatabase, data: CreateChannelContractInput): Promise<{
46
+ paymentOwner: "operator" | "channel" | "split";
47
+ createdAt: Date;
48
+ updatedAt: Date;
49
+ id: string;
50
+ status: "active" | "draft" | "expired" | "terminated";
51
+ rateLimitRps: number | null;
52
+ rateLimitBurst: number | null;
53
+ rateLimitPriorityGates: Record<string, number> | null;
54
+ channelId: string;
55
+ policy: Record<string, unknown> | null;
56
+ supplierId: string | null;
57
+ startsAt: string;
58
+ endsAt: string | null;
59
+ cancellationOwner: "operator" | "channel" | "mixed";
60
+ settlementTerms: string | null;
61
+ notes: string | null;
62
+ } | undefined>;
63
+ updateContract(db: PostgresJsDatabase, id: string, data: UpdateChannelContractInput): Promise<{
64
+ id: string;
65
+ channelId: string;
66
+ supplierId: string | null;
67
+ status: "active" | "draft" | "expired" | "terminated";
68
+ startsAt: string;
69
+ endsAt: string | null;
70
+ paymentOwner: "operator" | "channel" | "split";
71
+ cancellationOwner: "operator" | "channel" | "mixed";
72
+ settlementTerms: string | null;
73
+ notes: string | null;
74
+ rateLimitRps: number | null;
75
+ rateLimitBurst: number | null;
76
+ rateLimitPriorityGates: Record<string, number> | null;
77
+ policy: Record<string, unknown> | null;
78
+ createdAt: Date;
79
+ updatedAt: Date;
80
+ } | null>;
81
+ deleteContract(db: PostgresJsDatabase, id: string): Promise<{
82
+ id: string;
83
+ } | null>;
84
+ listCommissionRules(db: PostgresJsDatabase, query: ChannelCommissionRuleListQuery): Promise<{
85
+ data: {
86
+ id: string;
87
+ contractId: string;
88
+ scope: "booking" | "product" | "rate" | "category";
89
+ productId: string | null;
90
+ externalRateId: string | null;
91
+ externalCategoryId: string | null;
92
+ commissionType: "fixed" | "percentage";
93
+ amountCents: number | null;
94
+ percentBasisPoints: number | null;
95
+ validFrom: string | null;
96
+ validTo: string | null;
97
+ createdAt: Date;
98
+ updatedAt: Date;
99
+ }[];
100
+ total: number;
101
+ limit: number;
102
+ offset: number;
103
+ }>;
104
+ getCommissionRuleById(db: PostgresJsDatabase, id: string): Promise<{
105
+ id: string;
106
+ contractId: string;
107
+ scope: "booking" | "product" | "rate" | "category";
108
+ productId: string | null;
109
+ externalRateId: string | null;
110
+ externalCategoryId: string | null;
111
+ commissionType: "fixed" | "percentage";
112
+ amountCents: number | null;
113
+ percentBasisPoints: number | null;
114
+ validFrom: string | null;
115
+ validTo: string | null;
116
+ createdAt: Date;
117
+ updatedAt: Date;
118
+ } | null>;
119
+ createCommissionRule(db: PostgresJsDatabase, data: CreateChannelCommissionRuleInput): Promise<{
120
+ createdAt: Date;
121
+ updatedAt: Date;
122
+ id: string;
123
+ productId: string | null;
124
+ externalRateId: string | null;
125
+ externalCategoryId: string | null;
126
+ contractId: string;
127
+ validFrom: string | null;
128
+ validTo: string | null;
129
+ scope: "booking" | "product" | "rate" | "category";
130
+ commissionType: "fixed" | "percentage";
131
+ amountCents: number | null;
132
+ percentBasisPoints: number | null;
133
+ } | undefined>;
134
+ updateCommissionRule(db: PostgresJsDatabase, id: string, data: UpdateChannelCommissionRuleInput): Promise<{
135
+ id: string;
136
+ contractId: string;
137
+ scope: "booking" | "product" | "rate" | "category";
138
+ productId: string | null;
139
+ externalRateId: string | null;
140
+ externalCategoryId: string | null;
141
+ commissionType: "fixed" | "percentage";
142
+ amountCents: number | null;
143
+ percentBasisPoints: number | null;
144
+ validFrom: string | null;
145
+ validTo: string | null;
146
+ createdAt: Date;
147
+ updatedAt: Date;
148
+ } | null>;
149
+ deleteCommissionRule(db: PostgresJsDatabase, id: string): Promise<{
150
+ id: string;
151
+ } | null>;
152
+ listProductMappings(db: PostgresJsDatabase, query: ChannelProductMappingListQuery): Promise<{
153
+ data: {
154
+ id: string;
155
+ channelId: string;
156
+ productId: string;
157
+ externalProductId: string | null;
158
+ externalRateId: string | null;
159
+ externalCategoryId: string | null;
160
+ active: boolean;
161
+ sourceKind: string | null;
162
+ sourceConnectionId: string | null;
163
+ pushBookings: boolean;
164
+ pushAvailability: boolean;
165
+ pushContent: boolean;
166
+ policy: Record<string, unknown> | null;
167
+ lastPushedContentHash: string | null;
168
+ lastPushedContentAt: Date | null;
169
+ createdAt: Date;
170
+ updatedAt: Date;
171
+ }[];
172
+ total: number;
173
+ limit: number;
174
+ offset: number;
175
+ }>;
176
+ getProductMappingById(db: PostgresJsDatabase, id: string): Promise<{
177
+ id: string;
178
+ channelId: string;
179
+ productId: string;
180
+ externalProductId: string | null;
181
+ externalRateId: string | null;
182
+ externalCategoryId: string | null;
183
+ active: boolean;
184
+ sourceKind: string | null;
185
+ sourceConnectionId: string | null;
186
+ pushBookings: boolean;
187
+ pushAvailability: boolean;
188
+ pushContent: boolean;
189
+ policy: Record<string, unknown> | null;
190
+ lastPushedContentHash: string | null;
191
+ lastPushedContentAt: Date | null;
192
+ createdAt: Date;
193
+ updatedAt: Date;
194
+ } | null>;
195
+ createProductMapping(db: PostgresJsDatabase, data: CreateChannelProductMappingInput): Promise<{
196
+ createdAt: Date;
197
+ updatedAt: Date;
198
+ id: string;
199
+ active: boolean;
200
+ channelId: string;
201
+ sourceKind: string | null;
202
+ sourceConnectionId: string | null;
203
+ productId: string;
204
+ externalProductId: string | null;
205
+ externalRateId: string | null;
206
+ externalCategoryId: string | null;
207
+ pushBookings: boolean;
208
+ pushAvailability: boolean;
209
+ pushContent: boolean;
210
+ policy: Record<string, unknown> | null;
211
+ lastPushedContentHash: string | null;
212
+ lastPushedContentAt: Date | null;
213
+ } | undefined>;
214
+ updateProductMapping(db: PostgresJsDatabase, id: string, data: UpdateChannelProductMappingInput): Promise<{
215
+ id: string;
216
+ channelId: string;
217
+ productId: string;
218
+ externalProductId: string | null;
219
+ externalRateId: string | null;
220
+ externalCategoryId: string | null;
221
+ active: boolean;
222
+ sourceKind: string | null;
223
+ sourceConnectionId: string | null;
224
+ pushBookings: boolean;
225
+ pushAvailability: boolean;
226
+ pushContent: boolean;
227
+ policy: Record<string, unknown> | null;
228
+ lastPushedContentHash: string | null;
229
+ lastPushedContentAt: Date | null;
230
+ createdAt: Date;
231
+ updatedAt: Date;
232
+ } | null>;
233
+ deleteProductMapping(db: PostgresJsDatabase, id: string): Promise<{
234
+ id: string;
235
+ } | null>;
236
+ listBookingLinks(db: PostgresJsDatabase, query: ChannelBookingLinkListQuery): Promise<{
237
+ data: {
238
+ id: string;
239
+ channelId: string;
240
+ bookingId: string;
241
+ bookingItemId: string | null;
242
+ externalBookingId: string | null;
243
+ externalReference: string | null;
244
+ externalStatus: string | null;
245
+ bookedAtExternal: Date | null;
246
+ lastSyncedAt: Date | null;
247
+ sourceKind: string | null;
248
+ sourceConnectionId: string | null;
249
+ pushStatus: string;
250
+ pushAttempts: number;
251
+ lastPushAt: Date | null;
252
+ lastError: string | null;
253
+ pushedPayloadHash: string | null;
254
+ idempotencyKey: string | null;
255
+ createdAt: Date;
256
+ updatedAt: Date;
257
+ }[];
258
+ total: number;
259
+ limit: number;
260
+ offset: number;
261
+ }>;
262
+ getBookingLinkById(db: PostgresJsDatabase, id: string): Promise<{
263
+ id: string;
264
+ channelId: string;
265
+ bookingId: string;
266
+ bookingItemId: string | null;
267
+ externalBookingId: string | null;
268
+ externalReference: string | null;
269
+ externalStatus: string | null;
270
+ bookedAtExternal: Date | null;
271
+ lastSyncedAt: Date | null;
272
+ sourceKind: string | null;
273
+ sourceConnectionId: string | null;
274
+ pushStatus: string;
275
+ pushAttempts: number;
276
+ lastPushAt: Date | null;
277
+ lastError: string | null;
278
+ pushedPayloadHash: string | null;
279
+ idempotencyKey: string | null;
280
+ createdAt: Date;
281
+ updatedAt: Date;
282
+ } | null>;
283
+ createBookingLink(db: PostgresJsDatabase, data: CreateChannelBookingLinkInput): Promise<{
284
+ bookingId: string;
285
+ createdAt: Date;
286
+ updatedAt: Date;
287
+ idempotencyKey: string | null;
288
+ id: string;
289
+ channelId: string;
290
+ bookingItemId: string | null;
291
+ externalBookingId: string | null;
292
+ externalReference: string | null;
293
+ externalStatus: string | null;
294
+ bookedAtExternal: Date | null;
295
+ lastSyncedAt: Date | null;
296
+ sourceKind: string | null;
297
+ sourceConnectionId: string | null;
298
+ pushStatus: string;
299
+ pushAttempts: number;
300
+ lastPushAt: Date | null;
301
+ lastError: string | null;
302
+ pushedPayloadHash: string | null;
303
+ } | undefined>;
304
+ updateBookingLink(db: PostgresJsDatabase, id: string, data: UpdateChannelBookingLinkInput): Promise<{
305
+ id: string;
306
+ channelId: string;
307
+ bookingId: string;
308
+ bookingItemId: string | null;
309
+ externalBookingId: string | null;
310
+ externalReference: string | null;
311
+ externalStatus: string | null;
312
+ bookedAtExternal: Date | null;
313
+ lastSyncedAt: Date | null;
314
+ sourceKind: string | null;
315
+ sourceConnectionId: string | null;
316
+ pushStatus: string;
317
+ pushAttempts: number;
318
+ lastPushAt: Date | null;
319
+ lastError: string | null;
320
+ pushedPayloadHash: string | null;
321
+ idempotencyKey: string | null;
322
+ createdAt: Date;
323
+ updatedAt: Date;
324
+ } | null>;
325
+ deleteBookingLink(db: PostgresJsDatabase, id: string): Promise<{
326
+ id: string;
327
+ } | null>;
328
+ listWebhookEvents(db: PostgresJsDatabase, query: ChannelWebhookEventListQuery): Promise<{
329
+ data: {
330
+ id: string;
331
+ channelId: string;
332
+ eventType: string;
333
+ externalEventId: string | null;
334
+ payload: Record<string, unknown>;
335
+ receivedAt: Date;
336
+ processedAt: Date | null;
337
+ status: "pending" | "failed" | "processed" | "ignored";
338
+ errorMessage: string | null;
339
+ createdAt: Date;
340
+ }[];
341
+ total: number;
342
+ limit: number;
343
+ offset: number;
344
+ }>;
345
+ getWebhookEventById(db: PostgresJsDatabase, id: string): Promise<{
346
+ id: string;
347
+ channelId: string;
348
+ eventType: string;
349
+ externalEventId: string | null;
350
+ payload: Record<string, unknown>;
351
+ receivedAt: Date;
352
+ processedAt: Date | null;
353
+ status: "pending" | "failed" | "processed" | "ignored";
354
+ errorMessage: string | null;
355
+ createdAt: Date;
356
+ } | null>;
357
+ createWebhookEvent(db: PostgresJsDatabase, data: CreateChannelWebhookEventInput): Promise<{
358
+ createdAt: Date;
359
+ id: string;
360
+ status: "pending" | "failed" | "processed" | "ignored";
361
+ channelId: string;
362
+ errorMessage: string | null;
363
+ eventType: string;
364
+ externalEventId: string | null;
365
+ payload: Record<string, unknown>;
366
+ receivedAt: Date;
367
+ processedAt: Date | null;
368
+ } | undefined>;
369
+ updateWebhookEvent(db: PostgresJsDatabase, id: string, data: UpdateChannelWebhookEventInput): Promise<{
370
+ id: string;
371
+ channelId: string;
372
+ eventType: string;
373
+ externalEventId: string | null;
374
+ payload: Record<string, unknown>;
375
+ receivedAt: Date;
376
+ processedAt: Date | null;
377
+ status: "pending" | "failed" | "processed" | "ignored";
378
+ errorMessage: string | null;
379
+ createdAt: Date;
380
+ } | null>;
381
+ deleteWebhookEvent(db: PostgresJsDatabase, id: string): Promise<{
382
+ id: string;
383
+ } | null>;
384
+ };
385
+ //# sourceMappingURL=commercial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commercial.d.ts","sourceRoot":"","sources":["../../src/service/commercial.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAUjE,OAAO,KAAK,EACV,2BAA2B,EAC3B,8BAA8B,EAC9B,wBAAwB,EACxB,8BAA8B,EAC9B,4BAA4B,EAC5B,6BAA6B,EAC7B,gCAAgC,EAChC,0BAA0B,EAC1B,gCAAgC,EAChC,8BAA8B,EAC9B,6BAA6B,EAC7B,gCAAgC,EAChC,0BAA0B,EAC1B,gCAAgC,EAChC,8BAA8B,EAC/B,MAAM,YAAY,CAAA;AAEnB,eAAO,MAAM,2BAA2B;sBACd,kBAAkB,SAAS,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;wBAoBjD,kBAAkB,MAAM,MAAM;;;;;;;;;;;;;;;;;;uBAS/B,kBAAkB,QAAQ,0BAA0B;;;;;;;;;;;;;;;;;;uBAKpD,kBAAkB,MAAM,MAAM,QAAQ,0BAA0B;;;;;;;;;;;;;;;;;;uBAShE,kBAAkB,MAAM,MAAM;;;4BAQzB,kBAAkB,SAAS,8BAA8B;;;;;;;;;;;;;;;;;;;;8BAoBvD,kBAAkB,MAAM,MAAM;;;;;;;;;;;;;;;6BAS/B,kBAAkB,QAAQ,gCAAgC;;;;;;;;;;;;;;;6BAMnF,kBAAkB,MAClB,MAAM,QACJ,gCAAgC;;;;;;;;;;;;;;;6BAUT,kBAAkB,MAAM,MAAM;;;4BAQ/B,kBAAkB,SAAS,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;8BAoBvD,kBAAkB,MAAM,MAAM;;;;;;;;;;;;;;;;;;;6BAS/B,kBAAkB,QAAQ,gCAAgC;;;;;;;;;;;;;;;;;;;6BAMnF,kBAAkB,MAClB,MAAM,QACJ,gCAAgC;;;;;;;;;;;;;;;;;;;6BAUT,kBAAkB,MAAM,MAAM;;;yBAQlC,kBAAkB,SAAS,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;2BAqBpD,kBAAkB,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;0BAS/B,kBAAkB,QAAQ,6BAA6B;;;;;;;;;;;;;;;;;;;;;0BAYvD,kBAAkB,MAAM,MAAM,QAAQ,6BAA6B;;;;;;;;;;;;;;;;;;;;;0BAenE,kBAAkB,MAAM,MAAM;;;0BAQ9B,kBAAkB,SAAS,4BAA4B;;;;;;;;;;;;;;;;;4BAoBrD,kBAAkB,MAAM,MAAM;;;;;;;;;;;;2BAS/B,kBAAkB,QAAQ,8BAA8B;;;;;;;;;;;;2BAa/E,kBAAkB,MAClB,MAAM,QACJ,8BAA8B;;;;;;;;;;;;2BAcT,kBAAkB,MAAM,MAAM;;;CAO5D,CAAA"}