@voyantjs/products 0.20.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/booking-engine/handler.d.ts +203 -0
- package/dist/booking-engine/handler.d.ts.map +1 -0
- package/dist/booking-engine/handler.js +330 -0
- package/dist/booking-engine/index.d.ts +8 -0
- package/dist/booking-engine/index.d.ts.map +1 -0
- package/dist/booking-engine/index.js +7 -0
- package/dist/catalog-policy.d.ts.map +1 -1
- package/dist/catalog-policy.js +15 -1
- package/dist/content-shape.d.ts +217 -0
- package/dist/content-shape.d.ts.map +1 -0
- package/dist/content-shape.js +159 -0
- package/dist/draft-shape.d.ts +43 -0
- package/dist/draft-shape.d.ts.map +1 -0
- package/dist/draft-shape.js +46 -0
- package/dist/events.d.ts +37 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +32 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/routes-content.d.ts +74 -0
- package/dist/routes-content.d.ts.map +1 -0
- package/dist/routes-content.js +117 -0
- package/dist/routes.d.ts +40 -20
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +83 -13
- package/dist/schema-core.d.ts +240 -1
- package/dist/schema-core.d.ts.map +1 -1
- package/dist/schema-core.js +49 -0
- package/dist/schema-itinerary.d.ts +18 -1
- package/dist/schema-itinerary.d.ts.map +1 -1
- package/dist/schema-itinerary.js +1 -0
- package/dist/schema-settings.d.ts +1 -1
- package/dist/schema-sourced-content.d.ts +262 -0
- package/dist/schema-sourced-content.d.ts.map +1 -0
- package/dist/schema-sourced-content.js +69 -0
- package/dist/schema-taxonomy.d.ts +17 -0
- package/dist/schema-taxonomy.d.ts.map +1 -1
- package/dist/schema-taxonomy.js +13 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +1 -0
- package/dist/service-catalog-plane.d.ts.map +1 -1
- package/dist/service-catalog-plane.js +1 -0
- package/dist/service-content-owned.d.ts +68 -0
- package/dist/service-content-owned.d.ts.map +1 -0
- package/dist/service-content-owned.js +224 -0
- package/dist/service-content-synthesizer.d.ts +90 -0
- package/dist/service-content-synthesizer.d.ts.map +1 -0
- package/dist/service-content-synthesizer.js +171 -0
- package/dist/service-content.d.ts +106 -0
- package/dist/service-content.d.ts.map +1 -0
- package/dist/service-content.js +365 -0
- package/dist/service.d.ts +76 -22
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +4 -0
- package/dist/tasks/brochures.d.ts +1 -0
- package/dist/tasks/brochures.d.ts.map +1 -1
- package/dist/tasks/brochures.js +3 -0
- package/dist/validation-catalog.d.ts +4 -4
- package/dist/validation-config.d.ts +3 -3
- package/dist/validation-content.d.ts +34 -4
- package/dist/validation-content.d.ts.map +1 -1
- package/dist/validation-content.js +13 -0
- package/dist/validation-core.d.ts +53 -3
- package/dist/validation-core.d.ts.map +1 -1
- package/dist/validation-core.js +16 -0
- package/dist/validation-public.d.ts +9 -9
- package/dist/validation-shared.d.ts +4 -4
- package/package.json +12 -7
|
@@ -331,7 +331,7 @@ export declare const productDayServices: import("drizzle-orm/pg-core").PgTableWi
|
|
|
331
331
|
tableName: "product_day_services";
|
|
332
332
|
dataType: "string";
|
|
333
333
|
columnType: "PgEnumColumn";
|
|
334
|
-
data: "other" | "
|
|
334
|
+
data: "other" | "accommodation" | "transfer" | "experience" | "guide" | "meal";
|
|
335
335
|
driverParam: string;
|
|
336
336
|
notNull: true;
|
|
337
337
|
hasDefault: false;
|
|
@@ -377,6 +377,23 @@ export declare const productDayServices: import("drizzle-orm/pg-core").PgTableWi
|
|
|
377
377
|
identity: undefined;
|
|
378
378
|
generated: undefined;
|
|
379
379
|
}, {}, {}>;
|
|
380
|
+
countryCode: import("drizzle-orm/pg-core").PgColumn<{
|
|
381
|
+
name: "country_code";
|
|
382
|
+
tableName: "product_day_services";
|
|
383
|
+
dataType: "string";
|
|
384
|
+
columnType: "PgText";
|
|
385
|
+
data: string;
|
|
386
|
+
driverParam: string;
|
|
387
|
+
notNull: false;
|
|
388
|
+
hasDefault: false;
|
|
389
|
+
isPrimaryKey: false;
|
|
390
|
+
isAutoincrement: false;
|
|
391
|
+
hasRuntimeDefault: false;
|
|
392
|
+
enumValues: [string, ...string[]];
|
|
393
|
+
baseColumn: never;
|
|
394
|
+
identity: undefined;
|
|
395
|
+
generated: undefined;
|
|
396
|
+
}, {}, {}>;
|
|
380
397
|
costCurrency: import("drizzle-orm/pg-core").PgColumn<{
|
|
381
398
|
name: "cost_currency";
|
|
382
399
|
tableName: "product_day_services";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-itinerary.d.ts","sourceRoot":"","sources":["../src/schema-itinerary.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyB9B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACrE,MAAM,MAAM,mBAAmB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AAExE,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBvB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AAE3D,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"schema-itinerary.d.ts","sourceRoot":"","sources":["../src/schema-itinerary.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyB9B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACrE,MAAM,MAAM,mBAAmB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AAExE,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBvB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AAE3D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwB9B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AACtE,MAAM,MAAM,oBAAoB,GAAG,OAAO,kBAAkB,CAAC,YAAY,CAAA;AAEzE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB3B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,eAAe,CAAC,YAAY,CAAA;AAChE,MAAM,MAAM,iBAAiB,GAAG,OAAO,eAAe,CAAC,YAAY,CAAA;AAEnE,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAE7D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDxB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC3D,MAAM,MAAM,eAAe,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA"}
|
package/dist/schema-itinerary.js
CHANGED
|
@@ -45,6 +45,7 @@ export const productDayServices = pgTable("product_day_services", {
|
|
|
45
45
|
serviceType: serviceTypeEnum("service_type").notNull(),
|
|
46
46
|
name: text("name").notNull(),
|
|
47
47
|
description: text("description"),
|
|
48
|
+
countryCode: text("country_code"),
|
|
48
49
|
costCurrency: text("cost_currency").notNull(),
|
|
49
50
|
costAmountCents: integer("cost_amount_cents").notNull(),
|
|
50
51
|
quantity: integer("quantity").notNull().default(1),
|
|
@@ -521,7 +521,7 @@ export declare const productCapabilities: import("drizzle-orm/pg-core").PgTableW
|
|
|
521
521
|
tableName: "product_capabilities";
|
|
522
522
|
dataType: "string";
|
|
523
523
|
columnType: "PgEnumColumn";
|
|
524
|
-
data: "on_request" | "private" | "instant_confirmation" | "pickup_available" | "dropoff_available" | "guided" | "shared" | "digital_ticket" | "voucher_required" | "external_inventory" | "multi_day" | "
|
|
524
|
+
data: "accommodation" | "on_request" | "private" | "instant_confirmation" | "pickup_available" | "dropoff_available" | "guided" | "shared" | "digital_ticket" | "voucher_required" | "external_inventory" | "multi_day" | "transport";
|
|
525
525
|
driverParam: string;
|
|
526
526
|
notNull: true;
|
|
527
527
|
hasDefault: false;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Products sourced-content cache.
|
|
3
|
+
*
|
|
4
|
+
* One row per sourced product × locale × market. Stores the rich
|
|
5
|
+
* detail-page content the upstream adapter served via `getContent`, plus
|
|
6
|
+
* the SWR metadata the read service needs (TTL, ETag, fetch status,
|
|
7
|
+
* locale fallback bookkeeping).
|
|
8
|
+
*
|
|
9
|
+
* Locale-keyed (per-locale rows, not one JSONB-of-locales) so
|
|
10
|
+
* per-locale TTLs, per-locale fetch failures, "what's missing in ro-RO?"
|
|
11
|
+
* SQL queries, and per-locale invalidation on drift all stay simple.
|
|
12
|
+
*
|
|
13
|
+
* See `docs/architecture/catalog-sourced-content.md` §3.2.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Lifecycle status per cache row. Distinct from sourced-entry lifecycle
|
|
17
|
+
* (which tracks whether the upstream still advertises the entity);
|
|
18
|
+
* `fetch_status` tracks the last cache fetch attempt for one
|
|
19
|
+
* (entity, locale, market) tuple.
|
|
20
|
+
*/
|
|
21
|
+
export type ProductsSourcedContentFetchStatus = "ok" | "stale" | "error" | "unsupported";
|
|
22
|
+
/**
|
|
23
|
+
* Sentinel value for the `market` column when an adapter is not
|
|
24
|
+
* market-sensitive. The value `'*'` is the all-markets row; other
|
|
25
|
+
* values are specific markets the adapter served content for.
|
|
26
|
+
*/
|
|
27
|
+
export declare const PRODUCTS_CONTENT_MARKET_ANY = "*";
|
|
28
|
+
export declare const productsSourcedContentTable: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
29
|
+
name: "products_sourced_content";
|
|
30
|
+
schema: undefined;
|
|
31
|
+
columns: {
|
|
32
|
+
entity_id: import("drizzle-orm/pg-core").PgColumn<{
|
|
33
|
+
name: "entity_id";
|
|
34
|
+
tableName: "products_sourced_content";
|
|
35
|
+
dataType: "string";
|
|
36
|
+
columnType: "PgText";
|
|
37
|
+
data: string;
|
|
38
|
+
driverParam: string;
|
|
39
|
+
notNull: true;
|
|
40
|
+
hasDefault: false;
|
|
41
|
+
isPrimaryKey: false;
|
|
42
|
+
isAutoincrement: false;
|
|
43
|
+
hasRuntimeDefault: false;
|
|
44
|
+
enumValues: [string, ...string[]];
|
|
45
|
+
baseColumn: never;
|
|
46
|
+
identity: undefined;
|
|
47
|
+
generated: undefined;
|
|
48
|
+
}, {}, {}>;
|
|
49
|
+
locale: import("drizzle-orm/pg-core").PgColumn<{
|
|
50
|
+
name: "locale";
|
|
51
|
+
tableName: "products_sourced_content";
|
|
52
|
+
dataType: "string";
|
|
53
|
+
columnType: "PgText";
|
|
54
|
+
data: string;
|
|
55
|
+
driverParam: string;
|
|
56
|
+
notNull: true;
|
|
57
|
+
hasDefault: false;
|
|
58
|
+
isPrimaryKey: false;
|
|
59
|
+
isAutoincrement: false;
|
|
60
|
+
hasRuntimeDefault: false;
|
|
61
|
+
enumValues: [string, ...string[]];
|
|
62
|
+
baseColumn: never;
|
|
63
|
+
identity: undefined;
|
|
64
|
+
generated: undefined;
|
|
65
|
+
}, {}, {}>;
|
|
66
|
+
market: import("drizzle-orm/pg-core").PgColumn<{
|
|
67
|
+
name: "market";
|
|
68
|
+
tableName: "products_sourced_content";
|
|
69
|
+
dataType: "string";
|
|
70
|
+
columnType: "PgText";
|
|
71
|
+
data: string;
|
|
72
|
+
driverParam: string;
|
|
73
|
+
notNull: true;
|
|
74
|
+
hasDefault: true;
|
|
75
|
+
isPrimaryKey: false;
|
|
76
|
+
isAutoincrement: false;
|
|
77
|
+
hasRuntimeDefault: false;
|
|
78
|
+
enumValues: [string, ...string[]];
|
|
79
|
+
baseColumn: never;
|
|
80
|
+
identity: undefined;
|
|
81
|
+
generated: undefined;
|
|
82
|
+
}, {}, {}>;
|
|
83
|
+
payload: import("drizzle-orm/pg-core").PgColumn<{
|
|
84
|
+
name: "payload";
|
|
85
|
+
tableName: "products_sourced_content";
|
|
86
|
+
dataType: "json";
|
|
87
|
+
columnType: "PgJsonb";
|
|
88
|
+
data: Record<string, unknown>;
|
|
89
|
+
driverParam: unknown;
|
|
90
|
+
notNull: true;
|
|
91
|
+
hasDefault: false;
|
|
92
|
+
isPrimaryKey: false;
|
|
93
|
+
isAutoincrement: false;
|
|
94
|
+
hasRuntimeDefault: false;
|
|
95
|
+
enumValues: undefined;
|
|
96
|
+
baseColumn: never;
|
|
97
|
+
identity: undefined;
|
|
98
|
+
generated: undefined;
|
|
99
|
+
}, {}, {
|
|
100
|
+
$type: Record<string, unknown>;
|
|
101
|
+
}>;
|
|
102
|
+
content_schema_version: import("drizzle-orm/pg-core").PgColumn<{
|
|
103
|
+
name: "content_schema_version";
|
|
104
|
+
tableName: "products_sourced_content";
|
|
105
|
+
dataType: "string";
|
|
106
|
+
columnType: "PgText";
|
|
107
|
+
data: string;
|
|
108
|
+
driverParam: string;
|
|
109
|
+
notNull: true;
|
|
110
|
+
hasDefault: false;
|
|
111
|
+
isPrimaryKey: false;
|
|
112
|
+
isAutoincrement: false;
|
|
113
|
+
hasRuntimeDefault: false;
|
|
114
|
+
enumValues: [string, ...string[]];
|
|
115
|
+
baseColumn: never;
|
|
116
|
+
identity: undefined;
|
|
117
|
+
generated: undefined;
|
|
118
|
+
}, {}, {}>;
|
|
119
|
+
returned_locale: import("drizzle-orm/pg-core").PgColumn<{
|
|
120
|
+
name: "returned_locale";
|
|
121
|
+
tableName: "products_sourced_content";
|
|
122
|
+
dataType: "string";
|
|
123
|
+
columnType: "PgText";
|
|
124
|
+
data: string;
|
|
125
|
+
driverParam: string;
|
|
126
|
+
notNull: true;
|
|
127
|
+
hasDefault: false;
|
|
128
|
+
isPrimaryKey: false;
|
|
129
|
+
isAutoincrement: false;
|
|
130
|
+
hasRuntimeDefault: false;
|
|
131
|
+
enumValues: [string, ...string[]];
|
|
132
|
+
baseColumn: never;
|
|
133
|
+
identity: undefined;
|
|
134
|
+
generated: undefined;
|
|
135
|
+
}, {}, {}>;
|
|
136
|
+
machine_translated: import("drizzle-orm/pg-core").PgColumn<{
|
|
137
|
+
name: "machine_translated";
|
|
138
|
+
tableName: "products_sourced_content";
|
|
139
|
+
dataType: "boolean";
|
|
140
|
+
columnType: "PgBoolean";
|
|
141
|
+
data: boolean;
|
|
142
|
+
driverParam: boolean;
|
|
143
|
+
notNull: true;
|
|
144
|
+
hasDefault: true;
|
|
145
|
+
isPrimaryKey: false;
|
|
146
|
+
isAutoincrement: false;
|
|
147
|
+
hasRuntimeDefault: false;
|
|
148
|
+
enumValues: undefined;
|
|
149
|
+
baseColumn: never;
|
|
150
|
+
identity: undefined;
|
|
151
|
+
generated: undefined;
|
|
152
|
+
}, {}, {}>;
|
|
153
|
+
source_updated_at: import("drizzle-orm/pg-core").PgColumn<{
|
|
154
|
+
name: "source_updated_at";
|
|
155
|
+
tableName: "products_sourced_content";
|
|
156
|
+
dataType: "date";
|
|
157
|
+
columnType: "PgTimestamp";
|
|
158
|
+
data: Date;
|
|
159
|
+
driverParam: string;
|
|
160
|
+
notNull: false;
|
|
161
|
+
hasDefault: false;
|
|
162
|
+
isPrimaryKey: false;
|
|
163
|
+
isAutoincrement: false;
|
|
164
|
+
hasRuntimeDefault: false;
|
|
165
|
+
enumValues: undefined;
|
|
166
|
+
baseColumn: never;
|
|
167
|
+
identity: undefined;
|
|
168
|
+
generated: undefined;
|
|
169
|
+
}, {}, {}>;
|
|
170
|
+
fetched_at: import("drizzle-orm/pg-core").PgColumn<{
|
|
171
|
+
name: "fetched_at";
|
|
172
|
+
tableName: "products_sourced_content";
|
|
173
|
+
dataType: "date";
|
|
174
|
+
columnType: "PgTimestamp";
|
|
175
|
+
data: Date;
|
|
176
|
+
driverParam: string;
|
|
177
|
+
notNull: true;
|
|
178
|
+
hasDefault: true;
|
|
179
|
+
isPrimaryKey: false;
|
|
180
|
+
isAutoincrement: false;
|
|
181
|
+
hasRuntimeDefault: false;
|
|
182
|
+
enumValues: undefined;
|
|
183
|
+
baseColumn: never;
|
|
184
|
+
identity: undefined;
|
|
185
|
+
generated: undefined;
|
|
186
|
+
}, {}, {}>;
|
|
187
|
+
fresh_until: import("drizzle-orm/pg-core").PgColumn<{
|
|
188
|
+
name: "fresh_until";
|
|
189
|
+
tableName: "products_sourced_content";
|
|
190
|
+
dataType: "date";
|
|
191
|
+
columnType: "PgTimestamp";
|
|
192
|
+
data: Date;
|
|
193
|
+
driverParam: string;
|
|
194
|
+
notNull: false;
|
|
195
|
+
hasDefault: false;
|
|
196
|
+
isPrimaryKey: false;
|
|
197
|
+
isAutoincrement: false;
|
|
198
|
+
hasRuntimeDefault: false;
|
|
199
|
+
enumValues: undefined;
|
|
200
|
+
baseColumn: never;
|
|
201
|
+
identity: undefined;
|
|
202
|
+
generated: undefined;
|
|
203
|
+
}, {}, {}>;
|
|
204
|
+
etag: import("drizzle-orm/pg-core").PgColumn<{
|
|
205
|
+
name: "etag";
|
|
206
|
+
tableName: "products_sourced_content";
|
|
207
|
+
dataType: "string";
|
|
208
|
+
columnType: "PgText";
|
|
209
|
+
data: string;
|
|
210
|
+
driverParam: string;
|
|
211
|
+
notNull: false;
|
|
212
|
+
hasDefault: false;
|
|
213
|
+
isPrimaryKey: false;
|
|
214
|
+
isAutoincrement: false;
|
|
215
|
+
hasRuntimeDefault: false;
|
|
216
|
+
enumValues: [string, ...string[]];
|
|
217
|
+
baseColumn: never;
|
|
218
|
+
identity: undefined;
|
|
219
|
+
generated: undefined;
|
|
220
|
+
}, {}, {}>;
|
|
221
|
+
fetch_status: import("drizzle-orm/pg-core").PgColumn<{
|
|
222
|
+
name: "fetch_status";
|
|
223
|
+
tableName: "products_sourced_content";
|
|
224
|
+
dataType: "string";
|
|
225
|
+
columnType: "PgText";
|
|
226
|
+
data: ProductsSourcedContentFetchStatus;
|
|
227
|
+
driverParam: string;
|
|
228
|
+
notNull: true;
|
|
229
|
+
hasDefault: true;
|
|
230
|
+
isPrimaryKey: false;
|
|
231
|
+
isAutoincrement: false;
|
|
232
|
+
hasRuntimeDefault: false;
|
|
233
|
+
enumValues: [string, ...string[]];
|
|
234
|
+
baseColumn: never;
|
|
235
|
+
identity: undefined;
|
|
236
|
+
generated: undefined;
|
|
237
|
+
}, {}, {
|
|
238
|
+
$type: ProductsSourcedContentFetchStatus;
|
|
239
|
+
}>;
|
|
240
|
+
fetch_error: import("drizzle-orm/pg-core").PgColumn<{
|
|
241
|
+
name: "fetch_error";
|
|
242
|
+
tableName: "products_sourced_content";
|
|
243
|
+
dataType: "string";
|
|
244
|
+
columnType: "PgText";
|
|
245
|
+
data: string;
|
|
246
|
+
driverParam: string;
|
|
247
|
+
notNull: false;
|
|
248
|
+
hasDefault: false;
|
|
249
|
+
isPrimaryKey: false;
|
|
250
|
+
isAutoincrement: false;
|
|
251
|
+
hasRuntimeDefault: false;
|
|
252
|
+
enumValues: [string, ...string[]];
|
|
253
|
+
baseColumn: never;
|
|
254
|
+
identity: undefined;
|
|
255
|
+
generated: undefined;
|
|
256
|
+
}, {}, {}>;
|
|
257
|
+
};
|
|
258
|
+
dialect: "pg";
|
|
259
|
+
}>;
|
|
260
|
+
export type InsertProductsSourcedContent = typeof productsSourcedContentTable.$inferInsert;
|
|
261
|
+
export type SelectProductsSourcedContent = typeof productsSourcedContentTable.$inferSelect;
|
|
262
|
+
//# 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;;;;;;;;;;;;;GAaG;AAIH;;;;;GAKG;AACH,MAAM,MAAM,iCAAiC,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,CAAA;AAExF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DvC,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG,OAAO,2BAA2B,CAAC,YAAY,CAAA;AAC1F,MAAM,MAAM,4BAA4B,GAAG,OAAO,2BAA2B,CAAC,YAAY,CAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Products sourced-content cache.
|
|
3
|
+
*
|
|
4
|
+
* One row per sourced product × locale × market. Stores the rich
|
|
5
|
+
* detail-page content the upstream adapter served via `getContent`, plus
|
|
6
|
+
* the SWR metadata the read service needs (TTL, ETag, fetch status,
|
|
7
|
+
* locale fallback bookkeeping).
|
|
8
|
+
*
|
|
9
|
+
* Locale-keyed (per-locale rows, not one JSONB-of-locales) so
|
|
10
|
+
* per-locale TTLs, per-locale fetch failures, "what's missing in ro-RO?"
|
|
11
|
+
* SQL queries, and per-locale invalidation on drift all stay simple.
|
|
12
|
+
*
|
|
13
|
+
* See `docs/architecture/catalog-sourced-content.md` §3.2.
|
|
14
|
+
*/
|
|
15
|
+
import { boolean, index, jsonb, pgTable, primaryKey, text, timestamp } from "drizzle-orm/pg-core";
|
|
16
|
+
/**
|
|
17
|
+
* Sentinel value for the `market` column when an adapter is not
|
|
18
|
+
* market-sensitive. The value `'*'` is the all-markets row; other
|
|
19
|
+
* values are specific markets the adapter served content for.
|
|
20
|
+
*/
|
|
21
|
+
export const PRODUCTS_CONTENT_MARKET_ANY = "*";
|
|
22
|
+
export const productsSourcedContentTable = pgTable("products_sourced_content", {
|
|
23
|
+
/** TypeID matching the products module — `prod_*`. */
|
|
24
|
+
entity_id: text("entity_id").notNull(),
|
|
25
|
+
/** BCP 47 language tag (e.g. "ro-RO", "en-GB"). */
|
|
26
|
+
locale: text("locale").notNull(),
|
|
27
|
+
/** Market id, or `'*'` for all-markets. */
|
|
28
|
+
market: text("market").notNull().default(PRODUCTS_CONTENT_MARKET_ANY),
|
|
29
|
+
/**
|
|
30
|
+
* Vertical-shaped content payload. Schema-validated against the
|
|
31
|
+
* vertical's Zod validator before write; consumers must validate on
|
|
32
|
+
* read against the recorded `content_schema_version`.
|
|
33
|
+
*/
|
|
34
|
+
payload: jsonb("payload").$type().notNull(),
|
|
35
|
+
/** Vertical-managed schema version (e.g. "products/v1"). */
|
|
36
|
+
content_schema_version: text("content_schema_version").notNull(),
|
|
37
|
+
/**
|
|
38
|
+
* The locale the upstream actually served. May differ from
|
|
39
|
+
* `locale` (the request locale) when the upstream did its own
|
|
40
|
+
* fallback. Lets the read path mark `match_kind` accurately even
|
|
41
|
+
* when serving a stale row that originated from upstream-fallback.
|
|
42
|
+
*/
|
|
43
|
+
returned_locale: text("returned_locale").notNull(),
|
|
44
|
+
/** True when the upstream marks the payload as machine-translated. */
|
|
45
|
+
machine_translated: boolean("machine_translated").notNull().default(false),
|
|
46
|
+
/** When the upstream itself last modified this content. */
|
|
47
|
+
source_updated_at: timestamp("source_updated_at", { withTimezone: true }),
|
|
48
|
+
/** When this cache row was last written. */
|
|
49
|
+
fetched_at: timestamp("fetched_at", { withTimezone: true }).notNull().defaultNow(),
|
|
50
|
+
/** When the cache considers this row fresh until — SWR boundary. */
|
|
51
|
+
fresh_until: timestamp("fresh_until", { withTimezone: true }),
|
|
52
|
+
/** ETag-style marker for HTTP-cache revalidation on the next pull. */
|
|
53
|
+
etag: text("etag"),
|
|
54
|
+
/** Last fetch outcome. */
|
|
55
|
+
fetch_status: text("fetch_status")
|
|
56
|
+
.$type()
|
|
57
|
+
.notNull()
|
|
58
|
+
.default("ok"),
|
|
59
|
+
/** Error detail when fetch_status === "error". */
|
|
60
|
+
fetch_error: text("fetch_error"),
|
|
61
|
+
}, (table) => [
|
|
62
|
+
primaryKey({ columns: [table.entity_id, table.locale, table.market] }),
|
|
63
|
+
// "What's stale in ro-RO?"
|
|
64
|
+
index("products_sourced_content_locale_fresh_idx").on(table.locale, table.fresh_until),
|
|
65
|
+
// Fallback diagnostics: "what locales did upstream serve for prod_X?"
|
|
66
|
+
index("products_sourced_content_returned_locale_idx").on(table.entity_id, table.returned_locale),
|
|
67
|
+
// Cache flushes on schema bumps: DELETE WHERE schema_version != current.
|
|
68
|
+
index("products_sourced_content_schema_version_idx").on(table.content_schema_version),
|
|
69
|
+
]);
|
|
@@ -285,6 +285,23 @@ export declare const productCategories: import("drizzle-orm/pg-core").PgTableWit
|
|
|
285
285
|
identity: undefined;
|
|
286
286
|
generated: undefined;
|
|
287
287
|
}, {}, {}>;
|
|
288
|
+
customerPaymentPolicy: import("drizzle-orm/pg-core").PgColumn<{
|
|
289
|
+
name: "customer_payment_policy";
|
|
290
|
+
tableName: "product_categories";
|
|
291
|
+
dataType: "json";
|
|
292
|
+
columnType: "PgJsonb";
|
|
293
|
+
data: unknown;
|
|
294
|
+
driverParam: unknown;
|
|
295
|
+
notNull: false;
|
|
296
|
+
hasDefault: false;
|
|
297
|
+
isPrimaryKey: false;
|
|
298
|
+
isAutoincrement: false;
|
|
299
|
+
hasRuntimeDefault: false;
|
|
300
|
+
enumValues: undefined;
|
|
301
|
+
baseColumn: never;
|
|
302
|
+
identity: undefined;
|
|
303
|
+
generated: undefined;
|
|
304
|
+
}, {}, {}>;
|
|
288
305
|
metadata: import("drizzle-orm/pg-core").PgColumn<{
|
|
289
306
|
name: "metadata";
|
|
290
307
|
tableName: "product_categories";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-taxonomy.d.ts","sourceRoot":"","sources":["../src/schema-taxonomy.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBxB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAE7D,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"schema-taxonomy.d.ts","sourceRoot":"","sources":["../src/schema-taxonomy.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBxB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAE7D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuC7B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA;AACnE,MAAM,MAAM,kBAAkB,GAAG,OAAO,iBAAiB,CAAC,YAAY,CAAA;AAEtE,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASvB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AACxD,MAAM,MAAM,aAAa,GAAG,OAAO,WAAW,CAAC,YAAY,CAAA;AAE3D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBxB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAC1D,MAAM,MAAM,cAAc,GAAG,OAAO,YAAY,CAAC,YAAY,CAAA;AAE7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBnC,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,OAAO,uBAAuB,CAAC,YAAY,CAAA;AAChF,MAAM,MAAM,yBAAyB,GAAG,OAAO,uBAAuB,CAAC,YAAY,CAAA;AAEnF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBnC,CAAA;AAED,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe9B,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkB/B,CAAA"}
|
package/dist/schema-taxonomy.js
CHANGED
|
@@ -25,6 +25,19 @@ export const productCategories = pgTable("product_categories", {
|
|
|
25
25
|
description: text("description"),
|
|
26
26
|
sortOrder: integer("sort_order").notNull().default(0),
|
|
27
27
|
active: boolean("active").notNull().default(true),
|
|
28
|
+
/**
|
|
29
|
+
* Customer-facing payment policy override. When set, bookings
|
|
30
|
+
* for products in this category inherit these terms (unless
|
|
31
|
+
* the listing or booking sets its own override). Shape mirrors
|
|
32
|
+
* `PaymentPolicy` from `@voyantjs/finance`.
|
|
33
|
+
*
|
|
34
|
+
* `null` means "inherit from supplier / operator default".
|
|
35
|
+
*
|
|
36
|
+
* Multi-category products: the cascade picks the FIRST category
|
|
37
|
+
* (ordered by `productCategoryProducts.sortOrder` ascending) that
|
|
38
|
+
* has a non-null policy.
|
|
39
|
+
*/
|
|
40
|
+
customerPaymentPolicy: jsonb("customer_payment_policy"),
|
|
28
41
|
metadata: jsonb("metadata").$type(),
|
|
29
42
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
30
43
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
package/dist/schema.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export * from "./schema-itinerary";
|
|
|
4
4
|
export * from "./schema-relations";
|
|
5
5
|
export * from "./schema-settings";
|
|
6
6
|
export * from "./schema-shared";
|
|
7
|
+
export { type InsertProductsSourcedContent, PRODUCTS_CONTENT_MARKET_ANY, type ProductsSourcedContentFetchStatus, productsSourcedContentTable, type SelectProductsSourcedContent, } from "./schema-sourced-content";
|
|
7
8
|
export * from "./schema-taxonomy";
|
|
8
9
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AACtF,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AACtF,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,EAC3B,KAAK,iCAAiC,EACtC,2BAA2B,EAC3B,KAAK,4BAA4B,GAClC,MAAM,0BAA0B,CAAA;AACjC,cAAc,mBAAmB,CAAA"}
|
package/dist/schema.js
CHANGED
|
@@ -4,4 +4,5 @@ export * from "./schema-itinerary";
|
|
|
4
4
|
export * from "./schema-relations";
|
|
5
5
|
export * from "./schema-settings";
|
|
6
6
|
export * from "./schema-shared";
|
|
7
|
+
export { PRODUCTS_CONTENT_MARKET_ANY, productsSourcedContentTable, } from "./schema-sourced-content";
|
|
7
8
|
export * from "./schema-taxonomy";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-catalog-plane.d.ts","sourceRoot":"","sources":["../src/service-catalog-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAElB,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAIhD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAc3C;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,QAAQ,CAAC,YAAY,EACjC,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACpC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"service-catalog-plane.d.ts","sourceRoot":"","sources":["../src/service-catalog-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAElB,KAAK,UAAU,EAChB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAIhD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAc3C;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,QAAQ,CAAC,YAAY,EACjC,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACpC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAwC9B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,QAAQ,CAAC,YAAY,EAClC,QAAQ,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACrC,UAAU,CAKZ;AAED,8EAA8E;AAC9E,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,gBAAgB,EAAE,MAAM,CAAA;IACxB,qCAAqC;IACrC,KAAK,EAAE,aAAa,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAS9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,YAAY,EAChB,IAAI,EAAE,aAAa,CAAC,OAAO,QAAQ,CAAC,YAAY,CAAC,EACjD,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,YAAY,EAAE,CAAC,CAkBzB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAAG;IAAE,YAAY,CAAC,EAAE,YAAY,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,CASzD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,gBAAgB,EAAE,MAAM,CAAA;CACzB,GAAG,eAAe,CAAC,OAAO,QAAQ,CAAC,YAAY,CAAC,CAWhD;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,YAAY,EAChB,OAAO,EAAE;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACpC,eAAe,CAQjB;AAED;;GAEG;AACH,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,GACX,CAAA"}
|
|
@@ -65,6 +65,7 @@ export function productRowToProjection(row, context) {
|
|
|
65
65
|
["activated", row.activated],
|
|
66
66
|
["productTypeId", row.productTypeId],
|
|
67
67
|
["facilityId", row.facilityId],
|
|
68
|
+
["supplierId", row.supplierId],
|
|
68
69
|
["pax", row.pax],
|
|
69
70
|
["startDate", row.startDate],
|
|
70
71
|
["endDate", row.endDate],
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owned-product content builder.
|
|
3
|
+
*
|
|
4
|
+
* Projects an owned product (the products module's own tables) into the
|
|
5
|
+
* vertical-shared `ProductContent` shape so the catalog content service
|
|
6
|
+
* can return rich detail for owned products via the same API that
|
|
7
|
+
* sourced products go through (`getProductContent`).
|
|
8
|
+
*
|
|
9
|
+
* Per sourced-content §3.3: `getProductContent` is the unified read
|
|
10
|
+
* surface for owned + sourced. v1 of service-content.ts only handled
|
|
11
|
+
* sourced (returning null for owned); this helper closes that gap.
|
|
12
|
+
*
|
|
13
|
+
* Locale resolution uses the catalog plane's standard
|
|
14
|
+
* `pickBestCachedLocale` against `product_translations` and
|
|
15
|
+
* `product_option_translations` rows — exact > language-match >
|
|
16
|
+
* fallback-chain > any. Matches the same scoring semantics the sourced
|
|
17
|
+
* cache reads use, so the same `BookingDraft.scope.locale` chain works
|
|
18
|
+
* for both owned and sourced products.
|
|
19
|
+
*
|
|
20
|
+
* The projection reads in parallel:
|
|
21
|
+
* - `products` row → product summary + tags + supplier
|
|
22
|
+
* - `product_translations` → localized name + description per locale
|
|
23
|
+
* - `product_itineraries` + `product_days` → itinerary days (no
|
|
24
|
+
* translation table today; falls back to source)
|
|
25
|
+
* - `product_options` + `product_option_translations` → options +
|
|
26
|
+
* localized labels
|
|
27
|
+
* - `product_media` → hero + gallery
|
|
28
|
+
*
|
|
29
|
+
* Day translations don't exist in the schema yet — when
|
|
30
|
+
* `product_day_translations` lands, this function picks them up the
|
|
31
|
+
* same way.
|
|
32
|
+
*/
|
|
33
|
+
import type { ContentLocaleMatchKind } from "@voyantjs/catalog";
|
|
34
|
+
import type { AnyDrizzleDb } from "@voyantjs/db";
|
|
35
|
+
import { type ProductContent } from "./content-shape.js";
|
|
36
|
+
export interface BuildOwnedProductContentOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Ordered locale preference chain — most-preferred first. Same shape
|
|
39
|
+
* the catalog plane's `pickBestCachedLocale` consumes. Pass-through
|
|
40
|
+
* from the caller's `BookingDraft.scope.locale` (storefront /
|
|
41
|
+
* operator UI).
|
|
42
|
+
*/
|
|
43
|
+
preferredLocales: ReadonlyArray<string>;
|
|
44
|
+
}
|
|
45
|
+
export interface BuildOwnedProductContentResult {
|
|
46
|
+
/** The owned product projected to ProductContent. */
|
|
47
|
+
content: ProductContent;
|
|
48
|
+
/**
|
|
49
|
+
* The locale we actually served — may differ from
|
|
50
|
+
* `preferredLocales[0]` when a fallback was used. Per-product;
|
|
51
|
+
* options that fell back to a different locale don't override this
|
|
52
|
+
* (storefront UI hints at the product level).
|
|
53
|
+
*/
|
|
54
|
+
servedLocale: string;
|
|
55
|
+
/**
|
|
56
|
+
* How well the served locale matched the chain. Surfaces in the UI
|
|
57
|
+
* as a "served in English" hint when content was served in a
|
|
58
|
+
* non-preferred language.
|
|
59
|
+
*/
|
|
60
|
+
matchKind: ContentLocaleMatchKind;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read the owned product + related rows and project to `ProductContent`,
|
|
64
|
+
* resolving translations against the supplied locale-preference chain.
|
|
65
|
+
* Returns null when the product doesn't exist.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildOwnedProductContent(db: AnyDrizzleDb, entityId: string, options: BuildOwnedProductContentOptions): Promise<BuildOwnedProductContentResult | null>;
|
|
68
|
+
//# sourceMappingURL=service-content-owned.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-content-owned.d.ts","sourceRoot":"","sources":["../src/service-content-owned.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGhD,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,oBAAoB,CAAA;AAW3B,MAAM,WAAW,+BAA+B;IAC9C;;;;;OAKG;IACH,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACxC;AAED,MAAM,WAAW,8BAA8B;IAC7C,qDAAqD;IACrD,OAAO,EAAE,cAAc,CAAA;IACvB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,SAAS,EAAE,sBAAsB,CAAA;CAClC;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,YAAY,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAmIhD"}
|