@mohasinac/appkit 4.59.0 → 4.60.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 (531) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +62 -5
  3. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -2
  4. package/dist/_internal/server/features/brands/actions.js +78 -4
  5. package/dist/_internal/server/features/checkout/actions.d.ts +36 -13
  6. package/dist/_internal/server/features/checkout/actions.js +668 -183
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +18 -1
  8. package/dist/_internal/server/features/gateway-events/index.d.ts +10 -0
  9. package/dist/_internal/server/features/gateway-events/index.js +10 -0
  10. package/dist/_internal/server/features/gateway-events/ingest.d.ts +127 -0
  11. package/dist/_internal/server/features/gateway-events/ingest.js +188 -0
  12. package/dist/_internal/server/features/gateway-events/redact.d.ts +66 -0
  13. package/dist/_internal/server/features/gateway-events/redact.js +151 -0
  14. package/dist/_internal/server/features/grievance/actions.d.ts +63 -0
  15. package/dist/_internal/server/features/grievance/actions.js +173 -0
  16. package/dist/_internal/server/features/grievance/index.d.ts +8 -0
  17. package/dist/_internal/server/features/grievance/index.js +8 -0
  18. package/dist/_internal/server/features/grouped/data.js +28 -3
  19. package/dist/_internal/server/features/lottery/actions.js +99 -4
  20. package/dist/_internal/server/features/order-completion/actions.d.ts +92 -0
  21. package/dist/_internal/server/features/order-completion/actions.js +336 -0
  22. package/dist/_internal/server/features/order-completion/index.d.ts +7 -0
  23. package/dist/_internal/server/features/order-completion/index.js +7 -0
  24. package/dist/_internal/server/features/orders/actions.d.ts +13 -0
  25. package/dist/_internal/server/features/orders/actions.js +56 -2
  26. package/dist/_internal/server/features/orders/adapters.js +26 -0
  27. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
  28. package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
  29. package/dist/_internal/server/features/orders/index.d.ts +2 -1
  30. package/dist/_internal/server/features/orders/index.js +1 -1
  31. package/dist/_internal/server/features/orders/service.d.ts +60 -0
  32. package/dist/_internal/server/features/orders/service.js +74 -0
  33. package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
  34. package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
  35. package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
  36. package/dist/_internal/server/features/payment-cases/index.js +9 -0
  37. package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
  38. package/dist/_internal/server/features/payouts/actions.js +84 -10
  39. package/dist/_internal/server/features/points/adjust.d.ts +61 -0
  40. package/dist/_internal/server/features/points/adjust.js +121 -0
  41. package/dist/_internal/server/features/points/award.d.ts +65 -0
  42. package/dist/_internal/server/features/points/award.js +145 -0
  43. package/dist/_internal/server/features/price-index/market.d.ts +33 -0
  44. package/dist/_internal/server/features/price-index/market.js +54 -1
  45. package/dist/_internal/server/features/products/data.js +40 -22
  46. package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
  47. package/dist/_internal/server/features/protection-claims/actions.js +228 -0
  48. package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
  49. package/dist/_internal/server/features/protection-claims/index.js +8 -0
  50. package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
  51. package/dist/_internal/server/features/refunds/actions.js +259 -17
  52. package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
  53. package/dist/_internal/server/features/refunds/capacity.js +37 -0
  54. package/dist/_internal/server/features/reviews/actions.js +3 -2
  55. package/dist/_internal/server/features/search/index-build/sources.js +20 -1
  56. package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
  57. package/dist/_internal/server/features/shipping/reconcile.js +34 -3
  58. package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
  59. package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
  60. package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
  61. package/dist/_internal/server/features/stores/tabs.js +24 -4
  62. package/dist/_internal/server/functions/https.d.ts +31 -1
  63. package/dist/_internal/server/functions/https.js +52 -1
  64. package/dist/_internal/server/functions/scheduled.d.ts +72 -1
  65. package/dist/_internal/server/functions/scheduled.js +124 -1
  66. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
  67. package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
  68. package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
  69. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
  70. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
  71. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
  72. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  73. package/dist/_internal/server/jobs/core/index.js +2 -0
  74. package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
  75. package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
  76. package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
  77. package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
  78. package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
  79. package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
  80. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
  81. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
  82. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
  83. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
  84. package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
  85. package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
  86. package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
  87. package/dist/_internal/server/jobs/handlers/index.js +5 -0
  88. package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
  89. package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
  90. package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
  91. package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
  92. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
  93. package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
  94. package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
  95. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  96. package/dist/_internal/shared/actions/action-registry.js +71 -0
  97. package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
  98. package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
  99. package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
  100. package/dist/_internal/shared/checkout/lanes.js +46 -0
  101. package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
  102. package/dist/_internal/shared/checkout/order-math.js +251 -3
  103. package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
  104. package/dist/_internal/shared/checkout/refundable-base.js +122 -0
  105. package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
  106. package/dist/_internal/shared/features/auctions/config.js +30 -1
  107. package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
  108. package/dist/_internal/shared/features/brands/schema.js +18 -0
  109. package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
  110. package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
  111. package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
  112. package/dist/_internal/shared/features/print/label-profiles.js +350 -0
  113. package/dist/_internal/shared/features/products/to-product-item.js +33 -5
  114. package/dist/_internal/shared/fees/calculator.d.ts +31 -2
  115. package/dist/_internal/shared/fees/calculator.js +103 -5
  116. package/dist/_internal/shared/fees/india-states.d.ts +195 -0
  117. package/dist/_internal/shared/fees/india-states.js +190 -0
  118. package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
  119. package/dist/_internal/shared/fees/payout-hold.js +74 -0
  120. package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
  121. package/dist/_internal/shared/obligations/deadlines.js +155 -0
  122. package/dist/_internal/shared/shipping/quote.d.ts +96 -0
  123. package/dist/_internal/shared/shipping/quote.js +67 -0
  124. package/dist/_internal/shared/time/business-days.d.ts +91 -0
  125. package/dist/_internal/shared/time/business-days.js +185 -0
  126. package/dist/cli/index.js +0 -2
  127. package/dist/client.d.ts +9 -4
  128. package/dist/client.js +26 -3
  129. package/dist/configs/tailwind.d.ts +0 -12
  130. package/dist/configs/tailwind.js +28 -15
  131. package/dist/constants/api-endpoints.d.ts +51 -9
  132. package/dist/constants/api-endpoints.js +23 -7
  133. package/dist/constants/index.d.ts +1 -1
  134. package/dist/constants/index.js +1 -1
  135. package/dist/contracts/index.d.ts +1 -1
  136. package/dist/contracts/payment.d.ts +131 -0
  137. package/dist/features/about/components/AboutView.js +1 -1
  138. package/dist/features/about/components/DeveloperView.js +5 -2
  139. package/dist/features/about/components/FAQPageView.js +2 -1
  140. package/dist/features/about/components/FeesView.js +2 -1
  141. package/dist/features/about/components/HelpPageView.js +2 -1
  142. package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
  143. package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
  144. package/dist/features/about/components/HowEmiWorksView.js +2 -1
  145. package/dist/features/about/components/HowOffersWorkView.js +2 -1
  146. package/dist/features/about/components/HowOrdersWorkView.js +2 -1
  147. package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
  148. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
  149. package/dist/features/about/components/HowReviewsWorkView.js +2 -1
  150. package/dist/features/about/components/PolicyPageView.js +2 -1
  151. package/dist/features/about/components/ProseHero.d.ts +73 -0
  152. package/dist/features/about/components/ProseHero.js +18 -0
  153. package/dist/features/about/components/SecurityPrivacyView.js +2 -1
  154. package/dist/features/about/components/ShippingPolicyView.js +2 -1
  155. package/dist/features/about/components/TrackOrderView.js +2 -1
  156. package/dist/features/about/components/UnauthorizedView.js +1 -1
  157. package/dist/features/about/index.d.ts +2 -0
  158. package/dist/features/about/index.js +5 -0
  159. package/dist/features/account/actions/address-actions.d.ts +26 -2
  160. package/dist/features/account/actions/address-actions.js +25 -1
  161. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  162. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  163. package/dist/features/account/components/UserOrdersView.js +17 -0
  164. package/dist/features/account/components/UserSidebar.js +1 -1
  165. package/dist/features/account/hooks/useNotifications.js +29 -0
  166. package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
  167. package/dist/features/admin/components/AdminBeysView.js +2 -2
  168. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  169. package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
  170. package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
  171. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  172. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  173. package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
  174. package/dist/features/admin/components/AdminContactEditorView.js +1 -1
  175. package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
  176. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  177. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  178. package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
  179. package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
  180. package/dist/features/admin/components/AdminGuideHubView.js +1 -1
  181. package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
  182. package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
  183. package/dist/features/admin/components/AdminPartsView.js +2 -2
  184. package/dist/features/admin/components/AdminProductsView.js +75 -4
  185. package/dist/features/admin/components/AdminSidebar.js +2 -2
  186. package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
  187. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
  188. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  189. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  190. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  191. package/dist/features/admin/components/AdminUsersView.js +72 -1
  192. package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
  193. package/dist/features/admin/components/AdminViewCards.js +4 -4
  194. package/dist/features/admin/components/DataListingView.d.ts +28 -0
  195. package/dist/features/admin/components/DataListingView.js +175 -14
  196. package/dist/features/admin/components/DataTable.d.ts +12 -1
  197. package/dist/features/admin/components/DataTable.js +3 -3
  198. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  199. package/dist/features/admin/components/OwnerQuickActions.js +60 -2
  200. package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
  201. package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
  202. package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
  203. package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
  204. package/dist/features/admin/components/index.d.ts +4 -0
  205. package/dist/features/admin/components/index.js +6 -0
  206. package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
  207. package/dist/features/admin/constants/filter-tabs.js +106 -0
  208. package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
  209. package/dist/features/admin/repository/site-settings.repository.js +82 -1
  210. package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
  211. package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
  212. package/dist/features/admin/schemas/firestore.js +5 -1
  213. package/dist/features/admin/schemas/site-settings-form.js +30 -1
  214. package/dist/features/auctions/actions/bid-actions.js +13 -1
  215. package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
  216. package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
  217. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
  218. package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
  219. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
  220. package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
  221. package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
  222. package/dist/features/audit-log/schemas/firestore.js +14 -0
  223. package/dist/features/auth/permissions/constants.d.ts +17 -1
  224. package/dist/features/auth/permissions/constants.js +18 -0
  225. package/dist/features/blog/components/BlogPostView.js +1 -1
  226. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  227. package/dist/features/categories/api/[id]/description-template/route.js +107 -1
  228. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  229. package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
  230. package/dist/features/categories/components/BundleDetailView.js +1 -1
  231. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  232. package/dist/features/categories/components/CategoryForm.js +12 -1
  233. package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
  234. package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
  235. package/dist/features/categories/repository/market-price-index.repository.js +105 -0
  236. package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
  237. package/dist/features/categories/repository/price-observation.repository.js +132 -0
  238. package/dist/features/events/components/EventSaleBanner.js +1 -1
  239. package/dist/features/events/components/EventStatusBadge.js +1 -1
  240. package/dist/features/faq/components/FAQAccordion.js +2 -1
  241. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  242. package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
  243. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  244. package/dist/features/filters/FilterFacetSection.js +1 -1
  245. package/dist/features/filters/SwitchFilter.js +1 -1
  246. package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
  247. package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
  248. package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
  249. package/dist/features/gateway-events/schemas/firestore.js +125 -0
  250. package/dist/features/gateway-events/schemas/index.d.ts +81 -0
  251. package/dist/features/gateway-events/schemas/index.js +79 -0
  252. package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
  253. package/dist/features/homepage/components/AnnouncementBar.js +37 -1
  254. package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
  255. package/dist/features/homepage/components/BrandsSection.js +1 -1
  256. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  257. package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
  258. package/dist/features/homepage/components/HeroCarousel.js +2 -2
  259. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  260. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
  261. package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
  262. package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
  263. package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
  264. package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
  265. package/dist/features/inventory/components/ReceiveStationView.js +413 -0
  266. package/dist/features/inventory/components/operator-message.d.ts +29 -0
  267. package/dist/features/inventory/components/operator-message.js +41 -0
  268. package/dist/features/inventory/index.d.ts +13 -0
  269. package/dist/features/inventory/index.js +28 -0
  270. package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
  271. package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
  272. package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
  273. package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
  274. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
  275. package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
  276. package/dist/features/inventory/schemas/firestore.d.ts +197 -0
  277. package/dist/features/inventory/schemas/firestore.js +159 -0
  278. package/dist/features/layout/AppLayoutShell.d.ts +12 -1
  279. package/dist/features/layout/AppLayoutShell.js +25 -12
  280. package/dist/features/layout/AutoBreadcrumbs.js +162 -3
  281. package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
  282. package/dist/features/layout/BottomNavbar.d.ts +1 -1
  283. package/dist/features/layout/BottomNavbar.js +2 -2
  284. package/dist/features/media/MediaAvatar.js +1 -1
  285. package/dist/features/media/MediaImage.d.ts +24 -4
  286. package/dist/features/media/MediaImage.js +44 -4
  287. package/dist/features/media/MediaLightbox.js +1 -1
  288. package/dist/features/media/modals/ImageCropModal.js +1 -1
  289. package/dist/features/media/modals/ImageEditor.js +1 -1
  290. package/dist/features/media/upload/MediaUploadField.js +91 -3
  291. package/dist/features/obligations/constants/policies.d.ts +92 -0
  292. package/dist/features/obligations/constants/policies.js +378 -0
  293. package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
  294. package/dist/features/obligations/repository/obligations.repository.js +158 -0
  295. package/dist/features/obligations/schemas/firestore.d.ts +160 -0
  296. package/dist/features/obligations/schemas/firestore.js +87 -0
  297. package/dist/features/orders/actions/order-actions.d.ts +43 -4
  298. package/dist/features/orders/actions/order-actions.js +60 -3
  299. package/dist/features/orders/actions/refund-actions.js +70 -10
  300. package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
  301. package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
  302. package/dist/features/orders/components/OrdersList.js +2 -2
  303. package/dist/features/orders/components/RefundHistoryTable.js +3 -1
  304. package/dist/features/orders/components/index.d.ts +2 -0
  305. package/dist/features/orders/components/index.js +6 -0
  306. package/dist/features/orders/constants/transitions.d.ts +59 -0
  307. package/dist/features/orders/constants/transitions.js +104 -0
  308. package/dist/features/orders/repository/orders.repository.d.ts +109 -6
  309. package/dist/features/orders/repository/orders.repository.js +464 -21
  310. package/dist/features/orders/schemas/firestore.d.ts +270 -0
  311. package/dist/features/orders/schemas/firestore.js +24 -0
  312. package/dist/features/orders/schemas/index.d.ts +61 -0
  313. package/dist/features/orders/schemas/index.js +22 -0
  314. package/dist/features/orders/types/index.d.ts +79 -0
  315. package/dist/features/parts/components/PartsIndexPageView.js +8 -1
  316. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
  317. package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
  318. package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
  319. package/dist/features/payment-cases/schemas/firestore.js +105 -0
  320. package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
  321. package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
  322. package/dist/features/payments/repository/payout.repository.d.ts +0 -1
  323. package/dist/features/payments/repository/payout.repository.js +0 -1
  324. package/dist/features/points/repository/points.repository.d.ts +122 -0
  325. package/dist/features/points/repository/points.repository.js +304 -1
  326. package/dist/features/points/schemas/adjust-form.d.ts +58 -0
  327. package/dist/features/points/schemas/adjust-form.js +63 -0
  328. package/dist/features/points/schemas/firestore.d.ts +108 -1
  329. package/dist/features/points/schemas/firestore.js +84 -0
  330. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
  331. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  332. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
  333. package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
  334. package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
  335. package/dist/features/price-index/market-stats.d.ts +82 -0
  336. package/dist/features/price-index/market-stats.js +230 -0
  337. package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
  338. package/dist/features/print/components/BoxLabelPrintView.js +66 -0
  339. package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
  340. package/dist/features/print/components/LabelProfilePicker.js +38 -0
  341. package/dist/features/print/components/labels.d.ts +117 -0
  342. package/dist/features/print/components/labels.js +258 -0
  343. package/dist/features/print/components/labels.style.css +46 -0
  344. package/dist/features/print/index.d.ts +6 -0
  345. package/dist/features/print/index.js +16 -0
  346. package/dist/features/products/columns/productTableColumns.js +5 -4
  347. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  348. package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
  349. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  350. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  351. package/dist/features/products/components/PrizeRevealModal.js +2 -2
  352. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  353. package/dist/features/products/components/ProductForm.js +34 -23
  354. package/dist/features/products/components/ProductGrid.js +86 -62
  355. package/dist/features/products/constants/card-badges.d.ts +97 -0
  356. package/dist/features/products/constants/card-badges.js +100 -0
  357. package/dist/features/products/repository/products.repository.js +34 -1
  358. package/dist/features/products/schemas/firestore.d.ts +46 -3
  359. package/dist/features/products/schemas/firestore.js +21 -0
  360. package/dist/features/promotions/components/PromotionsView.js +1 -1
  361. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
  362. package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
  363. package/dist/features/promotions/schemas/firestore.js +30 -3
  364. package/dist/features/promotions/schemas/index.d.ts +6 -6
  365. package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
  366. package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
  367. package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
  368. package/dist/features/protection-claims/schemas/firestore.js +130 -0
  369. package/dist/features/reviews/actions/review-actions.js +3 -2
  370. package/dist/features/reviews/components/ReviewModal.js +1 -1
  371. package/dist/features/reviews/components/ReviewsList.js +1 -1
  372. package/dist/features/reviews/schemas/firestore.d.ts +20 -1
  373. package/dist/features/scams/constants/scam-types.d.ts +2 -0
  374. package/dist/features/scams/constants/scam-types.js +18 -0
  375. package/dist/features/scams/schemas/report-form.d.ts +3 -3
  376. package/dist/features/scams/schemas/report-form.js +26 -1
  377. package/dist/features/search/components/Search.js +9 -9
  378. package/dist/features/search/components/SearchResultsClient.js +18 -3
  379. package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
  380. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  381. package/dist/features/seller/actions/offer-actions.js +16 -1
  382. package/dist/features/seller/actions/seller-actions.js +14 -3
  383. package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
  384. package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
  385. package/dist/features/seller/components/PrintCenterView.js +41 -30
  386. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  387. package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
  388. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  389. package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
  390. package/dist/features/seller/components/SellerProductShell.js +123 -13
  391. package/dist/features/seller/components/SellerReviewsView.js +4 -2
  392. package/dist/features/seller/components/SellerSidebar.js +1 -1
  393. package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
  394. package/dist/features/seller/schemas/coupon-form.js +27 -0
  395. package/dist/features/seller/schemas/product-form.d.ts +3 -0
  396. package/dist/features/seller/schemas/product-form.js +5 -0
  397. package/dist/features/shell/FormShell.js +2 -2
  398. package/dist/features/shell/QuickFormDrawer.js +14 -0
  399. package/dist/features/shell/SectionForm.d.ts +19 -0
  400. package/dist/features/shell/SectionForm.js +133 -9
  401. package/dist/features/shell/SectionForm.style.css +54 -0
  402. package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
  403. package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
  404. package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
  405. package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
  406. package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
  407. package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
  408. package/dist/features/stores/components/StoreGuideHubView.js +1 -1
  409. package/dist/features/stores/components/StoreHeader.js +1 -1
  410. package/dist/features/support/schemas/firestore.d.ts +73 -2
  411. package/dist/features/support/schemas/firestore.js +59 -0
  412. package/dist/index.d.ts +16 -24
  413. package/dist/index.js +38 -47
  414. package/dist/next/ErrorBoundary.js +1 -1
  415. package/dist/next/routing/route-map.d.ts +24 -0
  416. package/dist/next/routing/route-map.js +40 -0
  417. package/dist/providers/payment-manual/index.d.ts +15 -1
  418. package/dist/providers/payment-manual/index.js +37 -0
  419. package/dist/providers/payment-phonepe/index.d.ts +14 -1
  420. package/dist/providers/payment-phonepe/index.js +36 -0
  421. package/dist/providers/payment-razorpay/index.d.ts +44 -1
  422. package/dist/providers/payment-razorpay/index.js +99 -0
  423. package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
  424. package/dist/providers/shipping-shiprocket/index.js +18 -0
  425. package/dist/schemas/registry.d.ts +44 -11
  426. package/dist/server-entry.d.ts +2 -0
  427. package/dist/server-entry.js +27 -0
  428. package/dist/server.d.ts +42 -0
  429. package/dist/server.js +93 -0
  430. package/dist/styles.css +418 -149
  431. package/dist/tailwind-utilities.css +1 -1
  432. package/dist/tokens/themes/default-dark.js +15 -12
  433. package/dist/tokens/themes/default-light.js +14 -11
  434. package/dist/tokens/tokens.css +106 -23
  435. package/dist/ui/DataTable.style.css +4 -4
  436. package/dist/ui/columns/cell-renderers.d.ts +20 -0
  437. package/dist/ui/columns/cell-renderers.js +26 -1
  438. package/dist/ui/columns/index.d.ts +1 -1
  439. package/dist/ui/columns/index.js +4 -1
  440. package/dist/ui/components/Badge.style.css +1 -1
  441. package/dist/ui/components/Breadcrumb.js +19 -1
  442. package/dist/ui/components/BulkActionBar.style.css +4 -4
  443. package/dist/ui/components/Button.style.css +1 -1
  444. package/dist/ui/components/Checkbox.style.css +1 -1
  445. package/dist/ui/components/FallbackShell.js +1 -1
  446. package/dist/ui/components/Form.d.ts +14 -1
  447. package/dist/ui/components/Form.js +2 -2
  448. package/dist/ui/components/FormField.js +18 -4
  449. package/dist/ui/components/FormField.style.css +43 -3
  450. package/dist/ui/components/GatedPrice.style.css +1 -1
  451. package/dist/ui/components/IconButton.style.css +1 -1
  452. package/dist/ui/components/Input.js +22 -1
  453. package/dist/ui/components/Input.style.css +38 -22
  454. package/dist/ui/components/ListingFilterDrawer.js +1 -1
  455. package/dist/ui/components/ListingToolbar.js +1 -1
  456. package/dist/ui/components/PaginatedSelect.js +0 -0
  457. package/dist/ui/components/Radio.style.css +1 -1
  458. package/dist/ui/components/Repeater.d.ts +53 -0
  459. package/dist/ui/components/Repeater.js +7 -0
  460. package/dist/ui/components/RichTextEditor.d.ts +20 -1
  461. package/dist/ui/components/RichTextEditor.js +23 -2
  462. package/dist/ui/components/Select.style.css +7 -21
  463. package/dist/ui/components/Semantic.js +27 -3
  464. package/dist/ui/components/TagInput.style.css +4 -9
  465. package/dist/ui/components/Textarea.style.css +4 -18
  466. package/dist/ui/components/Toggle.style.css +1 -1
  467. package/dist/ui/components/Typography.d.ts +3 -3
  468. package/dist/ui/components/Typography.js +15 -15
  469. package/dist/ui/components/ViewToggle.style.css +4 -4
  470. package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
  471. package/dist/ui/forms/AddAnotherToggle.js +56 -0
  472. package/dist/ui/forms/ColorPickerField.js +15 -2
  473. package/dist/ui/forms/FieldCheckbox.js +15 -2
  474. package/dist/ui/forms/FieldInput.d.ts +22 -1
  475. package/dist/ui/forms/FieldInput.js +19 -5
  476. package/dist/ui/forms/FieldLabel.d.ts +35 -0
  477. package/dist/ui/forms/FieldLabel.js +70 -0
  478. package/dist/ui/forms/FieldSelect.d.ts +4 -1
  479. package/dist/ui/forms/FieldSelect.js +27 -5
  480. package/dist/ui/forms/FieldTextarea.d.ts +4 -1
  481. package/dist/ui/forms/FieldTextarea.js +22 -5
  482. package/dist/ui/forms/FormShell.d.ts +17 -1
  483. package/dist/ui/forms/FormShell.js +36 -2
  484. package/dist/ui/forms/FormShell.style.css +41 -33
  485. package/dist/ui/forms/index.d.ts +5 -1
  486. package/dist/ui/forms/index.js +2 -0
  487. package/dist/ui/icons/icon-registry.d.ts +1 -0
  488. package/dist/ui/icons/icon-registry.js +17 -1
  489. package/dist/utils/id-generators.d.ts +80 -0
  490. package/dist/utils/id-generators.js +93 -0
  491. package/dist/utils/search-txt-builders.d.ts +12 -0
  492. package/dist/utils/search-txt-builders.js +17 -0
  493. package/package.json +1 -1
  494. package/scripts/seed-cli.mjs +106 -5
  495. package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
  496. package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
  497. package/dist/features/loyalty/api/balance/route.d.ts +0 -12
  498. package/dist/features/loyalty/api/balance/route.js +0 -41
  499. package/dist/features/loyalty/api/earn/route.d.ts +0 -12
  500. package/dist/features/loyalty/api/earn/route.js +0 -38
  501. package/dist/features/loyalty/api/history/route.d.ts +0 -12
  502. package/dist/features/loyalty/api/history/route.js +0 -58
  503. package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
  504. package/dist/features/loyalty/api/redeem/route.js +0 -38
  505. package/dist/features/loyalty/columns/index.d.ts +0 -17
  506. package/dist/features/loyalty/columns/index.js +0 -40
  507. package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
  508. package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
  509. package/dist/features/loyalty/components/index.d.ts +0 -1
  510. package/dist/features/loyalty/components/index.js +0 -1
  511. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
  512. package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
  513. package/dist/features/loyalty/index.d.ts +0 -6
  514. package/dist/features/loyalty/index.js +0 -6
  515. package/dist/features/loyalty/manifest.d.ts +0 -2
  516. package/dist/features/loyalty/manifest.js +0 -16
  517. package/dist/features/loyalty/messages/en.json +0 -19
  518. package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
  519. package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
  520. package/dist/features/loyalty/schemas/index.d.ts +0 -85
  521. package/dist/features/loyalty/schemas/index.js +0 -40
  522. package/dist/features/loyalty/server.d.ts +0 -6
  523. package/dist/features/loyalty/server.js +0 -6
  524. package/dist/features/loyalty/types/index.d.ts +0 -31
  525. package/dist/features/loyalty/types/index.js +0 -1
  526. package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
  527. package/dist/features/loyalty/types/loyalty-config.js +0 -1
  528. package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
  529. package/dist/features/loyalty/types/loyalty-math.js +0 -27
  530. package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
  531. package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
