@mohasinac/appkit 4.62.0 → 4.63.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 (391) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +8 -29
  3. package/dist/_internal/client/features/layout/filterNavItems.d.ts +28 -0
  4. package/dist/_internal/client/features/layout/filterNavItems.js +35 -0
  5. package/dist/_internal/server/features/ads/booking.d.ts +118 -0
  6. package/dist/_internal/server/features/ads/booking.js +326 -0
  7. package/dist/_internal/server/features/checkout/actions.d.ts +129 -9
  8. package/dist/_internal/server/features/checkout/actions.js +850 -79
  9. package/dist/_internal/server/features/checkout/expand-order-items.d.ts +1 -2
  10. package/dist/_internal/server/features/checkout/expand-order-items.js +32 -0
  11. package/dist/_internal/server/features/checkout/freeze-parts.d.ts +50 -0
  12. package/dist/_internal/server/features/checkout/freeze-parts.js +94 -0
  13. package/dist/_internal/server/features/checkout/value-otp-gate.d.ts +55 -0
  14. package/dist/_internal/server/features/checkout/value-otp-gate.js +60 -0
  15. package/dist/_internal/server/features/dashboard/attention.d.ts +128 -0
  16. package/dist/_internal/server/features/dashboard/attention.js +183 -0
  17. package/dist/_internal/server/features/dashboard/data.d.ts +47 -0
  18. package/dist/_internal/server/features/dashboard/data.js +82 -0
  19. package/dist/_internal/server/features/inventory/reservations.d.ts +99 -0
  20. package/dist/_internal/server/features/inventory/reservations.js +273 -0
  21. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  22. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  23. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  24. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  25. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  26. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  27. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  28. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  29. package/dist/_internal/server/features/offers/destinations.d.ts +40 -0
  30. package/dist/_internal/server/features/offers/destinations.js +65 -0
  31. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  32. package/dist/_internal/server/features/orders/actions.js +81 -8
  33. package/dist/_internal/server/features/orders/adapters.js +54 -0
  34. package/dist/_internal/server/features/orders/amend-delivery.d.ts +56 -0
  35. package/dist/_internal/server/features/orders/amend-delivery.js +124 -0
  36. package/dist/_internal/server/features/orders/balance.d.ts +89 -0
  37. package/dist/_internal/server/features/orders/balance.js +256 -0
  38. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  39. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  40. package/dist/_internal/server/features/points/award.js +46 -4
  41. package/dist/_internal/server/features/pricing/actions.d.ts +58 -0
  42. package/dist/_internal/server/features/pricing/actions.js +144 -0
  43. package/dist/_internal/server/features/refunds/actions.js +26 -0
  44. package/dist/_internal/server/features/shipping/book-split.d.ts +86 -0
  45. package/dist/_internal/server/features/shipping/book-split.js +130 -0
  46. package/dist/_internal/server/features/shipping/book.d.ts +61 -0
  47. package/dist/_internal/server/features/shipping/book.js +176 -0
  48. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  49. package/dist/_internal/server/features/shipping/courier-block.js +264 -0
  50. package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
  51. package/dist/_internal/server/features/site-settings/adapters.js +29 -0
  52. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  53. package/dist/_internal/server/features/stores/adapters.js +65 -0
  54. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  55. package/dist/_internal/server/functions/scheduled.js +95 -2
  56. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +11 -2
  57. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  58. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  59. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  60. package/dist/_internal/server/jobs/core/index.js +2 -1
  61. package/dist/_internal/server/jobs/core/jobRunners.js +45 -0
  62. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  63. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  64. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  65. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +65 -0
  66. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  67. package/dist/_internal/server/jobs/core/reservationExpiry.d.ts +17 -0
  68. package/dist/_internal/server/jobs/core/reservationExpiry.js +40 -0
  69. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  70. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  71. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +25 -2
  72. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  73. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  74. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  75. package/dist/_internal/server/jobs/handlers/reservationExpiry.d.ts +2 -0
  76. package/dist/_internal/server/jobs/handlers/reservationExpiry.js +2 -0
  77. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  78. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  79. package/dist/_internal/shared/actions/action-registry.js +296 -0
  80. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  81. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  82. package/dist/_internal/shared/checkout/order-math.d.ts +174 -0
  83. package/dist/_internal/shared/checkout/order-math.js +159 -0
  84. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  85. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  86. package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
  87. package/dist/_internal/shared/checkout/rules/index.js +1 -1
  88. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +18 -0
  89. package/dist/_internal/shared/checkout/rules/payment-gate.js +25 -0
  90. package/dist/_internal/shared/checkout/split.d.ts +75 -0
  91. package/dist/_internal/shared/checkout/split.js +120 -0
  92. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  93. package/dist/_internal/shared/content/disclaimers.js +217 -0
  94. package/dist/_internal/shared/content/published-values.d.ts +93 -0
  95. package/dist/_internal/shared/content/published-values.js +206 -0
  96. package/dist/_internal/shared/features/admin/integrations.d.ts +139 -0
  97. package/dist/_internal/shared/features/admin/integrations.js +263 -0
  98. package/dist/_internal/shared/features/dashboard/hub-sections.d.ts +72 -0
  99. package/dist/_internal/shared/features/dashboard/hub-sections.js +75 -0
  100. package/dist/_internal/shared/features/emi/choice.d.ts +98 -0
  101. package/dist/_internal/shared/features/emi/choice.js +69 -0
  102. package/dist/_internal/shared/features/emi/group.d.ts +84 -0
  103. package/dist/_internal/shared/features/emi/group.js +126 -0
  104. package/dist/_internal/shared/features/ledger/posting.d.ts +107 -0
  105. package/dist/_internal/shared/features/ledger/posting.js +165 -0
  106. package/dist/_internal/shared/features/ledger/reports.d.ts +76 -0
  107. package/dist/_internal/shared/features/ledger/reports.js +127 -0
  108. package/dist/_internal/shared/features/ledger/rules.d.ts +170 -0
  109. package/dist/_internal/shared/features/ledger/rules.js +221 -0
  110. package/dist/_internal/shared/features/offers/coordination.d.ts +122 -0
  111. package/dist/_internal/shared/features/offers/coordination.js +80 -0
  112. package/dist/_internal/shared/features/orders/delivery-snapshot.d.ts +114 -0
  113. package/dist/_internal/shared/features/orders/delivery-snapshot.js +116 -0
  114. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  115. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  116. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  117. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  118. package/dist/_internal/shared/features/payouts/pay-period.d.ts +91 -0
  119. package/dist/_internal/shared/features/payouts/pay-period.js +104 -0
  120. package/dist/_internal/shared/features/points/accepts.d.ts +29 -0
  121. package/dist/_internal/shared/features/points/accepts.js +49 -0
  122. package/dist/_internal/shared/features/pricing/rate-registry.d.ts +150 -0
  123. package/dist/_internal/shared/features/pricing/rate-registry.js +246 -0
  124. package/dist/_internal/shared/features/shipping/parcel.d.ts +123 -0
  125. package/dist/_internal/shared/features/shipping/parcel.js +139 -0
  126. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  127. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  128. package/dist/_internal/shared/features/site-settings/fees.d.ts +16 -8
  129. package/dist/_internal/shared/features/site-settings/fees.js +12 -8
  130. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  131. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  132. package/dist/_internal/shared/fees/calculator.js +32 -2
  133. package/dist/_internal/shared/fees/explain.d.ts +81 -0
  134. package/dist/_internal/shared/fees/explain.js +101 -0
  135. package/dist/_internal/shared/history/index.d.ts +1 -1
  136. package/dist/_internal/shared/history/index.js +1 -1
  137. package/dist/_internal/shared/history/types.d.ts +7 -1
  138. package/dist/_internal/shared/history/types.js +25 -0
  139. package/dist/client.d.ts +21 -0
  140. package/dist/client.js +43 -0
  141. package/dist/constants/api-endpoints.d.ts +114 -0
  142. package/dist/constants/api-endpoints.js +55 -0
  143. package/dist/constants/field-names.d.ts +42 -0
  144. package/dist/constants/field-names.js +52 -0
  145. package/dist/contracts/index.d.ts +1 -1
  146. package/dist/contracts/shipping.d.ts +45 -0
  147. package/dist/contracts/shipping.js +15 -0
  148. package/dist/features/about/components/AboutView.js +1 -1
  149. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  150. package/dist/features/account/components/UserOrdersView.js +47 -35
  151. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  152. package/dist/features/admin/components/AdminIntegrationsView.d.ts +55 -0
  153. package/dist/features/admin/components/AdminIntegrationsView.js +74 -0
  154. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  155. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  156. package/dist/features/admin/components/AdminOrderEditorView.d.ts +33 -1
  157. package/dist/features/admin/components/AdminOrderEditorView.js +81 -3
  158. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  159. package/dist/features/admin/components/AdminOrdersView.js +86 -5
  160. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  161. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  162. package/dist/features/admin/constants/filter-tabs.js +6 -0
  163. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  164. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  165. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  166. package/dist/features/admin/schemas/firestore.d.ts +62 -0
  167. package/dist/features/admin/schemas/firestore.js +5 -0
  168. package/dist/features/ads/schemas/booking-write.d.ts +120 -0
  169. package/dist/features/ads/schemas/booking-write.js +75 -0
  170. package/dist/features/ads/schemas/creative-form.d.ts +18 -0
  171. package/dist/features/ads/schemas/creative-form.js +51 -0
  172. package/dist/features/ads/schemas/firestore.d.ts +140 -0
  173. package/dist/features/ads/schemas/firestore.js +109 -0
  174. package/dist/features/auctions/repository/bid.repository.js +3 -1
  175. package/dist/features/audit-log/schemas/firestore.d.ts +140 -0
  176. package/dist/features/audit-log/schemas/firestore.js +89 -0
  177. package/dist/features/auth/actions/profile-actions.d.ts +69 -1
  178. package/dist/features/auth/actions/profile-actions.js +62 -1
  179. package/dist/features/auth/permissions/constants.js +13 -0
  180. package/dist/features/auth/schemas/firestore.d.ts +16 -2
  181. package/dist/features/auth/schemas/firestore.js +2 -1
  182. package/dist/features/blog/actions/blog-actions.d.ts +6 -0
  183. package/dist/features/blog/actions/blog-actions.js +17 -2
  184. package/dist/features/blog/api/route.js +4 -1
  185. package/dist/features/blog/columns/index.js +5 -0
  186. package/dist/features/blog/components/BlogIndexPageView.js +2 -1
  187. package/dist/features/blog/repository/blog.repository.d.ts +4 -0
  188. package/dist/features/blog/repository/blog.repository.js +5 -0
  189. package/dist/features/blog/schemas/blog-form.d.ts +3 -0
  190. package/dist/features/blog/schemas/blog-form.js +1 -0
  191. package/dist/features/blog/schemas/firestore.d.ts +38 -1
  192. package/dist/features/blog/schemas/firestore.js +23 -0
  193. package/dist/features/blog/schemas/index.d.ts +6 -0
  194. package/dist/features/blog/schemas/index.js +2 -0
  195. package/dist/features/blog/types/index.d.ts +2 -0
  196. package/dist/features/cart/components/CartPriceBreakdown.d.ts +25 -1
  197. package/dist/features/cart/components/CartPriceBreakdown.js +29 -6
  198. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  199. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  200. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  201. package/dist/features/cart/components/index.d.ts +2 -0
  202. package/dist/features/cart/components/index.js +1 -0
  203. package/dist/features/cart/repository/cart.repository.d.ts +33 -0
  204. package/dist/features/cart/repository/cart.repository.js +47 -0
  205. package/dist/features/cart/schemas/firestore.d.ts +116 -0
  206. package/dist/features/contact/email.d.ts +27 -10
  207. package/dist/features/contact/email.js +20 -3
  208. package/dist/features/dashboard/components/DashboardHubView.d.ts +83 -0
  209. package/dist/features/dashboard/components/DashboardHubView.js +56 -0
  210. package/dist/features/dashboard/components/DashboardSectionsClient.d.ts +23 -0
  211. package/dist/features/dashboard/components/DashboardSectionsClient.js +66 -0
  212. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.d.ts +55 -0
  213. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +175 -0
  214. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +62 -0
  215. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +108 -0
  216. package/dist/features/dispute-reasons/schemas/firestore.d.ts +62 -0
  217. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  218. package/dist/features/events/components/EventSaleBanner.js +1 -1
  219. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  220. package/dist/features/faq/components/FAQAccordion.js +29 -4
  221. package/dist/features/faq/components/FAQPageContent.js +2 -2
  222. package/dist/features/gateway-events/schemas/index.d.ts +2 -2
  223. package/dist/features/homepage/schemas/index.d.ts +8 -8
  224. package/dist/features/inventory/schemas/stock-reservation.d.ts +114 -0
  225. package/dist/features/inventory/schemas/stock-reservation.js +103 -0
  226. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  227. package/dist/features/invoicing/schemas/firestore.js +45 -0
  228. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  229. package/dist/features/invoicing/utils/financial-year.js +53 -0
  230. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  231. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  232. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  233. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  234. package/dist/features/jobs/schemas/firestore.js +37 -0
  235. package/dist/features/layout/AppLayoutShell.d.ts +9 -1
  236. package/dist/features/layout/AppLayoutShell.js +12 -4
  237. package/dist/features/layout/BottomActions.js +2 -1
  238. package/dist/features/layout/BottomNavbar.d.ts +10 -2
  239. package/dist/features/layout/SideActionDock.js +52 -2
  240. package/dist/features/layout/TitleBarLayout.js +13 -4
  241. package/dist/features/layout/TitleBarLayout.style.css +59 -0
  242. package/dist/features/layout/useCtaReveal.d.ts +16 -1
  243. package/dist/features/layout/useCtaReveal.js +17 -26
  244. package/dist/features/ledger/repository/journal.repository.d.ts +110 -0
  245. package/dist/features/ledger/repository/journal.repository.js +312 -0
  246. package/dist/features/ledger/schemas/expenses.d.ts +87 -0
  247. package/dist/features/ledger/schemas/expenses.js +27 -0
  248. package/dist/features/ledger/schemas/firestore.d.ts +183 -0
  249. package/dist/features/ledger/schemas/firestore.js +69 -0
  250. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  251. package/dist/features/media/MediaImage.js +22 -1
  252. package/dist/features/media/upload/ImageUpload.js +1 -1
  253. package/dist/features/obligations/constants/policies.js +24 -1
  254. package/dist/features/orders/components/BalancePaymentPanel.d.ts +12 -0
  255. package/dist/features/orders/components/BalancePaymentPanel.js +94 -0
  256. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  257. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  258. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  259. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  260. package/dist/features/orders/components/RaiseDisputeForm.js +119 -0
  261. package/dist/features/orders/components/RefundRequestView.js +19 -1
  262. package/dist/features/orders/components/index.d.ts +4 -0
  263. package/dist/features/orders/components/index.js +2 -0
  264. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  265. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  266. package/dist/features/orders/repository/orders.repository.d.ts +85 -1
  267. package/dist/features/orders/repository/orders.repository.js +205 -6
  268. package/dist/features/orders/schemas/balance.d.ts +40 -0
  269. package/dist/features/orders/schemas/balance.js +47 -0
  270. package/dist/features/orders/schemas/firestore.d.ts +398 -1
  271. package/dist/features/orders/schemas/firestore.js +43 -0
  272. package/dist/features/orders/schemas/index.d.ts +56 -8
  273. package/dist/features/orders/schemas/index.js +12 -0
  274. package/dist/features/orders/types/index.d.ts +47 -0
  275. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  276. package/dist/features/orders/utils/courier-block.js +23 -0
  277. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  278. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  279. package/dist/features/payments/repository/payout.repository.js +3 -2
  280. package/dist/features/payments/schemas/firestore.d.ts +92 -1
  281. package/dist/features/payments/schemas/firestore.js +23 -0
  282. package/dist/features/pricing/components/AdminPricingView.d.ts +13 -0
  283. package/dist/features/pricing/components/AdminPricingView.js +157 -0
  284. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  285. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  286. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  287. package/dist/features/products/schemas/firestore.d.ts +26 -1
  288. package/dist/features/products/schemas/firestore.js +2 -0
  289. package/dist/features/products/schemas/index.d.ts +2 -2
  290. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  291. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  292. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  293. package/dist/features/promotions/components/CouponCard.js +13 -0
  294. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  295. package/dist/features/promotions/constants/coupon-help.js +9 -1
  296. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  297. package/dist/features/promotions/schemas/firestore.js +4 -0
  298. package/dist/features/promotions/types/index.d.ts +19 -1
  299. package/dist/features/reviews/repository/reviews.repository.d.ts +14 -0
  300. package/dist/features/reviews/repository/reviews.repository.js +16 -0
  301. package/dist/features/scams/components/ScamProfileView.js +2 -2
  302. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  303. package/dist/features/scams/repository/scammer.repository.js +2 -1
  304. package/dist/features/scams/schemas/firestore.d.ts +2 -1
  305. package/dist/features/scams/schemas/firestore.js +2 -1
  306. package/dist/features/search/action-index/tab-entries.js +1 -1
  307. package/dist/features/seller/actions/offer-actions.js +56 -0
  308. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  309. package/dist/features/seller/actions/seller-actions.js +37 -3
  310. package/dist/features/seller/components/DispatchForm.d.ts +11 -0
  311. package/dist/features/seller/components/DispatchForm.js +190 -0
  312. package/dist/features/seller/components/SellerOrdersView.js +221 -27
  313. package/dist/features/seller/components/index.d.ts +1 -0
  314. package/dist/features/seller/components/index.js +1 -0
  315. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  316. package/dist/features/seller/repository/offer.repository.js +4 -3
  317. package/dist/features/seller/schemas/firestore.d.ts +23 -2
  318. package/dist/features/seller/schemas/firestore.js +3 -2
  319. package/dist/features/seller/schemas/index.d.ts +4 -4
  320. package/dist/features/seller/schemas/order-forms.d.ts +61 -4
  321. package/dist/features/seller/schemas/order-forms.js +41 -8
  322. package/dist/features/shipments/schemas/firestore.d.ts +25 -0
  323. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  324. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +82 -0
  325. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +145 -0
  326. package/dist/features/shipping-boxes/schemas/firestore.d.ts +80 -0
  327. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  328. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  329. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  330. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  331. package/dist/features/stores/repository/store.repository.d.ts +18 -0
  332. package/dist/features/stores/repository/store.repository.js +27 -1
  333. package/dist/features/stores/schemas/firestore.d.ts +112 -0
  334. package/dist/features/stores/schemas/firestore.js +20 -0
  335. package/dist/features/stores/schemas/index.d.ts +6 -6
  336. package/dist/features/stores/types/index.d.ts +19 -0
  337. package/dist/features/support/repository/support.repository.js +72 -6
  338. package/dist/features/support/schemas/firestore.d.ts +17 -0
  339. package/dist/features/support/schemas/index.d.ts +8 -8
  340. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  341. package/dist/index.d.ts +11 -1
  342. package/dist/index.js +33 -1
  343. package/dist/next/routing/route-map.d.ts +112 -0
  344. package/dist/next/routing/route-map.js +63 -0
  345. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  346. package/dist/providers/shipping-shiprocket/index.js +84 -1
  347. package/dist/react/contexts/SessionContext.d.ts +17 -1
  348. package/dist/schemas/registry.d.ts +69 -34
  349. package/dist/schemas/sieve.d.ts +2 -2
  350. package/dist/security/pii-schemas.d.ts +1 -1
  351. package/dist/security/pii-schemas.js +45 -0
  352. package/dist/server-entry.d.ts +2 -2
  353. package/dist/server-entry.js +8 -1
  354. package/dist/server.d.ts +36 -1
  355. package/dist/server.js +183 -1
  356. package/dist/styles.css +412 -80
  357. package/dist/tailwind-utilities.css +1 -1
  358. package/dist/tokens/themes/default-dark.js +1 -0
  359. package/dist/tokens/themes/default-light.js +1 -0
  360. package/dist/tokens/themes/required.d.ts +1 -1
  361. package/dist/tokens/themes/required.js +1 -0
  362. package/dist/tokens/tokens.css +15 -0
  363. package/dist/ui/components/Button.d.ts +10 -1
  364. package/dist/ui/components/Button.js +25 -3
  365. package/dist/ui/components/Chart.d.ts +63 -0
  366. package/dist/ui/components/Chart.js +169 -0
  367. package/dist/ui/components/Chart.style.css +214 -0
  368. package/dist/ui/components/Disclaimer.d.ts +19 -0
  369. package/dist/ui/components/Disclaimer.js +83 -0
  370. package/dist/ui/components/OverflowRow.js +54 -2
  371. package/dist/ui/components/OverflowRow.style.css +38 -0
  372. package/dist/ui/components/RichTextEditor.js +99 -8
  373. package/dist/ui/components/chart-spec.d.ts +68 -0
  374. package/dist/ui/components/chart-spec.js +140 -0
  375. package/dist/ui/components/index.style.css +1 -0
  376. package/dist/ui/components/surface-tokens.d.ts +1 -1
  377. package/dist/ui/components/surface-tokens.js +9 -0
  378. package/dist/ui/components/tabs-overflow.js +64 -11
  379. package/dist/ui/components/toolbar-collapse.d.ts +13 -0
  380. package/dist/ui/components/toolbar-collapse.js +10 -1
  381. package/dist/ui/index.d.ts +8 -0
  382. package/dist/ui/index.js +9 -0
  383. package/dist/ui/rich-text/RichText.d.ts +10 -1
  384. package/dist/ui/rich-text/RichText.js +33 -2
  385. package/dist/ui/rich-text/RichText.style.css +83 -79
  386. package/dist/ui/rich-text/RichTextRenderer.d.ts +30 -1
  387. package/dist/ui/rich-text/RichTextRenderer.js +34 -2
  388. package/dist/ui/rich-text/chart-blocks.d.ts +62 -0
  389. package/dist/ui/rich-text/chart-blocks.js +87 -0
  390. package/package.json +1 -1
  391. package/scripts/seed-cli.mjs +1834 -1822
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The ONE write path for a platform rate.
3
+ *
4
+ * ## Why there is exactly one
5
+ *
6
+ * Rates live on `siteSettings`, which `PUT /api/admin/site` can already write
7
+ * — so this is not the only way the numbers CAN move. It is the only way they
8
+ * move with a recorded reason, an effective date and an `adminAuditLog` row,
9
+ * and that difference is the whole point of `/admin/pricing`.
10
+ *
11
+ * The general settings form stays able to write them. Locking it out would
12
+ * mean an admin fixing a typo in the COD ceiling gets a 400 from the page that
13
+ * has always owned it, and the fix would be to come here — which is a worse
14
+ * outcome than an occasional unlogged edit. What this buys is that the
15
+ * DELIBERATE act of repricing has one door with a record behind it.
16
+ *
17
+ * ## 🛑 Forward-only, enforced at the WRITE
18
+ *
19
+ * `rejectRateChange` is a pure function and lives in the registry so the form
20
+ * can run it too — but the form running it is a courtesy, and this is the
21
+ * enforcement. A backdated change here would restate figures already invoiced
22
+ * and already paid out; see the registry header.
23
+ */
24
+ /**
25
+ * How many changes the log keeps, newest first.
26
+ *
27
+ * Sized so a year of ordinary repricing fits: 16 rates changed a few times
28
+ * each is well under this, and the page shows only the most recent per rate
29
+ * anyway. The cap exists because the array rides on a document every request
30
+ * reads, not because 200 entries is a lot of data.
31
+ */
32
+ export declare const RATE_CHANGE_LOG_MAX = 200;
33
+ export interface ApplyRateChangeInput {
34
+ path: string;
35
+ newValue: number;
36
+ /** Omit for "now". Never earlier than now — see `rejectRateChange`. */
37
+ effectiveFrom?: Date;
38
+ reason?: string;
39
+ }
40
+ export interface ApplyRateChangeResult {
41
+ path: string;
42
+ previousValue: number | null;
43
+ newValue: number;
44
+ effectiveFrom: Date;
45
+ }
46
+ /**
47
+ * Change one rate.
48
+ *
49
+ * 🛑 **One rate per call, on purpose.** A bulk form would need one reason
50
+ * covering a heterogeneous set, which is the same argument that removed the
51
+ * bulk offer-cancel: one shared reason across unlike records is worse audit
52
+ * data than no bulk action. Repricing three things is three decisions.
53
+ */
54
+ export declare function applyRateChange(input: ApplyRateChangeInput, actor: {
55
+ uid: string;
56
+ name?: string;
57
+ isAdmin: boolean;
58
+ }, now?: Date): Promise<ApplyRateChangeResult>;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The ONE write path for a platform rate.
3
+ *
4
+ * ## Why there is exactly one
5
+ *
6
+ * Rates live on `siteSettings`, which `PUT /api/admin/site` can already write
7
+ * — so this is not the only way the numbers CAN move. It is the only way they
8
+ * move with a recorded reason, an effective date and an `adminAuditLog` row,
9
+ * and that difference is the whole point of `/admin/pricing`.
10
+ *
11
+ * The general settings form stays able to write them. Locking it out would
12
+ * mean an admin fixing a typo in the COD ceiling gets a 400 from the page that
13
+ * has always owned it, and the fix would be to come here — which is a worse
14
+ * outcome than an occasional unlogged edit. What this buys is that the
15
+ * DELIBERATE act of repricing has one door with a record behind it.
16
+ *
17
+ * ## 🛑 Forward-only, enforced at the WRITE
18
+ *
19
+ * `rejectRateChange` is a pure function and lives in the registry so the form
20
+ * can run it too — but the form running it is a courtesy, and this is the
21
+ * enforcement. A backdated change here would restate figures already invoiced
22
+ * and already paid out; see the registry header.
23
+ */
24
+ import { getAdminDb } from "../../../../providers/db-firebase/index.js";
25
+ import { siteSettingsRepository } from "../../../../features/admin/repository/site-settings.repository.js";
26
+ import { SITE_SETTINGS_COLLECTION, } from "../../../../features/admin/schemas/firestore.js";
27
+ import { canEditRate, rateByPath, rejectRateChange, } from "../../../shared/features/pricing/rate-registry.js";
28
+ import { recordAdminAction } from "../audit-log/actions.js";
29
+ import { AdminAuditActionValues } from "../../../../features/audit-log/schemas/firestore.js";
30
+ import { normalizeError } from "../../../../errors/normalize.js";
31
+ import { serverLogger } from "../../../../monitoring/server-logger.js";
32
+ import { ValidationError } from "../../../../errors/validation-error.js";
33
+ const SINGLETON_ID = "global";
34
+ /**
35
+ * How many changes the log keeps, newest first.
36
+ *
37
+ * Sized so a year of ordinary repricing fits: 16 rates changed a few times
38
+ * each is well under this, and the page shows only the most recent per rate
39
+ * anyway. The cap exists because the array rides on a document every request
40
+ * reads, not because 200 entries is a lot of data.
41
+ */
42
+ export const RATE_CHANGE_LOG_MAX = 200;
43
+ /** Read a dotted path off the settings document. `null` when absent. */
44
+ function readRate(settings, path) {
45
+ const value = path
46
+ .split(".")
47
+ .reduce((acc, key) => (acc && typeof acc === "object" ? acc[key] : undefined), settings);
48
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
49
+ }
50
+ /**
51
+ * Change one rate.
52
+ *
53
+ * 🛑 **One rate per call, on purpose.** A bulk form would need one reason
54
+ * covering a heterogeneous set, which is the same argument that removed the
55
+ * bulk offer-cancel: one shared reason across unlike records is worse audit
56
+ * data than no bulk action. Repricing three things is three decisions.
57
+ */
58
+ export async function applyRateChange(input, actor, now = new Date()) {
59
+ const descriptor = rateByPath(input.path);
60
+ if (!descriptor) {
61
+ throw new ValidationError("That is not a rate this platform charges.", {
62
+ path: `Unknown rate: ${input.path}`,
63
+ });
64
+ }
65
+ if (!canEditRate(descriptor.tier, actor.isAdmin)) {
66
+ /*
67
+ * A statutory rate reaches this branch for EVERYONE, admins included —
68
+ * which is why the message names the real destination rather than
69
+ * implying the caller lacks a permission they could be granted.
70
+ */
71
+ throw new ValidationError(descriptor.tier === "statutory"
72
+ ? "Statutory rates are not set here — they are sourced per HSN code in Tax codes."
73
+ : "Only an administrator can change a policy ceiling.", { path: descriptor.label });
74
+ }
75
+ const settings = await siteSettingsRepository.getSingleton();
76
+ const previousValue = readRate(settings, descriptor.path);
77
+ const effectiveFrom = input.effectiveFrom ?? now;
78
+ const problem = rejectRateChange({ effectiveFrom, previousValue, newValue: input.newValue, reason: input.reason }, descriptor.tier, now);
79
+ if (problem) {
80
+ throw new ValidationError(problem, { newValue: problem });
81
+ }
82
+ const entry = {
83
+ path: descriptor.path,
84
+ previousValue,
85
+ newValue: input.newValue,
86
+ effectiveFrom,
87
+ changedByUid: actor.uid,
88
+ changedByName: actor.name ?? "",
89
+ ...(input.reason?.trim() ? { reason: input.reason.trim() } : {}),
90
+ changedAt: now,
91
+ };
92
+ /*
93
+ * 🛑 A DOTTED path for the rate, and a whole-array write for the log.
94
+ *
95
+ * `update()` replaces a nested map wholesale (D13, recorded at length in
96
+ * `updateSingleton`), so writing `{ commissions: { platformFeePercent: 2 } }`
97
+ * would delete every other commission. The dotted form touches one leaf.
98
+ *
99
+ * The log cannot use `arrayUnion` because that cannot enforce the cap — the
100
+ * same reason `withHistory`'s batch paths fold in memory. Newest first, so
101
+ * the slice drops the OLDEST.
102
+ */
103
+ const nextLog = [entry, ...(settings.rateChanges ?? [])].slice(0, RATE_CHANGE_LOG_MAX);
104
+ await getAdminDb()
105
+ .collection(SITE_SETTINGS_COLLECTION)
106
+ .doc(SINGLETON_ID)
107
+ .update({
108
+ [descriptor.path]: input.newValue,
109
+ rateChanges: nextLog,
110
+ updatedAt: now,
111
+ });
112
+ /*
113
+ * Best-effort, never fails the change — the same contract every other
114
+ * `recordAdminAction` caller has. The rate has already moved; refusing to
115
+ * acknowledge it because the log write failed would leave the admin
116
+ * believing it had not.
117
+ */
118
+ try {
119
+ await recordAdminAction({
120
+ actorUid: actor.uid,
121
+ actorName: actor.name,
122
+ action: AdminAuditActionValues.PRICING_UPDATE,
123
+ targetType: "siteSettings",
124
+ targetId: descriptor.path,
125
+ targetLabel: descriptor.label,
126
+ ...(input.reason?.trim() ? { reason: input.reason.trim() } : {}),
127
+ metadata: {
128
+ tier: descriptor.tier,
129
+ unit: descriptor.unit,
130
+ previousValue,
131
+ newValue: input.newValue,
132
+ effectiveFrom: effectiveFrom.toISOString(),
133
+ },
134
+ });
135
+ }
136
+ catch (err) {
137
+ const normalized = normalizeError(err);
138
+ serverLogger.warn("applyRateChange: audit log write failed", {
139
+ path: descriptor.path,
140
+ message: normalized.message,
141
+ });
142
+ }
143
+ return { path: descriptor.path, previousValue, newValue: input.newValue, effectiveFrom };
144
+ }
@@ -45,6 +45,8 @@ import { serverLogger } from "../../../../monitoring/index.js";
45
45
  import { isFinalSaleExempt, RETURN_REASON_LABEL, } from "../../../shared/features/orders/return-reasons.js";
