@rovela-ai/sdk 0.19.7 → 0.20.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 (96) hide show
  1. package/dist/admin/api/index.d.ts +2 -2
  2. package/dist/admin/api/index.d.ts.map +1 -1
  3. package/dist/admin/api/index.js +2 -2
  4. package/dist/admin/api/index.js.map +1 -1
  5. package/dist/admin/api/orders.d.ts +49 -0
  6. package/dist/admin/api/orders.d.ts.map +1 -1
  7. package/dist/admin/api/orders.js +293 -30
  8. package/dist/admin/api/orders.js.map +1 -1
  9. package/dist/admin/api/settings.d.ts.map +1 -1
  10. package/dist/admin/api/settings.js +6 -1
  11. package/dist/admin/api/settings.js.map +1 -1
  12. package/dist/admin/api/shipping.d.ts +49 -0
  13. package/dist/admin/api/shipping.d.ts.map +1 -1
  14. package/dist/admin/api/shipping.js +144 -0
  15. package/dist/admin/api/shipping.js.map +1 -1
  16. package/dist/admin/components/OrderDetails.d.ts.map +1 -1
  17. package/dist/admin/components/OrderDetails.js +69 -1
  18. package/dist/admin/components/OrderDetails.js.map +1 -1
  19. package/dist/admin/components/ShippingSettings.d.ts.map +1 -1
  20. package/dist/admin/components/ShippingSettings.js +313 -134
  21. package/dist/admin/components/ShippingSettings.js.map +1 -1
  22. package/dist/admin/components/UsersTable.d.ts.map +1 -1
  23. package/dist/admin/components/UsersTable.js +65 -8
  24. package/dist/admin/components/UsersTable.js.map +1 -1
  25. package/dist/admin/types.d.ts +13 -0
  26. package/dist/admin/types.d.ts.map +1 -1
  27. package/dist/checkout/api/colissimo-relays.d.ts +24 -0
  28. package/dist/checkout/api/colissimo-relays.d.ts.map +1 -0
  29. package/dist/checkout/api/colissimo-relays.js +60 -0
  30. package/dist/checkout/api/colissimo-relays.js.map +1 -0
  31. package/dist/checkout/api/manual.d.ts.map +1 -1
  32. package/dist/checkout/api/manual.js +21 -5
  33. package/dist/checkout/api/manual.js.map +1 -1
  34. package/dist/checkout/api/shipping.d.ts.map +1 -1
  35. package/dist/checkout/api/shipping.js +60 -82
  36. package/dist/checkout/api/shipping.js.map +1 -1
  37. package/dist/checkout/components/CheckoutFlow.d.ts.map +1 -1
  38. package/dist/checkout/components/CheckoutFlow.js +142 -3
  39. package/dist/checkout/components/CheckoutFlow.js.map +1 -1
  40. package/dist/checkout/components/ShippingOptions.d.ts +8 -1
  41. package/dist/checkout/components/ShippingOptions.d.ts.map +1 -1
  42. package/dist/checkout/components/ShippingOptions.js +40 -11
  43. package/dist/checkout/components/ShippingOptions.js.map +1 -1
  44. package/dist/checkout/components/colissimo-logo.d.ts +12 -0
  45. package/dist/checkout/components/colissimo-logo.d.ts.map +1 -0
  46. package/dist/checkout/components/colissimo-logo.js +12 -0
  47. package/dist/checkout/components/colissimo-logo.js.map +1 -0
  48. package/dist/checkout/server/create-checkout-session.d.ts.map +1 -1
  49. package/dist/checkout/server/create-checkout-session.js +55 -13
  50. package/dist/checkout/server/create-checkout-session.js.map +1 -1
  51. package/dist/checkout/server/handle-webhook.js +7 -3
  52. package/dist/checkout/server/handle-webhook.js.map +1 -1
  53. package/dist/checkout/server/order-service.d.ts.map +1 -1
  54. package/dist/checkout/server/order-service.js +25 -0
  55. package/dist/checkout/server/order-service.js.map +1 -1
  56. package/dist/checkout/server/pricing.d.ts +20 -0
  57. package/dist/checkout/server/pricing.d.ts.map +1 -1
  58. package/dist/checkout/server/pricing.js +51 -5
  59. package/dist/checkout/server/pricing.js.map +1 -1
  60. package/dist/checkout/types.d.ts +57 -1
  61. package/dist/checkout/types.d.ts.map +1 -1
  62. package/dist/core/db/queries.d.ts +157 -35
  63. package/dist/core/db/queries.d.ts.map +1 -1
  64. package/dist/core/db/queries.js +223 -1
  65. package/dist/core/db/queries.js.map +1 -1
  66. package/dist/core/db/schema.d.ts +323 -5
  67. package/dist/core/db/schema.d.ts.map +1 -1
  68. package/dist/core/db/schema.js +70 -0
  69. package/dist/core/db/schema.js.map +1 -1
  70. package/dist/core/i18n/messages/en.d.ts.map +1 -1
  71. package/dist/core/i18n/messages/en.js +9 -0
  72. package/dist/core/i18n/messages/en.js.map +1 -1
  73. package/dist/core/i18n/messages/fr.d.ts.map +1 -1
  74. package/dist/core/i18n/messages/fr.js +9 -0
  75. package/dist/core/i18n/messages/fr.js.map +1 -1
  76. package/dist/shipping/colissimo.d.ts +166 -0
  77. package/dist/shipping/colissimo.d.ts.map +1 -0
  78. package/dist/shipping/colissimo.js +424 -0
  79. package/dist/shipping/colissimo.js.map +1 -0
  80. package/dist/shipping/index.d.ts +4 -1
  81. package/dist/shipping/index.d.ts.map +1 -1
  82. package/dist/shipping/index.js +3 -1
  83. package/dist/shipping/index.js.map +1 -1
  84. package/docs/changelog/epoch-02-platform-commerce.md +11 -0
  85. package/docs/changelog/epoch-06-mobile-integrity.md +29 -1
  86. package/docs/changelog/epoch-07-shipping-carriers.md +125 -0
  87. package/package.json +6 -1
  88. package/templates/store-template/.claude/skills/build-feature/SKILL.md +2 -0
  89. package/templates/store-template/.claude/skills/manage-products/SKILL.md +1 -1
  90. package/templates/store-template/.claude/skills/override-sdk-component/SKILL.md +7 -0
  91. package/templates/store-template/app/api/admin/orders/[id]/colissimo-defaults/route.ts +6 -0
  92. package/templates/store-template/app/api/admin/orders/[id]/label/route.ts +6 -0
  93. package/templates/store-template/app/api/admin/orders/[id]/ship-with-colissimo/route.ts +6 -0
  94. package/templates/store-template/app/api/admin/shipping/colissimo/route.ts +10 -0
  95. package/templates/store-template/app/api/checkout/colissimo-relays/route.ts +4 -0
  96. package/templates/store-template/package.json +1 -1
