@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,114 @@
1
+ /**
2
+ * The delivery snapshot — what the buyer chose, frozen at checkout.
3
+ *
4
+ * ## 🛑 Why the fields are flat and ugly
5
+ *
6
+ * 🛑 **CORRECTED.** This read "`encryptPiiFields` is a flat top-level loop
7
+ * that never descends", which is FALSE — it handles `a.b` and `a[].b` via
8
+ * `encryptInArray`, and `CONVERSATION_PII_FIELDS` ships `lastMessage.body`.
9
+ *
10
+ * What it does not do is INFER. A nested `deliveryAddress: {fullName, …}`
11
+ * is covered only if somebody writes `deliveryAddress.fullName` into
12
+ * `ORDER_PII_FIELDS`, and the near-miss `"fullName"` reads as covering it
13
+ * while storing plaintext.
14
+ *
15
+ * The decisive argument is not tidiness: **an unencrypted nested field looks
16
+ * identical to an encrypted one in every inspection** — both are `string`,
17
+ * and `Encrypted<string>` is erased at runtime. Flat keys cannot
18
+ * silently half-apply, because `ORDER_PII_FIELDS` either names them or does
19
+ * not and the audit can see which.
20
+ *
21
+ * ## 🛑 Four fields are deliberately NOT encrypted
22
+ *
23
+ * `city` / `state` / `pincode` / `country` decide tax and serviceability and
24
+ * must stay QUERYABLE. An encrypted pincode cannot be filtered, grouped into
25
+ * a courier manifest, or read by `placeOfSupply` without a decrypt per row.
26
+ * They are not PII in any useful sense on their own.
27
+ */
28
+ import type { AddressPlain } from "../../../../features/addresses/schemas/firestore";
29
+ /** The plaintext shape — what a caller builds and what the repository encrypts. */
30
+ export interface DeliverySnapshot {
31
+ deliveryFullName: string;
32
+ deliveryPhone: string;
33
+ deliveryAddressLine1: string;
34
+ deliveryAddressLine2?: string;
35
+ deliveryLandmark?: string;
36
+ deliveryCity: string;
37
+ deliveryState: string;
38
+ deliveryPincode: string;
39
+ deliveryCountry: string;
40
+ deliveryAddressId: string;
41
+ }
42
+ /**
43
+ * Freeze a chosen address onto an order.
44
+ *
45
+ * 🛑 Takes the resolved DOCUMENT, never an id. Resolving here would mean a
46
+ * second read on the money path, and — worse — would invite a caller to pass
47
+ * an id it had not verified belongs to the buyer. The checkout already loads
48
+ * and ownership-checks the address; this just copies it.
49
+ *
50
+ * 🛑 Takes `AddressPlain`, not `AddressDocument`, and that is the point.
51
+ * `addressesRepository` encrypts `fullName` / `phone` / `addressLine1` on
52
+ * write, so a raw `findById` returns CIPHERTEXT — snapshotting it would put
53
+ * `enc:v1:…` on the invoice, and nothing would catch it because both are
54
+ * `string` at runtime and `Encrypted<string>` is erased.
55
+ *
56
+ * Demanding the revealed type makes the mistake a COMPILE error instead of a
57
+ * comment nobody reads. Call `addressesRepository.revealAddress(doc)` first.
58
+ */
59
+ export declare function snapshotDeliveryAddress(address: AddressPlain): DeliverySnapshot;
60
+ /** Everything a carrier booking needs, in `CreateShipmentInput`'s shape. */
61
+ export interface DeliveryParty {
62
+ name: string;
63
+ phone: string;
64
+ addressLine1: string;
65
+ addressLine2?: string;
66
+ city: string;
67
+ state: string;
68
+ pincode: string;
69
+ country: string;
70
+ }
71
+ /**
72
+ * What the PARCEL goes to — the latest amendment, or the snapshot.
73
+ *
74
+ * 🛑 This is the one read that must NOT use the snapshot, and the invoice is
75
+ * the one that must. A buyer who corrects their address before dispatch
76
+ * expects the parcel to follow; the invoice records what was agreed when they
77
+ * paid. Collapsing the two is how a parcel goes to the old address or an
78
+ * invoice silently restates itself.
79
+ *
80
+ * Returns `null` rather than a partial party when a required field is
81
+ * missing — a booking built from blanks is accepted by the carrier and
82
+ * delivered nowhere.
83
+ */
84
+ export declare function deliveryPartyFor(order: {
85
+ deliveryFullName?: string;
86
+ deliveryPhone?: string;
87
+ deliveryAddressLine1?: string;
88
+ deliveryAddressLine2?: string;
89
+ deliveryCity?: string;
90
+ deliveryState?: string;
91
+ deliveryPincode?: string;
92
+ deliveryCountry?: string;
93
+ deliveryAmendments?: Array<{
94
+ fullName: string;
95
+ phone: string;
96
+ addressLine1: string;
97
+ addressLine2?: string;
98
+ city: string;
99
+ state: string;
100
+ pincode: string;
101
+ country: string;
102
+ }>;
103
+ }): DeliveryParty | null;
104
+ /**
105
+ * The state the tax split was decided from.
106
+ *
107
+ * 🛑 Reads the SNAPSHOT, never an amendment. Place of supply is fixed at the
108
+ * time of supply; an address correction after the fact does not re-decide
109
+ * CGST/SGST versus IGST on an invoice that has been issued and may have been
110
+ * filed. That is the same forward-only rule `/admin/pricing` holds for rates.
111
+ */
112
+ export declare function placeOfSupplyFrom(order: {
113
+ deliveryState?: string;
114
+ }): string | undefined;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * The delivery snapshot — what the buyer chose, frozen at checkout.
3
+ *
4
+ * ## 🛑 Why the fields are flat and ugly
5
+ *
6
+ * 🛑 **CORRECTED.** This read "`encryptPiiFields` is a flat top-level loop
7
+ * that never descends", which is FALSE — it handles `a.b` and `a[].b` via
8
+ * `encryptInArray`, and `CONVERSATION_PII_FIELDS` ships `lastMessage.body`.
9
+ *
10
+ * What it does not do is INFER. A nested `deliveryAddress: {fullName, …}`
11
+ * is covered only if somebody writes `deliveryAddress.fullName` into
12
+ * `ORDER_PII_FIELDS`, and the near-miss `"fullName"` reads as covering it
13
+ * while storing plaintext.
14
+ *
15
+ * The decisive argument is not tidiness: **an unencrypted nested field looks
16
+ * identical to an encrypted one in every inspection** — both are `string`,
17
+ * and `Encrypted<string>` is erased at runtime. Flat keys cannot
18
+ * silently half-apply, because `ORDER_PII_FIELDS` either names them or does
19
+ * not and the audit can see which.
20
+ *
21
+ * ## 🛑 Four fields are deliberately NOT encrypted
22
+ *
23
+ * `city` / `state` / `pincode` / `country` decide tax and serviceability and
24
+ * must stay QUERYABLE. An encrypted pincode cannot be filtered, grouped into
25
+ * a courier manifest, or read by `placeOfSupply` without a decrypt per row.
26
+ * They are not PII in any useful sense on their own.
27
+ */
28
+ /**
29
+ * Freeze a chosen address onto an order.
30
+ *
31
+ * 🛑 Takes the resolved DOCUMENT, never an id. Resolving here would mean a
32
+ * second read on the money path, and — worse — would invite a caller to pass
33
+ * an id it had not verified belongs to the buyer. The checkout already loads
34
+ * and ownership-checks the address; this just copies it.
35
+ *
36
+ * 🛑 Takes `AddressPlain`, not `AddressDocument`, and that is the point.
37
+ * `addressesRepository` encrypts `fullName` / `phone` / `addressLine1` on
38
+ * write, so a raw `findById` returns CIPHERTEXT — snapshotting it would put
39
+ * `enc:v1:…` on the invoice, and nothing would catch it because both are
40
+ * `string` at runtime and `Encrypted<string>` is erased.
41
+ *
42
+ * Demanding the revealed type makes the mistake a COMPILE error instead of a
43
+ * comment nobody reads. Call `addressesRepository.revealAddress(doc)` first.
44
+ */
45
+ export function snapshotDeliveryAddress(address) {
46
+ return {
47
+ deliveryFullName: String(address.fullName ?? ""),
48
+ deliveryPhone: String(address.phone ?? ""),
49
+ deliveryAddressLine1: String(address.addressLine1 ?? ""),
50
+ ...(address.addressLine2 ? { deliveryAddressLine2: String(address.addressLine2) } : {}),
51
+ ...(address.landmark ? { deliveryLandmark: String(address.landmark) } : {}),
52
+ deliveryCity: address.city ?? "",
53
+ deliveryState: address.state ?? "",
54
+ deliveryPincode: address.postalCode ?? "",
55
+ deliveryCountry: address.country ?? "",
56
+ deliveryAddressId: address.id,
57
+ };
58
+ }
59
+ /**
60
+ * What the PARCEL goes to — the latest amendment, or the snapshot.
61
+ *
62
+ * 🛑 This is the one read that must NOT use the snapshot, and the invoice is
63
+ * the one that must. A buyer who corrects their address before dispatch
64
+ * expects the parcel to follow; the invoice records what was agreed when they
65
+ * paid. Collapsing the two is how a parcel goes to the old address or an
66
+ * invoice silently restates itself.
67
+ *
68
+ * Returns `null` rather than a partial party when a required field is
69
+ * missing — a booking built from blanks is accepted by the carrier and
70
+ * delivered nowhere.
71
+ */
72
+ export function deliveryPartyFor(order) {
73
+ const latest = order.deliveryAmendments?.[order.deliveryAmendments.length - 1];
74
+ const party = latest
75
+ ? {
76
+ name: latest.fullName,
77
+ phone: latest.phone,
78
+ addressLine1: latest.addressLine1,
79
+ ...(latest.addressLine2 ? { addressLine2: latest.addressLine2 } : {}),
80
+ city: latest.city,
81
+ state: latest.state,
82
+ pincode: latest.pincode,
83
+ country: latest.country,
84
+ }
85
+ : {
86
+ name: order.deliveryFullName ?? "",
87
+ phone: order.deliveryPhone ?? "",
88
+ addressLine1: order.deliveryAddressLine1 ?? "",
89
+ ...(order.deliveryAddressLine2 ? { addressLine2: order.deliveryAddressLine2 } : {}),
90
+ city: order.deliveryCity ?? "",
91
+ state: order.deliveryState ?? "",
92
+ pincode: order.deliveryPincode ?? "",
93
+ country: order.deliveryCountry ?? "",
94
+ };
95
+ const required = [
96
+ party.name,
97
+ party.phone,
98
+ party.addressLine1,
99
+ party.city,
100
+ party.state,
101
+ party.pincode,
102
+ party.country,
103
+ ];
104
+ return required.every((v) => v.trim().length > 0) ? party : null;
105
+ }
106
+ /**
107
+ * The state the tax split was decided from.
108
+ *
109
+ * 🛑 Reads the SNAPSHOT, never an amendment. Place of supply is fixed at the
110
+ * time of supply; an address correction after the fact does not re-decide
111
+ * CGST/SGST versus IGST on an invoice that has been issued and may have been
112
+ * filed. That is the same forward-only rule `/admin/pricing` holds for rates.
113
+ */
114
+ export function placeOfSupplyFrom(order) {
115
+ return order.deliveryState || undefined;
116
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Dispute KINDS and the gate each one must pass.
3
+ *
4
+ * ## Why the kind is closed and the reason list is not
5
+ *
6
+ * The owner's two rules are policy:
7
+ *
8
+ * > An item dispute can only be raised after the order was received. A
9
+ * > "not reached" dispute is allowed once the ETD is more than 3 days past.
10
+ *
11
+ * A gate cannot branch on a user-created string. `return-reasons.ts` already
12
+ * makes this argument in its own header — *"'No returns, unless the buyer
13
+ * didn't get what they paid for' is not a policy that can be enforced against
14
+ * a free-text box: it needs a machine-readable statement of what went
15
+ * wrong"* — and it applies with more force here, because these two gates are
16
+ * MUTUALLY EXCLUSIVE.
17
+ *
18
+ * So there are two levels:
19
+ *
20
+ * 1. **`DisputeKind` — closed, here, two values.** It picks the gate.
21
+ * 2. **`disputeReasons` — a staff-creatable Firestore collection.** Every row
22
+ * carries a `kind`, so a new reason inherits an existing gate and cannot
23
+ * invent one. That list is for triage and analytics, never for policy.
24
+ *
25
+ * ## What this replaces
26
+ *
27
+ * `raiseOrderDisputeAction` took `reason: string` and checked only that it was
28
+ * non-empty. So today a buyer can file "it never arrived" on an order that was
29
+ * delivered last week, and "it arrived damaged" on one still in transit — both
30
+ * nonsense, both accepted, and both raising a `severity: "error"` fraud-category
31
+ * admin alert. The gate is the point of this file.
32
+ */
33
+ export declare const DISPUTE_KIND: readonly ["item", "not_reached"];
34
+ export type DisputeKind = (typeof DISPUTE_KIND)[number];
35
+ /**
36
+ * 🛑 `Record<DisputeKind, string>`, so a third kind is a COMPILE error here
37
+ * rather than a dispute that renders `undefined` and passes no gate.
38
+ */
39
+ export declare const DISPUTE_KIND_LABEL: Record<DisputeKind, string>;
40
+ export declare function isDisputeKind(value: unknown): value is DisputeKind;
41
+ /**
42
+ * How long after dispatch a parcel is ASSUMED to have been deliverable, when
43
+ * the courier gave us no estimate.
44
+ *
45
+ * 🛑 This exists so the `not_reached` gate is reachable AT ALL. There is no
46
+ * courier ETD on an order today: nothing platform-books (`createShipment` has
47
+ * zero callers), and a self-shipping seller types a tracking number with no
48
+ * estimate attached. Gate solely on a stored ETD and no buyer could ever file
49
+ * a non-delivery dispute — a gate nobody can pass is the same as no feature.
50
+ *
51
+ * Published through `PublishedValueKey` so the policy page and this gate
52
+ * cannot disagree (Phase 9).
53
+ */
54
+ export declare const DISPUTE_TRANSIT_WINDOW_DAYS = 7;
55
+ /**
56
+ * The owner's "more than 3 days" grace, measured from the ETD.
57
+ *
58
+ * Separate from the transit window on purpose: one is "when should it have
59
+ * arrived", the other is "how long after that before we believe it is lost".
60
+ * Folding them into a single 10 would make neither number explicable on a
61
+ * policy page.
62
+ */
63
+ export declare const DISPUTE_NOT_REACHED_GRACE_DAYS = 3;
64
+ /** Fields the gates read. Narrow, so a caller need not hold a whole order. */
65
+ export interface DisputeGateOrder {
66
+ deliveryDate?: Date | null;
67
+ completedAt?: Date | null;
68
+ shippingDate?: Date | null;
69
+ estimatedDeliveryDate?: Date | null;
70
+ }
71
+ export type DisputeGateResult = {
72
+ allowed: true;
73
+ }
74
+ /** `message` is buyer-facing and must name the next action, not just refuse. */
75
+ | {
76
+ allowed: false;
77
+ message: string;
78
+ };
79
+ /**
80
+ * The effective ETD, and WHY we think so.
81
+ *
82
+ * Exported because the buyer-facing form needs to show the date they can file
83
+ * from — telling someone "not yet" without saying when is a dead end.
84
+ */
85
+ export declare function resolveDisputeEtd(order: DisputeGateOrder, transitWindowDays?: number): {
86
+ etd: Date;
87
+ source: "courier" | "assumed";
88
+ } | null;
89
+ /** The date from which a `not_reached` dispute becomes filable. */
90
+ export declare function disputeNotReachedFilableFrom(order: DisputeGateOrder, graceDays?: number): Date | null;
91
+ /**
92
+ * 🛑 `Record<DisputeKind, …>`. A third kind cannot be added without deciding
93
+ * what gates it — which is the whole reason the kind is closed.
94
+ */
95
+ export declare const DISPUTE_GATE: Record<DisputeKind, (order: DisputeGateOrder, now?: Date) => DisputeGateResult>;
96
+ /**
97
+ * Convenience wrapper so callers do not index the record by hand.
98
+ *
99
+ * 🛑 Takes the NARROW `DisputeGateOrder`, and an `OrderDocument` satisfies it
100
+ * structurally — so no adapter is needed and none should be added.
101
+ *
102
+ * A first draft had a `toDisputeGateOrder(order: OrderDocument)` helper, which
103
+ * meant this module imported the order schema while the order schema imports
104
+ * `DisputeKind` from here. That cycle is type-only and therefore erased, so it
105
+ * would have compiled and run — but it is also entirely avoidable, and a
106
+ * module that defines a policy should not depend on the document the policy is
107
+ * applied to. `return-reasons.ts` beside it has no imports at all for the same
108
+ * reason.
109
+ *
110
+ * Nothing leaks by passing the whole order in: what crosses back out is a
111
+ * `DisputeGateResult`, never the document (Root Cause #70).
112
+ */
113
+ export declare function checkDisputeGate(kind: DisputeKind, order: DisputeGateOrder, now?: Date): DisputeGateResult;
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Dispute KINDS and the gate each one must pass.
3
+ *
4
+ * ## Why the kind is closed and the reason list is not
5
+ *
6
+ * The owner's two rules are policy:
7
+ *
8
+ * > An item dispute can only be raised after the order was received. A
9
+ * > "not reached" dispute is allowed once the ETD is more than 3 days past.
10
+ *
11
+ * A gate cannot branch on a user-created string. `return-reasons.ts` already
12
+ * makes this argument in its own header — *"'No returns, unless the buyer
13
+ * didn't get what they paid for' is not a policy that can be enforced against
14
+ * a free-text box: it needs a machine-readable statement of what went
15
+ * wrong"* — and it applies with more force here, because these two gates are
16
+ * MUTUALLY EXCLUSIVE.
17
+ *
18
+ * So there are two levels:
19
+ *
20
+ * 1. **`DisputeKind` — closed, here, two values.** It picks the gate.
21
+ * 2. **`disputeReasons` — a staff-creatable Firestore collection.** Every row
22
+ * carries a `kind`, so a new reason inherits an existing gate and cannot
23
+ * invent one. That list is for triage and analytics, never for policy.
24
+ *
25
+ * ## What this replaces
26
+ *
27
+ * `raiseOrderDisputeAction` took `reason: string` and checked only that it was
28
+ * non-empty. So today a buyer can file "it never arrived" on an order that was
29
+ * delivered last week, and "it arrived damaged" on one still in transit — both
30
+ * nonsense, both accepted, and both raising a `severity: "error"` fraud-category
31
+ * admin alert. The gate is the point of this file.
32
+ */
33
+ export const DISPUTE_KIND = ["item", "not_reached"];
34
+ /**
35
+ * 🛑 `Record<DisputeKind, string>`, so a third kind is a COMPILE error here
36
+ * rather than a dispute that renders `undefined` and passes no gate.
37
+ */
38
+ export const DISPUTE_KIND_LABEL = {
39
+ item: "There's a problem with what I received",
40
+ not_reached: "My order hasn't arrived",
41
+ };
42
+ export function isDisputeKind(value) {
43
+ return typeof value === "string" && DISPUTE_KIND.includes(value);
44
+ }
45
+ /**
46
+ * How long after dispatch a parcel is ASSUMED to have been deliverable, when
47
+ * the courier gave us no estimate.
48
+ *
49
+ * 🛑 This exists so the `not_reached` gate is reachable AT ALL. There is no
50
+ * courier ETD on an order today: nothing platform-books (`createShipment` has
51
+ * zero callers), and a self-shipping seller types a tracking number with no
52
+ * estimate attached. Gate solely on a stored ETD and no buyer could ever file
53
+ * a non-delivery dispute — a gate nobody can pass is the same as no feature.
54
+ *
55
+ * Published through `PublishedValueKey` so the policy page and this gate
56
+ * cannot disagree (Phase 9).
57
+ */
58
+ export const DISPUTE_TRANSIT_WINDOW_DAYS = 7;
59
+ /**
60
+ * The owner's "more than 3 days" grace, measured from the ETD.
61
+ *
62
+ * Separate from the transit window on purpose: one is "when should it have
63
+ * arrived", the other is "how long after that before we believe it is lost".
64
+ * Folding them into a single 10 would make neither number explicable on a
65
+ * policy page.
66
+ */
67
+ export const DISPUTE_NOT_REACHED_GRACE_DAYS = 3;
68
+ const DAY_MS = 24 * 60 * 60 * 1000;
69
+ function asDate(v) {
70
+ if (!v)
71
+ return null;
72
+ const d = v instanceof Date ? v : new Date(v);
73
+ return Number.isFinite(d.getTime()) ? d : null;
74
+ }
75
+ function fmt(d) {
76
+ return d.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
77
+ }
78
+ /**
79
+ * The effective ETD, and WHY we think so.
80
+ *
81
+ * Exported because the buyer-facing form needs to show the date they can file
82
+ * from — telling someone "not yet" without saying when is a dead end.
83
+ */
84
+ export function resolveDisputeEtd(order, transitWindowDays = DISPUTE_TRANSIT_WINDOW_DAYS) {
85
+ const courier = asDate(order.estimatedDeliveryDate);
86
+ if (courier)
87
+ return { etd: courier, source: "courier" };
88
+ const shipped = asDate(order.shippingDate);
89
+ if (shipped) {
90
+ return { etd: new Date(shipped.getTime() + transitWindowDays * DAY_MS), source: "assumed" };
91
+ }
92
+ return null;
93
+ }
94
+ /** The date from which a `not_reached` dispute becomes filable. */
95
+ export function disputeNotReachedFilableFrom(order, graceDays = DISPUTE_NOT_REACHED_GRACE_DAYS) {
96
+ const resolved = resolveDisputeEtd(order);
97
+ if (!resolved)
98
+ return null;
99
+ return new Date(resolved.etd.getTime() + graceDays * DAY_MS);
100
+ }
101
+ /**
102
+ * 🛑 `Record<DisputeKind, …>`. A third kind cannot be added without deciding
103
+ * what gates it — which is the whole reason the kind is closed.
104
+ */
105
+ export const DISPUTE_GATE = {
106
+ /**
107
+ * You cannot judge an item you have not seen.
108
+ *
109
+ * `completedAt` counts as well as `deliveryDate`: a buyer who pressed "Mark
110
+ * complete" has told us they received it, and refusing them because no
111
+ * courier scan landed would be refusing the more reliable signal of the two.
112
+ */
113
+ item: (order) => {
114
+ if (asDate(order.deliveryDate) || asDate(order.completedAt))
115
+ return { allowed: true };
116
+ return {
117
+ allowed: false,
118
+ message: "You can report a problem with an item once it arrives. If it hasn't arrived, raise a delivery issue instead.",
119
+ };
120
+ },
121
+ /**
122
+ * Only valid BEFORE receipt, and only once the parcel is genuinely late.
123
+ *
124
+ * Three refusals, each pointing somewhere:
125
+ * - delivered → the wrong kind; offer the item route or a return.
126
+ * - never dispatched → not a courier problem at all. That is the
127
+ * `seller-dispatch` obligation's job, and it is already running.
128
+ * - too early → say the date, not just "not yet".
129
+ */
130
+ not_reached: (order, now = new Date()) => {
131
+ const delivered = asDate(order.deliveryDate);
132
+ if (delivered) {
133
+ return {
134
+ allowed: false,
135
+ message: `This order was marked delivered on ${fmt(delivered)}. If something is wrong with what arrived, report a problem with the item instead.`,
136
+ };
137
+ }
138
+ if (!asDate(order.shippingDate) && !asDate(order.estimatedDeliveryDate)) {
139
+ return {
140
+ allowed: false,
141
+ message: "This order hasn't been dispatched yet, so there's nothing in transit to chase. We already track late dispatch and will act on it without you needing to do anything.",
142
+ };
143
+ }
144
+ const filableFrom = disputeNotReachedFilableFrom(order);
145
+ if (!filableFrom) {
146
+ // Unreachable given the check above; kept rather than asserted, because
147
+ // a thrown non-null assertion here would be a 500 on a buyer action.
148
+ return {
149
+ allowed: false,
150
+ message: "We can't work out an expected delivery date for this order yet. Contact support.",
151
+ };
152
+ }
153
+ if (now.getTime() < filableFrom.getTime()) {
154
+ return {
155
+ allowed: false,
156
+ message: `It's still within the expected delivery window. If it hasn't arrived by ${fmt(filableFrom)}, you can raise a delivery issue then.`,
157
+ };
158
+ }
159
+ return { allowed: true };
160
+ },
161
+ };
162
+ /**
163
+ * Convenience wrapper so callers do not index the record by hand.
164
+ *
165
+ * 🛑 Takes the NARROW `DisputeGateOrder`, and an `OrderDocument` satisfies it
166
+ * structurally — so no adapter is needed and none should be added.
167
+ *
168
+ * A first draft had a `toDisputeGateOrder(order: OrderDocument)` helper, which
169
+ * meant this module imported the order schema while the order schema imports
170
+ * `DisputeKind` from here. That cycle is type-only and therefore erased, so it
171
+ * would have compiled and run — but it is also entirely avoidable, and a
172
+ * module that defines a policy should not depend on the document the policy is
173
+ * applied to. `return-reasons.ts` beside it has no imports at all for the same
174
+ * reason.
175
+ *
176
+ * Nothing leaks by passing the whole order in: what crosses back out is a
177
+ * `DisputeGateResult`, never the document (Root Cause #70).
178
+ */
179
+ export function checkDisputeGate(kind, order, now) {
180
+ return DISPUTE_GATE[kind](order, now);
181
+ }
@@ -35,7 +35,7 @@ export declare const REFUND_COPY: {
35
35
  readonly reasonSelectPlaceholder: "Choose a reason";
36
36
  readonly reasonNoteLabel: "Anything else we should know? (optional)";
37
37
  readonly alreadyRefundedMessage: "A refund has already been processed on this order. No further disputes or refund requests can be filed.";
38
- readonly acknowledgments: readonly ["I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.", "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).", "I understand the refund amount may take 5–7 business days to reflect and that platform fees may be non-recoverable."];
38
+ readonly acknowledgments: readonly ["I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.", "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).", "I understand the refund amount may take {{refundBusinessDaysMin}}–{{refundBusinessDaysMax}} business days to reflect and that platform fees may be non-recoverable."];
39
39
  };
40
40
  readonly siblingPayments: {
41
41
  readonly heading: (count: number) => string;
@@ -38,7 +38,24 @@ export const REFUND_COPY = {
38
38
  acknowledgments: [
39
39
  "I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.",
40
40
  "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).",
41
- "I understand the refund amount may take 5–7 business days to reflect and that platform fees may be non-recoverable.",
41
+ /*
42
+ * 🛑 Phase 9 — TOKENS, resolved by `resolvePublishedCopy` at render.
43
+ *
44
+ * This literal was one of the three contradicting owners of the refund
45
+ * timeline: "5–7 business days" here, "5–7 business days via Razorpay"
46
+ * on the policy page (naming a gateway that was not even the one in
47
+ * use), and "3–5 business days" in the FAQ. Three statements of one
48
+ * fact, no reconciliation, and the FAQ one admin-editable so it could
49
+ * drift further after deployment.
50
+ *
51
+ * The caller renders this through `resolvePublishedCopy`, so the number
52
+ * now has exactly one definition. Note this string is an
53
+ * ACKNOWLEDGEMENT the buyer ticks — a token left unresolved here would
54
+ * appear in something they are agreeing to, which is the strongest
55
+ * possible argument for the unknown-token rule leaving `{{…}}` visible
56
+ * rather than blanking it.
57
+ */
58
+ "I understand the refund amount may take {{refundBusinessDaysMin}}–{{refundBusinessDaysMax}} business days to reflect and that platform fees may be non-recoverable.",
42
59
  ],
43
60
  },
44
61
  siblingPayments: {
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Pay periods for employee payouts — ONE resolver, two cadences.
3
+ *
4
+ * ## 🛑 Why this is a module and not a ternary at each call site
5
+ *
6
+ * Two cadences means two period-boundary rules, and a reopened ticket can
7
+ * straddle a boundary differently per employee: the same reopen is inside the
8
+ * period for a monthly payee and across it for a weekly one. A branch written
9
+ * at each call site is two chances per site to disagree about where a week
10
+ * starts — and the symptom is a payslip that is quietly short, which nobody
11
+ * reports as a bug because nobody has the other number to compare it to.
12
+ *
13
+ * So the period is resolved once, from a date and a cadence, and every caller
14
+ * takes the pair it returns.
15
+ *
16
+ * ## 🛑 Go-forward, no clawback
17
+ *
18
+ * A payslip is final once issued. If a ticket is reopened after the period it
19
+ * was paid in has closed, the money is not recovered and the period is not
20
+ * recomputed — the ticket simply does not count again in the period where it
21
+ * is next resolved. Recomputing a closed period would mean an employee's pay
22
+ * changing after they were told what it was, which is a worse failure than
23
+ * occasionally paying for work that was later reopened.
24
+ */
25
+ export type PayCadence = "weekly" | "monthly";
26
+ export declare const PAY_CADENCE_VALUES: readonly ["weekly", "monthly"];
27
+ export interface PayPeriod {
28
+ start: Date;
29
+ /** EXCLUSIVE. See the note below — this is the half-open convention. */
30
+ end: Date;
31
+ cadence: PayCadence;
32
+ }
33
+ /**
34
+ * The period containing `when`.
35
+ *
36
+ * ## 🛑 Half-open: `start <= t < end`
37
+ *
38
+ * An inclusive end means the last millisecond of a period is also the first of
39
+ * the next, so a ticket resolved exactly at midnight is counted twice — paid
40
+ * in two periods — or, if one side uses `<` and the other `<=`, in neither.
41
+ * Half-open makes both impossible by construction, and every consumer must
42
+ * compare with `< end`, never `<= end`.
43
+ *
44
+ * ## 🛑 Weeks start MONDAY
45
+ *
46
+ * `Date.getDay()` returns 0 for Sunday, so the naive `d - d.getDay()` produces
47
+ * a Sunday-start week. India's working week is Monday–Saturday and a support
48
+ * rota is read that way, so a Sunday boundary would split every weekend across
49
+ * two payslips. The `(day + 6) % 7` shift is what makes Monday day 0.
50
+ *
51
+ * ## 🛑 Local midnight, not UTC
52
+ *
53
+ * Wages are a human-calendar concept: an employee's Monday is their Monday.
54
+ * `setHours(0,0,0,0)` is local, and the server runs in the deployment's zone —
55
+ * which is why `periodLabel` renders the same boundary a payslip prints.
56
+ */
57
+ export declare function payPeriodFor(when: Date, cadence: PayCadence): PayPeriod;
58
+ /** The period immediately before the one containing `when`. */
59
+ export declare function previousPayPeriod(when: Date, cadence: PayCadence): PayPeriod;
60
+ /** Half-open membership. The ONLY correct way to ask; see `payPeriodFor`. */
61
+ export declare function isWithinPeriod(t: Date, period: PayPeriod): boolean;
62
+ /**
63
+ * What a payslip prints.
64
+ *
65
+ * 🛑 Renders the end as the LAST DAY INSIDE the period, not the exclusive
66
+ * boundary. "1 Jan – 1 Feb" on a January payslip reads as an overlap with
67
+ * February's and invites someone to "fix" the half-open convention that makes
68
+ * the arithmetic correct.
69
+ */
70
+ export declare function periodLabel(period: PayPeriod, locale?: string): string;
71
+ /**
72
+ * The tickets a period actually pays for.
73
+ *
74
+ * 🛑 **Tickets STILL RESOLVED at period end — not tickets closed during it.**
75
+ * Paying per ticket closed rewards closing rather than resolving: close it,
76
+ * let the buyer reopen it, close it again, and it pays twice. So a ticket
77
+ * counts only when it is resolved, was resolved inside the period, and is
78
+ * still resolved when the period ends.
79
+ *
80
+ * A reopen therefore removes the ticket from that period even if the reopen
81
+ * happened after the resolution — which is why this takes the whole ticket
82
+ * rather than a timestamp, and why `resolvedBy` must be CLEARED on reopen.
83
+ */
84
+ export interface PayableTicket {
85
+ id: string;
86
+ resolvedAt?: Date | null;
87
+ resolvedBy?: string | null;
88
+ /** The live status, read at the moment the period is computed. */
89
+ isResolved: boolean;
90
+ }
91
+ export declare function resolvedTicketsForPeriod(tickets: readonly PayableTicket[], employeeUid: string, period: PayPeriod): string[];