@voyant-travel/catalog 0.117.2

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 (243) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +190 -0
  3. package/dist/adapter/booking-forwarding.d.ts +2 -0
  4. package/dist/adapter/booking-forwarding.d.ts.map +1 -0
  5. package/dist/adapter/booking-forwarding.js +1 -0
  6. package/dist/adapter/channel-push-contracts.d.ts +2 -0
  7. package/dist/adapter/channel-push-contracts.d.ts.map +1 -0
  8. package/dist/adapter/channel-push-contracts.js +1 -0
  9. package/dist/adapter/contract.d.ts +2 -0
  10. package/dist/adapter/contract.d.ts.map +1 -0
  11. package/dist/adapter/contract.js +1 -0
  12. package/dist/adapter/contract.test.d.ts +2 -0
  13. package/dist/adapter/contract.test.d.ts.map +1 -0
  14. package/dist/adapter/contract.test.js +390 -0
  15. package/dist/adapter/provider-contracts.d.ts +2 -0
  16. package/dist/adapter/provider-contracts.d.ts.map +1 -0
  17. package/dist/adapter/provider-contracts.js +1 -0
  18. package/dist/adapter/provider-contracts.test.d.ts +2 -0
  19. package/dist/adapter/provider-contracts.test.d.ts.map +1 -0
  20. package/dist/adapter/provider-contracts.test.js +206 -0
  21. package/dist/adapter/schemas.d.ts +2 -0
  22. package/dist/adapter/schemas.d.ts.map +1 -0
  23. package/dist/adapter/schemas.js +1 -0
  24. package/dist/adapter/schemas.test.d.ts +2 -0
  25. package/dist/adapter/schemas.test.d.ts.map +1 -0
  26. package/dist/adapter/schemas.test.js +344 -0
  27. package/dist/booking-engine/book.d.ts +124 -0
  28. package/dist/booking-engine/book.d.ts.map +1 -0
  29. package/dist/booking-engine/book.js +311 -0
  30. package/dist/booking-engine/cancel.d.ts +40 -0
  31. package/dist/booking-engine/cancel.d.ts.map +1 -0
  32. package/dist/booking-engine/cancel.js +56 -0
  33. package/dist/booking-engine/checkout-finalize.d.ts +146 -0
  34. package/dist/booking-engine/checkout-finalize.d.ts.map +1 -0
  35. package/dist/booking-engine/checkout-finalize.js +132 -0
  36. package/dist/booking-engine/contracts.d.ts +9 -0
  37. package/dist/booking-engine/contracts.d.ts.map +1 -0
  38. package/dist/booking-engine/contracts.js +8 -0
  39. package/dist/booking-engine/contracts.test.d.ts +2 -0
  40. package/dist/booking-engine/contracts.test.d.ts.map +1 -0
  41. package/dist/booking-engine/contracts.test.js +116 -0
  42. package/dist/booking-engine/draft-shape.d.ts +10 -0
  43. package/dist/booking-engine/draft-shape.d.ts.map +1 -0
  44. package/dist/booking-engine/draft-shape.js +9 -0
  45. package/dist/booking-engine/draft-shape.test.d.ts +2 -0
  46. package/dist/booking-engine/draft-shape.test.d.ts.map +1 -0
  47. package/dist/booking-engine/draft-shape.test.js +74 -0
  48. package/dist/booking-engine/drafts-schema.d.ts +302 -0
  49. package/dist/booking-engine/drafts-schema.d.ts.map +1 -0
  50. package/dist/booking-engine/drafts-schema.js +53 -0
  51. package/dist/booking-engine/drafts-service.d.ts +41 -0
  52. package/dist/booking-engine/drafts-service.d.ts.map +1 -0
  53. package/dist/booking-engine/drafts-service.js +108 -0
  54. package/dist/booking-engine/errors.d.ts +81 -0
  55. package/dist/booking-engine/errors.d.ts.map +1 -0
  56. package/dist/booking-engine/errors.js +113 -0
  57. package/dist/booking-engine/index.d.ts +36 -0
  58. package/dist/booking-engine/index.d.ts.map +1 -0
  59. package/dist/booking-engine/index.js +34 -0
  60. package/dist/booking-engine/orders.d.ts +41 -0
  61. package/dist/booking-engine/orders.d.ts.map +1 -0
  62. package/dist/booking-engine/orders.js +49 -0
  63. package/dist/booking-engine/owned-handler.d.ts +166 -0
  64. package/dist/booking-engine/owned-handler.d.ts.map +1 -0
  65. package/dist/booking-engine/owned-handler.js +50 -0
  66. package/dist/booking-engine/owned-handler.test.d.ts +2 -0
  67. package/dist/booking-engine/owned-handler.test.d.ts.map +1 -0
  68. package/dist/booking-engine/owned-handler.test.js +63 -0
  69. package/dist/booking-engine/promotions-contract.d.ts +8 -0
  70. package/dist/booking-engine/promotions-contract.d.ts.map +1 -0
  71. package/dist/booking-engine/promotions-contract.js +7 -0
  72. package/dist/booking-engine/quote-enricher.test.d.ts +12 -0
  73. package/dist/booking-engine/quote-enricher.test.d.ts.map +1 -0
  74. package/dist/booking-engine/quote-enricher.test.js +138 -0
  75. package/dist/booking-engine/quote.d.ts +163 -0
  76. package/dist/booking-engine/quote.d.ts.map +1 -0
  77. package/dist/booking-engine/quote.js +259 -0
  78. package/dist/booking-engine/registry.d.ts +85 -0
  79. package/dist/booking-engine/registry.d.ts.map +1 -0
  80. package/dist/booking-engine/registry.js +118 -0
  81. package/dist/booking-engine/registry.test.d.ts +2 -0
  82. package/dist/booking-engine/registry.test.d.ts.map +1 -0
  83. package/dist/booking-engine/registry.test.js +132 -0
  84. package/dist/booking-engine/routes-contracts.d.ts +169 -0
  85. package/dist/booking-engine/routes-contracts.d.ts.map +1 -0
  86. package/dist/booking-engine/routes-contracts.js +63 -0
  87. package/dist/booking-engine/routes.d.ts +7 -0
  88. package/dist/booking-engine/routes.d.ts.map +1 -0
  89. package/dist/booking-engine/routes.js +443 -0
  90. package/dist/booking-engine/routes.test.d.ts +2 -0
  91. package/dist/booking-engine/routes.test.d.ts.map +1 -0
  92. package/dist/booking-engine/routes.test.js +304 -0
  93. package/dist/booking-engine/schema.d.ts +455 -0
  94. package/dist/booking-engine/schema.d.ts.map +1 -0
  95. package/dist/booking-engine/schema.js +75 -0
  96. package/dist/booking-engine/snapshot-content.d.ts +120 -0
  97. package/dist/booking-engine/snapshot-content.d.ts.map +1 -0
  98. package/dist/booking-engine/snapshot-content.js +110 -0
  99. package/dist/booking-engine/snapshot-content.test.d.ts +2 -0
  100. package/dist/booking-engine/snapshot-content.test.d.ts.map +1 -0
  101. package/dist/booking-engine/snapshot-content.test.js +213 -0
  102. package/dist/booking-engine/sync.d.ts +136 -0
  103. package/dist/booking-engine/sync.d.ts.map +1 -0
  104. package/dist/booking-engine/sync.js +177 -0
  105. package/dist/booking-engine/sync.test.d.ts +2 -0
  106. package/dist/booking-engine/sync.test.d.ts.map +1 -0
  107. package/dist/booking-engine/sync.test.js +377 -0
  108. package/dist/contract.d.ts +2 -0
  109. package/dist/contract.d.ts.map +1 -0
  110. package/dist/contract.js +1 -0
  111. package/dist/contract.test.d.ts +2 -0
  112. package/dist/contract.test.d.ts.map +1 -0
  113. package/dist/contract.test.js +107 -0
  114. package/dist/drift/events.d.ts +2 -0
  115. package/dist/drift/events.d.ts.map +1 -0
  116. package/dist/drift/events.js +1 -0
  117. package/dist/drift/events.test.d.ts +2 -0
  118. package/dist/drift/events.test.d.ts.map +1 -0
  119. package/dist/drift/events.test.js +100 -0
  120. package/dist/embeddings/contract.d.ts +85 -0
  121. package/dist/embeddings/contract.d.ts.map +1 -0
  122. package/dist/embeddings/contract.js +42 -0
  123. package/dist/embeddings/contract.test.d.ts +2 -0
  124. package/dist/embeddings/contract.test.d.ts.map +1 -0
  125. package/dist/embeddings/contract.test.js +30 -0
  126. package/dist/embeddings/gemini.d.ts +110 -0
  127. package/dist/embeddings/gemini.d.ts.map +1 -0
  128. package/dist/embeddings/gemini.js +118 -0
  129. package/dist/embeddings/gemini.test.d.ts +2 -0
  130. package/dist/embeddings/gemini.test.d.ts.map +1 -0
  131. package/dist/embeddings/gemini.test.js +132 -0
  132. package/dist/embeddings/model-registry.d.ts +62 -0
  133. package/dist/embeddings/model-registry.d.ts.map +1 -0
  134. package/dist/embeddings/model-registry.js +78 -0
  135. package/dist/embeddings/model-registry.test.d.ts +2 -0
  136. package/dist/embeddings/model-registry.test.d.ts.map +1 -0
  137. package/dist/embeddings/model-registry.test.js +81 -0
  138. package/dist/embeddings/openai.d.ts +81 -0
  139. package/dist/embeddings/openai.d.ts.map +1 -0
  140. package/dist/embeddings/openai.js +123 -0
  141. package/dist/embeddings/openai.test.d.ts +2 -0
  142. package/dist/embeddings/openai.test.d.ts.map +1 -0
  143. package/dist/embeddings/openai.test.js +164 -0
  144. package/dist/events/taxonomy.d.ts +158 -0
  145. package/dist/events/taxonomy.d.ts.map +1 -0
  146. package/dist/events/taxonomy.js +99 -0
  147. package/dist/events/taxonomy.test.d.ts +2 -0
  148. package/dist/events/taxonomy.test.d.ts.map +1 -0
  149. package/dist/events/taxonomy.test.js +48 -0
  150. package/dist/index.d.ts +27 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +39 -0
  153. package/dist/indexer/contract.d.ts +203 -0
  154. package/dist/indexer/contract.d.ts.map +1 -0
  155. package/dist/indexer/contract.js +16 -0
  156. package/dist/indexer/typesense-search-query.d.ts +31 -0
  157. package/dist/indexer/typesense-search-query.d.ts.map +1 -0
  158. package/dist/indexer/typesense-search-query.js +185 -0
  159. package/dist/indexer/typesense.d.ts +105 -0
  160. package/dist/indexer/typesense.d.ts.map +1 -0
  161. package/dist/indexer/typesense.js +394 -0
  162. package/dist/indexer/typesense.test.d.ts +2 -0
  163. package/dist/indexer/typesense.test.d.ts.map +1 -0
  164. package/dist/indexer/typesense.test.js +253 -0
  165. package/dist/overlay/resolver.d.ts +101 -0
  166. package/dist/overlay/resolver.d.ts.map +1 -0
  167. package/dist/overlay/resolver.js +167 -0
  168. package/dist/overlay/resolver.test.d.ts +2 -0
  169. package/dist/overlay/resolver.test.d.ts.map +1 -0
  170. package/dist/overlay/resolver.test.js +179 -0
  171. package/dist/overlay/schema.d.ts +266 -0
  172. package/dist/overlay/schema.d.ts.map +1 -0
  173. package/dist/overlay/schema.js +71 -0
  174. package/dist/provenance.d.ts +2 -0
  175. package/dist/provenance.d.ts.map +1 -0
  176. package/dist/provenance.js +1 -0
  177. package/dist/schema-sourced-entries.d.ts +344 -0
  178. package/dist/schema-sourced-entries.d.ts.map +1 -0
  179. package/dist/schema-sourced-entries.js +75 -0
  180. package/dist/schema.d.ts +21 -0
  181. package/dist/schema.d.ts.map +1 -0
  182. package/dist/schema.js +20 -0
  183. package/dist/search/federate.d.ts +58 -0
  184. package/dist/search/federate.d.ts.map +1 -0
  185. package/dist/search/federate.js +103 -0
  186. package/dist/search/federate.test.d.ts +2 -0
  187. package/dist/search/federate.test.d.ts.map +1 -0
  188. package/dist/search/federate.test.js +146 -0
  189. package/dist/search/rerank.d.ts +77 -0
  190. package/dist/search/rerank.d.ts.map +1 -0
  191. package/dist/search/rerank.js +68 -0
  192. package/dist/search/rerank.test.d.ts +2 -0
  193. package/dist/search/rerank.test.d.ts.map +1 -0
  194. package/dist/search/rerank.test.js +60 -0
  195. package/dist/search/routes.d.ts +144 -0
  196. package/dist/search/routes.d.ts.map +1 -0
  197. package/dist/search/routes.js +288 -0
  198. package/dist/search/routes.test.d.ts +2 -0
  199. package/dist/search/routes.test.d.ts.map +1 -0
  200. package/dist/search/routes.test.js +322 -0
  201. package/dist/search/semantic.d.ts +63 -0
  202. package/dist/search/semantic.d.ts.map +1 -0
  203. package/dist/search/semantic.js +75 -0
  204. package/dist/search/semantic.test.d.ts +2 -0
  205. package/dist/search/semantic.test.d.ts.map +1 -0
  206. package/dist/search/semantic.test.js +143 -0
  207. package/dist/services/build-indexer-document.test.d.ts +2 -0
  208. package/dist/services/build-indexer-document.test.d.ts.map +1 -0
  209. package/dist/services/build-indexer-document.test.js +102 -0
  210. package/dist/services/content-service.d.ts +125 -0
  211. package/dist/services/content-service.d.ts.map +1 -0
  212. package/dist/services/content-service.js +139 -0
  213. package/dist/services/content-service.test.d.ts +2 -0
  214. package/dist/services/content-service.test.d.ts.map +1 -0
  215. package/dist/services/content-service.test.js +322 -0
  216. package/dist/services/indexer-service.d.ts +109 -0
  217. package/dist/services/indexer-service.d.ts.map +1 -0
  218. package/dist/services/indexer-service.js +123 -0
  219. package/dist/services/indexer-service.test.d.ts +2 -0
  220. package/dist/services/indexer-service.test.d.ts.map +1 -0
  221. package/dist/services/indexer-service.test.js +176 -0
  222. package/dist/services/overlay-service.d.ts +108 -0
  223. package/dist/services/overlay-service.d.ts.map +1 -0
  224. package/dist/services/overlay-service.js +211 -0
  225. package/dist/services/overlay-service.test.d.ts +2 -0
  226. package/dist/services/overlay-service.test.d.ts.map +1 -0
  227. package/dist/services/overlay-service.test.js +79 -0
  228. package/dist/services/snapshot-builder.test.d.ts +2 -0
  229. package/dist/services/snapshot-builder.test.d.ts.map +1 -0
  230. package/dist/services/snapshot-builder.test.js +93 -0
  231. package/dist/services/snapshot-service.d.ts +78 -0
  232. package/dist/services/snapshot-service.d.ts.map +1 -0
  233. package/dist/services/snapshot-service.js +165 -0
  234. package/dist/services/sourced-entry-service.d.ts +142 -0
  235. package/dist/services/sourced-entry-service.d.ts.map +1 -0
  236. package/dist/services/sourced-entry-service.js +203 -0
  237. package/dist/services/sourced-entry-service.test.d.ts +10 -0
  238. package/dist/services/sourced-entry-service.test.d.ts.map +1 -0
  239. package/dist/services/sourced-entry-service.test.js +66 -0
  240. package/dist/snapshot/schema.d.ts +362 -0
  241. package/dist/snapshot/schema.d.ts.map +1 -0
  242. package/dist/snapshot/schema.js +102 -0
  243. package/package.json +210 -0