@@ -0,0 +1,155 @@
1
+ /**
2
+ * `deadlinesFor(order)` — every deadline an order currently owes, derived.
3
+ *
4
+ * ## Pure, so a page can render it for free
5
+ *
6
+ * No reads, no writes, no `obligations` lookup. A buyer or seller page calls
7
+ * this on an order it already has and renders "Dispatch by Thu 3 Nov".
8
+ *
9
+ * 🛑 That is why deadlines are DERIVED rather than stored on the order. A
10
+ * stored `dispatchDueAt` would need a backfill for every existing order, and
11
+ * would drift from the policy the moment an admin changed the duration — the
12
+ * denormalised-mirror trap (Root Cause #42). The `obligations` collection
13
+ * stores one too, and that copy is explicitly a due-date INDEX for the sweep
14
+ * to query, not the answer.
15
+ *
16
+ * ## Test-window compression is PER SUBJECT
17
+ *
18
+ * 🛑 A tester run must be able to watch a 3-day acceptance window close inside
19
+ * a 90-minute session, and a hard-coded duration cannot be shortened — which is
20
+ * what made those cases untestable in any run shorter than the literal. So
21
+ * durations scale by `TESTER_WINDOW_MINUTES`, but **only when the subject
22
+ * itself carries `isTestData: true`.** A global switch would compress every
23
+ * live buyer's deadline the moment somebody ran the tester, which is the one
24
+ * mistake this must not make.
25
+ */
26
+ /*
27
+ * 🛑 `addBusinessDays` ONLY — `resolveHolidays` is module-private and takes
28
+ * `(startYear, endYear, opts)`, not a Date. I imported it first and it would
29
+ * not have compiled; `addBusinessDays` already resolves the holiday set
30
+ * internally for every year the window spans, so the correct call passes no
31
+ * holiday argument at all.
32
+ */
33
+ import { addBusinessDays } from "../time/business-days.js";
34
+ import { OBLIGATION_POLICIES, durationToMinutes, } from "../../../features/obligations/constants/policies.js";
35
+ import { ALL_OBLIGATION_KINDS, } from "../../../features/obligations/schemas/firestore.js";
36
+ import { windowMinutes } from "../../../features/tester/seed-data/tester-window.js";
37
+ /**
38
+ * How much a test fixture's deadlines are compressed.
39
+ *
40
+ * The real window is scaled so the LONGEST obligation (14-day delivery
41
+ * confirmation) still fits inside one tester window, while the shortest
42
+ * (24-hour proof re-upload) stays long enough to observe. Expressed as a
43
+ * fraction of `TESTER_WINDOW_MINUTES` per real day.
44
+ */
45
+ const TEST_MINUTES_PER_REAL_DAY = 1 / 14;
46
+ function compressForTest(minutes) {
47
+ const realDays = minutes / (24 * 60);
48
+ const scaled = realDays * windowMinutes() * TEST_MINUTES_PER_REAL_DAY;
49
+ /*
50
+ * Floored at one minute. A deadline computed as zero would fire on the same
51
+ * sweep tick that created it, so the tester could never observe the BEFORE
52
+ * state — and a case written as "before → after" needs both halves.
53
+ */
54
+ return Math.max(1, scaled);
55
+ }
56
+ /**
57
+ * Resolve one duration into an absolute date.
58
+ *
59
+ * 🛑 `business` goes through `addBusinessDays`, which counts weekends AND the
60
+ * Indian holiday calendar. The predecessor helper subtracted CALENDAR days and
61
+ * called them business days, so the "7-business-day" payout hold was really
62
+ * about 5 — and a missed holiday silently SHORTENS a deadline, which is why
63
+ * the calendar has an owner and a horizon warning.
64
+ */
65
+ export function resolveDueAt(anchor, duration, opts) {
66
+ if (opts?.isTestData) {
67
+ /*
68
+ * A compressed fixture is always wall-clock. Business-day arithmetic on a
69
+ * 6-minute window is meaningless, and worse: a fixture seeded on a Friday
70
+ * would land its "2 business day" deadline on Tuesday regardless of
71
+ * compression, so the case could never run.
72
+ */
73
+ return new Date(anchor.getTime() + compressForTest(durationToMinutes(duration)) * 60000);
74
+ }
75
+ if (duration.calendar === "business" && duration.unit === "days") {
76
+ return addBusinessDays(anchor, duration.value);
77
+ }
78
+ return new Date(anchor.getTime() + durationToMinutes(duration) * 60000);
79
+ }
80
+ /**
81
+ * Every deadline this order currently owes.
82
+ *
83
+ * Only kinds whose `precondition` holds AND whose `anchor` has fired appear —
84
+ * an order that has not shipped owes no delivery confirmation, and that is the
85
+ * difference between "not yet" and "overdue".
86
+ */
87
+ export function deadlinesFor(order) {
88
+ const out = [];
89
+ const isTestData = order.isTestData === true;
90
+ for (const kind of ALL_OBLIGATION_KINDS) {
91
+ const policy = OBLIGATION_POLICIES[kind];
92
+ const anchor = policy.anchor(order);
93
+ if (!anchor)
94
+ continue;
95
+ if (!policy.precondition(order))
96
+ continue;
97
+ out.push({
98
+ kind,
99
+ anchoredAt: anchor,
100
+ dueAt: resolveDueAt(anchor, policy.duration, { isTestData }),
101
+ policy,
102
+ });
103
+ }
104
+ return out.sort((a, b) => a.dueAt.getTime() - b.dueAt.getTime());
105
+ }
106
+ /**
107
+ * Which obligations this order should have open, and which should be closed.
108
+ *
109
+ * Called from the order's own write (`updateWithHistory`), where the current
110
+ * document is already in hand — so reconciling costs **zero extra reads**.
111
+ *
112
+ * 🛑 Derived from the POLICY's own `precondition`, not from a hand-written
113
+ * `Record<OrderStatus, {opens, closes}>` table.
114
+ *
115
+ * The plan proposed that table, and building it this way instead is a
116
+ * deliberate departure worth stating: a status→opens/closes map is a SECOND
117
+ * encoding of the same facts the preconditions already express, and the two
118
+ * would drift exactly as the plan's own proposed transition map had already
119
+ * drifted from the census (it omitted `pending → processing`, which a live
120
+ * sweep writes). One source, evaluated twice — once for display, once for
121
+ * reconciliation — cannot disagree with itself.
122
+ */
123
+ export function reconcileObligations(order,
124
+ /**
125
+ * The order as it was BEFORE this write, when the caller has it.
126
+ *
127
+ * 🛑 THIS PARAMETER IS A COST FIX, not an optimisation. My first version
128
+ * closed "every kind not currently open", which on an 11-kind union meant
129
+ * **11 Firestore update attempts on every single order write** — each one a
130
+ * billed write against a document that mostly does not exist, on the hottest
131
+ * collection in the project. Rule #6 exists for exactly that.
132
+ *
133
+ * With `previous` in hand the close set is `was-open MINUS is-open`, which is
134
+ * usually empty and never larger than the number of obligations that
135
+ * genuinely just completed. Zero reads either way, because `updateWithHistory`
136
+ * already holds the pre-write document.
137
+ *
138
+ * Omitting it falls back to the full set, which is correct for a deliberate
139
+ * backfill over existing orders and wrong for the write path.
140
+ */
141
+ previous) {
142
+ const shouldBeOpen = deadlinesFor(order);
143
+ const openKinds = new Set(shouldBeOpen.map((d) => d.kind));
144
+ if (previous) {
145
+ const wasOpen = deadlinesFor(previous).map((d) => d.kind);
146
+ return {
147
+ open: shouldBeOpen,
148
+ close: wasOpen.filter((k) => !openKinds.has(k)),
149
+ };
150
+ }
151
+ return {
152
+ open: shouldBeOpen,
153
+ close: ALL_OBLIGATION_KINDS.filter((k) => !openKinds.has(k)),
154
+ };
155
+ }
@@ -114,6 +114,45 @@ export interface ShippingReconciliation {
114
114
  sellerAbsorbs: number;
115
115
  /** Points credited to the buyer, 1 point = ₹1. */
116
116
  buyerPoints: number;
117
+ /**
118
+ * Rupees the seller is REIMBURSED for postage — `min(spent, charged)`.
119
+ *
120
+ * ## 🛑 This is the D45 decision, and it applies to BOTH branches
121
+ *
122
+ * Owner, 2026-10-21: *"if seller ships on their own then they have to upload
123
+ * the receipt of the shipment with the tracking number so that it is paid to
124
+ * them directly; if they use our platform's integration (Shiprocket) they do
125
+ * not get the money, the platform keeps it."* Plus: reimbursement **capped at
126
+ * what the buyer paid**, and the saving goes to the **buyer as points**.
127
+ *
128
+ * So shipping stops being revenue to allocate and becomes a COST TO
129
+ * REIMBURSE. The third output completes a formula whose other two terms this
130
+ * function already computed from the same two inputs:
131
+ *
132
+ * ```
133
+ * reimbursable = min(spent, charged)
134
+ * sellerAbsorbs = max(0, spent − charged)
135
+ * buyerPoints = max(0, charged − spent)
136
+ * ```
137
+ *
138
+ * 🛑 **The platform nets exactly zero on shipping in every case**, which is
139
+ * the property that makes it defensible to both sides and is worth stating as
140
+ * an invariant rather than leaving to be inferred:
141
+ *
142
+ * | buyer paid | receipt | seller gets | buyer gets | platform |
143
+ * |---|---|---|---|---|
144
+ * | ₹120 | ₹80 | ₹80 | ₹40 points | **₹0** |
145
+ * | ₹80 | ₹120 | ₹80 | — | **₹0** |
146
+ * | ₹100 | ₹100 | ₹100 | — | **₹0** |
147
+ *
148
+ * It is computed here for every order rather than only on the self-shipped
149
+ * branch, because today the platform keeps shipping in the QUOTED path too —
150
+ * so this is the fix for both, not a new rule for one. Whether it is actually
151
+ * PAID is gated separately: a Shiprocket-booked parcel was paid for by us, so
152
+ * `reimbursable` must not reach the payout base there. See
153
+ * `isReimbursableShipment`.
154
+ */
155
+ reimbursable: number;
117
156
  /** True when the seller shipped with a courier the buyer did not choose. */
118
157
  courierChanged: boolean;
119
158
  }
