@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,76 @@
1
+ /**
2
+ * Turn a `payment.dispute.*` webhook into a case with the gateway's own clock
3
+ * on it.
4
+ *
5
+ * ## Why a dispute is the sharpest case kind
6
+ *
7
+ * Every other case in this collection has a deadline we invented or no deadline
8
+ * at all. A dispute has `respond_by`, set by the gateway, and **missing it loses
9
+ * the money by default** — irrespective of whether we were right. That single
10
+ * property is why `paymentCases` exists as its own queue rather than as rows in
11
+ * `serverErrors`: an error log is read when someone is curious, and this needs
12
+ * to be read before a date.
13
+ *
14
+ * ## 🛑 THIS HANDLER IS READS ONLY
15
+ *
16
+ * It fetches, it records, it notifies. It never contests, never submits
17
+ * evidence, never accepts liability. `IPaymentProvider` deliberately has no
18
+ * `contestDispute` (see the 🛑 on that contract), and `acceptDispute` requires
19
+ * an explicit irrevocability confirmation plus an admin uid — so neither is
20
+ * reachable from here even by accident.
21
+ *
22
+ * Submitting evidence is irreversible and is judged by a third party looking at
23
+ * documents. That decision belongs to a human in Razorpay's own dashboard. A
24
+ * later session wanting to "complete the dispute feature" should read this
25
+ * paragraph: the feature is complete, and this is the shape.
26
+ */
27
+ import type { Dispute } from "../../../../contracts/payment";
28
+ /**
29
+ * Which `payment.dispute.*` events exist.
30
+ *
31
+ * 🛑 TRAINING-SOURCED NAMES, NOT VERIFIED. The plan's capability matrix marks
32
+ * these `TRAINING` and says to read the live dashboard's event picker before
33
+ * trusting them — and that has not happened, because it needs the dashboard.
34
+ *
35
+ * This is why the route matches on the **`payment.dispute.` PREFIX** rather
36
+ * than on an exact list: a dispute event whose name we guessed wrong still
37
+ * classifies as a dispute, still gets a case, and still carries its
38
+ * `respond_by`. Guessing a name wrong then costs a slightly less precise title,
39
+ * not a missed chargeback. `razorpay.webhooks.all()` enumerates the real
40
+ * subscription set for free whenever someone has credentials to hand.
41
+ */
42
+ export declare const DISPUTE_EVENT_PREFIX = "payment.dispute.";
43
+ export interface DisputeWebhookEntity {
44
+ id?: string;
45
+ payment_id?: string;
46
+ amount?: number;
47
+ currency?: string;
48
+ amount_deducted?: number;
49
+ reason_code?: string;
50
+ respond_by?: number;
51
+ status?: string;
52
+ phase?: string;
53
+ created_at?: number;
54
+ }
55
+ /**
56
+ * Record a dispute as a case.
57
+ *
58
+ * Returns the case id, or `null` when the payload carried no usable dispute —
59
+ * in which case the caller still has a `gatewayEvents` row with the verbatim
60
+ * body, so nothing is lost.
61
+ */
62
+ export declare function ingestDispute(entity: DisputeWebhookEntity, opts: {
63
+ gateway: string;
64
+ gatewayEventId?: string;
65
+ rawEvent: string;
66
+ }): Promise<string | null>;
67
+ /**
68
+ * Poll the gateway for every dispute it knows about and reconcile them into
69
+ * cases. Phase 4's R4 calls this; it is idempotent by construction, since
70
+ * `openOrObserve` is.
71
+ *
72
+ * Takes the already-normalised `Dispute[]` from the provider adapter, which has
73
+ * done the unit conversions — so this function performs none, and there is one
74
+ * place per direction that does.
75
+ */
76
+ export declare function reconcileDisputes(disputes: readonly Dispute[]): Promise<number>;
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Turn a `payment.dispute.*` webhook into a case with the gateway's own clock
3
+ * on it.
4
+ *
5
+ * ## Why a dispute is the sharpest case kind
6
+ *
7
+ * Every other case in this collection has a deadline we invented or no deadline
8
+ * at all. A dispute has `respond_by`, set by the gateway, and **missing it loses
9
+ * the money by default** — irrespective of whether we were right. That single
10
+ * property is why `paymentCases` exists as its own queue rather than as rows in
11
+ * `serverErrors`: an error log is read when someone is curious, and this needs
12
+ * to be read before a date.
13
+ *
14
+ * ## 🛑 THIS HANDLER IS READS ONLY
15
+ *
16
+ * It fetches, it records, it notifies. It never contests, never submits
17
+ * evidence, never accepts liability. `IPaymentProvider` deliberately has no
18
+ * `contestDispute` (see the 🛑 on that contract), and `acceptDispute` requires
19
+ * an explicit irrevocability confirmation plus an admin uid — so neither is
20
+ * reachable from here even by accident.
21
+ *
22
+ * Submitting evidence is irreversible and is judged by a third party looking at
23
+ * documents. That decision belongs to a human in Razorpay's own dashboard. A
24
+ * later session wanting to "complete the dispute feature" should read this
25
+ * paragraph: the feature is complete, and this is the shape.
26
+ */
27
+ import { normalizeError } from "../../../../errors/normalize.js";
28
+ import { serverLogger } from "../../../../monitoring/index.js";
29
+ import { paiseToRupees, rupeesToPaise } from "../../../../core/money.js";
30
+ import { paymentCasesRepository } from "../../../../features/payment-cases/repository/payment-cases.repository.js";
31
+ import { orderRepository } from "../../../../features/orders/repository/orders.repository.js";
32
+ /**
33
+ * Dispute statuses, as Razorpay spells them.
34
+ *
35
+ * 🛑 NOT a TypeScript union on `Dispute.status` — the SDK declares that field
36
+ * as `string` and the value set is the gateway's to change. These constants are
37
+ * for COMPARISON, and every comparison below treats an unrecognised value as
38
+ * "still open", which fails in the safe direction: an unknown state leaves the
39
+ * case needing attention rather than silently closing it.
40
+ */
41
+ const DISPUTE_CLOSED_STATUSES = new Set(["won", "lost", "closed"]);
42
+ /**
43
+ * Which `payment.dispute.*` events exist.
44
+ *
45
+ * 🛑 TRAINING-SOURCED NAMES, NOT VERIFIED. The plan's capability matrix marks
46
+ * these `TRAINING` and says to read the live dashboard's event picker before
47
+ * trusting them — and that has not happened, because it needs the dashboard.
48
+ *
49
+ * This is why the route matches on the **`payment.dispute.` PREFIX** rather
50
+ * than on an exact list: a dispute event whose name we guessed wrong still
51
+ * classifies as a dispute, still gets a case, and still carries its
52
+ * `respond_by`. Guessing a name wrong then costs a slightly less precise title,
53
+ * not a missed chargeback. `razorpay.webhooks.all()` enumerates the real
54
+ * subscription set for free whenever someone has credentials to hand.
55
+ */
56
+ export const DISPUTE_EVENT_PREFIX = "payment.dispute.";
57
+ /**
58
+ * Severity from the dispute's own state.
59
+ *
60
+ * Always at least `warning`, and `error` while a response is still owed —
61
+ * because that is the window in which a human can still change the outcome.
62
+ * A closed dispute drops to `warning`: it still needs handling (a lost dispute
63
+ * means a payout clawback and an order-status decision) but no longer has a
64
+ * clock.
65
+ *
66
+ * 🛑 `openOrObserve` only ever escalates, so a `won`/`lost` event arriving
67
+ * after the `created` one will NOT downgrade the case from `error`. That is
68
+ * deliberate and is the correct direction: the operator was told this was
69
+ * urgent, and the fact that the window closed does not make the consequence
70
+ * smaller.
71
+ */
72
+ function severityFor(status) {
73
+ return status && DISPUTE_CLOSED_STATUSES.has(status) ? "warning" : "error";
74
+ }
75
+ /**
76
+ * Record a dispute as a case.
77
+ *
78
+ * Returns the case id, or `null` when the payload carried no usable dispute —
79
+ * in which case the caller still has a `gatewayEvents` row with the verbatim
80
+ * body, so nothing is lost.
81
+ */
82
+ export async function ingestDispute(entity, opts) {
83
+ const disputeId = entity.id;
84
+ const paymentId = entity.payment_id;
85
+ if (!disputeId || !paymentId) {
86
+ serverLogger.error("dispute ingest: payload carried no dispute id or payment id", {
87
+ rawEvent: opts.rawEvent,
88
+ });
89
+ return null;
90
+ }
91
+ /*
92
+ * 🛑 Two conversions, both silent when wrong, and they fail differently.
93
+ *
94
+ * amount / amount_deducted — currency SUBUNITS → rupees, via the shared
95
+ * helper. Hand-writing `/ 100` here would be blocked by
96
+ * `audit-money-units`, and rightly: six money fields survived the 2026-05
97
+ * migration with the wrong unit precisely because the arithmetic was
98
+ * scattered rather than named.
99
+ *
100
+ * respond_by — Unix SECONDS → Date, so `* 1000`. Getting this wrong yields
101
+ * 21 January 1970, which does not throw and does not read as a unit bug —
102
+ * it reads as corrupt data, and it would make a live deadline sort as
103
+ * decades overdue, so an escalation query would either flood on it or
104
+ * ignore it. There is no helper for this one because it is a timestamp,
105
+ * not money.
106
+ */
107
+ const amount = typeof entity.amount === "number" ? paiseToRupees(entity.amount) : undefined;
108
+ const amountDeducted = typeof entity.amount_deducted === "number"
109
+ ? paiseToRupees(entity.amount_deducted)
110
+ : undefined;
111
+ const respondBy = typeof entity.respond_by === "number" ? new Date(entity.respond_by * 1000) : undefined;
112
+ /*
113
+ * Which of OUR orders this dispute concerns. Best-effort: a dispute on a
114
+ * payment we cannot find is MORE urgent, not less — it means either our
115
+ * records are wrong or somebody is disputing a payment we never recorded —
116
+ * so a failed lookup must not stop the case being opened.
117
+ */
118
+ let orderIds = [];
119
+ try {
120
+ const orders = await orderRepository.findByPaymentId(paymentId);
121
+ orderIds = orders.map((o) => o.id);
122
+ }
123
+ catch (err) {
124
+ void normalizeError(err);
125
+ serverLogger.warn("dispute ingest: order lookup failed — opening the case regardless", {
126
+ paymentId,
127
+ });
128
+ }
129
+ const status = entity.status ?? "unknown";
130
+ const detailLines = [
131
+ `Gateway: ${opts.gateway}`,
132
+ `Event: ${opts.rawEvent}`,
133
+ `Dispute: ${disputeId}`,
134
+ `Payment: ${paymentId}`,
135
+ `Status: ${status}${entity.phase ? ` (phase ${entity.phase})` : ""}`,
136
+ entity.reason_code ? `Reason code: ${entity.reason_code}` : null,
137
+ amount !== undefined ? `Amount disputed: ${amount}` : null,
138
+ amountDeducted !== undefined && amountDeducted > 0
139
+ ? `Already deducted from our balance: ${amountDeducted}`
140
+ : null,
141
+ respondBy ? `Respond by: ${respondBy.toISOString()}` : "Respond by: not supplied",
142
+ orderIds.length
143
+ ? `Our orders: ${orderIds.join(", ")}`
144
+ : "🛑 No order found for this payment — records disagree with the gateway",
145
+ "",
146
+ "Respond in the gateway's own dashboard. This system does not submit evidence.",
147
+ ].filter((line) => line !== null);
148
+ const result = await paymentCasesRepository().openOrObserve({
149
+ kind: "dispute",
150
+ /*
151
+ * Keyed on the DISPUTE id, so every event in one dispute's lifecycle —
152
+ * created, under_review, won/lost, closed — lands on ONE case rather than
153
+ * four. That is the whole mechanism; keying on the event id would produce a
154
+ * case per notification.
155
+ */
156
+ subjectId: disputeId,
157
+ severity: severityFor(entity.status),
158
+ title: `Chargeback ${status} — ${disputeId}`,
159
+ detail: detailLines.join("\n"),
160
+ entityType: orderIds.length > 0 ? "order" : "payment",
161
+ entityId: orderIds[0] ?? paymentId,
162
+ ...(respondBy ? { dueAt: respondBy } : {}),
163
+ ...(amount !== undefined ? { amountAtRisk: amount } : {}),
164
+ ...(opts.gatewayEventId ? { gatewayEventIds: [opts.gatewayEventId] } : {}),
165
+ ...(orderIds.length ? { orderIds } : {}),
166
+ gatewayPaymentId: paymentId,
167
+ });
168
+ /*
169
+ * 🛑 A closed dispute MARKS SELF-HEALED AND STAYS OPEN.
170
+ *
171
+ * "Razorpay closed the dispute" and "we have finished handling it" are
172
+ * different facts, and the gap between them is work: a LOST dispute needs a
173
+ * payout clawback from the seller and a decision about the order's status,
174
+ * and a WON one still needs the order un-flagged. Auto-closing on the
175
+ * gateway's say-so would file both as done.
176
+ */
177
+ if (entity.status && DISPUTE_CLOSED_STATUSES.has(entity.status)) {
178
+ await paymentCasesRepository().markSelfHealed(result.id);
179
+ serverLogger.info("dispute ingest: gateway closed the dispute — case left open for a human", {
180
+ disputeId,
181
+ status: entity.status,
182
+ caseId: result.id,
183
+ });
184
+ }
185
+ serverLogger.warn("dispute ingest: case recorded", {
186
+ disputeId,
187
+ paymentId,
188
+ caseId: result.id,
189
+ created: result.created,
190
+ dueAt: respondBy?.toISOString(),
191
+ });
192
+ return result.id;
193
+ }
194
+ /**
195
+ * Poll the gateway for every dispute it knows about and reconcile them into
196
+ * cases. Phase 4's R4 calls this; it is idempotent by construction, since
197
+ * `openOrObserve` is.
198
+ *
199
+ * Takes the already-normalised `Dispute[]` from the provider adapter, which has
200
+ * done the unit conversions — so this function performs none, and there is one
201
+ * place per direction that does.
202
+ */
203
+ export async function reconcileDisputes(disputes) {
204
+ let recorded = 0;
205
+ for (const d of disputes) {
206
+ try {
207
+ await ingestDispute({
208
+ id: d.id,
209
+ payment_id: d.paymentId,
210
+ /*
211
+ * Converted BACK to subunits, because `ingestDispute` takes a
212
+ * WEBHOOK-shaped entity (subunits) while `Dispute` is already in
213
+ * rupees. One input contract rather than two — the alternative is an
214
+ * "already converted" boolean, which is exactly the kind of flag that
215
+ * ends up wrong at one of two call sites.
216
+ *
217
+ * Via `rupeesToPaise`, not `* 100`: the round-trip must use the same
218
+ * rounding as the forward conversion, or a ₹1,499.50 dispute comes
219
+ * back a paisa light and the `amountAtRisk` on the case disagrees
220
+ * with the gateway by a rounding error nobody can explain.
221
+ */
222
+ amount: rupeesToPaise(d.amount),
223
+ currency: d.currency,
224
+ amount_deducted: rupeesToPaise(d.amountDeducted),
225
+ reason_code: d.reasonCode,
226
+ respond_by: Math.floor(d.respondBy.getTime() / 1000),
227
+ status: d.status,
228
+ phase: d.phase,
229
+ created_at: Math.floor(d.createdAt.getTime() / 1000),
230
+ }, { gateway: d.gateway, rawEvent: "reconcile.disputes.all" });
231
+ recorded += 1;
232
+ }
233
+ catch (err) {
234
+ void normalizeError(err);
235
+ serverLogger.error("dispute reconcile: one dispute failed — continuing", {
236
+ disputeId: d.id,
237
+ });
238
+ }
239
+ }
240
+ return recorded;
241
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * payment-cases — server surface.
3
+ *
4
+ * A narrow barrel for one feature's public entry points (Root Cause #18), not a
5
+ * convenience hub. The repository is imported directly by anything that
6
+ * queries; only the ingest/reconcile helpers go through here, because those are
7
+ * what a route or a job calls.
8
+ */
9
+ export { ingestDispute, reconcileDisputes, DISPUTE_EVENT_PREFIX, type DisputeWebhookEntity, } from "./disputes";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * payment-cases — server surface.
3
+ *
4
+ * A narrow barrel for one feature's public entry points (Root Cause #18), not a
5
+ * convenience hub. The repository is imported directly by anything that
6
+ * queries; only the ingest/reconcile helpers go through here, because those are
7
+ * what a route or a job calls.
8
+ */
9
+ export { ingestDispute, reconcileDisputes, DISPUTE_EVENT_PREFIX, } from "./disputes.js";
@@ -9,12 +9,37 @@ export type ApplyRefundDeductionInput = {
9
9
  platformFeeRate?: number;
10
10
  reason: string;
11
11
  };
12
- export type ApplyRefundDeductionResult = {
12
+ /**
13
+ * Where the clawback landed.
14
+ *
15
+ * 🛑 Deliberately has NO `{ applied: false }` member. That shape is what let
16
+ * four lines of caller code treat "we could not recover the money" as an
17
+ * unremarkable outcome. Every variant here names a destination, and
18
+ * `unrecovered` is explicit about being a debt rather than a non-event.
19
+ *
20
+ * `applied` is kept as the discriminant for source compatibility with the two
21
+ * existing readers, so this is a widening rather than a rename.
22
+ */
23
+ export type ApplyRefundDeductionResult =
24
+ /** Netted off a pending payout before it was sent. The good case. */
25
+ {
13
26
  applied: true;
27
+ to: "payout";
14
28
  payoutId: string;
15
29
  netAmount: number;
16
- } | {
30
+ }
31
+ /**
32
+ * The payout has already settled, or this order was not in it. The seller
33
+ * holds money for returned goods and WE CANNOT TAKE IT BACK from here.
34
+ * `recordedAs` is the durable row an operator can act on.
35
+ */
36
+ | {
17
37
  applied: false;
18
- reason: string;
38
+ to: "unrecovered";
39
+ reason: "no_pending_payout" | "order_not_in_payout";
40
+ storeId: string;
41
+ orderId: string;
42
+ amount: number;
43
+ recordedAs: string;
19
44
  };
20
45
  export declare function applyRefundDeductionAction(input: ApplyRefundDeductionInput): Promise<ActionResult<ApplyRefundDeductionResult>>;
@@ -3,17 +3,54 @@ import { wrapAction } from "@mohasinac/appkit/server";
3
3
  /**
4
4
  * applyRefundDeductionAction — deduct a refund from a seller's pending payout.
5
5
  *
6
- * Called fire-and-forget after processRefundAction succeeds:
6
+ * Called after processRefundAction succeeds:
7
7
  * 1. Locate the most recent pending payout for the order's store.
8
8
  * 2. If found and it covers the refunded order, apply the deduction.
9
- * 3. If no pending payout exists (already settled), return applied:false —
10
- * the reduced net revenue is automatically reflected in the next payout
11
- * cycle because the order revenue was never re-added.
9
+ * 3. Otherwise the money cannot be recovered automatically — record it.
12
10
  *
13
11
  * deductedAmount = refundedAmount × (1 − platformFeeRate).
14
12
  * The platform keeps its fee share on every refund.
13
+ *
14
+ * ──────────────────────────────────────────────────────────────────────────
15
+ * 🛑 THIS DOCSTRING USED TO CONTAIN A FALSE CLAIM, and it was load-bearing
16
+ * ──────────────────────────────────────────────────────────────────────────
17
+ *
18
+ * Step 3 read:
19
+ *
20
+ * > If no pending payout exists (already settled), return applied:false —
21
+ * > the reduced net revenue is automatically reflected in the next payout
22
+ * > cycle because the order revenue was never re-added.
23
+ *
24
+ * **There is no such mechanism.** Verified 2026-10-21: there is no
25
+ * `sellerLedger`, no running balance, no carry-forward of any kind anywhere in
26
+ * the codebase, and each payout's `grossAmount` is computed fresh as
27
+ * `ordersTaxableValue(<this batch of newly delivered orders>)`. A refund on an
28
+ * order whose payout has ALREADY SETTLED is therefore never recovered — the
29
+ * seller keeps money for goods that came back, and nothing records that a
30
+ * clawback was attempted and failed.
31
+ *
32
+ * That claim is why the caller could reasonably write
33
+ * `.catch(() => {/* best-effort *\/})` and discard the result: the comment
34
+ * said the money was handled elsewhere. It was not.
35
+ *
36
+ * So the return type is now a DESTINATION rather than a boolean. Two reasons,
37
+ * and the second is the durable one:
38
+ *
39
+ * 1. It names where the money went, which is the question an operator
40
+ * actually has.
41
+ * 2. A discriminated union with no `applied: false` member means the
42
+ * "ignore the result" shape no longer type-checks into silence — the
43
+ * caller has to acknowledge the unrecovered case. Making the bug
44
+ * UNCOMPILABLE is stronger than asking nobody to reintroduce it.
45
+ *
46
+ * 🛑 This does NOT recover the money. Automatic recovery needs a seller
47
+ * ledger that can hold a negative balance and net it against the next payout,
48
+ * which is Phase 11 (books) and is deliberately not smuggled in here. What
49
+ * this change buys is that the loss is now VISIBLE — a durable row with the
50
+ * store, the order and the amount — instead of silently absorbed.
15
51
  */
16
52
  import { payoutRepository } from "../../../../repositories/index.js";
53
+ import { serverErrorsRepository } from "../../../../features/server-errors/repository/server-errors.repository.js";
17
54
  import { ValidationError } from "../../../../errors/index.js";
18
55
  import { roundRupees } from "../../../../utils/number.formatter.js";
19
56
  export async function applyRefundDeductionAction(input) {
@@ -24,12 +61,44 @@ export async function applyRefundDeductionAction(input) {
24
61
  const feeRate = input.platformFeeRate ?? 0.05;
25
62
  const deductedAmount = roundRupees(input.refundedAmount * (1 - feeRate));
26
63
  const pending = await payoutRepository.findPendingByStore(input.storeId);
27
- if (!pending) {
28
- return { applied: false, reason: "no_pending_payout" };
29
- }
30
- if (!pending.orderIds.includes(input.orderId)) {
31
- return { applied: false, reason: "order_not_in_payout" };
64
+ const unrecoverable = !pending
65
+ ? "no_pending_payout"
66
+ : !pending.orderIds.includes(input.orderId)
67
+ ? "order_not_in_payout"
68
+ : null;
69
+ if (unrecoverable) {
70
+ /*
71
+ * The seller has already been paid for an order that came back. Record
72
+ * it durably — this is the money, and a `warn` would scroll past in a
73
+ * log buffer that drops at ~4 KB/s.
74
+ *
75
+ * `/admin/maintenance/payment-rollbacks` already filters on
76
+ * `PAYMENT_ROLLBACK_*`, so this surfaces there with no new page.
77
+ *
78
+ * `record()` is documented never to throw, so this cannot turn a
79
+ * failed clawback into a failed refund — the refund has already been
80
+ * posted and must not be rolled back by an accounting side effect.
81
+ */
82
+ const code = `PAYMENT_ROLLBACK_${unrecoverable.toUpperCase()}`;
83
+ await serverErrorsRepository().record({
84
+ source: "vercel",
85
+ route: "applyRefundDeductionAction",
86
+ code,
87
+ message: `Clawback of ₹${deductedAmount} for order ${input.orderId} (store ${input.storeId}) could not be applied: ${unrecoverable}. ` +
88
+ `The seller retains this amount for returned goods; there is no automatic recovery until a seller ledger exists.`,
89
+ requestId: input.refundId,
90
+ });
91
+ return {
92
+ applied: false,
93
+ to: "unrecovered",
94
+ reason: unrecoverable,
95
+ storeId: input.storeId,
96
+ orderId: input.orderId,
97
+ amount: deductedAmount,
98
+ recordedAs: code,
99
+ };
32
100
  }
101
+ // `pending` is non-null here: `unrecoverable` is only null when it is set.
33
102
  const updated = await payoutRepository.applyRefundDeduction(pending.id, {
34
103
  orderId: input.orderId,
35
104
  refundId: input.refundId,
@@ -37,6 +106,11 @@ export async function applyRefundDeductionAction(input) {
37
106
  deductedAmount,
38
107
  reason: input.reason,
39
108
  });
40
- return { applied: true, payoutId: updated.id, netAmount: updated.netAmount ?? updated.amount };
109
+ return {
110
+ applied: true,
111
+ to: "payout",
112
+ payoutId: updated.id,
113
+ netAmount: updated.netAmount ?? updated.amount,
114
+ };
41
115
  });
42
116
  }
@@ -0,0 +1,61 @@
1
+ import type { PointsAdjustFormValues } from "../../../../features/points/schemas/adjust-form";
2
+ /**
3
+ * `admin_adjustment`'s first HUMAN writer.
4
+ *
5
+ * ## Why this is the last piece of D48 rather than the first
6
+ *
7
+ * `admin_adjustment` and `redemption_reversal` were both fully specified —
8
+ * signed-amount invariant, mandatory `adminReason`, the lot — and had **zero
9
+ * writers**. The reversal got one when cancellation was built. This is the
10
+ * other, and it was left until last on purpose: it is the only path by which a
11
+ * human can create spendable money from nothing, so it should not have existed
12
+ * before the ledger could expire a batch, consume FIFO, reverse a spend and
13
+ * reconcile against its own mirror. All four now do.
14
+ *
15
+ * ## 🛑 The one writer it must NOT be confused with
16
+ *
17
+ * `expireLapsedBatches` also appends `admin_adjustment`, with
18
+ * `actorUid: "system:points-expiry"`, and its docstring calls that **the one
19
+ * place a system actor may write an adjustment** — because expiry is a rule
20
+ * with a date attached rather than a discretionary decision.
21
+ *
22
+ * So this function takes a REAL `actorUid` and never that sentinel. Reusing it
23
+ * would make a human's decision indistinguishable from a scheduled rule in the
24
+ * one record that exists to tell them apart.
25
+ *
26
+ * ## Credits expire; debits and the reason do not
27
+ *
28
+ * A positive adjustment gets `pointsExpiryFrom(now)` like any other credit — an
29
+ * admin-granted goodwill credit is not more permanent than an earned one, and
30
+ * leaving `expiresAt` absent would mean NEVER EXPIRES, quietly making this the
31
+ * one way to mint a perpetual balance.
32
+ *
33
+ * A negative adjustment passes nothing, matching every other spend: there is
34
+ * nothing left to expire.
35
+ *
36
+ * ## Two records, deliberately
37
+ *
38
+ * The ledger entry answers "why does this account have 53 points". The
39
+ * `adminAuditLog` row answers "what have admins done lately". The second is the
40
+ * one you need when the account is not yet suspected, which is why a feature
41
+ * that already records `actorUid` on the entry still writes both.
42
+ *
43
+ * ## The buyer is told
44
+ *
45
+ * A balance that changes with no explanation is indistinguishable from a bug,
46
+ * and the buyer is the only party who cannot query the ledger. `description` is
47
+ * the buyer-facing line and is already mandatory in the schema; the
48
+ * notification carries it. `adminReason` is NOT sent — it is written for the
49
+ * next admin and may name an internal case.
50
+ *
51
+ * Best-effort: a notification that fails must not undo an applied adjustment,
52
+ * because the money has already moved and the ledger is the record that
53
+ * matters.
54
+ */
55
+ export declare function adjustUserPoints(input: PointsAdjustFormValues, actor: {
56
+ uid: string;
57
+ name?: string;
58
+ }): Promise<{
59
+ entryId: string;
60
+ balance: number;
61
+ }>;