46
46
  import { REFUND_COPY } from "../../../shared/features/orders/refund-copy.js";
47
47
  import { applyRefundDeductionAction } from "../payouts/actions.js";
48
+ /* Phase 7c — the credit note. Swallows its own failures by design: see its 🛑. */
49
+ import { issueCreditNoteForRefund } from "../invoicing/credit-note.js";
48
50
  import { getAdminDb } from "../../../../providers/db-firebase/index.js";
49
51
  import { PRODUCT_COLLECTION, PRODUCT_CODES_SUBCOLLECTION, } from "../../../../features/products/schemas/firestore.js";
50
52
  /**
@@ -362,6 +364,30 @@ export async function processRefundAction(input) {
362
364
  // the reconciler will look at it once and find it already done.
363
365
  serverLogger.warn("refund: claim not marked settled", { refundId });
364
366
  });
367
+ /*
368
+ * ── PHASE 7c: the credit note that documents this reversal ────────────
369
+ *
370
+ * 🛑 HERE, at settlement, and not at reservation. A credit note numbered
371
+ * when the entry was reserved would leave a numbered reversal in the
372
+ * series on every provider failure — for money that never moved, with a
373
+ * number that cannot be withdrawn.
374
+ *
375
+ * 🛑 AWAITED but never allowed to throw (the issuer swallows its own
376
+ * failures and says so). The money has already left the gateway by this
377
+ * line; raising here would report a successful refund as failed, and an
378
+ * operator would retry a refund that already happened. A missing credit
379
+ * note is a reporting gap a backfill can close; a double refund is not.
380
+ *
381
+ * No renderer is passed, so this NUMBERS the reversal without producing
382
+ * a PDF. That is what the GSTR-1 export needs — it reconciles numbers
383
+ * and amounts. The buyer's PDF follows the invoice's own lazy pattern
384
+ * when a surface asks for it.
385
+ */
386
+ const settledOrder = await orderRepository.findById(input.orderId);
387
+ const settledEvent = settledOrder?.refunds?.find((r) => r.refundId === refundId);
388
+ if (settledOrder && settledEvent) {
389
+ await issueCreditNoteForRefund(settledOrder, settledEvent);
390
+ }
365
391
  // SB-UNI-N — revoke any available (unclaimed) digital codes linked to this order.