@@ -133,6 +172,63 @@ export interface ShippingReconciliation {
133
172
  * buyer's (rounding down).
134
173
  */
135
174
  export declare function reconcileShipping(quote: Pick<SelectedShippingQuote, "chargedRate" | "courierId">, actual: ActualShipmentCost): ShippingReconciliation;
175
+ /**
176
+ * May this order's postage be reimbursed to the seller at all?
177
+ *
178
+ * ## 🛑 Gated on WHO BOOKED, never on whether a receipt exists
179
+ *
180
+ * Owner's rule: a seller who ships themselves is paid the approved amount on
181
+ * proof; a seller who uses our Shiprocket integration gets nothing, because we
182
+ * already paid the courier.
183
+ *
184
+ * Testing for a receipt instead would be the exploitable version — a seller
185
+ * could upload a receipt for a parcel the platform paid for and be reimbursed
186
+ * for someone else's spend. The discriminator has to be the booking, which is
187
+ * a fact about how the shipment was created and not something the claimant
188
+ * supplies.
189
+ *
190
+ * ## 🛑 It fails OPEN on an unknown booker, and the previous docstring claimed
191
+ * the opposite
192
+ *
193
+ * That text read: *"It returns FALSE when the booker is unknown, and that
194
+ * direction is deliberate: paying out on an unverified premise is the error
195
+ * that cannot be undone."* **The code has always returned TRUE.** Corrected
196
+ * 2026-10-21 — the code is right and the comment was wrong, which is the
197
+ * dangerous way round: a reader trusted a safety property that was not there.
198
+ *
199
+ * Fail-open is correct here because **nothing writes
200
+ * `platformBookedShipment`.** A self-shipped parcel has no flag to set, so a
201
+ * fail-closed gate would refuse every seller and the reimbursement feature
202
+ * would be entirely dead. Absence means "self-shipped", which is the common
203
+ * case, and the real protection on that path is the evidence-plus-approval
204
+ * step — a seller is paid the amount an admin approves from an uploaded
205
+ * receipt, never an amount they assert.
206
+ *
207
+ * ## 🛑 THE GATE IS THEREFORE INERT, and that is a prerequisite, not a bug
208
+ *
209
+ * Measured 2026-10-21: `platformBookedShipment` has ZERO writers — only this
210
+ * declaration, the `ShippingReconciliation` field and the order schema. The
211
+ * exposure is nil **today** because nothing creates a platform booking either:
212
+ * `ShiprocketShippingProvider` is registered in `providers.config.ts` but
213
+ * nothing calls its `createShipment`.
214
+ *
215
+ * So the day that booking path is wired, THE SAME COMMIT must write this flag.
216
+ * Otherwise the gate fails open on a parcel the platform paid for and the
217
+ * seller is reimbursed for our spend — the exact double-payment this function
218
+ * exists to prevent.
219
+ *
220
+ * Gated on WHO BOOKED rather than on whether a receipt exists, because testing
221
+ * for a receipt is the exploitable version: a seller could upload a receipt for
222
+ * a parcel the platform paid for. The discriminator has to be a fact about how
223
+ * the shipment was created, not something the claimant supplies — which is
224
+ * also why this function deliberately does NOT look at
225
+ * `shippingReimbursement`. That parameter was accepted and never read, and an
226
+ * unread parameter invites exactly the misuse it was meant to forbid, so it is
227
+ * gone.
228
+ */
229
+ export declare function isReimbursableShipment(order: {
230
+ platformBookedShipment?: boolean;
231
+ }): boolean;
136
232
  /**
137
233
  * Turn carrier serviceability results into offerable options.
138
234
  *
@@ -82,9 +82,76 @@ export function reconcileShipping(quote, actual) {
82
82
  return {
83
83
  sellerAbsorbs: delta < 0 ? Math.abs(delta) : 0,
84
84
  buyerPoints: delta > 0 ? delta : 0,
85
+ /*
86
+ * `min(spent, charged)` — capped at what the buyer paid, per the owner's
87
+ * decision. Rounded through the same helper as the others: a bare
88
+ * `Math.min` of two 2dp figures is safe, but keeping all three terms on one
89
+ * rounding path is what stops `reimbursable + buyerPoints` drifting a paisa
90
+ * away from `charged`, which is the invariant an auditor would check.
91
+ */
92
+ reimbursable: roundMoney(Math.min(spent, charged)),
85
93
  courierChanged: quote.courierId !== actual.courierId,
86
94
  };
