@voyantjs/products 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.
Files changed (72) hide show
  1. package/dist/booking-engine/handler.d.ts +203 -0
  2. package/dist/booking-engine/handler.d.ts.map +1 -0
  3. package/dist/booking-engine/handler.js +330 -0
  4. package/dist/booking-engine/index.d.ts +8 -0
  5. package/dist/booking-engine/index.d.ts.map +1 -0
  6. package/dist/booking-engine/index.js +7 -0
  7. package/dist/catalog-policy.d.ts +33 -0
  8. package/dist/catalog-policy.d.ts.map +1 -0
  9. package/dist/catalog-policy.js +421 -0
  10. package/dist/content-shape.d.ts +217 -0
  11. package/dist/content-shape.d.ts.map +1 -0
  12. package/dist/content-shape.js +159 -0
  13. package/dist/draft-shape.d.ts +43 -0
  14. package/dist/draft-shape.d.ts.map +1 -0
  15. package/dist/draft-shape.js +46 -0
  16. package/dist/events.d.ts +37 -0
  17. package/dist/events.d.ts.map +1 -0
  18. package/dist/events.js +32 -0
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +1 -0
  22. package/dist/routes-content.d.ts +74 -0
  23. package/dist/routes-content.d.ts.map +1 -0
  24. package/dist/routes-content.js +117 -0
  25. package/dist/routes.d.ts +47 -26
  26. package/dist/routes.d.ts.map +1 -1
  27. package/dist/routes.js +88 -16
  28. package/dist/schema-core.d.ts +240 -1
  29. package/dist/schema-core.d.ts.map +1 -1
  30. package/dist/schema-core.js +49 -0
  31. package/dist/schema-itinerary.d.ts +18 -1
  32. package/dist/schema-itinerary.d.ts.map +1 -1
  33. package/dist/schema-itinerary.js +1 -0
  34. package/dist/schema-settings.d.ts +1 -1
  35. package/dist/schema-sourced-content.d.ts +262 -0
  36. package/dist/schema-sourced-content.d.ts.map +1 -0
  37. package/dist/schema-sourced-content.js +69 -0
  38. package/dist/schema-taxonomy.d.ts +17 -0
  39. package/dist/schema-taxonomy.d.ts.map +1 -1
  40. package/dist/schema-taxonomy.js +13 -0
  41. package/dist/schema.d.ts +1 -0
  42. package/dist/schema.d.ts.map +1 -1
  43. package/dist/schema.js +1 -0
  44. package/dist/service-catalog-plane.d.ts +129 -0
  45. package/dist/service-catalog-plane.d.ts.map +1 -0
  46. package/dist/service-catalog-plane.js +212 -0
  47. package/dist/service-content-owned.d.ts +68 -0
  48. package/dist/service-content-owned.d.ts.map +1 -0
  49. package/dist/service-content-owned.js +224 -0
  50. package/dist/service-content-synthesizer.d.ts +90 -0
  51. package/dist/service-content-synthesizer.d.ts.map +1 -0
  52. package/dist/service-content-synthesizer.js +171 -0
  53. package/dist/service-content.d.ts +106 -0
  54. package/dist/service-content.d.ts.map +1 -0
  55. package/dist/service-content.js +365 -0
  56. package/dist/service.d.ts +82 -28
  57. package/dist/service.d.ts.map +1 -1
  58. package/dist/service.js +4 -0
  59. package/dist/tasks/brochures.d.ts +2 -1
  60. package/dist/tasks/brochures.d.ts.map +1 -1
  61. package/dist/tasks/brochures.js +3 -0
  62. package/dist/validation-catalog.d.ts +4 -4
  63. package/dist/validation-config.d.ts +3 -3
  64. package/dist/validation-content.d.ts +34 -4
  65. package/dist/validation-content.d.ts.map +1 -1
  66. package/dist/validation-content.js +13 -0
  67. package/dist/validation-core.d.ts +53 -3
  68. package/dist/validation-core.d.ts.map +1 -1
  69. package/dist/validation-core.js +16 -0
  70. package/dist/validation-public.d.ts +9 -9
  71. package/dist/validation-shared.d.ts +4 -4
  72. package/package.json +12 -6