@@ -0,0 +1,125 @@
1
+ # E7 Shipping carriers — 0.20.0..0.20.0
2
+
3
+ ## What landed
4
+ Shipping became a carrier REGISTRY (the payments-registry model): multiple
5
+ carriers coexist, each with its own zones + rates, and the global
6
+ `store_settings.shipping_mode` either/or is retired (column kept, ignored).
7
+ Colissimo (La Poste) is the first integrated carrier: label generation from
8
+ the admin order page (home + point relais products), pickup-point (relay)
9
+ delivery at checkout with a nested point picker, tracking links, and the
10
+ order-shipped email carrying the tracking number. Relay offers are ordinary
11
+ `shipping_rates` rows (`fulfillment='relay'`) — zones, cart thresholds and
12
+ customer-group gating apply to every carrier through the one rate engine.
13
+
14
+ ## SDK-internal (free via pin bump)
15
+ - Checkout `ShippingOptions` renders carrier groups as contained parent
16
+ cards (identity header w/ provider badge or merchant `logo_url`, child
17
+ option cards at full width) and sorts groups + options by price
18
+ descending. `renderOptionDetail` slot nests content under an option.
19
+ - Quote API degrades gracefully: a Shippo outage drops its live quotes but
20
+ no longer blanks the other carriers' options.
21
+ - `sendStatusNotification` logs shipped-email failures honestly (was an
22
+ unconditional "sent" log).
23
+ - Order confirmation + shipped emails label relay orders' address block
24
+ "Point relais — {name}" instead of presenting the relay street as the
25
+ customer's home address.
26
+
27
+ ## Template contract
28
+ - `app/api/checkout/colissimo-relays/route.ts` (NEW) — re-export of
29
+ `@rovela-ai/sdk/checkout/api/colissimo-relays`; the checkout relay picker
30
+ POSTs here. Without it, selecting a relay rate shows a permanent
31
+ "search failed" state.
32
+ - `app/api/admin/shipping/colissimo/route.ts` (NEW) — GET/POST/DELETE
33
+ re-exports (`getColissimoConfig`/`saveColissimoSettings`/
34
+ `deleteColissimoSettings`); the ShippingSettings Colissimo panel reads and
35
+ writes through it.
36
+ - `app/api/admin/orders/[id]/ship-with-colissimo/route.ts` (NEW) — POST
37
+ `shipWithColissimo`; `app/api/admin/orders/[id]/colissimo-defaults/route.ts`
38
+ (NEW) — GET `getColissimoDefaults`; `app/api/admin/orders/[id]/label/route.ts`
39
+ (NEW) — GET `downloadOrderLabel` (admin-gated label bytes; `orders.label_url`
40
+ points at this path for Colissimo labels).
41
+
42
+ ## Behavior contracts
43
+ - `checkout/api/shipping` (quote) now UNIONS all active carriers' DB rates
44
+ with Shippo live quotes when a `provider='shippo'` carrier is active —
45
+ `store_settings.shipping_mode` no longer selects a path. A legacy
46
+ `shipping_mode='shippo'` store self-heals a shippo carrier row
47
+ (`ensureLegacyShippoCarrier`) on the first quote/admin-carriers read.
48
+ Response `mode` field is now the constant `'manual'` (legacy shape only).
49
+ - `resolveShippingSelection` manual branch: rates from provider-bound
50
+ carriers stamp `orders.carrier` with the PROVIDER (`'colissimo'`), not the
51
+ carrier's slug. Rates with `fulfillment='relay'` REQUIRE
52
+ `selection.relayPointId`; the point is re-verified with the carrier and a
53
+ French mobile is required on the shipping address (PricingError
54
+ otherwise). The relay's address becomes the order's `shippingAddress`
55
+ snapshot ("Point relais — {name}" convention, mirroring §59 pickup); the
56
+ customer's own entered address is preserved as `billingAddress` when no
57
+ separate billing was given.
58
+ - `ShippingOption.source` union is unchanged (`manual|shippo|pickup`) but
59
+ options gained `provider?`/`fulfillment?`/`relayPointId?` — custom
60
+ checkout code switching on `source` keeps working.
61
+ - Admin `ShippingSettings` is carriers-first: the manual/shippo mode toggle
62
+ is GONE; Shippo config renders inside its carrier card (own transactional
63
+ Save), the AdminSaveBar document now tracks only `shippingCountries`.
64
+
65
+ ## Custom-code hazards
66
+ - grep `shippingMode` in store code: any UI/logic branching on
67
+ `'manual' | 'shippo'` is dead — the quote response's `mode` is now a
68
+ constant. Replace with capability checks on the options themselves.
69
+ - grep `source === 'relay'` (stores that adopted 0.20.0 pre-releases only):
70
+ the relay discriminator is `fulfillment === 'relay'`; `'relay'` was never
71
+ a published `source` value.
72
+ - Stores with a custom checkout that forked `ShippingOptions`: the fork
73
+ misses the carrier-group containers and the `renderOptionDetail` slot —
74
+ relay rates will render without a point picker. Replace the fork or port
75
+ the slot.
76
+
77
+ ## DB
78
+ - `shipping_carriers.provider varchar(20) NOT NULL DEFAULT 'manual'`,
79
+ `shipping_carriers.logo_url varchar(500)`,
80
+ `shipping_rates.fulfillment varchar(20) NOT NULL DEFAULT 'home'` — all
81
+ self-heal via `ensureShippingCarrierSchema()` at every carrier/zone/rate
82
+ chokepoint. Defaults make existing data behave identically.
83
+ - `orders.relay jsonb` (`{provider,id,type,name}`) — rides
84
+ `ensurePaymentMethodsSchema()`.
85
+ - `shipping_labels` (NEW table: order_id FK cascade, carrier, format,
86
+ data base64) — self-heals whole via `ensureShippingLabelsSchema()`.
87
+ Deliberately not a column on orders (drizzle full-row selects).
88
+ - `store_settings`: `colissimo_contract_number varchar(20)`,
89
+ `colissimo_password varchar(64)` (SERVER-ONLY secret — stripped from the
90
+ admin settings GET; never `NEXT_PUBLIC_`, never client-side),
91
+ `colissimo_enabled boolean`, `colissimo_sender_address jsonb`,
92
+ `colissimo_default_weight_kg decimal` — ride `ensureStoreSettingsSchema()`.
93
+
94
+ ## New surfaces
95
+ - The five routes in Template contract above. No new admin PAGES — the
96
+ Colissimo panel lives inside `/admin/shipping`'s carrier card and the
97
+ "Ship with Colissimo" card inside the existing order detail page.
98
+
99
+ ## MERCHANT-DATA HAZARD
100
+ - A store that ran `shipping_mode='shippo'`: its Shippo config keeps working
101
+ through the self-healed carrier row, but the row is created ACTIVE — if
102
+ the merchant had abandoned Shippo (mode set but key removed), the quote
103
+ path silently skips it (no key → degraded, no options added). Audit: does
104
+ the store have `shippo_api_key` set AND `shipping_mode='shippo'`? If mode
105
+ is shippo but the key is gone, deactivate the self-healed carrier row.
106
+ - Parcel weight for Colissimo labels reads the product `weight` METAFIELD
107
+ (kg, PrestaShop-import convention) with `colissimo_default_weight_kg` as
108
+ the per-item fallback — stores without weight metafields ship at the
109
+ default weight unless the admin overrides per label.
110
+
111
+ ## Verify
112
+ - `/admin/shipping`: carriers list renders (no mode toggle); "Add carrier"
113
+ offers Manual/Colissimo/Shippo with duplicates disabled; a Colissimo
114
+ carrier card shows the Connection panel and its zones/rates; the rate
115
+ editor on a Colissimo carrier shows "Delivery type: Home / Pickup point".
116
+ - Checkout with a FR address: carrier groups render with badges, sorted by
117
+ price desc; selecting a relay rate opens the nested point picker; continue
118
+ is blocked until a point is picked and the address has a FR mobile.
119
+ - Place a relay order (manual payment path is fine): `orders.relay` set,
120
+ `shipping_address` = the relay's address, `carrier='colissimo'`.
121
+ - Admin: mark paid → "Ship with Colissimo" (weight prefilled from
122
+ metafields) → Generate Label & Ship → tracking number appears (`6M`/`6H`
123
+ prefix for relay, `6A`/`6C` for home), label downloads from
124
+ `/api/admin/orders/{id}/label`, shipped email sent with tracking.
125
+ - `npm run build` green.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rovela-ai/sdk",
3
- "version": "0.19.7",
3
+ "version": "0.20.0",
4
4
  "description": "Rovela SDK - Pre-built e-commerce components for AI-powered store generation",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -90,6 +90,10 @@