@@ -0,0 +1,455 @@
1
+ /**
2
+ * `catalog_quotes` — short-lived quote records the booking engine writes
3
+ * before a `bookEntity` call validates and consumes them.
4
+ *
5
+ * One quote = one (entity_module, entity_id, scope) combination at a
6
+ * specific time, with an `expires_at` driven by the engine's quote TTL
7
+ * (default 10 minutes). Re-quoting the same row produces a new row;
8
+ * quotes are not de-duped.
9
+ *
10
+ * The structured columns mirror `booking_catalog_snapshot`'s pricing
11
+ * layout so finance can read both shapes without parsing JSONB.
12
+ *
13
+ * Plain text references (no FK) preserve the cross-module decoupling
14
+ * rule from `schema-discipline.md`.
15
+ */
16
+ import type { AppliedOffer } from "./promotions-contract.js";
17
+ export declare const catalogQuotesTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
18
+ name: "catalog_quotes";
19
+ schema: undefined;
20
+ columns: {
21
+ id: import("drizzle-orm/pg-core").PgColumn<{
22
+ name: string;
23
+ tableName: "catalog_quotes";
24
+ dataType: "string";
25
+ columnType: "PgText";
26
+ data: string;
27
+ driverParam: string;
28
+ notNull: true;
29
+ hasDefault: true;
30
+ isPrimaryKey: true;
31
+ isAutoincrement: false;
32
+ hasRuntimeDefault: true;
33
+ enumValues: [string, ...string[]];
34
+ baseColumn: never;
35
+ identity: undefined;
36
+ generated: undefined;
37
+ }, {}, {}>;
38
+ entity_module: import("drizzle-orm/pg-core").PgColumn<{
39
+ name: "entity_module";
40
+ tableName: "catalog_quotes";
41
+ dataType: "string";
42
+ columnType: "PgText";
43
+ data: string;
44
+ driverParam: string;
45
+ notNull: true;
46
+ hasDefault: false;
47
+ isPrimaryKey: false;
48
+ isAutoincrement: false;
49
+ hasRuntimeDefault: false;
50
+ enumValues: [string, ...string[]];
51
+ baseColumn: never;
52
+ identity: undefined;
53
+ generated: undefined;
54
+ }, {}, {}>;
55
+ entity_id: import("drizzle-orm/pg-core").PgColumn<{
56
+ name: "entity_id";
57
+ tableName: "catalog_quotes";
58
+ dataType: "string";
59
+ columnType: "PgText";
60
+ data: string;
61
+ driverParam: string;
62
+ notNull: true;
63
+ hasDefault: false;
64
+ isPrimaryKey: false;
65
+ isAutoincrement: false;
66
+ hasRuntimeDefault: false;
67
+ enumValues: [string, ...string[]];
68
+ baseColumn: never;
69
+ identity: undefined;
70
+ generated: undefined;
71
+ }, {}, {}>;
72
+ source_kind: import("drizzle-orm/pg-core").PgColumn<{
73
+ name: "source_kind";
74
+ tableName: "catalog_quotes";
75
+ dataType: "string";
76
+ columnType: "PgText";
77
+ data: string;
78
+ driverParam: string;
79
+ notNull: true;
80
+ hasDefault: false;
81
+ isPrimaryKey: false;
82
+ isAutoincrement: false;
83
+ hasRuntimeDefault: false;
84
+ enumValues: [string, ...string[]];
85
+ baseColumn: never;
86
+ identity: undefined;
87
+ generated: undefined;
88
+ }, {}, {}>;
89
+ source_provider: import("drizzle-orm/pg-core").PgColumn<{
90
+ name: "source_provider";
91
+ tableName: "catalog_quotes";
92
+ dataType: "string";
93
+ columnType: "PgText";
94
+ data: string;
95
+ driverParam: string;
96
+ notNull: false;
97
+ hasDefault: false;
98
+ isPrimaryKey: false;
99
+ isAutoincrement: false;
100
+ hasRuntimeDefault: false;
101
+ enumValues: [string, ...string[]];
102
+ baseColumn: never;
103
+ identity: undefined;
104
+ generated: undefined;
105
+ }, {}, {}>;
106
+ source_connection_id: import("drizzle-orm/pg-core").PgColumn<{
107
+ name: "source_connection_id";
108
+ tableName: "catalog_quotes";
109
+ dataType: "string";
110
+ columnType: "PgText";
111
+ data: string;
112
+ driverParam: string;
113
+ notNull: false;
114
+ hasDefault: false;
115
+ isPrimaryKey: false;
116
+ isAutoincrement: false;
117
+ hasRuntimeDefault: false;
118
+ enumValues: [string, ...string[]];
119
+ baseColumn: never;
120
+ identity: undefined;
121
+ generated: undefined;
122
+ }, {}, {}>;
123
+ source_ref: import("drizzle-orm/pg-core").PgColumn<{
124
+ name: "source_ref";
125
+ tableName: "catalog_quotes";
126
+ dataType: "string";
127
+ columnType: "PgText";
128
+ data: string;
129
+ driverParam: string;
130
+ notNull: false;
131
+ hasDefault: false;
132
+ isPrimaryKey: false;
133
+ isAutoincrement: false;
134
+ hasRuntimeDefault: false;
135
+ enumValues: [string, ...string[]];
136
+ baseColumn: never;
137
+ identity: undefined;
138
+ generated: undefined;
139
+ }, {}, {}>;
140
+ available: import("drizzle-orm/pg-core").PgColumn<{
141
+ name: "available";
142
+ tableName: "catalog_quotes";
143
+ dataType: "boolean";
144
+ columnType: "PgBoolean";
145
+ data: boolean;
146
+ driverParam: boolean;
147
+ notNull: true;
148
+ hasDefault: false;
149
+ isPrimaryKey: false;
150
+ isAutoincrement: false;
151
+ hasRuntimeDefault: false;
152
+ enumValues: undefined;
153
+ baseColumn: never;
154
+ identity: undefined;
155
+ generated: undefined;
156
+ }, {}, {}>;
157
+ invalid_reason: import("drizzle-orm/pg-core").PgColumn<{
158
+ name: "invalid_reason";
159
+ tableName: "catalog_quotes";
160
+ dataType: "string";
161
+ columnType: "PgText";
162
+ data: string;
163
+ driverParam: string;
164
+ notNull: false;
165
+ hasDefault: false;
166
+ isPrimaryKey: false;
167
+ isAutoincrement: false;
168
+ hasRuntimeDefault: false;
169
+ enumValues: [string, ...string[]];
170
+ baseColumn: never;
171
+ identity: undefined;
172
+ generated: undefined;
173
+ }, {}, {}>;
174
+ locale: import("drizzle-orm/pg-core").PgColumn<{
175
+ name: "locale";
176
+ tableName: "catalog_quotes";
177
+ dataType: "string";
178
+ columnType: "PgText";
179
+ data: string;
180
+ driverParam: string;
181
+ notNull: true;
182
+ hasDefault: false;
183
+ isPrimaryKey: false;
184
+ isAutoincrement: false;
185
+ hasRuntimeDefault: false;
186
+ enumValues: [string, ...string[]];
187
+ baseColumn: never;
188
+ identity: undefined;
189
+ generated: undefined;
190
+ }, {}, {}>;
191
+ audience: import("drizzle-orm/pg-core").PgColumn<{
192
+ name: "audience";
193
+ tableName: "catalog_quotes";
194
+ dataType: "string";
195
+ columnType: "PgText";
196
+ data: string;
197
+ driverParam: string;
198
+ notNull: true;
199
+ hasDefault: false;
200
+ isPrimaryKey: false;
201
+ isAutoincrement: false;
202
+ hasRuntimeDefault: false;
203
+ enumValues: [string, ...string[]];
204
+ baseColumn: never;
205
+ identity: undefined;
206
+ generated: undefined;
207
+ }, {}, {}>;
208
+ market: import("drizzle-orm/pg-core").PgColumn<{
209
+ name: "market";
210
+ tableName: "catalog_quotes";
211
+ dataType: "string";
212
+ columnType: "PgText";
213
+ data: string;
214
+ driverParam: string;
215
+ notNull: true;
216
+ hasDefault: false;
217
+ isPrimaryKey: false;
218
+ isAutoincrement: false;
219
+ hasRuntimeDefault: false;
220
+ enumValues: [string, ...string[]];
221
+ baseColumn: never;
222
+ identity: undefined;
223
+ generated: undefined;
224
+ }, {}, {}>;
225
+ currency: import("drizzle-orm/pg-core").PgColumn<{
226
+ name: "currency";
227
+ tableName: "catalog_quotes";
228
+ dataType: "string";
229
+ columnType: "PgText";
230
+ data: string;
231
+ driverParam: string;
232
+ notNull: false;
233
+ hasDefault: false;
234
+ isPrimaryKey: false;
235
+ isAutoincrement: false;
236
+ hasRuntimeDefault: false;
237
+ enumValues: [string, ...string[]];
238
+ baseColumn: never;
239
+ identity: undefined;
240
+ generated: undefined;
241
+ }, {}, {}>;
242
+ pricing_base_amount: import("drizzle-orm/pg-core").PgColumn<{
243
+ name: "pricing_base_amount";
244
+ tableName: "catalog_quotes";
245
+ dataType: "string";
246
+ columnType: "PgNumeric";
247
+ data: string;
248
+ driverParam: string;
249
+ notNull: false;
250
+ hasDefault: false;
251
+ isPrimaryKey: false;
252
+ isAutoincrement: false;
253
+ hasRuntimeDefault: false;
254
+ enumValues: undefined;
255
+ baseColumn: never;
256
+ identity: undefined;
257
+ generated: undefined;
258
+ }, {}, {}>;
259
+ pricing_taxes: import("drizzle-orm/pg-core").PgColumn<{
260
+ name: "pricing_taxes";
261
+ tableName: "catalog_quotes";
262
+ dataType: "string";
263
+ columnType: "PgNumeric";
264
+ data: string;
265
+ driverParam: string;
266
+ notNull: false;
267
+ hasDefault: false;
268
+ isPrimaryKey: false;
269
+ isAutoincrement: false;
270
+ hasRuntimeDefault: false;
271
+ enumValues: undefined;
272
+ baseColumn: never;
273
+ identity: undefined;
274
+ generated: undefined;
275
+ }, {}, {}>;
276
+ pricing_fees: import("drizzle-orm/pg-core").PgColumn<{
277
+ name: "pricing_fees";
278
+ tableName: "catalog_quotes";
279
+ dataType: "string";
280
+ columnType: "PgNumeric";
281
+ data: string;
282
+ driverParam: string;
283
+ notNull: false;
284
+ hasDefault: false;
285
+ isPrimaryKey: false;
286
+ isAutoincrement: false;
287
+ hasRuntimeDefault: false;
288
+ enumValues: undefined;
289
+ baseColumn: never;
290
+ identity: undefined;
291
+ generated: undefined;
292
+ }, {}, {}>;
293
+ pricing_surcharges: import("drizzle-orm/pg-core").PgColumn<{
294
+ name: "pricing_surcharges";
295
+ tableName: "catalog_quotes";
296
+ dataType: "string";
297
+ columnType: "PgNumeric";
298
+ data: string;
299
+ driverParam: string;
300
+ notNull: false;
301
+ hasDefault: false;
302
+ isPrimaryKey: false;
303
+ isAutoincrement: false;
304
+ hasRuntimeDefault: false;
305
+ enumValues: undefined;
306
+ baseColumn: never;
307
+ identity: undefined;
308
+ generated: undefined;
309
+ }, {}, {}>;
310
+ pricing_currency: import("drizzle-orm/pg-core").PgColumn<{
311
+ name: "pricing_currency";
312
+ tableName: "catalog_quotes";
313
+ dataType: "string";
314
+ columnType: "PgText";
315
+ data: string;
316
+ driverParam: string;
317
+ notNull: false;
318
+ hasDefault: false;
319
+ isPrimaryKey: false;
320
+ isAutoincrement: false;
321
+ hasRuntimeDefault: false;
322
+ enumValues: [string, ...string[]];
323
+ baseColumn: never;
324
+ identity: undefined;
325
+ generated: undefined;
326
+ }, {}, {}>;
327
+ pricing_breakdown: import("drizzle-orm/pg-core").PgColumn<{
328
+ name: "pricing_breakdown";
329
+ tableName: "catalog_quotes";
330
+ dataType: "json";
331
+ columnType: "PgJsonb";
332
+ data: Record<string, unknown>;
333
+ driverParam: unknown;
334
+ notNull: false;
335
+ hasDefault: false;
336
+ isPrimaryKey: false;
337
+ isAutoincrement: false;
338
+ hasRuntimeDefault: false;
339
+ enumValues: undefined;
340
+ baseColumn: never;
341
+ identity: undefined;
342
+ generated: undefined;
343
+ }, {}, {
344
+ $type: Record<string, unknown>;
345
+ }>;
346
+ pricing_applied_offers: import("drizzle-orm/pg-core").PgColumn<{
347
+ name: "pricing_applied_offers";
348
+ tableName: "catalog_quotes";
349
+ dataType: "json";
350
+ columnType: "PgJsonb";
351
+ data: AppliedOffer[];
352
+ driverParam: unknown;
353
+ notNull: false;
354
+ hasDefault: false;
355
+ isPrimaryKey: false;
356
+ isAutoincrement: false;
357
+ hasRuntimeDefault: false;
358
+ enumValues: undefined;
359
+ baseColumn: never;
360
+ identity: undefined;
361
+ generated: undefined;
362
+ }, {}, {
363
+ $type: AppliedOffer[];
364
+ }>;
365
+ upstream_payload: import("drizzle-orm/pg-core").PgColumn<{
366
+ name: "upstream_payload";
367
+ tableName: "catalog_quotes";
368
+ dataType: "json";
369
+ columnType: "PgJsonb";
370
+ data: unknown;
371
+ driverParam: unknown;
372
+ notNull: false;
373
+ hasDefault: false;
374
+ isPrimaryKey: false;
375
+ isAutoincrement: false;
376
+ hasRuntimeDefault: false;
377
+ enumValues: undefined;
378
+ baseColumn: never;
379
+ identity: undefined;
380
+ generated: undefined;
381
+ }, {}, {}>;
382
+ consumed_at: import("drizzle-orm/pg-core").PgColumn<{
383
+ name: "consumed_at";
384
+ tableName: "catalog_quotes";
385
+ dataType: "date";
386
+ columnType: "PgTimestamp";
387
+ data: Date;
388
+ driverParam: string;
389
+ notNull: false;
390
+ hasDefault: false;
391
+ isPrimaryKey: false;
392
+ isAutoincrement: false;
393
+ hasRuntimeDefault: false;
394
+ enumValues: undefined;
395
+ baseColumn: never;
396
+ identity: undefined;
397
+ generated: undefined;
398
+ }, {}, {}>;
399
+ consumed_booking_id: import("drizzle-orm/pg-core").PgColumn<{
400
+ name: "consumed_booking_id";
401
+ tableName: "catalog_quotes";
402
+ dataType: "string";
403
+ columnType: "PgText";
404
+ data: string;
405
+ driverParam: string;
406
+ notNull: false;
407
+ hasDefault: false;
408
+ isPrimaryKey: false;
409
+ isAutoincrement: false;
410
+ hasRuntimeDefault: false;
411
+ enumValues: [string, ...string[]];
412
+ baseColumn: never;
413
+ identity: undefined;
414
+ generated: undefined;
415
+ }, {}, {}>;
416
+ created_at: import("drizzle-orm/pg-core").PgColumn<{
417
+ name: "created_at";
418
+ tableName: "catalog_quotes";
419
+ dataType: "date";
420
+ columnType: "PgTimestamp";
421
+ data: Date;
422
+ driverParam: string;
423
+ notNull: true;
424
+ hasDefault: true;
425
+ isPrimaryKey: false;
426
+ isAutoincrement: false;
427
+ hasRuntimeDefault: false;
428
+ enumValues: undefined;
429
+ baseColumn: never;
430
+ identity: undefined;
431
+ generated: undefined;
432
+ }, {}, {}>;
433
+ expires_at: import("drizzle-orm/pg-core").PgColumn<{
434
+ name: "expires_at";
435
+ tableName: "catalog_quotes";
436
+ dataType: "date";
437
+ columnType: "PgTimestamp";
438
+ data: Date;
439
+ driverParam: string;
440
+ notNull: true;
441
+ hasDefault: false;
442
+ isPrimaryKey: false;
443
+ isAutoincrement: false;
444
+ hasRuntimeDefault: false;
445
+ enumValues: undefined;
446
+ baseColumn: never;
447
+ identity: undefined;
448
+ generated: undefined;
449
+ }, {}, {}>;
450
+ };
451
+ dialect: "pg";
452
+ }>;
453
+ export type SelectCatalogQuote = typeof catalogQuotesTable.$inferSelect;
454
+ export type InsertCatalogQuote = typeof catalogQuotesTable.$inferInsert;
455
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/booking-engine/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAE5D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqE9B,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACvE,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `catalog_quotes` — short-lived quote records the booking engine writes
3
+ * before a `bookEntity` call validates and consumes them.
4
+ *
5
+ * One quote = one (entity_module, entity_id, scope) combination at a
6
+ * specific time, with an `expires_at` driven by the engine's quote TTL
7
+ * (default 10 minutes). Re-quoting the same row produces a new row;
8
+ * quotes are not de-duped.
9
+ *
10
+ * The structured columns mirror `booking_catalog_snapshot`'s pricing
11
+ * layout so finance can read both shapes without parsing JSONB.
12
+ *
13
+ * Plain text references (no FK) preserve the cross-module decoupling
14
+ * rule from `schema-discipline.md`.
15
+ */
16
+ import { typeId } from "@voyant-travel/db/lib/typeid-column";
17
+ import { boolean, index, jsonb, numeric, pgTable, text, timestamp } from "drizzle-orm/pg-core";
18
+ export const catalogQuotesTable = pgTable("catalog_quotes", {
19
+ id: typeId("catalog_quotes"),
20
+ entity_module: text("entity_module").notNull(),
21
+ entity_id: text("entity_id").notNull(),
22
+ /** Mirrors the snapshot row's source pointer so a book can echo it back. */
23
+ source_kind: text("source_kind").notNull(),
24
+ source_provider: text("source_provider"),
25
+ source_connection_id: text("source_connection_id"),
26
+ source_ref: text("source_ref"),
27
+ /** Whether the upstream/owned source flagged this entity as bookable. */
28
+ available: boolean("available").notNull(),
29
+ /** Populated when `available = false`; carries the upstream reason. */
30
+ invalid_reason: text("invalid_reason"),
31
+ /** Locale/audience/market scope captured for the quote. */
32
+ locale: text("locale").notNull(),
33
+ audience: text("audience").notNull(),
34
+ market: text("market").notNull(),
35
+ currency: text("currency"),
36
+ /** Pricing breakdown — same shape as `booking_catalog_snapshot`. */
37
+ pricing_base_amount: numeric("pricing_base_amount", { precision: 18, scale: 4 }),
38
+ pricing_taxes: numeric("pricing_taxes", { precision: 18, scale: 4 }),
39
+ pricing_fees: numeric("pricing_fees", { precision: 18, scale: 4 }),
40
+ pricing_surcharges: numeric("pricing_surcharges", { precision: 18, scale: 4 }),
41
+ pricing_currency: text("pricing_currency"),
42
+ pricing_breakdown: jsonb("pricing_breakdown").$type(),
43
+ /**
44
+ * Promotional offers applied to this quote. Populated by the
45
+ * `evaluatePromotions` hook on `QuoteEntityDeps` (per
46
+ * `docs/architecture/promotions-architecture.md` §7.1.3). The
47
+ * post-commit redemption recorder reads this back via
48
+ * `consumed_booking_id` and aggregates into
49
+ * `promotional_offer_redemptions`.
50
+ *
51
+ * Dedicated column (vs. nesting in `pricing_breakdown`) so the
52
+ * dependency from the redemption recorder to this data is explicit
53
+ * at the schema level — anyone touching the quote writer sees the
54
+ * column and knows it has a downstream consumer.
55
+ */
56
+ pricing_applied_offers: jsonb("pricing_applied_offers").$type(),
57
+ /** Opaque adapter payload echoed forward into `bookEntity` if supported. */
58
+ upstream_payload: jsonb("upstream_payload"),
59
+ /**
60
+ * Set when a `bookEntity` call consumes this quote. Consumed quotes
61
+ * are kept (audit) but rejected on subsequent book calls.
62
+ */
63
+ consumed_at: timestamp("consumed_at", { withTimezone: true }),
64
+ consumed_booking_id: text("consumed_booking_id"),
65
+ created_at: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
66
+ expires_at: timestamp("expires_at", { withTimezone: true }).notNull(),
67
+ }, (table) => [
68
+ index("idx_catalog_quotes_entity").on(table.entity_module, table.entity_id),
69
+ index("idx_catalog_quotes_expires").on(table.expires_at),
70
+ index("idx_catalog_quotes_source").on(table.source_kind, table.source_ref),
71
+ // Lookup index for the post-commit redemption recorder, which scans
72
+ // for "every quote consumed by this booking" to aggregate
73
+ // `pricing_applied_offers` per offer.
74
+ index("idx_catalog_quotes_consumed_booking").on(table.consumed_booking_id),
75
+ ]);
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Snapshot content capture per sourced-content §5.1.
3
+ *
4
+ * The booking engine calls a `SnapshotContentCapturer` at commit time
5
+ * to refresh content from the adapter and embed the result in the
6
+ * snapshot's `frozen_payload.content_capture` envelope. The
7
+ * capturer's contract is "refresh-with-fallback":
8
+ *
9
+ * 1. Try to fetch fresh content from the adapter (and write through
10
+ * to the per-vertical content cache so the next read sees the
11
+ * fresh row).
12
+ * 2. On adapter error (network blip, rate limit, transient outage),
13
+ * fall back to the cache — including stale rows.
14
+ * 3. If neither is available, throw `SnapshotContentUnavailableError`.
15
+ * The booking engine propagates this and aborts the commit. We
16
+ * deliberately do NOT snapshot from the indexed projection —
17
+ * refunds and audit need real "what was sold" content, not a
18
+ * stub.
19
+ *
20
+ * The orchestrator stays in the booking-engine sub-package because the
21
+ * envelope shape, error types, and integration point all live with
22
+ * `bookEntity`. Per-vertical content services (products, cruises,
23
+ * etc.) implement `ContentSnapshotAdapter` and the template wires them
24
+ * into a single capturer via `composeSnapshotContentCapturer`.
25
+ *
26
+ * See `docs/architecture/catalog-sourced-content.md` §5.1.
27
+ */
28
+ import type { AnyDrizzleDb } from "@voyant-travel/db";
29
+ import type { GetContentRequest, GetContentResult, SourceAdapter, SourceAdapterContext } from "../adapter/contract.js";
30
+ import type { SourceAdapterRegistry } from "./registry.js";
31
+ /**
32
+ * Input the booking engine threads into the capturer. Carries the
33
+ * entity identity, the snapshot source pointer, and the locale/market
34
+ * scope from the original quote.
35
+ */
36
+ export interface SnapshotContentCaptureInput {
37
+ db: AnyDrizzleDb;
38
+ entity_module: string;
39
+ entity_id: string;
40
+ source_kind: string;
41
+ source_connection_id?: string;
42
+ source_ref?: string;
43
+ locale: string;
44
+ market?: string;
45
+ currency?: string;
46
+ adapterContext: SourceAdapterContext;
47
+ }
48
+ /**
49
+ * The envelope embedded in `frozen_payload.content_capture`. Carries
50
+ * provenance so audit can distinguish a fresh capture from a cache
51
+ * fallback later (refund flows, invoice rendering).
52
+ */
53
+ export interface SnapshotContentCapture {
54
+ source: "fresh" | "cache_fallback";
55
+ fetched_at: Date;
56
+ fallback_reason?: string;
57
+ content_etag?: string;
58
+ content_schema_version: string;
59
+ content: unknown;
60
+ }
61
+ /**
62
+ * Per-vertical adapter for snapshot capture: refresh + read-cached.
63
+ * Each vertical's content service implements this and the template
64
+ * registers them by `entity_module`. The capturer (built via
65
+ * `composeSnapshotContentCapturer`) routes calls to the right adapter.
66
+ */
67
+ export interface ContentSnapshotAdapter {
68
+ /**
69
+ * Refresh content from the upstream adapter and write through to the
70
+ * per-vertical content cache. Returns the fresh `GetContentResult`
71
+ * on success; throws on adapter error (which the orchestrator
72
+ * catches to fall back to cache).
73
+ */
74
+ refresh(db: AnyDrizzleDb, adapter: SourceAdapter, ctx: SourceAdapterContext, request: GetContentRequest): Promise<GetContentResult>;
75
+ /**
76
+ * Read the per-vertical cache row for this entity / locale / market,
77
+ * INCLUDING stale rows. Returns null if no row exists. Used as the
78
+ * fallback when `refresh` fails.
79
+ */
80
+ readCached(db: AnyDrizzleDb, request: GetContentRequest): Promise<{
81
+ payload: unknown;
82
+ content_schema_version: string;
83
+ fetched_at: Date;
84
+ etag: string | null;
85
+ } | null>;
86
+ }
87
+ /**
88
+ * The function the booking engine receives via
89
+ * `BookEntityDeps.captureSnapshotContent`. Templates implement this
90
+ * (typically via `composeSnapshotContentCapturer`) and pass the
91
+ * resulting function in.
92
+ *
93
+ * Returning `null` means "this entity has no sourced content to
94
+ * capture" (e.g. owned entities) — the engine skips the envelope and
95
+ * the snapshot keeps its legacy shape.
96
+ */
97
+ export type SnapshotContentCapturer = (input: SnapshotContentCaptureInput) => Promise<SnapshotContentCapture | null>;
98
+ /**
99
+ * Compose a `SnapshotContentCapturer` from a registry of per-vertical
100
+ * `ContentSnapshotAdapter`s and an adapter registry. Use when the
101
+ * template wants the §5.1 refresh-with-fallback behavior wired
102
+ * uniformly across verticals.
103
+ *
104
+ * Returns null when:
105
+ * - The entity_module isn't in the per-vertical adapter map
106
+ * (assumed owned or out-of-scope; engine skips the envelope).
107
+ * - The source adapter for `source_kind` doesn't implement
108
+ * `getContent` AND no cache row exists. (When `getContent` is
109
+ * missing but a cache row exists, we serve the cache row — the
110
+ * vertical's synthesizer is for read paths, not write paths.)
111
+ *
112
+ * Throws `SnapshotContentUnavailableError` when neither fresh nor
113
+ * cached content can be produced.
114
+ */
115
+ export declare function composeSnapshotContentCapturer(options: {
116
+ registry: SourceAdapterRegistry;
117
+ /** Per-vertical adapters keyed by `entity_module`. */
118
+ contentAdapters: ReadonlyMap<string, ContentSnapshotAdapter>;
119
+ }): SnapshotContentCapturer;
120
+ //# sourceMappingURL=snapshot-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-content.d.ts","sourceRoot":"","sources":["../../src/booking-engine/snapshot-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,oBAAoB,EACrB,MAAM,wBAAwB,CAAA;AAG/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAE1D;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,YAAY,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,oBAAoB,CAAA;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAAA;IAClC,UAAU,EAAE,IAAI,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,OAAO,CACL,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,aAAa,EACtB,GAAG,EAAE,oBAAoB,EACzB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC5B;;;;OAIG;IACH,UAAU,CACR,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAA;QAChB,sBAAsB,EAAE,MAAM,CAAA;QAC9B,UAAU,EAAE,IAAI,CAAA;QAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KACpB,GAAG,IAAI,CAAC,CAAA;CACV;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,2BAA2B,KAC/B,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAA;AAE3C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE;IACtD,QAAQ,EAAE,qBAAqB,CAAA;IAC/B,sDAAsD;IACtD,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAA;CAC7D,GAAG,uBAAuB,CAoD1B"}