@voyantjs/products 0.77.1 → 0.77.6

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.
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Catalog plane field policy for product → pricing denormalization.
3
3
  *
4
- * Aggregates a "price from" value across the product's configured
5
- * default-rule prices so storefront cards can render `from $X` without
6
- * fanning out to per-option pricing on every render. See
4
+ * Aggregates a "price from" value across the product's future bookable
5
+ * default rate-plan prices so storefront cards can render `from $X`
6
+ * without fanning out to per-option pricing on every render. See
7
7
  * `docs/architecture/catalog-architecture.md` §5.4.
8
8
  *
9
9
  * Storefront product cards filter and display by:
@@ -26,16 +26,16 @@
26
26
  * Why a separate field instead of reusing the existing `sellAmountCents`
27
27
  * from `productCatalogPolicy`: that path projects the product-row
28
28
  * configured default verbatim. Multi-option products often leave
29
- * `products.sellAmountCents` null and put the real prices on options —
30
- * this projection MINs across both, giving storefront a value that's
31
- * always meaningful even for the option-driven case.
29
+ * `products.sellAmountCents` null or stale and put the real prices on
30
+ * active rate-plan room/base/unit rows. This projection prefers those
31
+ * bookable prices and only falls back to the product row when no rate-
32
+ * plan price exists.
32
33
  *
33
34
  * Out of scope here (deferred):
34
- * - Schedule-aware rule resolution. The kernel reads `isDefault=true`
35
- * rule prices only it does NOT walk seasonal schedules, per-
36
- * departure overrides, or per-unit occupancy tiers. A "true cheapest
37
- * bookable price right now" projection requires per-slice rule
38
- * evaluation with a moving "now" date and is a follow-up.
35
+ * - Full schedule-aware rule resolution. The kernel reads
36
+ * `isDefault=true` rule prices on options that have a future
37
+ * bookable departure; it does NOT walk seasonal schedules or per-
38
+ * departure overrides.
39
39
  * - Per-audience / per-market currency conversion. The currency we
40
40
  * emit is `products.sellCurrency`; multi-catalog operators using
41
41
  * mixed currencies for the same product will see prices clipped
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Catalog plane field policy for product → pricing denormalization.
3
3
  *
4
- * Aggregates a "price from" value across the product's configured
5
- * default-rule prices so storefront cards can render `from $X` without
6
- * fanning out to per-option pricing on every render. See
4
+ * Aggregates a "price from" value across the product's future bookable
5
+ * default rate-plan prices so storefront cards can render `from $X`
6
+ * without fanning out to per-option pricing on every render. See
7
7
  * `docs/architecture/catalog-architecture.md` §5.4.
8
8
  *
9
9
  * Storefront product cards filter and display by:
@@ -26,16 +26,16 @@
26
26
  * Why a separate field instead of reusing the existing `sellAmountCents`
27
27
  * from `productCatalogPolicy`: that path projects the product-row
28
28
  * configured default verbatim. Multi-option products often leave
29
- * `products.sellAmountCents` null and put the real prices on options —
30
- * this projection MINs across both, giving storefront a value that's
31
- * always meaningful even for the option-driven case.
29
+ * `products.sellAmountCents` null or stale and put the real prices on
30
+ * active rate-plan room/base/unit rows. This projection prefers those
31
+ * bookable prices and only falls back to the product row when no rate-
32
+ * plan price exists.
32
33
  *
33
34
  * Out of scope here (deferred):
34
- * - Schedule-aware rule resolution. The kernel reads `isDefault=true`
35
- * rule prices only it does NOT walk seasonal schedules, per-
36
- * departure overrides, or per-unit occupancy tiers. A "true cheapest
37
- * bookable price right now" projection requires per-slice rule
38
- * evaluation with a moving "now" date and is a follow-up.
35
+ * - Full schedule-aware rule resolution. The kernel reads
36
+ * `isDefault=true` rule prices on options that have a future
37
+ * bookable departure; it does NOT walk seasonal schedules or per-
38
+ * departure overrides.
39
39
  * - Per-audience / per-market currency conversion. The currency we
40
40
  * emit is `products.sellCurrency`; multi-catalog operators using
41
41
  * mixed currencies for the same product will see prices clipped
@@ -47,9 +47,9 @@
47
47
  import { defineFieldPolicy } from "@voyantjs/catalog/contract";
48
48
  const PRODUCT_PRICING_FIELD_POLICY = [
49
49
  // ── Aggregated "price from" amount ───────────────────────────────────────
50
- // MIN across `products.sellAmountCents` and the active default
51
- // `optionPriceRules.baseSellAmountCents` (plus option-unit-rule MINs for
52
- // per-unit-priced options). `null` when no source has a non-null amount.
50
+ // MIN across future bookable active default room prices first, then
51
+ // base/unit fallbacks, then `products.sellAmountCents`. `null` when no
52
+ // source has a positive amount.
53
53
  {
54
54
  path: "priceFromAmountCents",
55
55
  class: "structural",
@@ -83,8 +83,8 @@ const PRODUCT_PRICING_FIELD_POLICY = [
83
83
  sourceFreshness: "sync",
84
84
  },
85
85
  // ── Existence flag ───────────────────────────────────────────────────────
86
- // `false` when neither the product row nor any active default rule has a
87
- // configured price. Storefront filters use this for "show only priced
86
+ // `false` when neither future rate-plan pricing nor the product row has
87
+ // a positive amount. Storefront filters use this for "show only priced
88
88
  // products" and to suppress an empty `from` badge.
89
89
  {
90
90
  path: "hasPricing",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/products",
3
- "version": "0.77.1",
3
+ "version": "0.77.6",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -132,13 +132,13 @@
132
132
  "pdf-lib": "^1.17.1",
133
133
  "sanitize-html": "^2.17.4",
134
134
  "zod": "^4.3.6",
135
- "@voyantjs/action-ledger": "0.77.1",
136
- "@voyantjs/core": "0.77.1",
137
- "@voyantjs/db": "0.77.1",
138
- "@voyantjs/hono": "0.77.1",
139
- "@voyantjs/utils": "0.77.1",
140
- "@voyantjs/catalog": "0.77.1",
141
- "@voyantjs/storage": "0.77.1"
135
+ "@voyantjs/action-ledger": "0.77.6",
136
+ "@voyantjs/core": "0.77.6",
137
+ "@voyantjs/db": "0.77.6",
138
+ "@voyantjs/hono": "0.77.6",
139
+ "@voyantjs/utils": "0.77.6",
140
+ "@voyantjs/catalog": "0.77.6",
141
+ "@voyantjs/storage": "0.77.6"
142
142
  },
143
143
  "devDependencies": {
144
144
  "@types/sanitize-html": "^2.16.1",