@voyantjs/extras 0.19.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/routes.d.ts CHANGED
@@ -13,10 +13,11 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
13
13
  data: {
14
14
  id: string;
15
15
  productId: string;
16
+ supplierId: string | null;
16
17
  code: string | null;
17
18
  name: string;
18
19
  description: string | null;
19
- selectionType: "optional" | "required" | "default_selected" | "unavailable";
20
+ selectionType: "unavailable" | "optional" | "default_selected" | "required";
20
21
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
21
22
  pricedPerPerson: boolean;
22
23
  minQuantity: number | null;
@@ -44,24 +45,25 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
44
45
  input: {};
45
46
  output: {
46
47
  data: {
47
- metadata: {
48
- [x: string]: import("hono/utils/types").JSONValue;
49
- } | null;
50
48
  id: string;
51
- name: string;
49
+ code: string | null;
52
50
  createdAt: string;
53
51
  updatedAt: string;
54
- description: string | null;
55
- code: string | null;
56
- active: boolean;
57
52
  productId: string;
58
- selectionType: "optional" | "required" | "default_selected" | "unavailable";
53
+ supplierId: string | null;
54
+ name: string;
55
+ description: string | null;
56
+ selectionType: "unavailable" | "optional" | "default_selected" | "required";
59
57
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
60
58
  pricedPerPerson: boolean;
61
59
  minQuantity: number | null;
62
60
  maxQuantity: number | null;
63
61
  defaultQuantity: number | null;
62
+ active: boolean;
64
63
  sortOrder: number;
64
+ metadata: {
65
+ [x: string]: import("hono/utils/types").JSONValue;
66
+ } | null;
65
67
  } | null;
66
68
  };
67
69
  outputFormat: "json";
@@ -91,10 +93,11 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
91
93
  data: {
92
94
  id: string;
93
95
  productId: string;
96
+ supplierId: string | null;
94
97
  code: string | null;
95
98
  name: string;
96
99
  description: string | null;
97
- selectionType: "optional" | "required" | "default_selected" | "unavailable";
100
+ selectionType: "unavailable" | "optional" | "default_selected" | "required";
98
101
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
99
102
  pricedPerPerson: boolean;
100
103
  minQuantity: number | null;
@@ -136,10 +139,11 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
136
139
  data: {
137
140
  id: string;
138
141
  productId: string;
142
+ supplierId: string | null;
139
143
  code: string | null;
140
144
  name: string;
141
145
  description: string | null;
142
- selectionType: "optional" | "required" | "default_selected" | "unavailable";
146
+ selectionType: "unavailable" | "optional" | "default_selected" | "required";
143
147
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
144
148
  pricedPerPerson: boolean;
145
149
  minQuantity: number | null;
@@ -193,7 +197,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
193
197
  id: string;
194
198
  optionId: string;
195
199
  productExtraId: string;
196
- selectionType: "optional" | "required" | "default_selected" | "unavailable" | null;
200
+ selectionType: "unavailable" | "optional" | "default_selected" | "required" | null;
197
201
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free" | null;
198
202
  pricedPerPerson: boolean | null;
199
203
  minQuantity: number | null;
@@ -223,21 +227,21 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
223
227
  input: {};
224
228
  output: {
225
229
  data: {
226
- metadata: {
227
- [x: string]: import("hono/utils/types").JSONValue;
228
- } | null;
229
230
  id: string;
230
231
  createdAt: string;
231
232
  updatedAt: string;
232
- notes: string | null;
233
- active: boolean;
234
- selectionType: "optional" | "required" | "default_selected" | "unavailable" | null;
233
+ selectionType: "unavailable" | "optional" | "default_selected" | "required" | null;
235
234
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free" | null;
236
235
  pricedPerPerson: boolean | null;
237
236
  minQuantity: number | null;
238
237
  maxQuantity: number | null;
239
238
  defaultQuantity: number | null;
239
+ active: boolean;
240
240
  sortOrder: number;
241
+ metadata: {
242
+ [x: string]: import("hono/utils/types").JSONValue;
243
+ } | null;
244
+ notes: string | null;
241
245
  optionId: string;
242
246
  productExtraId: string;
243
247
  isDefault: boolean;
@@ -271,7 +275,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
271
275
  id: string;
272
276
  optionId: string;
273
277
  productExtraId: string;
274
- selectionType: "optional" | "required" | "default_selected" | "unavailable" | null;
278
+ selectionType: "unavailable" | "optional" | "default_selected" | "required" | null;
275
279
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free" | null;
276
280
  pricedPerPerson: boolean | null;
277
281
  minQuantity: number | null;
@@ -316,7 +320,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
316
320
  id: string;
317
321
  optionId: string;
318
322
  productExtraId: string;
319
- selectionType: "optional" | "required" | "default_selected" | "unavailable" | null;
323
+ selectionType: "unavailable" | "optional" | "default_selected" | "required" | null;
320
324
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free" | null;
321
325
  pricedPerPerson: boolean | null;
322
326
  minQuantity: number | null;
@@ -375,7 +379,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
375
379
  optionExtraConfigId: string | null;
376
380
  name: string;
377
381
  description: string | null;
378
- status: "draft" | "selected" | "confirmed" | "cancelled" | "fulfilled";
382
+ status: "confirmed" | "cancelled" | "draft" | "selected" | "fulfilled";
379
383
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
380
384
  pricedPerPerson: boolean;
381
385
  quantity: number;
@@ -406,22 +410,22 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
406
410
  input: {};
407
411
  output: {
408
412
  data: {
409
- metadata: {
410
- [x: string]: import("hono/utils/types").JSONValue;
411
- } | null;
412
413
  id: string;
413
- name: string;
414
414
  createdAt: string;
415
415
  updatedAt: string;
416
- status: "draft" | "selected" | "confirmed" | "cancelled" | "fulfilled";
417
- notes: string | null;
416
+ name: string;
418
417
  description: string | null;
419
- bookingId: string;
420
418
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
421
419
  pricedPerPerson: boolean;
420
+ status: "confirmed" | "cancelled" | "draft" | "selected" | "fulfilled";
421
+ metadata: {
422
+ [x: string]: import("hono/utils/types").JSONValue;
423
+ } | null;
424
+ bookingId: string;
425
+ quantity: number;
426
+ notes: string | null;
422
427
  productExtraId: string | null;
423
428
  optionExtraConfigId: string | null;
424
- quantity: number;
425
429
  sellCurrency: string;
426
430
  unitSellAmountCents: number | null;
427
431
  totalSellAmountCents: number | null;
@@ -461,7 +465,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
461
465
  optionExtraConfigId: string | null;
462
466
  name: string;
463
467
  description: string | null;
464
- status: "draft" | "selected" | "confirmed" | "cancelled" | "fulfilled";
468
+ status: "confirmed" | "cancelled" | "draft" | "selected" | "fulfilled";
465
469
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
466
470
  pricedPerPerson: boolean;
467
471
  quantity: number;
@@ -510,7 +514,7 @@ export declare const extrasRoutes: import("hono/hono-base").HonoBase<Env, {
510
514
  optionExtraConfigId: string | null;
511
515
  name: string;
512
516
  description: string | null;
513
- status: "draft" | "selected" | "confirmed" | "cancelled" | "fulfilled";
517
+ status: "confirmed" | "cancelled" | "draft" | "selected" | "fulfilled";
514
518
  pricingMode: "included" | "per_person" | "per_booking" | "quantity_based" | "on_request" | "free";
515
519
  pricedPerPerson: boolean;
516
520
  quantity: number;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAgBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGrB,CAAA;AAEJ,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAA"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAgBjE,KAAK,GAAG,GAAG;IACT,SAAS,EAAE;QACT,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGrB,CAAA;AAEJ,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAA"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Extras sourced-content cache. Sibling to the products / cruises /
3
+ * hospitality / charters variants — same shape, different vertical.
4
+ *
5
+ * One row per sourced extra × locale × market. Stores the content the
6
+ * upstream adapter served via `getContent`, plus the SWR metadata the
7
+ * read service needs.
8
+ *
9
+ * Extras are booking add-ons (optional line items layered on a parent
10
+ * product). Per `catalog-policy.ts`, extras are a partial-adoption
11
+ * vertical: they don't appear in the search index, but sourced extras
12
+ * (e.g. a TUI excursion add-on) still need rich content for the
13
+ * booking-flow's add-on selection UI. The sourced-content cache covers
14
+ * exactly that surface.
15
+ *
16
+ * See `docs/architecture/catalog-sourced-content.md` §3.2.
17
+ */
18
+ export type ExtrasSourcedContentFetchStatus = "ok" | "stale" | "error" | "unsupported";
19
+ export declare const EXTRAS_CONTENT_MARKET_ANY = "*";
20
+ export declare const extrasSourcedContentTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
21
+ name: "extras_sourced_content";
22
+ schema: undefined;
23
+ columns: {
24
+ entity_id: import("drizzle-orm/pg-core").PgColumn<{
25
+ name: "entity_id";
26
+ tableName: "extras_sourced_content";
27
+ dataType: "string";
28
+ columnType: "PgText";
29
+ data: string;
30
+ driverParam: string;
31
+ notNull: true;
32
+ hasDefault: false;
33
+ isPrimaryKey: false;
34
+ isAutoincrement: false;
35
+ hasRuntimeDefault: false;
36
+ enumValues: [string, ...string[]];
37
+ baseColumn: never;
38
+ identity: undefined;
39
+ generated: undefined;
40
+ }, {}, {}>;
41
+ locale: import("drizzle-orm/pg-core").PgColumn<{
42
+ name: "locale";
43
+ tableName: "extras_sourced_content";
44
+ dataType: "string";
45
+ columnType: "PgText";
46
+ data: string;
47
+ driverParam: string;
48
+ notNull: true;
49
+ hasDefault: false;
50
+ isPrimaryKey: false;
51
+ isAutoincrement: false;
52
+ hasRuntimeDefault: false;
53
+ enumValues: [string, ...string[]];
54
+ baseColumn: never;
55
+ identity: undefined;
56
+ generated: undefined;
57
+ }, {}, {}>;
58
+ market: import("drizzle-orm/pg-core").PgColumn<{
59
+ name: "market";
60
+ tableName: "extras_sourced_content";
61
+ dataType: "string";
62
+ columnType: "PgText";
63
+ data: string;
64
+ driverParam: string;
65
+ notNull: true;
66
+ hasDefault: true;
67
+ isPrimaryKey: false;
68
+ isAutoincrement: false;
69
+ hasRuntimeDefault: false;
70
+ enumValues: [string, ...string[]];
71
+ baseColumn: never;
72
+ identity: undefined;
73
+ generated: undefined;
74
+ }, {}, {}>;
75
+ payload: import("drizzle-orm/pg-core").PgColumn<{
76
+ name: "payload";
77
+ tableName: "extras_sourced_content";
78
+ dataType: "json";
79
+ columnType: "PgJsonb";
80
+ data: Record<string, unknown>;
81
+ driverParam: unknown;
82
+ notNull: true;
83
+ hasDefault: false;
84
+ isPrimaryKey: false;
85
+ isAutoincrement: false;
86
+ hasRuntimeDefault: false;
87
+ enumValues: undefined;
88
+ baseColumn: never;
89
+ identity: undefined;
90
+ generated: undefined;
91
+ }, {}, {
92
+ $type: Record<string, unknown>;
93
+ }>;
94
+ content_schema_version: import("drizzle-orm/pg-core").PgColumn<{
95
+ name: "content_schema_version";
96
+ tableName: "extras_sourced_content";
97
+ dataType: "string";
98
+ columnType: "PgText";
99
+ data: string;
100
+ driverParam: string;
101
+ notNull: true;
102
+ hasDefault: false;
103
+ isPrimaryKey: false;
104
+ isAutoincrement: false;
105
+ hasRuntimeDefault: false;
106
+ enumValues: [string, ...string[]];
107
+ baseColumn: never;
108
+ identity: undefined;
109
+ generated: undefined;
110
+ }, {}, {}>;
111
+ returned_locale: import("drizzle-orm/pg-core").PgColumn<{
112
+ name: "returned_locale";
113
+ tableName: "extras_sourced_content";
114
+ dataType: "string";
115
+ columnType: "PgText";
116
+ data: string;
117
+ driverParam: string;
118
+ notNull: true;
119
+ hasDefault: false;
120
+ isPrimaryKey: false;
121
+ isAutoincrement: false;
122
+ hasRuntimeDefault: false;
123
+ enumValues: [string, ...string[]];
124
+ baseColumn: never;
125
+ identity: undefined;
126
+ generated: undefined;
127
+ }, {}, {}>;
128
+ machine_translated: import("drizzle-orm/pg-core").PgColumn<{
129
+ name: "machine_translated";
130
+ tableName: "extras_sourced_content";
131
+ dataType: "boolean";
132
+ columnType: "PgBoolean";
133
+ data: boolean;
134
+ driverParam: boolean;
135
+ notNull: true;
136
+ hasDefault: true;
137
+ isPrimaryKey: false;
138
+ isAutoincrement: false;
139
+ hasRuntimeDefault: false;
140
+ enumValues: undefined;
141
+ baseColumn: never;
142
+ identity: undefined;
143
+ generated: undefined;
144
+ }, {}, {}>;
145
+ source_updated_at: import("drizzle-orm/pg-core").PgColumn<{
146
+ name: "source_updated_at";
147
+ tableName: "extras_sourced_content";
148
+ dataType: "date";
149
+ columnType: "PgTimestamp";
150
+ data: Date;
151
+ driverParam: string;
152
+ notNull: false;
153
+ hasDefault: false;
154
+ isPrimaryKey: false;
155
+ isAutoincrement: false;
156
+ hasRuntimeDefault: false;
157
+ enumValues: undefined;
158
+ baseColumn: never;
159
+ identity: undefined;
160
+ generated: undefined;
161
+ }, {}, {}>;
162
+ fetched_at: import("drizzle-orm/pg-core").PgColumn<{
163
+ name: "fetched_at";
164
+ tableName: "extras_sourced_content";
165
+ dataType: "date";
166
+ columnType: "PgTimestamp";
167
+ data: Date;
168
+ driverParam: string;
169
+ notNull: true;
170
+ hasDefault: true;
171
+ isPrimaryKey: false;
172
+ isAutoincrement: false;
173
+ hasRuntimeDefault: false;
174
+ enumValues: undefined;
175
+ baseColumn: never;
176
+ identity: undefined;
177
+ generated: undefined;
178
+ }, {}, {}>;
179
+ fresh_until: import("drizzle-orm/pg-core").PgColumn<{
180
+ name: "fresh_until";
181
+ tableName: "extras_sourced_content";
182
+ dataType: "date";
183
+ columnType: "PgTimestamp";
184
+ data: Date;
185
+ driverParam: string;
186
+ notNull: false;
187
+ hasDefault: false;
188
+ isPrimaryKey: false;
189
+ isAutoincrement: false;
190
+ hasRuntimeDefault: false;
191
+ enumValues: undefined;
192
+ baseColumn: never;
193
+ identity: undefined;
194
+ generated: undefined;
195
+ }, {}, {}>;
196
+ etag: import("drizzle-orm/pg-core").PgColumn<{
197
+ name: "etag";
198
+ tableName: "extras_sourced_content";
199
+ dataType: "string";
200
+ columnType: "PgText";
201
+ data: string;
202
+ driverParam: string;
203
+ notNull: false;
204
+ hasDefault: false;
205
+ isPrimaryKey: false;
206
+ isAutoincrement: false;
207
+ hasRuntimeDefault: false;
208
+ enumValues: [string, ...string[]];
209
+ baseColumn: never;
210
+ identity: undefined;
211
+ generated: undefined;
212
+ }, {}, {}>;
213
+ fetch_status: import("drizzle-orm/pg-core").PgColumn<{
214
+ name: "fetch_status";
215
+ tableName: "extras_sourced_content";
216
+ dataType: "string";
217
+ columnType: "PgText";
218
+ data: ExtrasSourcedContentFetchStatus;
219
+ driverParam: string;
220
+ notNull: true;
221
+ hasDefault: true;
222
+ isPrimaryKey: false;
223
+ isAutoincrement: false;
224
+ hasRuntimeDefault: false;
225
+ enumValues: [string, ...string[]];
226
+ baseColumn: never;
227
+ identity: undefined;
228
+ generated: undefined;
229
+ }, {}, {
230
+ $type: ExtrasSourcedContentFetchStatus;
231
+ }>;
232
+ fetch_error: import("drizzle-orm/pg-core").PgColumn<{
233
+ name: "fetch_error";
234
+ tableName: "extras_sourced_content";
235
+ dataType: "string";
236
+ columnType: "PgText";
237
+ data: string;
238
+ driverParam: string;
239
+ notNull: false;
240
+ hasDefault: false;
241
+ isPrimaryKey: false;
242
+ isAutoincrement: false;
243
+ hasRuntimeDefault: false;
244
+ enumValues: [string, ...string[]];
245
+ baseColumn: never;
246
+ identity: undefined;
247
+ generated: undefined;
248
+ }, {}, {}>;
249
+ };
250
+ dialect: "pg";
251
+ }>;
252
+ export type InsertExtrasSourcedContent = typeof extrasSourcedContentTable.$inferInsert;
253
+ export type SelectExtrasSourcedContent = typeof extrasSourcedContentTable.$inferSelect;
254
+ //# sourceMappingURL=schema-sourced-content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-sourced-content.d.ts","sourceRoot":"","sources":["../src/schema-sourced-content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,MAAM,+BAA+B,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAA;AAEtF,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAE5C,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCrC,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,OAAO,yBAAyB,CAAC,YAAY,CAAA;AACtF,MAAM,MAAM,0BAA0B,GAAG,OAAO,yBAAyB,CAAC,YAAY,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Extras sourced-content cache. Sibling to the products / cruises /
3
+ * hospitality / charters variants — same shape, different vertical.
4
+ *
5
+ * One row per sourced extra × locale × market. Stores the content the
6
+ * upstream adapter served via `getContent`, plus the SWR metadata the
7
+ * read service needs.
8
+ *
9
+ * Extras are booking add-ons (optional line items layered on a parent
10
+ * product). Per `catalog-policy.ts`, extras are a partial-adoption
11
+ * vertical: they don't appear in the search index, but sourced extras
12
+ * (e.g. a TUI excursion add-on) still need rich content for the
13
+ * booking-flow's add-on selection UI. The sourced-content cache covers
14
+ * exactly that surface.
15
+ *
16
+ * See `docs/architecture/catalog-sourced-content.md` §3.2.
17
+ */
18
+ import { boolean, index, jsonb, pgTable, primaryKey, text, timestamp } from "drizzle-orm/pg-core";
19
+ export const EXTRAS_CONTENT_MARKET_ANY = "*";
20
+ export const extrasSourcedContentTable = pgTable("extras_sourced_content", {
21
+ /** TypeID matching the extras module — `pxtr_*` (product_extras). */
22
+ entity_id: text("entity_id").notNull(),
23
+ /** BCP 47 language tag. */
24
+ locale: text("locale").notNull(),
25
+ /** Market id, or `'*'` for all-markets. */
26
+ market: text("market").notNull().default(EXTRAS_CONTENT_MARKET_ANY),
27
+ payload: jsonb("payload").$type().notNull(),
28
+ content_schema_version: text("content_schema_version").notNull(),
29
+ returned_locale: text("returned_locale").notNull(),
30
+ machine_translated: boolean("machine_translated").notNull().default(false),
31
+ source_updated_at: timestamp("source_updated_at", { withTimezone: true }),
32
+ fetched_at: timestamp("fetched_at", { withTimezone: true }).notNull().defaultNow(),
33
+ fresh_until: timestamp("fresh_until", { withTimezone: true }),
34
+ etag: text("etag"),
35
+ fetch_status: text("fetch_status")
36
+ .$type()
37
+ .notNull()
38
+ .default("ok"),
39
+ fetch_error: text("fetch_error"),
40
+ }, (table) => [
41
+ primaryKey({ columns: [table.entity_id, table.locale, table.market] }),
42
+ index("extras_sourced_content_locale_fresh_idx").on(table.locale, table.fresh_until),
43
+ index("extras_sourced_content_returned_locale_idx").on(table.entity_id, table.returned_locale),
44
+ index("extras_sourced_content_schema_version_idx").on(table.content_schema_version),
45
+ ]);
package/dist/schema.d.ts CHANGED
@@ -39,6 +39,23 @@ export declare const productExtras: import("drizzle-orm/pg-core").PgTableWithCol
39
39
  identity: undefined;
40
40
  generated: undefined;
41
41
  }, {}, {}>;
42
+ supplierId: import("drizzle-orm/pg-core").PgColumn<{
43
+ name: "supplier_id";
44
+ tableName: "product_extras";
45
+ dataType: "string";
46
+ columnType: "PgText";
47
+ data: string;
48
+ driverParam: string;
49
+ notNull: false;
50
+ hasDefault: false;
51
+ isPrimaryKey: false;
52
+ isAutoincrement: false;
53
+ hasRuntimeDefault: false;
54
+ enumValues: [string, ...string[]];
55
+ baseColumn: never;
56
+ identity: undefined;
57
+ generated: undefined;
58
+ }, {}, {}>;
42
59
  code: import("drizzle-orm/pg-core").PgColumn<{
43
60
  name: "code";
44
61
  tableName: "product_extras";
@@ -95,7 +112,7 @@ export declare const productExtras: import("drizzle-orm/pg-core").PgTableWithCol
95
112
  tableName: "product_extras";
96
113
  dataType: "string";
97
114
  columnType: "PgEnumColumn";
98
- data: "optional" | "required" | "default_selected" | "unavailable";
115
+ data: "unavailable" | "optional" | "default_selected" | "required";
99
116
  driverParam: string;
100
117
  notNull: true;
101
118
  hasDefault: true;
@@ -342,7 +359,7 @@ export declare const optionExtraConfigs: import("drizzle-orm/pg-core").PgTableWi
342
359
  tableName: "option_extra_configs";
343
360
  dataType: "string";
344
361
  columnType: "PgEnumColumn";
345
- data: "optional" | "required" | "default_selected" | "unavailable";
362
+ data: "unavailable" | "optional" | "default_selected" | "required";
346
363
  driverParam: string;
347
364
  notNull: false;
348
365
  hasDefault: false;
@@ -674,7 +691,7 @@ export declare const bookingExtras: import("drizzle-orm/pg-core").PgTableWithCol
674
691
  tableName: "booking_extras";
675
692
  dataType: "string";
676
693
  columnType: "PgEnumColumn";
677
- data: "draft" | "selected" | "confirmed" | "cancelled" | "fulfilled";
694
+ data: "confirmed" | "cancelled" | "draft" | "selected" | "fulfilled";
678
695
  driverParam: string;
679
696
  notNull: true;
680
697
  hasDefault: true;
@@ -930,4 +947,5 @@ export declare const bookingExtrasRelations: import("drizzle-orm").Relations<"bo
930
947
  productExtra: import("drizzle-orm").One<"product_extras", false>;
931
948
  optionExtraConfig: import("drizzle-orm").One<"option_extra_configs", false>;
932
949
  }>;
950
+ export { EXTRAS_CONTENT_MARKET_ANY, type ExtrasSourcedContentFetchStatus, extrasSourcedContentTable, type InsertExtrasSourcedContent, type SelectExtrasSourcedContent, } from "./schema-sourced-content.js";
933
951
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,sBAAsB,mGAKjC,CAAA;AAEF,eAAO,MAAM,oBAAoB,yHAO/B,CAAA;AAEF,eAAO,MAAM,sBAAsB,oGAMjC,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BzB,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC9B,CAAA;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCzB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,iBAAiB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACzE,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAE/D,eAAO,MAAM,sBAAsB;;;EAGhC,CAAA;AAEH,eAAO,MAAM,2BAA2B;;;EAMrC,CAAA;AAEH,eAAO,MAAM,sBAAsB;;;EAShC,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,sBAAsB,mGAKjC,CAAA;AAEF,eAAO,MAAM,oBAAoB,yHAO/B,CAAA;AAEF,eAAO,MAAM,sBAAsB,oGAMjC,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCzB,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC9B,CAAA;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyCzB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC/D,MAAM,MAAM,iBAAiB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACzE,MAAM,MAAM,YAAY,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,aAAa,CAAC,YAAY,CAAA;AAE/D,eAAO,MAAM,sBAAsB;;;EAGhC,CAAA;AAEH,eAAO,MAAM,2BAA2B;;;EAMrC,CAAA;AAEH,eAAO,MAAM,sBAAsB;;;EAShC,CAAA;AAKH,OAAO,EACL,yBAAyB,EACzB,KAAK,+BAA+B,EACpC,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,GAChC,MAAM,6BAA6B,CAAA"}
package/dist/schema.js CHANGED
@@ -25,6 +25,7 @@ export const bookingExtraStatusEnum = pgEnum("booking_extra_status", [
25
25
  export const productExtras = pgTable("product_extras", {
26
26
  id: typeId("product_extras"),
27
27
  productId: text("product_id").notNull(),
28
+ supplierId: text("supplier_id"),
28
29
  code: text("code"),
29
30
  name: text("name").notNull(),
30
31
  description: text("description"),
@@ -42,6 +43,7 @@ export const productExtras = pgTable("product_extras", {
42
43
  }, (table) => [
43
44
  index("idx_product_extras_sort_name").on(table.sortOrder, table.name),
44
45
  index("idx_product_extras_product_sort_name").on(table.productId, table.sortOrder, table.name),
46
+ index("idx_product_extras_supplier_sort_name").on(table.supplierId, table.sortOrder, table.name),
45
47
  index("idx_product_extras_active_sort_name").on(table.active, table.sortOrder, table.name),
46
48
  uniqueIndex("uidx_product_extras_product_code").on(table.productId, table.code),
47
49
  ]);
@@ -124,3 +126,7 @@ export const bookingExtrasRelations = relations(bookingExtras, ({ one }) => ({
124
126
  references: [optionExtraConfigs.id],
125
127
  }),
126
128
  }));
129
+ // ─── Sourced-content cache ──────────────────────────────────────────
130
+ // Re-exported here so templates pick it up via the package's `./schema`
131
+ // entry without needing a separate config entry.
132
+ export { EXTRAS_CONTENT_MARKET_ANY, extrasSourcedContentTable, } from "./schema-sourced-content.js";