366
392
  revokeAvailableDigitalCodes(input.orderId, digitalCodeItems);
367
393
  /*
@@ -0,0 +1,86 @@
1
+ /**
2
+ * S5a — one parcel per destination on a coordinated purchase.
3
+ *
4
+ * A coordinated purchase can send each member's share to their own address
5
+ * (`CoordinationMember.destinationAddressId`). That is N parcels from one
6
+ * order, which is N bookings and N serviceability checks.
7
+ *
8
+ * ## 🛑 Serviceability is checked for EVERY destination BEFORE any booking
9
+ *
10
+ * Booking as you go and failing on the fourth leaves three parcels already
11
+ * accepted by the carrier and a coordinator who cannot undo them — the
12
+ * cancel path exists but the money and the pickup slot are gone. A
13
+ * pre-flight over all destinations turns that into one refusal naming the
14
+ * pincode that cannot be served, before anything is committed.
15
+ *
16
+ * Two-phase on purpose, and it is NOT a transaction: a carrier booking has
17
+ * no rollback. What the pre-flight buys is that the common failure — an
18
+ * unservable pincode — is caught while rolling back is still free.
19
+ *
20
+ * ## 🛑 Bounded by `SHARED_PURCHASE_MAX_MEMBERS`
21
+ *
22
+ * Five destinations is five outbound calls for serviceability and five more
23
+ * to book, on a path somebody is waiting on. That ceiling is why the limit
24
+ * exists at all; see the registry's own header.
25
+ */
26
+ import { type CoordinationMember } from "../../../shared/features/offers/coordination";
27
+ export interface DestinationCheck {
28
+ addressId: string;
29
+ pincode: string;
30
+ serviceable: boolean;
31
+ }
32
+ /**
33
+ * Can every named destination actually be delivered to?
34
+ *
35
+ * 🛑 Returns the FULL list, not the first failure. A coordinator fixing one
36
+ * unservable address only to be told about the next one is three round trips
37
+ * for a problem that was knowable in one — and each round trip is another
38
+ * chance for someone to give up with the arrangement half-built.
39
+ *
40
+ * 🛑 An UNREADABLE check is treated as serviceable. A provider timeout is not
41
+ * evidence that a pincode cannot be served, and refusing on it would block a
42
+ * legitimate purchase on an outage we caused. The booking itself will fail
43
+ * loudly if the address really is unservable, which is the recoverable
44
+ * direction — and it is the same reasoning `bookShipment` applies to a wallet
45
+ * balance it could not read.
46
+ *
47
+ * A MISSING pincode is the opposite case and is reported unserviceable: that
48
+ * is a fact about the stored address, not about the provider, and it will not
49
+ * fix itself on a retry.
50
+ */
51
+ export declare function checkDestinations(members: readonly CoordinationMember[],
52
+ /**
53
+ * 🛑 The parcel's weight in kg, NOT an origin pincode.
54
+ *
55
+ * `IShippingProvider.checkServiceability(pincode, weight)` reads its first
56
+ * argument as the DESTINATION. A reasonable guess of `(origin, destination)`
57
+ * would pass two strings into a `(string, number)` signature — caught by
58
+ * `tsc` here, but worth naming because the argument ORDER is the part a
59
+ * reader assumes.
60
+ */
61
+ weightKg: number): Promise<DestinationCheck[]>;
62
+ /**
63
+ * Refuse the whole arrangement if any destination cannot be served.
64
+ *
65
+ * Names every failing pincode, for the reason above.
66
+ */
67
+ export declare function assertAllServiceable(checks: readonly DestinationCheck[]): void;
68
+ /**
69
+ * The parcels one coordinated order produces.
70
+ *
71
+ * 🛑 **Keyed by ADDRESS, not by member.** Two members naming the same address
72
+ * are one parcel, not two — that is the whole reason `destinationIds` returns
73
+ * a distinct set. Fanning out per member would book the courier twice to the
74
+ * same door and bill for both.
75
+ *
76
+ * 🛑 **A member with no `destinationAddressId` is NOT in this list.** Absent
77
+ * means "the coordinator's address", which is the ordinary one-parcel case
78
+ * and is handled by `bookShipment`'s existing single-delivery path — the
79
+ * order's own snapshot. Inventing a parcel for them here would duplicate it.
80
+ */
81
+ export interface ParcelPlan {
82
+ addressId: string;
83
+ /** Members whose share rides in this parcel. Never empty. */
84
+ memberUids: string[];
85
+ }
86
+ export declare function planParcels(members: readonly CoordinationMember[]): ParcelPlan[];
@@ -0,0 +1,130 @@
1
+ /**
2
+ * S5a — one parcel per destination on a coordinated purchase.
3
+ *
4
+ * A coordinated purchase can send each member's share to their own address
5
+ * (`CoordinationMember.destinationAddressId`). That is N parcels from one
6
+ * order, which is N bookings and N serviceability checks.
7
+ *
8
+ * ## 🛑 Serviceability is checked for EVERY destination BEFORE any booking
9
+ *
10
+ * Booking as you go and failing on the fourth leaves three parcels already
11
+ * accepted by the carrier and a coordinator who cannot undo them — the
12
+ * cancel path exists but the money and the pickup slot are gone. A
13
+ * pre-flight over all destinations turns that into one refusal naming the
14
+ * pincode that cannot be served, before anything is committed.
15
+ *
16
+ * Two-phase on purpose, and it is NOT a transaction: a carrier booking has
17
+ * no rollback. What the pre-flight buys is that the common failure — an
18
+ * unservable pincode — is caught while rolling back is still free.
19
+ *
20
+ * ## 🛑 Bounded by `SHARED_PURCHASE_MAX_MEMBERS`
21
+ *
22
+ * Five destinations is five outbound calls for serviceability and five more
23
+ * to book, on a path somebody is waiting on. That ceiling is why the limit
24
+ * exists at all; see the registry's own header.
25
+ */
26
+ import { getProviders } from "../../../../contracts/registry.js";
27
+ import { addressesRepository } from "../../../../features/addresses/repository/addresses.repository.js";
28
+ import { SHARED_PURCHASE_MAX_MEMBERS, destinationIds, } from "../../../shared/features/offers/coordination.js";
29
+ import { ValidationError } from "../../../../errors/validation-error.js";
30
+ import { normalizeError } from "../../../../errors/normalize.js";
31
+ import { serverLogger } from "../../../../monitoring/server-logger.js";
32
+ /**
33
+ * Can every named destination actually be delivered to?
34
+ *
35
+ * 🛑 Returns the FULL list, not the first failure. A coordinator fixing one
36
+ * unservable address only to be told about the next one is three round trips
37
+ * for a problem that was knowable in one — and each round trip is another
38
+ * chance for someone to give up with the arrangement half-built.
39
+ *
40
+ * 🛑 An UNREADABLE check is treated as serviceable. A provider timeout is not
41
+ * evidence that a pincode cannot be served, and refusing on it would block a
42
+ * legitimate purchase on an outage we caused. The booking itself will fail
43
+ * loudly if the address really is unservable, which is the recoverable
44
+ * direction — and it is the same reasoning `bookShipment` applies to a wallet
45
+ * balance it could not read.
46
+ *
47
+ * A MISSING pincode is the opposite case and is reported unserviceable: that
48
+ * is a fact about the stored address, not about the provider, and it will not
49
+ * fix itself on a retry.
50
+ */
51
+ export async function checkDestinations(members,
52
+ /**
53
+ * 🛑 The parcel's weight in kg, NOT an origin pincode.
54
+ *
55
+ * `IShippingProvider.checkServiceability(pincode, weight)` reads its first
56
+ * argument as the DESTINATION. A reasonable guess of `(origin, destination)`
57
+ * would pass two strings into a `(string, number)` signature — caught by
58
+ * `tsc` here, but worth naming because the argument ORDER is the part a
59
+ * reader assumes.
60
+ */
61
+ weightKg) {
62
+ const ids = destinationIds(members);
63
+ if (ids.length === 0)
64
+ return [];
65
+ if (ids.length > SHARED_PURCHASE_MAX_MEMBERS) {
66
+ throw new ValidationError(`A coordinated purchase can ship to at most ${SHARED_PURCHASE_MAX_MEMBERS} addresses.`, { destinations: `${ids.length} distinct addresses named.` });
67
+ }
68
+ /*
69
+ * 🛑 Optional on the registry. This is the serviceability PRE-FLIGHT, so
70
+ * with no provider the honest answer is "unknown", not "unserviceable":
71
+ * reporting every destination as unserviceable would block an accept that
72
+ * manual dispatch handles perfectly well.
73
+ */
74
+ const provider = getProviders().shipping;
75
+ if (!provider) {
76
+ return ids.map((addressId) => ({ addressId, pincode: "", serviceable: true }));
77
+ }
78
+ const docs = await Promise.all(ids.map((id) => addressesRepository.findById(id)));
79
+ return Promise.all(ids.map(async (addressId, i) => {
80
+ /*
81
+ * 🛑 `.postalCode` needs no reveal — it is not PII and
82
+ * `AddressRepository` deliberately leaves it unencrypted so it stays
83
+ * queryable (see its own `computeAddressHash` comment). Calling
84
+ * `revealAddress` here would decrypt a name and a phone number we have
85
+ * no use for, on a path that only needs six digits.
86
+ */
87
+ const pincode = docs[i]?.postalCode ?? "";
88
+ if (!pincode)
89
+ return { addressId, pincode, serviceable: false };
90
+ try {
91
+ const res = await provider.checkServiceability(pincode, weightKg);
92
+ return { addressId, pincode, serviceable: res.isServiceable };
93
+ }
94
+ catch (err) {
95
+ void normalizeError(err);
96
+ serverLogger.warn("checkDestinations: serviceability unreadable", { addressId, pincode });
97
+ return { addressId, pincode, serviceable: true };
98
+ }
99
+ }));
100
+ }
101
+ /**
102
+ * Refuse the whole arrangement if any destination cannot be served.
103
+ *
104
+ * Names every failing pincode, for the reason above.
105
+ */
106
+ export function assertAllServiceable(checks) {
107
+ const bad = checks.filter((c) => !c.serviceable);
108
+ if (bad.length === 0)
109
+ return;
110
+ throw new ValidationError(bad.length === 1
111
+ ? "One delivery address cannot be served by the courier."
112
+ : `${bad.length} delivery addresses cannot be served by the courier.`, {
113
+ destinations: bad
114
+ .map((b) => (b.pincode ? `${b.pincode}: not serviceable` : "missing pincode"))
115
+ .join("; "),
116
+ });
117
+ }
118
+ export function planParcels(members) {
119
+ const byAddress = new Map();
120
+ for (const m of members) {
121
+ if (!m.destinationAddressId)
122
+ continue;
123
+ const uids = byAddress.get(m.destinationAddressId);
124
+ if (uids)
125
+ uids.push(m.uid);
126
+ else
127
+ byAddress.set(m.destinationAddressId, [m.uid]);
128
+ }
129
+ return [...byAddress].map(([addressId, memberUids]) => ({ addressId, memberUids }));
130
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Booking a parcel through the platform's own carrier account — Part 1′.
3
+ *
4
+ * ## 🛑 Why this could not be built until Part 14
5
+ *
6
+ * `CreateShipmentInput` needs a structured `{name, phone, addressLine1, city,
7
+ * state, pincode, country}` for BOTH ends. Until the delivery snapshot landed
8
+ * the order carried `shippingAddress?: string` — flat free text with no
9
+ * pincode and no phone — and the only way to produce a party from it was to
10
+ * parse prose. The `placeOfSupply` comment already refuses that for tax, and
11
+ * the same argument holds here: a mis-parsed pincode is a parcel that goes to
12
+ * the wrong city, except nothing errors and the label prints fine.
13
+ *
14
+ * `deliveryPartyFor(order)` now returns exactly that shape, or `null` when a
15
+ * required field is missing — which is the only honest answer for an order
16
+ * placed before the snapshot existed.
17
+ *
18
+ * ## 🛑 `platformBookedShipment` is the flag this writes
19
+ *
20
+ * `order-math.ts` gates shipping reimbursement on it
21
+ * (`if (order.platformBookedShipment === true) return 0`) and
22
+ * `quote.ts:241` records that it has had **ZERO writers** — so the
23
+ * reimbursement rule has been reading a flag nothing sets. This is its
24
+ * writer, which is why the booking and the dispatch form are one unit of
25
+ * work and why the form must not ship first: a "Book through us" button with
26
+ * no booking behind it is a control the server refuses.
27
+ */
28
+ export interface BookShipmentInput {
29
+ orderId: string;
30
+ /** Centimetres and kilograms, from the dispatch form's box preset. */
31
+ dimensions: {
32
+ weight: number;
33
+ length: number;
34
+ width: number;
35
+ height: number;
36
+ };
37
+ /** The store address the courier collects from. */
38
+ pickupAddressId: string;
39
+ }
40
+ export interface BookShipmentResult {
41
+ trackingId: string;
42
+ courier?: string;
43
+ estimatedDelivery?: string;
44
+ }
45
+ /**
46
+ * Book one parcel.
47
+ *
48
+ * ## 🛑 The wallet is checked BEFORE the booking, and a failure is a 409
49
+ *
50
+ * A carrier account with no balance rejects the booking — but some providers
51
+ * accept it and then silently fail to hand over, which produces a tracking id
52
+ * that never moves. Checking first turns "the parcel vanished" into "top up
53
+ * the account", and the 409 is deliberate: the request is well-formed and the
54
+ * seller is not confused, the world is simply not ready.
55
+ *
56
+ * 🛑 `getWalletBalance` is NOT abstract on `IShippingProvider` — manual
57
+ * shipping has no wallet, so a provider that does not implement it returns
58
+ * undefined and the check is SKIPPED rather than failing. A missing balance
59
+ * must never block a manual dispatch.
60
+ */
61
+ export declare function bookShipment(input: BookShipmentInput): Promise<BookShipmentResult>;