87
95
  }
96
+ /**
97
+ * May this order's postage be reimbursed to the seller at all?
98
+ *
99
+ * ## 🛑 Gated on WHO BOOKED, never on whether a receipt exists
100
+ *
101
+ * Owner's rule: a seller who ships themselves is paid the approved amount on
102
+ * proof; a seller who uses our Shiprocket integration gets nothing, because we
103
+ * already paid the courier.
104
+ *
105
+ * Testing for a receipt instead would be the exploitable version — a seller
106
+ * could upload a receipt for a parcel the platform paid for and be reimbursed
107
+ * for someone else's spend. The discriminator has to be the booking, which is
108
+ * a fact about how the shipment was created and not something the claimant
109
+ * supplies.
110
+ *
111
+ * ## 🛑 It fails OPEN on an unknown booker, and the previous docstring claimed
112
+ * the opposite
113
+ *
114
+ * That text read: *"It returns FALSE when the booker is unknown, and that
115
+ * direction is deliberate: paying out on an unverified premise is the error
116
+ * that cannot be undone."* **The code has always returned TRUE.** Corrected
117
+ * 2026-10-21 — the code is right and the comment was wrong, which is the
118
+ * dangerous way round: a reader trusted a safety property that was not there.
119
+ *
120
+ * Fail-open is correct here because **nothing writes
121
+ * `platformBookedShipment`.** A self-shipped parcel has no flag to set, so a
122
+ * fail-closed gate would refuse every seller and the reimbursement feature
123
+ * would be entirely dead. Absence means "self-shipped", which is the common
124
+ * case, and the real protection on that path is the evidence-plus-approval
125
+ * step — a seller is paid the amount an admin approves from an uploaded
126
+ * receipt, never an amount they assert.
127
+ *
128
+ * ## 🛑 THE GATE IS THEREFORE INERT, and that is a prerequisite, not a bug
129
+ *
130
+ * Measured 2026-10-21: `platformBookedShipment` has ZERO writers — only this
131
+ * declaration, the `ShippingReconciliation` field and the order schema. The
132
+ * exposure is nil **today** because nothing creates a platform booking either:
133
+ * `ShiprocketShippingProvider` is registered in `providers.config.ts` but
134
+ * nothing calls its `createShipment`.
135
+ *
136
+ * So the day that booking path is wired, THE SAME COMMIT must write this flag.
137
+ * Otherwise the gate fails open on a parcel the platform paid for and the
138
+ * seller is reimbursed for our spend — the exact double-payment this function
139
+ * exists to prevent.
140
+ *
141
+ * Gated on WHO BOOKED rather than on whether a receipt exists, because testing
142
+ * for a receipt is the exploitable version: a seller could upload a receipt for
143
+ * a parcel the platform paid for. The discriminator has to be a fact about how
144
+ * the shipment was created, not something the claimant supplies — which is
145
+ * also why this function deliberately does NOT look at
146
+ * `shippingReimbursement`. That parameter was accepted and never read, and an
147
+ * unread parameter invites exactly the misuse it was meant to forbid, so it is
148
+ * gone.
149
+ */
150
+ export function isReimbursableShipment(order) {
151
+ if (order.platformBookedShipment === true)
152
+ return false;
153
+ return true;
154
+ }
88
155
  /**
89
156
  * Two decimal places.
90
157
  *
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Business-day arithmetic for India, with an admin-maintained holiday list.
3
+ *
4
+ * WHY: every deadline in the order lifecycle that matters commercially is
5
+ * quoted in *business* days — the payout hold, the seller dispatch
6
+ * window, the return-response window, the inspection window. Before this
7
+ * module the only implementation was `getBusinessDayCutoff` in
8
+ * `autoPayoutEligibility.ts`, which did this:
9
+ *
10
+ * cutoff.setUTCDate(cutoff.getUTCDate() - daysAgo)
11
+ *
12
+ * i.e. it subtracted CALENDAR days and called them business days. A
13
+ * 7-"business"-day hold computed on a Monday reached back to the previous
14
+ * Monday — 5 business days, not 7 — so every payout over a weekend was
15
+ * released two business days early, in the seller's favour, with no
16
+ * record that the stated hold had not been honoured.
17
+ *
18
+ * WHAT: `addBusinessDays` / `subBusinessDays` / `isBusinessDay` /
19
+ * `businessDaysBetween`, all operating on IST calendar days and all
20
+ * taking the holiday list as an explicit parameter.
21
+ *
22
+ * 🛑 A MISSED HOLIDAY SILENTLY SHORTENS A DEADLINE. There is no error, no
23
+ * log, and nothing to notice — the hold simply releases a day early. So the
24
+ * list below needs an owner and a review before each financial year; it is
25
+ * not fire-and-forget config. That hazard is the reason the list is DATA
26
+ * (admin-editable, see `resolveHolidays`) rather than a constant someone has
27
+ * to ship a release to change.
28
+ */
29
+ /**
30
+ * 🛑 IST, not UTC, and this is not a preference.
31
+ *
32
+ * A business day is a property of the *place the business operates in*. India
33
+ * is UTC+5:30, so 23:00 UTC on a Friday is already Saturday morning in
34
+ * Mumbai. Computing weekends in UTC therefore misclassifies a 5.5-hour band
35
+ * at the edge of every single day — which is 23% of a working Friday evening
36
+ * treated as a working day when the office is shut, and the inverse on Sunday
37
+ * night.
38
+ *
39
+ * The old helper's `setUTCHours(4, 30, 0, 0)` was reaching for exactly this
40
+ * (04:30 UTC = 10:00 IST) without saying so. Making the offset explicit is
41
+ * what lets the weekend test be correct rather than approximately correct.
42
+ */
43
+ import type { JsonValue } from "../../../schemas/types";
44
+ /** `YYYY-MM-DD` in IST. The key format the holiday list uses. */
45
+ export declare function toIstDateKey(d: Date): string;
46
+ /**
47
+ * Indian public holidays on which we do not count a business day.
48
+ *
49
+ * Deliberately NARROW: only the days on which banking and courier movement
50
+ * genuinely stop nationwide. A regional festival that closes one state's
51
+ * offices is not here, because treating it as a national holiday would
52
+ * *lengthen* every seller's deadline across the country — and unlike a missed
53
+ * holiday, that error is invisible in the seller's favour and compounds.
54
+ *
55
+ * 🛑 Dates are LITERAL, never computed. Several of these move year to year
56
+ * (they follow lunar calendars), so a formula would be wrong rather than
57
+ * stale — and stale is detectable while wrong is not. Entries end at the last
58
+ * declared year on purpose: `resolveHolidays` warns past that horizon instead
59
+ * of silently treating an unlisted Diwali as a working day.
60
+ */
61
+ export declare const INDIA_HOLIDAYS_BY_YEAR: Readonly<Record<number, readonly string[]>>;
62
+ /** The last year with a curated list — past this, `resolveHolidays` warns. */
63
+ export declare const HOLIDAY_HORIZON_YEAR: number;
64
+ export interface BusinessDayOptions {
65
+ /**
66
+ * Extra closure dates (`YYYY-MM-DD`, IST), from
67
+ * `siteSettings.platformLimits.businessHolidays` once that field exists.
68
+ * Merged with the built-in list rather than replacing it, so an admin
69
+ * cannot accidentally delete Independence Day by saving an empty field.
70
+ */
71
+ extraHolidays?: readonly string[];
72
+ /** Injected for the warning path; defaults to no-op so pure callers stay pure. */
73
+ onWarn?: (message: string, meta?: Record<string, JsonValue>) => void;
74
+ }
75
+ /** Saturday/Sunday in IST, or a listed holiday. */
76
+ export declare function isBusinessDay(d: Date, holidays: ReadonlySet<string>): boolean;
77
+ /** A deadline: `count` business days after `start`. */
78
+ export declare function addBusinessDays(start: Date, count: number, opts?: BusinessDayOptions): Date;
79
+ /** A cutoff: `count` business days before `start`. */
80
+ export declare function subBusinessDays(start: Date, count: number, opts?: BusinessDayOptions): Date;
81
+ /**
82
+ * The cutoff instant for "delivered at least `days` business days ago".
83
+ *
84
+ * Normalised to **10:00 IST** on the cutoff day, which is what the old helper's
85
+ * unexplained `setUTCHours(4, 30)` meant. It matters: without a fixed
86
+ * time-of-day the cutoff drifts with the hour the job happens to run, so an
87
+ * order can be eligible on one run and not the next.
88
+ */
89
+ export declare function businessDayCutoff(days: number, opts?: BusinessDayOptions, now?: Date): Date;
90
+ /** Inclusive-of-neither count of business days in `[from, to)`. */
91
+ export declare function businessDaysBetween(from: Date, to: Date, opts?: BusinessDayOptions): number;
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Business-day arithmetic for India, with an admin-maintained holiday list.
3
+ *
4
+ * WHY: every deadline in the order lifecycle that matters commercially is
5
+ * quoted in *business* days — the payout hold, the seller dispatch
6
+ * window, the return-response window, the inspection window. Before this
7
+ * module the only implementation was `getBusinessDayCutoff` in
8
+ * `autoPayoutEligibility.ts`, which did this:
9
+ *
10
+ * cutoff.setUTCDate(cutoff.getUTCDate() - daysAgo)
11
+ *
12
+ * i.e. it subtracted CALENDAR days and called them business days. A
13
+ * 7-"business"-day hold computed on a Monday reached back to the previous
14
+ * Monday — 5 business days, not 7 — so every payout over a weekend was
15
+ * released two business days early, in the seller's favour, with no
16
+ * record that the stated hold had not been honoured.
17
+ *
18
+ * WHAT: `addBusinessDays` / `subBusinessDays` / `isBusinessDay` /
19
+ * `businessDaysBetween`, all operating on IST calendar days and all
20
+ * taking the holiday list as an explicit parameter.
21
+ *
22
+ * 🛑 A MISSED HOLIDAY SILENTLY SHORTENS A DEADLINE. There is no error, no
23
+ * log, and nothing to notice — the hold simply releases a day early. So the
24
+ * list below needs an owner and a review before each financial year; it is
25
+ * not fire-and-forget config. That hazard is the reason the list is DATA
26
+ * (admin-editable, see `resolveHolidays`) rather than a constant someone has
27
+ * to ship a release to change.
28
+ */
29
+ const IST_OFFSET_MS = 5.5 * 60 * 60 * 1000;
30
+ /** `YYYY-MM-DD` in IST. The key format the holiday list uses. */
31
+ export function toIstDateKey(d) {
32
+ return new Date(d.getTime() + IST_OFFSET_MS).toISOString().slice(0, 10);
33
+ }
34
+ /**
35
+ * Indian public holidays on which we do not count a business day.
36
+ *
37
+ * Deliberately NARROW: only the days on which banking and courier movement
38
+ * genuinely stop nationwide. A regional festival that closes one state's
39
+ * offices is not here, because treating it as a national holiday would
40
+ * *lengthen* every seller's deadline across the country — and unlike a missed
41
+ * holiday, that error is invisible in the seller's favour and compounds.
42
+ *
43
+ * 🛑 Dates are LITERAL, never computed. Several of these move year to year
44
+ * (they follow lunar calendars), so a formula would be wrong rather than
45
+ * stale — and stale is detectable while wrong is not. Entries end at the last
46
+ * declared year on purpose: `resolveHolidays` warns past that horizon instead
47
+ * of silently treating an unlisted Diwali as a working day.
48
+ */
49
+ export const INDIA_HOLIDAYS_BY_YEAR = {
50
+ 2026: [
51
+ "2026-01-26", // Republic Day
52
+ "2026-03-04", // Holi
53
+ "2026-03-21", // Id-ul-Fitr
54
+ "2026-04-01", // Bank closing (annual)
55
+ "2026-05-01", // Maharashtra Day / May Day
56
+ "2026-05-28", // Bakrid
57
+ "2026-08-15", // Independence Day
58
+ "2026-08-26", // Janmashtami
59
+ "2026-09-14", // Ganesh Chaturthi
60
+ "2026-10-02", // Gandhi Jayanti
61
+ "2026-10-20", // Dussehra
62
+ "2026-11-08", // Diwali
63
+ "2026-11-24", // Guru Nanak Jayanti
64
+ "2026-12-25", // Christmas
65
+ ],
66
+ 2027: [
67
+ "2027-01-26",
68
+ "2027-04-01",
69
+ "2027-05-01",
70
+ "2027-08-15",
71
+ "2027-10-02",
72
+ "2027-12-25",
73
+ ],
74
+ };
75
+ /** The last year with a curated list — past this, `resolveHolidays` warns. */
76
+ export const HOLIDAY_HORIZON_YEAR = Math.max(...Object.keys(INDIA_HOLIDAYS_BY_YEAR).map(Number));
77
+ /**
78
+ * The holiday set covering every year the window could span.
79
+ *
80
+ * Takes a range rather than a single year because a 7-business-day window
81
+ * ending on 2 January reaches back into the previous year — resolving only the
82
+ * end year's holidays would count the Christmas break as working days.
83
+ */
84
+ function resolveHolidays(fromYear, toYear, opts) {
85
+ const out = new Set(opts?.extraHolidays ?? []);
86
+ for (let y = fromYear; y <= toYear; y++) {
87
+ const list = INDIA_HOLIDAYS_BY_YEAR[y];
88
+ if (list) {
89
+ for (const d of list)
90
+ out.add(d);
91
+ }
92
+ else if (y > HOLIDAY_HORIZON_YEAR) {
93
+ /*
94
+ * Loud, because the failure is otherwise invisible: with no list for the
95
+ * year every holiday counts as a working day, so every deadline computed
96
+ * in that year is SHORT. Nothing breaks, nothing errors, sellers are
97
+ * paid early and buyers' windows close early.
98
+ */
99
+ opts?.onWarn?.(`No holiday list for ${y} — business-day deadlines in that year will treat every public holiday as a working day. Extend INDIA_HOLIDAYS_BY_YEAR.`, { year: y, horizon: HOLIDAY_HORIZON_YEAR });
100
+ }
101
+ }
102
+ return out;
103
+ }
104
+ /** Saturday/Sunday in IST, or a listed holiday. */
105
+ export function isBusinessDay(d, holidays) {
106
+ const ist = new Date(d.getTime() + IST_OFFSET_MS);
107
+ const dow = ist.getUTCDay(); // 0 = Sunday, 6 = Saturday — of the IST date
108
+ if (dow === 0 || dow === 6)
109
+ return false;
110
+ return !holidays.has(toIstDateKey(d));
111
+ }
112
+ const DAY_MS = 24 * 60 * 60 * 1000;
113
+ /**
114
+ * Walk `count` business days from `start`, in whole days.
115
+ *
116
+ * `direction` is +1 (forward, a deadline) or −1 (backward, a cutoff). One
117
+ * function for both so the two can never disagree about what a business day
118
+ * is — two mirrored implementations is how Root Cause #30 is written.
119
+ *
120
+ * 🛑 The loop is bounded. An exhausted holiday list or a pathological input
121
+ * must not spin: `MAX_ITERATIONS` is generous enough that no real window
122
+ * reaches it (a 30-business-day window needs ~44 calendar days) and small
123
+ * enough to fail fast rather than hang a Cloud Function to its 540s ceiling.
124
+ */
125
+ const MAX_ITERATIONS = 400;
126
+ function walkBusinessDays(start, count, direction, opts) {
127
+ if (count <= 0)
128
+ return new Date(start);
129
+ const startYear = Number(toIstDateKey(start).slice(0, 4));
130
+ // Widen by a year either side — a window can straddle a year boundary, and
131
+ // over-resolving costs nothing while under-resolving silently drops a holiday.
132
+ const holidays = resolveHolidays(startYear - 1, startYear + 1, opts);
133
+ let cursor = new Date(start);
134
+ let remaining = count;
135
+ let guard = 0;
136
+ while (remaining > 0) {
137
+ if (++guard > MAX_ITERATIONS) {
138
+ opts?.onWarn?.("business-day walk exceeded its iteration bound — returning the cursor as-is", { count, direction, start: start.toISOString() });
139
+ break;
140
+ }
141
+ cursor = new Date(cursor.getTime() + direction * DAY_MS);
142
+ if (isBusinessDay(cursor, holidays))
143
+ remaining--;
144
+ }
145
+ return cursor;
146
+ }
147
+ /** A deadline: `count` business days after `start`. */
148
+ export function addBusinessDays(start, count, opts) {
149
+ return walkBusinessDays(start, count, 1, opts);
150
+ }
151
+ /** A cutoff: `count` business days before `start`. */
152
+ export function subBusinessDays(start, count, opts) {
153
+ return walkBusinessDays(start, count, -1, opts);
154
+ }
155
+ /**
156
+ * The cutoff instant for "delivered at least `days` business days ago".
157
+ *
158
+ * Normalised to **10:00 IST** on the cutoff day, which is what the old helper's
159
+ * unexplained `setUTCHours(4, 30)` meant. It matters: without a fixed
160
+ * time-of-day the cutoff drifts with the hour the job happens to run, so an
161
+ * order can be eligible on one run and not the next.
162
+ */
163
+ export function businessDayCutoff(days, opts, now = new Date()) {
164
+ const cutoff = subBusinessDays(now, days, opts);
165
+ const ist = new Date(cutoff.getTime() + IST_OFFSET_MS);
166
+ ist.setUTCHours(10, 0, 0, 0);
167
+ return new Date(ist.getTime() - IST_OFFSET_MS);
168
+ }
169
+ /** Inclusive-of-neither count of business days in `[from, to)`. */
170
+ export function businessDaysBetween(from, to, opts) {
171
+ if (to <= from)
172
+ return 0;
173
+ const fromYear = Number(toIstDateKey(from).slice(0, 4));
174
+ const toYear = Number(toIstDateKey(to).slice(0, 4));
175
+ const holidays = resolveHolidays(fromYear, toYear, opts);
176
+ let count = 0;
177
+ let cursor = new Date(from.getTime() + DAY_MS);
178
+ let guard = 0;
179
+ while (cursor <= to && ++guard <= MAX_ITERATIONS) {
180
+ if (isBusinessDay(cursor, holidays))
181
+ count++;
182
+ cursor = new Date(cursor.getTime() + DAY_MS);
183
+ }
184
+ return count;
185
+ }
package/dist/cli/index.js CHANGED
@@ -57,7 +57,6 @@ export const FEATURE_SUBPATH_MAP = {
57
57
  consultation: "@mohasinac/appkit/features/consultation",
58
58
  corporate: "@mohasinac/appkit/features/corporate",
59
59
  "before-after": "@mohasinac/appkit/features/before-after",
60
- loyalty: "@mohasinac/appkit/features/loyalty",
61
60
  collections: "@mohasinac/appkit/features/collections",
62
61
  preorders: "@mohasinac/appkit/features/pre-orders",
63
62
  };
@@ -109,7 +108,6 @@ const FEATURE_NAMESPACE_MAP = {
109
108
  consultation: "consultation",
110
109
  corporate: "corporate",
111
110
  "before-after": "beforeAfter",
112
- loyalty: "loyalty",
113
111
  collections: "collections",
114
112
  };
115
113
  // Opaque dynamic import — prevents bundlers from statically analysing the path