@@ -17,16 +17,35 @@ export const products = pgTable("products", {
17
17
  costAmountCents: integer("cost_amount_cents"),
18
18
  marginPercent: integer("margin_percent"),
19
19
  facilityId: text("facility_id"),
20
+ supplierId: text("supplier_id"),
20
21
  startDate: date("start_date"),
21
22
  endDate: date("end_date"),
22
23
  pax: integer("pax"),
23
24
  productTypeId: text("product_type_id"),
25
+ /**
26
+ * Per-product tax class — drives the engine's tax computation at
27
+ * quote time. Plain text (no FK) since `tax_classes` lives in
28
+ * @voyantjs/finance and cross-domain refs go through the link
29
+ * service per schema-discipline. Default null → falls through to a
30
+ * market-level default. Per booking-journey-architecture §9.
31
+ */
32
+ taxClassId: text("tax_class_id"),
33
+ /**
34
+ * Per-listing customer payment policy override. Wins over the
35
+ * product's category and supplier policies in the cascade. Shape
36
+ * mirrors `PaymentPolicy` from `@voyantjs/finance`.
37
+ *
38
+ * `null` means "inherit from category / supplier / operator
39
+ * default" — most products leave this empty.
40
+ */
41
+ customerPaymentPolicy: jsonb("customer_payment_policy"),
24
42
  tags: jsonb("tags").$type().default([]),
25
43
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
26
44
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
27
45
  }, (table) => [
28
46
  index("idx_products_status").on(table.status),
29
47
  index("idx_products_facility").on(table.facilityId),
48
+ index("idx_products_supplier").on(table.supplierId),
30
49
  index("idx_products_product_type").on(table.productTypeId),
31
50
  index("idx_products_status_created").on(table.status, table.createdAt),
32
51
  index("idx_products_booking_mode_created").on(table.bookingMode, table.createdAt),
@@ -34,6 +53,7 @@ export const products = pgTable("products", {
34
53
  index("idx_products_visibility_created").on(table.visibility, table.createdAt),
35
54
  index("idx_products_activated_created").on(table.activated, table.createdAt),
36
55
  index("idx_products_facility_created").on(table.facilityId, table.createdAt),
56
+ index("idx_products_supplier_created").on(table.supplierId, table.createdAt),
37
57
  index("idx_products_product_type_created").on(table.productTypeId, table.createdAt),
38
58
  index("idx_products_public_created").on(table.status, table.activated, table.visibility, table.createdAt),
39
59
  ]);
@@ -85,3 +105,32 @@ export const optionUnits = pgTable("option_units", {
85
105
  index("idx_option_units_type").on(table.unitType),
86
106
  uniqueIndex("uidx_option_units_option_code").on(table.optionId, table.code),
87
107
  ]);
108
+ /**
109
+ * Per-product per-occupancy rate tiers for non-cruise verticals.
110
+ * Cruises keep the specialized `cruise_prices` table; everyone else
111
+ * uses this. Per booking-journey-architecture §9.
112
+ *
113
+ * `tier_pax` is the occupancy count the rate applies to (1-supp, 2-default,
114
+ * 3-share, 4). Falls back to `option_unit_tiers` (quantity-based, not
115
+ * occupancy-based) when no occupancy tier exists.
116
+ */
117
+ export const productPaxPricingTiers = pgTable("product_pax_pricing_tiers", {
118
+ id: typeId("product_pax_pricing_tiers"),
119
+ productId: typeIdRef("product_id")
120
+ .notNull()
121
+ .references(() => products.id, { onDelete: "cascade" }),
122
+ optionUnitId: typeIdRef("option_unit_id").references(() => optionUnits.id, {
123
+ onDelete: "cascade",
124
+ }),
125
+ tierPax: integer("tier_pax").notNull(),
126
+ pricePerPaxCents: integer("price_per_pax_cents").notNull(),
127
+ promoPricePerPaxCents: integer("promo_price_per_pax_cents"),
128
+ effectiveFrom: date("effective_from"),
129
+ effectiveTo: date("effective_to"),
130
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
131
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
132
+ }, (table) => [
133
+ index("idx_pax_tiers_product").on(table.productId),
134
+ index("idx_pax_tiers_unit").on(table.optionUnitId),
135
+ uniqueIndex("uidx_pax_tiers_unit_pax").on(table.optionUnitId, table.tierPax),
136
+ ]);
@@ -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" | "transfer" | "accommodation" | "experience" | "guide" | "meal";
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB9B,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"}
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"}
@@ -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" | "accommodation" | "transport";
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0B7B,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"}
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"}
@@ -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
@@ -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";