90
90
  "types": "./dist/checkout/api/pickup-locations.d.ts",
91
91
  "import": "./dist/checkout/api/pickup-locations.js"
92
92
  },
93
+ "./checkout/api/colissimo-relays": {
94
+ "types": "./dist/checkout/api/colissimo-relays.d.ts",
95
+ "import": "./dist/checkout/api/colissimo-relays.js"
96
+ },
93
97
  "./checkout/server": {
94
98
  "types": "./dist/checkout/server/index.d.ts",
95
99
  "import": "./dist/checkout/server/index.js"
@@ -292,6 +296,7 @@
292
296
  },
293
297
  "scripts": {
294
298
  "build": "tsc && cp -r src/admin/styles dist/admin/",
299
+ "prepublishOnly": "npm run build && cd ../.. && bash scripts/check-prompts.sh",
295
300
  "dev": "tsc --watch",
296
301
  "clean": "rm -rf dist tsconfig.tsbuildinfo",
297
302
  "db:push": "drizzle-kit push",
@@ -123,6 +123,8 @@ export default function AdminMyFeaturePage() {
123
123
  useEffect(() => {
124
124
  fetch('/api/admin/my-feature')
125
125
  .then(res => res.ok ? res.json() : Promise.reject(res))
126
+ // Admin API responses are ENVELOPED: { data: … }. Always unwrap — reading
127
+ // the top level fails silently (your own null-guard hides the miss).
126
128
  .then(json => setData(json.data || []))
127
129
  .catch(() => setLoadError('Could not load. Refresh to retry.'))
128
130
  .finally(() => setLoading(false))
@@ -33,7 +33,7 @@ Usage: `nextjs_call` with `port="3000"` and `toolName="execute_sql"`
33
33
  | `orders` | id, customerId, email, status, total, currency (ISO snapshot — display orders in THIS currency), refundAmount, returnReason, shippingAddress (JSONB) |
34
34
  | `order_items` | id, orderId (CASCADE), productId, variantId, name, price, quantity |
35
35
  | `customers` | id, email (unique), name, passwordHash, phone, groupId, locale, stripeCustomerId, emailVerified |
36
- | `store_settings` | id, storeName, storeEmail, storeCurrency, storeTimezone, storeCountry, defaultLocale, enabledLocales, taxIncludedInPrices, shippingMode |
36
+ | `store_settings` | id, storeName, storeEmail, storeCurrency, storeTimezone, storeCountry, defaultLocale, enabledLocales, taxIncludedInPrices, shippingMode (retired — the shipping_carriers registry decides; carriers have provider manual/shippo/colissimo, rates have fulfillment home/relay) |
37
37
 
38
38
  **Money contract (load-bearing)**: `price`, `total` etc. are DECIMAL CURRENCY UNITS — `29.99`, NEVER cents (`2999`). No ×100/÷100 anywhere except the Stripe API boundary. On multilingual stores (`enabled_locales`), catalog content can carry per-locale `translations` — when editing names/descriptions, keep every enabled locale in sync (CLAUDE.md §5.5).
39
39
 
@@ -135,6 +135,13 @@ Import: `@rovela-ai/sdk/auth`
135
135
  Import: `@rovela-ai/sdk/media`
136
136
 
137
137
  ### Other modules (rarely overridden)
138
+ **Cart-reading contract (any component that touches the cart):** read via
139
+ `useCart((s) => s.items)` selectors — NEVER read the cart's localStorage during
140
+ render (hydration mismatch) and never call `persist.rehydrate()` yourself
141
+ (`CartProvider` hydrates pre-paint). A page that redirects on an empty cart
142
+ gates the redirect on `useCartHydrated()` first, or it ejects real carts on
143
+ reload.
144
+
138
145
  The SDK has 11 modules total. Also available: `core` (StoreSettingsProvider, i18n `useT`/`LocaleLink`, cookie consent), `analytics` (AnalyticsProvider + admin views), `emails` (templates + the merchant-editable layer — edited at `/admin/emails`, not by overriding components), `admin` (the dashboard kit — admin components are NOT candidates for copy-and-modify overrides; custom admin pages compose the kit per CLAUDE.md §7.6 instead), `shipping`, `theme`.
139
146
 
140
147
  ## Common Overrides
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Pre-fill data for the "Ship with Colissimo" card (weight suggestion, relay)
3
+ */
4
+ import { getColissimoDefaults } from '@rovela-ai/sdk/admin/api'
5
+
6
+ export { getColissimoDefaults as GET }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Download the stored carrier label for an order (admin-gated — labels carry PII)
3
+ */
4
+ import { downloadOrderLabel } from '@rovela-ai/sdk/admin/api'
5
+
6
+ export { downloadOrderLabel as GET }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generate a Colissimo shipping label for an order
3
+ */
4
+ import { shipWithColissimo } from '@rovela-ai/sdk/admin/api'
5
+
6
+ export { shipWithColissimo as POST }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Colissimo configuration (connection, sender address, relay delivery)
3
+ */
4
+ import {
5
+ getColissimoConfig,
6
+ saveColissimoSettings,
7
+ deleteColissimoSettings,
8
+ } from '@rovela-ai/sdk/admin/api'
9
+
10
+ export { getColissimoConfig as GET, saveColissimoSettings as POST, deleteColissimoSettings as DELETE }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Colissimo pickup-point search (checkout relay picker)
3
+ */
4
+ export { POST } from '@rovela-ai/sdk/checkout/api/colissimo-relays'
@@ -9,7 +9,7 @@
9
9
  "lint": "eslint ."
10
10
  },
11
11
  "dependencies": {
12
- "@rovela-ai/sdk": "0.19.7",
12
+ "@rovela-ai/sdk": "0.20.0",
13
13
  "@tailwindcss/forms": "0.5.11",
14
14
  "@tailwindcss/typography": "0.5.19",
15
15
  "autoprefixer": "10.4.24",