@mohasinac/appkit 4.59.0 → 4.60.1

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 (532) 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.d.ts +20 -2
  27. package/dist/_internal/server/features/orders/adapters.js +44 -0
  28. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
  29. package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
  30. package/dist/_internal/server/features/orders/index.d.ts +2 -1
  31. package/dist/_internal/server/features/orders/index.js +1 -1
  32. package/dist/_internal/server/features/orders/service.d.ts +60 -0
  33. package/dist/_internal/server/features/orders/service.js +74 -0
  34. package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
  35. package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
  36. package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
  37. package/dist/_internal/server/features/payment-cases/index.js +9 -0
  38. package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
  39. package/dist/_internal/server/features/payouts/actions.js +84 -10
  40. package/dist/_internal/server/features/points/adjust.d.ts +61 -0
  41. package/dist/_internal/server/features/points/adjust.js +121 -0
  42. package/dist/_internal/server/features/points/award.d.ts +65 -0
  43. package/dist/_internal/server/features/points/award.js +145 -0
  44. package/dist/_internal/server/features/price-index/market.d.ts +33 -0
  45. package/dist/_internal/server/features/price-index/market.js +54 -1
  46. package/dist/_internal/server/features/products/data.js +40 -22
  47. package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
  48. package/dist/_internal/server/features/protection-claims/actions.js +228 -0
  49. package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
  50. package/dist/_internal/server/features/protection-claims/index.js +8 -0
  51. package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
  52. package/dist/_internal/server/features/refunds/actions.js +259 -17
  53. package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
  54. package/dist/_internal/server/features/refunds/capacity.js +37 -0
  55. package/dist/_internal/server/features/reviews/actions.js +3 -2
  56. package/dist/_internal/server/features/search/index-build/sources.js +20 -1
  57. package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
  58. package/dist/_internal/server/features/shipping/reconcile.js +34 -3
  59. package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
  60. package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
  61. package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
  62. package/dist/_internal/server/features/stores/tabs.js +24 -4
  63. package/dist/_internal/server/functions/https.d.ts +31 -1
  64. package/dist/_internal/server/functions/https.js +52 -1
  65. package/dist/_internal/server/functions/scheduled.d.ts +72 -1
  66. package/dist/_internal/server/functions/scheduled.js +124 -1
  67. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
  68. package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
  69. package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
  70. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
  71. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
  72. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
  73. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  74. package/dist/_internal/server/jobs/core/index.js +2 -0
  75. package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
  76. package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
  77. package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
  78. package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
  79. package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
  80. package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
  81. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
  82. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
  83. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
  84. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
  85. package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
  86. package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
  87. package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
  88. package/dist/_internal/server/jobs/handlers/index.js +5 -0
  89. package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
  90. package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
  91. package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
  92. package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
  93. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
  94. package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
  95. package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
  96. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  97. package/dist/_internal/shared/actions/action-registry.js +71 -0
  98. package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
  99. package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
  100. package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
  101. package/dist/_internal/shared/checkout/lanes.js +46 -0
  102. package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
  103. package/dist/_internal/shared/checkout/order-math.js +251 -3
  104. package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
  105. package/dist/_internal/shared/checkout/refundable-base.js +122 -0
  106. package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
  107. package/dist/_internal/shared/features/auctions/config.js +30 -1
  108. package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
  109. package/dist/_internal/shared/features/brands/schema.js +18 -0
  110. package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
  111. package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
  112. package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
  113. package/dist/_internal/shared/features/print/label-profiles.js +350 -0
  114. package/dist/_internal/shared/features/products/to-product-item.js +33 -5
  115. package/dist/_internal/shared/fees/calculator.d.ts +31 -2
  116. package/dist/_internal/shared/fees/calculator.js +103 -5
  117. package/dist/_internal/shared/fees/india-states.d.ts +195 -0
  118. package/dist/_internal/shared/fees/india-states.js +190 -0
  119. package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
  120. package/dist/_internal/shared/fees/payout-hold.js +74 -0
  121. package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
  122. package/dist/_internal/shared/obligations/deadlines.js +155 -0
  123. package/dist/_internal/shared/shipping/quote.d.ts +96 -0
  124. package/dist/_internal/shared/shipping/quote.js +67 -0
  125. package/dist/_internal/shared/time/business-days.d.ts +91 -0
  126. package/dist/_internal/shared/time/business-days.js +185 -0
  127. package/dist/cli/index.js +0 -2
  128. package/dist/client.d.ts +10 -4
  129. package/dist/client.js +29 -3
  130. package/dist/configs/tailwind.d.ts +0 -12
  131. package/dist/configs/tailwind.js +28 -15
  132. package/dist/constants/api-endpoints.d.ts +51 -9
  133. package/dist/constants/api-endpoints.js +23 -7
  134. package/dist/constants/index.d.ts +1 -1
  135. package/dist/constants/index.js +1 -1
  136. package/dist/contracts/index.d.ts +1 -1
  137. package/dist/contracts/payment.d.ts +131 -0
  138. package/dist/features/about/components/AboutView.js +1 -1
  139. package/dist/features/about/components/DeveloperView.js +5 -2
  140. package/dist/features/about/components/FAQPageView.js +2 -1
  141. package/dist/features/about/components/FeesView.js +2 -1
  142. package/dist/features/about/components/HelpPageView.js +2 -1
  143. package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
  144. package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
  145. package/dist/features/about/components/HowEmiWorksView.js +2 -1
  146. package/dist/features/about/components/HowOffersWorkView.js +2 -1
  147. package/dist/features/about/components/HowOrdersWorkView.js +2 -1
  148. package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
  149. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
  150. package/dist/features/about/components/HowReviewsWorkView.js +2 -1
  151. package/dist/features/about/components/PolicyPageView.js +2 -1
  152. package/dist/features/about/components/ProseHero.d.ts +73 -0
  153. package/dist/features/about/components/ProseHero.js +18 -0
  154. package/dist/features/about/components/SecurityPrivacyView.js +2 -1
  155. package/dist/features/about/components/ShippingPolicyView.js +2 -1
  156. package/dist/features/about/components/TrackOrderView.js +2 -1
  157. package/dist/features/about/components/UnauthorizedView.js +1 -1
  158. package/dist/features/about/index.d.ts +2 -0
  159. package/dist/features/about/index.js +5 -0
  160. package/dist/features/account/actions/address-actions.d.ts +26 -2
  161. package/dist/features/account/actions/address-actions.js +25 -1
  162. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  163. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  164. package/dist/features/account/components/UserOrdersView.js +17 -0
  165. package/dist/features/account/components/UserSidebar.js +1 -1
  166. package/dist/features/account/hooks/useNotifications.js +29 -0
  167. package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
  168. package/dist/features/admin/components/AdminBeysView.js +2 -2
  169. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  170. package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
  171. package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
  172. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  173. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  174. package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
  175. package/dist/features/admin/components/AdminContactEditorView.js +1 -1
  176. package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
  177. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  178. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  179. package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
  180. package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
  181. package/dist/features/admin/components/AdminGuideHubView.js +1 -1
  182. package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
  183. package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
  184. package/dist/features/admin/components/AdminPartsView.js +2 -2
  185. package/dist/features/admin/components/AdminProductsView.js +75 -4
  186. package/dist/features/admin/components/AdminSidebar.js +2 -2
  187. package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
  188. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
  189. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  190. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  191. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  192. package/dist/features/admin/components/AdminUsersView.js +72 -1
  193. package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
  194. package/dist/features/admin/components/AdminViewCards.js +4 -4
  195. package/dist/features/admin/components/DataListingView.d.ts +28 -0
  196. package/dist/features/admin/components/DataListingView.js +175 -14
  197. package/dist/features/admin/components/DataTable.d.ts +12 -1
  198. package/dist/features/admin/components/DataTable.js +3 -3
  199. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  200. package/dist/features/admin/components/OwnerQuickActions.js +60 -2
  201. package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
  202. package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
  203. package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
  204. package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
  205. package/dist/features/admin/components/index.d.ts +4 -0
  206. package/dist/features/admin/components/index.js +6 -0
  207. package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
  208. package/dist/features/admin/constants/filter-tabs.js +106 -0
  209. package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
  210. package/dist/features/admin/repository/site-settings.repository.js +82 -1
  211. package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
  212. package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
  213. package/dist/features/admin/schemas/firestore.js +5 -1
  214. package/dist/features/admin/schemas/site-settings-form.js +30 -1
  215. package/dist/features/auctions/actions/bid-actions.js +13 -1
  216. package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
  217. package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
  218. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
  219. package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
  220. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
  221. package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
  222. package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
  223. package/dist/features/audit-log/schemas/firestore.js +14 -0
  224. package/dist/features/auth/permissions/constants.d.ts +17 -1
  225. package/dist/features/auth/permissions/constants.js +18 -0
  226. package/dist/features/blog/components/BlogPostView.js +1 -1
  227. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  228. package/dist/features/categories/api/[id]/description-template/route.js +107 -1
  229. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  230. package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
  231. package/dist/features/categories/components/BundleDetailView.js +1 -1
  232. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  233. package/dist/features/categories/components/CategoryForm.js +12 -1
  234. package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
  235. package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
  236. package/dist/features/categories/repository/market-price-index.repository.js +105 -0
  237. package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
  238. package/dist/features/categories/repository/price-observation.repository.js +132 -0
  239. package/dist/features/events/components/EventSaleBanner.js +1 -1
  240. package/dist/features/events/components/EventStatusBadge.js +1 -1
  241. package/dist/features/faq/components/FAQAccordion.js +2 -1
  242. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  243. package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
  244. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  245. package/dist/features/filters/FilterFacetSection.js +1 -1
  246. package/dist/features/filters/SwitchFilter.js +1 -1
  247. package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
  248. package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
  249. package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
  250. package/dist/features/gateway-events/schemas/firestore.js +125 -0
  251. package/dist/features/gateway-events/schemas/index.d.ts +81 -0
  252. package/dist/features/gateway-events/schemas/index.js +79 -0
  253. package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
  254. package/dist/features/homepage/components/AnnouncementBar.js +37 -1
  255. package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
  256. package/dist/features/homepage/components/BrandsSection.js +1 -1
  257. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  258. package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
  259. package/dist/features/homepage/components/HeroCarousel.js +2 -2
  260. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  261. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
  262. package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
  263. package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
  264. package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
  265. package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
  266. package/dist/features/inventory/components/ReceiveStationView.js +413 -0
  267. package/dist/features/inventory/components/operator-message.d.ts +29 -0
  268. package/dist/features/inventory/components/operator-message.js +41 -0
  269. package/dist/features/inventory/index.d.ts +13 -0
  270. package/dist/features/inventory/index.js +28 -0
  271. package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
  272. package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
  273. package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
  274. package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
  275. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
  276. package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
  277. package/dist/features/inventory/schemas/firestore.d.ts +197 -0
  278. package/dist/features/inventory/schemas/firestore.js +159 -0
  279. package/dist/features/layout/AppLayoutShell.d.ts +12 -1
  280. package/dist/features/layout/AppLayoutShell.js +25 -12
  281. package/dist/features/layout/AutoBreadcrumbs.js +162 -3
  282. package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
  283. package/dist/features/layout/BottomNavbar.d.ts +1 -1
  284. package/dist/features/layout/BottomNavbar.js +2 -2
  285. package/dist/features/media/MediaAvatar.js +1 -1
  286. package/dist/features/media/MediaImage.d.ts +24 -4
  287. package/dist/features/media/MediaImage.js +44 -4
  288. package/dist/features/media/MediaLightbox.js +1 -1
  289. package/dist/features/media/modals/ImageCropModal.js +1 -1
  290. package/dist/features/media/modals/ImageEditor.js +1 -1
  291. package/dist/features/media/upload/MediaUploadField.js +91 -3
  292. package/dist/features/obligations/constants/policies.d.ts +92 -0
  293. package/dist/features/obligations/constants/policies.js +378 -0
  294. package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
  295. package/dist/features/obligations/repository/obligations.repository.js +158 -0
  296. package/dist/features/obligations/schemas/firestore.d.ts +160 -0
  297. package/dist/features/obligations/schemas/firestore.js +87 -0
  298. package/dist/features/orders/actions/order-actions.d.ts +43 -4
  299. package/dist/features/orders/actions/order-actions.js +60 -3
  300. package/dist/features/orders/actions/refund-actions.js +70 -10
  301. package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
  302. package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
  303. package/dist/features/orders/components/OrdersList.js +2 -2
  304. package/dist/features/orders/components/RefundHistoryTable.js +3 -1
  305. package/dist/features/orders/components/index.d.ts +2 -0
  306. package/dist/features/orders/components/index.js +6 -0
  307. package/dist/features/orders/constants/transitions.d.ts +59 -0
  308. package/dist/features/orders/constants/transitions.js +104 -0
  309. package/dist/features/orders/repository/orders.repository.d.ts +109 -6
  310. package/dist/features/orders/repository/orders.repository.js +464 -21
  311. package/dist/features/orders/schemas/firestore.d.ts +270 -0
  312. package/dist/features/orders/schemas/firestore.js +24 -0
  313. package/dist/features/orders/schemas/index.d.ts +61 -0
  314. package/dist/features/orders/schemas/index.js +22 -0
  315. package/dist/features/orders/types/index.d.ts +79 -0
  316. package/dist/features/parts/components/PartsIndexPageView.js +8 -1
  317. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
  318. package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
  319. package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
  320. package/dist/features/payment-cases/schemas/firestore.js +105 -0
  321. package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
  322. package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
  323. package/dist/features/payments/repository/payout.repository.d.ts +0 -1
  324. package/dist/features/payments/repository/payout.repository.js +0 -1
  325. package/dist/features/points/repository/points.repository.d.ts +122 -0
  326. package/dist/features/points/repository/points.repository.js +304 -1
  327. package/dist/features/points/schemas/adjust-form.d.ts +58 -0
  328. package/dist/features/points/schemas/adjust-form.js +63 -0
  329. package/dist/features/points/schemas/firestore.d.ts +108 -1
  330. package/dist/features/points/schemas/firestore.js +84 -0
  331. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
  332. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  333. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
  334. package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
  335. package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
  336. package/dist/features/price-index/market-stats.d.ts +82 -0
  337. package/dist/features/price-index/market-stats.js +230 -0
  338. package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
  339. package/dist/features/print/components/BoxLabelPrintView.js +66 -0
  340. package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
  341. package/dist/features/print/components/LabelProfilePicker.js +38 -0
  342. package/dist/features/print/components/labels.d.ts +117 -0
  343. package/dist/features/print/components/labels.js +258 -0
  344. package/dist/features/print/components/labels.style.css +46 -0
  345. package/dist/features/print/index.d.ts +6 -0
  346. package/dist/features/print/index.js +16 -0
  347. package/dist/features/products/columns/productTableColumns.js +5 -4
  348. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  349. package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
  350. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  351. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  352. package/dist/features/products/components/PrizeRevealModal.js +2 -2
  353. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  354. package/dist/features/products/components/ProductForm.js +34 -23
  355. package/dist/features/products/components/ProductGrid.js +86 -62
  356. package/dist/features/products/constants/card-badges.d.ts +97 -0
  357. package/dist/features/products/constants/card-badges.js +100 -0
  358. package/dist/features/products/repository/products.repository.js +34 -1
  359. package/dist/features/products/schemas/firestore.d.ts +46 -3
  360. package/dist/features/products/schemas/firestore.js +21 -0
  361. package/dist/features/promotions/components/PromotionsView.js +1 -1
  362. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
  363. package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
  364. package/dist/features/promotions/schemas/firestore.js +30 -3
  365. package/dist/features/promotions/schemas/index.d.ts +6 -6
  366. package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
  367. package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
  368. package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
  369. package/dist/features/protection-claims/schemas/firestore.js +130 -0
  370. package/dist/features/reviews/actions/review-actions.js +3 -2
  371. package/dist/features/reviews/components/ReviewModal.js +1 -1
  372. package/dist/features/reviews/components/ReviewsList.js +1 -1
  373. package/dist/features/reviews/schemas/firestore.d.ts +20 -1
  374. package/dist/features/scams/constants/scam-types.d.ts +2 -0
  375. package/dist/features/scams/constants/scam-types.js +18 -0
  376. package/dist/features/scams/schemas/report-form.d.ts +3 -3
  377. package/dist/features/scams/schemas/report-form.js +26 -1
  378. package/dist/features/search/components/Search.js +9 -9
  379. package/dist/features/search/components/SearchResultsClient.js +18 -3
  380. package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
  381. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  382. package/dist/features/seller/actions/offer-actions.js +16 -1
  383. package/dist/features/seller/actions/seller-actions.js +14 -3
  384. package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
  385. package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
  386. package/dist/features/seller/components/PrintCenterView.js +41 -30
  387. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  388. package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
  389. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  390. package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
  391. package/dist/features/seller/components/SellerProductShell.js +123 -13
  392. package/dist/features/seller/components/SellerReviewsView.js +4 -2
  393. package/dist/features/seller/components/SellerSidebar.js +1 -1
  394. package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
  395. package/dist/features/seller/schemas/coupon-form.js +27 -0
  396. package/dist/features/seller/schemas/product-form.d.ts +3 -0
  397. package/dist/features/seller/schemas/product-form.js +5 -0
  398. package/dist/features/shell/FormShell.js +2 -2
  399. package/dist/features/shell/QuickFormDrawer.js +14 -0
  400. package/dist/features/shell/SectionForm.d.ts +19 -0
  401. package/dist/features/shell/SectionForm.js +133 -9
  402. package/dist/features/shell/SectionForm.style.css +54 -0
  403. package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
  404. package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
  405. package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
  406. package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
  407. package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
  408. package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
  409. package/dist/features/stores/components/StoreGuideHubView.js +1 -1
  410. package/dist/features/stores/components/StoreHeader.js +1 -1
  411. package/dist/features/support/schemas/firestore.d.ts +73 -2
  412. package/dist/features/support/schemas/firestore.js +59 -0
  413. package/dist/index.d.ts +16 -24
  414. package/dist/index.js +38 -47
  415. package/dist/next/ErrorBoundary.js +1 -1
  416. package/dist/next/routing/route-map.d.ts +24 -0
  417. package/dist/next/routing/route-map.js +40 -0
  418. package/dist/providers/payment-manual/index.d.ts +15 -1
  419. package/dist/providers/payment-manual/index.js +37 -0
  420. package/dist/providers/payment-phonepe/index.d.ts +14 -1
  421. package/dist/providers/payment-phonepe/index.js +36 -0
  422. package/dist/providers/payment-razorpay/index.d.ts +44 -1
  423. package/dist/providers/payment-razorpay/index.js +99 -0
  424. package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
  425. package/dist/providers/shipping-shiprocket/index.js +18 -0
  426. package/dist/schemas/registry.d.ts +44 -11
  427. package/dist/server-entry.d.ts +2 -0
  428. package/dist/server-entry.js +27 -0
  429. package/dist/server.d.ts +43 -0
  430. package/dist/server.js +98 -0
  431. package/dist/styles.css +418 -149
  432. package/dist/tailwind-utilities.css +1 -1
  433. package/dist/tokens/themes/default-dark.js +15 -12
  434. package/dist/tokens/themes/default-light.js +14 -11
  435. package/dist/tokens/tokens.css +106 -23
  436. package/dist/ui/DataTable.style.css +4 -4
  437. package/dist/ui/columns/cell-renderers.d.ts +20 -0
  438. package/dist/ui/columns/cell-renderers.js +26 -1
  439. package/dist/ui/columns/index.d.ts +1 -1
  440. package/dist/ui/columns/index.js +4 -1
  441. package/dist/ui/components/Badge.style.css +1 -1
  442. package/dist/ui/components/Breadcrumb.js +19 -1
  443. package/dist/ui/components/BulkActionBar.style.css +4 -4
  444. package/dist/ui/components/Button.style.css +1 -1
  445. package/dist/ui/components/Checkbox.style.css +1 -1
  446. package/dist/ui/components/FallbackShell.js +1 -1
  447. package/dist/ui/components/Form.d.ts +14 -1
  448. package/dist/ui/components/Form.js +2 -2
  449. package/dist/ui/components/FormField.js +18 -4
  450. package/dist/ui/components/FormField.style.css +43 -3
  451. package/dist/ui/components/GatedPrice.style.css +1 -1
  452. package/dist/ui/components/IconButton.style.css +1 -1
  453. package/dist/ui/components/Input.js +22 -1
  454. package/dist/ui/components/Input.style.css +38 -22
  455. package/dist/ui/components/ListingFilterDrawer.js +1 -1
  456. package/dist/ui/components/ListingToolbar.js +1 -1
  457. package/dist/ui/components/PaginatedSelect.js +0 -0
  458. package/dist/ui/components/Radio.style.css +1 -1
  459. package/dist/ui/components/Repeater.d.ts +53 -0
  460. package/dist/ui/components/Repeater.js +7 -0
  461. package/dist/ui/components/RichTextEditor.d.ts +20 -1
  462. package/dist/ui/components/RichTextEditor.js +23 -2
  463. package/dist/ui/components/Select.style.css +7 -21
  464. package/dist/ui/components/Semantic.js +27 -3
  465. package/dist/ui/components/TagInput.style.css +4 -9
  466. package/dist/ui/components/Textarea.style.css +4 -18
  467. package/dist/ui/components/Toggle.style.css +1 -1
  468. package/dist/ui/components/Typography.d.ts +3 -3
  469. package/dist/ui/components/Typography.js +15 -15
  470. package/dist/ui/components/ViewToggle.style.css +4 -4
  471. package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
  472. package/dist/ui/forms/AddAnotherToggle.js +56 -0
  473. package/dist/ui/forms/ColorPickerField.js +15 -2
  474. package/dist/ui/forms/FieldCheckbox.js +15 -2
  475. package/dist/ui/forms/FieldInput.d.ts +22 -1
  476. package/dist/ui/forms/FieldInput.js +19 -5
  477. package/dist/ui/forms/FieldLabel.d.ts +35 -0
  478. package/dist/ui/forms/FieldLabel.js +70 -0
  479. package/dist/ui/forms/FieldSelect.d.ts +4 -1
  480. package/dist/ui/forms/FieldSelect.js +27 -5
  481. package/dist/ui/forms/FieldTextarea.d.ts +4 -1
  482. package/dist/ui/forms/FieldTextarea.js +22 -5
  483. package/dist/ui/forms/FormShell.d.ts +17 -1
  484. package/dist/ui/forms/FormShell.js +36 -2
  485. package/dist/ui/forms/FormShell.style.css +41 -33
  486. package/dist/ui/forms/index.d.ts +5 -1
  487. package/dist/ui/forms/index.js +2 -0
  488. package/dist/ui/icons/icon-registry.d.ts +1 -0
  489. package/dist/ui/icons/icon-registry.js +17 -1
  490. package/dist/utils/id-generators.d.ts +80 -0
  491. package/dist/utils/id-generators.js +93 -0
  492. package/dist/utils/search-txt-builders.d.ts +12 -0
  493. package/dist/utils/search-txt-builders.js +17 -0
  494. package/package.json +1 -1
  495. package/scripts/seed-cli.mjs +106 -5
  496. package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
  497. package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
  498. package/dist/features/loyalty/api/balance/route.d.ts +0 -12
  499. package/dist/features/loyalty/api/balance/route.js +0 -41
  500. package/dist/features/loyalty/api/earn/route.d.ts +0 -12
  501. package/dist/features/loyalty/api/earn/route.js +0 -38
  502. package/dist/features/loyalty/api/history/route.d.ts +0 -12
  503. package/dist/features/loyalty/api/history/route.js +0 -58
  504. package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
  505. package/dist/features/loyalty/api/redeem/route.js +0 -38
  506. package/dist/features/loyalty/columns/index.d.ts +0 -17
  507. package/dist/features/loyalty/columns/index.js +0 -40
  508. package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
  509. package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
  510. package/dist/features/loyalty/components/index.d.ts +0 -1
  511. package/dist/features/loyalty/components/index.js +0 -1
  512. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
  513. package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
  514. package/dist/features/loyalty/index.d.ts +0 -6
  515. package/dist/features/loyalty/index.js +0 -6
  516. package/dist/features/loyalty/manifest.d.ts +0 -2
  517. package/dist/features/loyalty/manifest.js +0 -16
  518. package/dist/features/loyalty/messages/en.json +0 -19
  519. package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
  520. package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
  521. package/dist/features/loyalty/schemas/index.d.ts +0 -85
  522. package/dist/features/loyalty/schemas/index.js +0 -40
  523. package/dist/features/loyalty/server.d.ts +0 -6
  524. package/dist/features/loyalty/server.js +0 -6
  525. package/dist/features/loyalty/types/index.d.ts +0 -31
  526. package/dist/features/loyalty/types/index.js +0 -1
  527. package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
  528. package/dist/features/loyalty/types/loyalty-config.js +0 -1
  529. package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
  530. package/dist/features/loyalty/types/loyalty-math.js +0 -27
  531. package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
  532. package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
@@ -0,0 +1,274 @@
1
+ import { BaseRepository, applySieveToFirestore, parseSieveDateValue, prepareForFirestore, } from "../../../providers/db-firebase/index.js";
2
+ import { normalizeError } from "../../../errors/normalize.js";
3
+ import { GATEWAY_EVENTS_COLLECTION, GATEWAY_EVENT_ERROR_MAX_BYTES, GATEWAY_EVENT_FIELDS, GATEWAY_EVENT_LEASE_SECONDS, GATEWAY_EVENT_RETENTION_DAYS, createGatewayEventId, } from "../schemas/firestore.js";
4
+ /** gRPC `ALREADY_EXISTS`. The one failure of `.create()` that means "duplicate". */
5
+ const GRPC_ALREADY_EXISTS = 6;
6
+ /**
7
+ * Is this the specific "a document with that id already exists" failure, as
8
+ * opposed to any other write failure?
9
+ *
10
+ * 🛑 THIS DISTINCTION IS THE WHOLE POINT, and it is where the inbox differs
11
+ * from every other `.create()` claim in the codebase.
12
+ *
13
+ * `refunds/actions.ts` catches *every* error from its claim and treats it as a
14
+ * duplicate — and that is correct THERE, because the cost of being wrong is
15
+ * issuing a second real refund, so it must fail CLOSED.
16
+ *
17
+ * Here the cost of being wrong is inverted: treating a permissions error or a
18
+ * Firestore outage as "already have it" would make the route ack 200 and the
19
+ * event would be **silently lost** — which is the exact failure this collection
20
+ * exists to prevent. So the inbox fails OPEN: anything that is not
21
+ * ALREADY_EXISTS propagates, the route answers 503, and the gateway sends it
22
+ * again.
23
+ *
24
+ * Same primitive, opposite failure direction, because the asymmetry of harm is
25
+ * opposite. Do not "unify" these two call sites.
26
+ */
27
+ function isAlreadyExists(err) {
28
+ if (typeof err !== "object" || err === null)
29
+ return false;
30
+ const code = err.code;
31
+ if (code === GRPC_ALREADY_EXISTS)
32
+ return true;
33
+ /*
34
+ * The Admin SDK has also surfaced this as a string code and as a plain
35
+ * message depending on version and transport. Checked in addition to, never
36
+ * instead of, the numeric code — a message test alone is the kind of
37
+ * stringly-typed guard that breaks silently on an SDK bump.
38
+ */
39
+ if (code === "already-exists" || code === "ALREADY_EXISTS")
40
+ return true;
41
+ const message = err.message;
42
+ return typeof message === "string" && message.includes("ALREADY_EXISTS");
43
+ }
44
+ function truncate(value, maxBytes) {
45
+ if (!value)
46
+ return undefined;
47
+ return value.length <= maxBytes ? value : value.slice(0, maxBytes);
48
+ }
49
+ export class GatewayEventsRepository extends BaseRepository {
50
+ constructor() {
51
+ super(GATEWAY_EVENTS_COLLECTION);
52
+ }
53
+ /**
54
+ * Persist-and-claim in one write. Returns `claimed: false` for a duplicate.
55
+ *
56
+ * 🛑 THROWS on any write failure that is not a duplicate — see
57
+ * `isAlreadyExists`. The caller must translate that into a 503 so the gateway
58
+ * redelivers; swallowing it is how an event is lost.
59
+ */
60
+ async claim(input) {
61
+ const now = input.now ?? new Date();
62
+ const id = createGatewayEventId(input.gateway, input.providerEventId, input.bodySha256);
63
+ const doc = {
64
+ id,
65
+ gateway: input.gateway,
66
+ rawEvent: input.rawEvent,
67
+ kind: input.kind,
68
+ status: "received",
69
+ bodySha256: input.bodySha256,
70
+ ...(input.providerEventId ? { providerEventId: input.providerEventId } : {}),
71
+ ...(input.gatewayOrderId ? { gatewayOrderId: input.gatewayOrderId } : {}),
72
+ ...(input.gatewayPaymentId ? { gatewayPaymentId: input.gatewayPaymentId } : {}),
73
+ ...(typeof input.amount === "number" ? { amount: input.amount } : {}),
74
+ ...(input.payload ? { payload: input.payload } : {}),
75
+ ...(input.payloadTruncated ? { payloadTruncated: true } : {}),
76
+ receivedAt: now,
77
+ claimedAt: now,
78
+ leaseExpiresAt: new Date(now.getTime() + GATEWAY_EVENT_LEASE_SECONDS * 1000),
79
+ attempts: 1,
80
+ expiresAt: new Date(now.getTime() + GATEWAY_EVENT_RETENTION_DAYS * 86400000),
81
+ createdAt: now,
82
+ updatedAt: now,
83
+ };
84
+ try {
85
+ await this.getCollection().doc(id).create(prepareForFirestore(doc));
86
+ return { claimed: true, id, doc };
87
+ }
88
+ catch (err) {
89
+ if (isAlreadyExists(err)) {
90
+ void normalizeError(err);
91
+ return { claimed: false, id };
92
+ }
93
+ /*
94
+ * Not a duplicate — a real write failure. Normalised for the log trail
95
+ * and then RETHROWN, deliberately: the inbox holds no record, so the only
96
+ * honest answer to the gateway is "send it again".
97
+ */
98
+ void normalizeError(err);
99
+ throw err;
100
+ }
101
+ }
102
+ /** Flip a claimed row to its outcome. Never throws — see the docstring. */
103
+ async settle(id, input) {
104
+ const now = input.now ?? new Date();
105
+ try {
106
+ await this.getCollection()
107
+ .doc(id)
108
+ .update({
109
+ status: input.status,
110
+ processedAt: now,
111
+ updatedAt: now,
112
+ ...(input.orderIds?.length ? { orderIds: input.orderIds } : {}),
113
+ ...(input.lastError
114
+ ? { lastError: truncate(input.lastError, GATEWAY_EVENT_ERROR_MAX_BYTES) }
115
+ : {}),
116
+ ...(typeof input.terminal === "boolean" ? { terminal: input.terminal } : {}),
117
+ });
118
+ }
119
+ catch (err) {
120
+ /*
121
+ * Swallowed on purpose, and the asymmetry with `claim` is the reason: by
122
+ * the time we settle, the EVENT IS ALREADY DURABLE and the work is
123
+ * already done. Rethrowing would turn a bookkeeping failure into a 5xx
124
+ * and have the gateway redeliver an event we successfully processed. The
125
+ * row is left `received` with a lease that expires, which the stuck-event
126
+ * sweep then picks up — the right failure mode.
127
+ */
128
+ void normalizeError(err);
129
+ console.error("[gatewayEvents.settle] failed to persist outcome", { id, err });
130
+ }
131
+ }
132
+ /**
133
+ * R1's query: rows claimed but never settled, whose lease has lapsed.
134
+ *
135
+ * 🛑 `status` is an `in` equality and `leaseExpiresAt` the single inequality,
136
+ * which is the only shape Firestore will serve without demanding the
137
+ * inequality field lead the `orderBy` (Root Cause #59). Ordered by
138
+ * `leaseExpiresAt` for exactly that reason — not by `receivedAt`, which would
139
+ * need an index in an order nobody declares.
140
+ */
141
+ async listStuck(now, limit = 20) {
142
+ const snap = await this.getCollection()
143
+ .where(GATEWAY_EVENT_FIELDS.STATUS, "in", ["received", "processing"])
144
+ .where(GATEWAY_EVENT_FIELDS.LEASE_EXPIRES_AT, "<", now)
145
+ .orderBy(GATEWAY_EVENT_FIELDS.LEASE_EXPIRES_AT, "asc")
146
+ .limit(limit)
147
+ .get();
148
+ return snap.docs.map((d) => this.mapDoc(d));
149
+ }
150
+ /**
151
+ * Make the NEXT delivery of this event be accepted instead of acked.
152
+ *
153
+ * ## 🛑 IT DOES NOT REPROCESS ANYTHING, AND THE NAME SAYS SO
154
+ *
155
+ * There is no way to replay a gateway event from here, deliberately. R1's own
156
+ * header gives the reason: re-dispatching from a job or an admin button would
157
+ * mean duplicating the webhook route's entire switch — and its RTDB
158
+ * signalling — in a second place, which is Root Cause #75 on the dispatch
159
+ * axis. The webhook route is the only thing that knows how to handle an event.
160
+ *
161
+ * So this reopens the DOOR and nothing more. The operator still has to press
162
+ * Resend in the gateway dashboard (or wait for the gateway's own retry); this
163
+ * is what stops the inbox from refusing that redelivery as a duplicate.
164
+ *
165
+ * Anything calling this must tell the operator that second step is theirs. A
166
+ * button labelled "Reprocess" that only did this would be the worst kind of
167
+ * half-truth — it would look like the work had been done.
168
+ *
169
+ * ## Why these four fields, read off `resolveDuplicateDelivery`'s table
170
+ *
171
+ * That function decides ack-vs-redispatch, and three of its branches would
172
+ * otherwise swallow the redelivery:
173
+ *
174
+ * · `processed` / `ignored` / `conflict` → always ack. Hence `status` is
175
+ * reset to `failed`, the one non-terminal state that redispatches.
176
+ * · `failed` + `terminal: true` → ack. Hence `terminal: false`.
177
+ * · lapsed lease but `attempts >= GATEWAY_EVENT_MAX_ATTEMPTS` → ack. Hence
178
+ * `attempts: 0`.
179
+ *
180
+ * And the lease is set to `now`, i.e. already expired, because the
181
+ * received/processing branch is decided by the LEASE rather than the status —
182
+ * a live lease means "another worker has this" and must keep acking.
183
+ *
184
+ * `lastError` records that a human did this, so the row does not read as a
185
+ * fresh transient failure to whoever looks next.
186
+ */
187
+ async reopenForRedelivery(id, actorUid, now = new Date()) {
188
+ await this.getCollection()
189
+ .doc(id)
190
+ .update({
191
+ status: "failed",
192
+ terminal: false,
193
+ attempts: 0,
194
+ claimedAt: now,
195
+ // Already lapsed — see the docstring: the lease, not the status, is what
196
+ // decides the received/processing branch.
197
+ leaseExpiresAt: now,
198
+ lastError: `Reopened for redelivery by ${actorUid}`,
199
+ updatedAt: now,
200
+ });
201
+ }
202
+ /** Take over a lapsed lease and count the attempt. */
203
+ async renewLease(id, attempts, now) {
204
+ await this.getCollection()
205
+ .doc(id)
206
+ .update({
207
+ status: "processing",
208
+ attempts: attempts + 1,
209
+ claimedAt: now,
210
+ leaseExpiresAt: new Date(now.getTime() + GATEWAY_EVENT_LEASE_SECONDS * 1000),
211
+ updatedAt: now,
212
+ });
213
+ }
214
+ /** Every event for one gateway order — the reconciliation join. */
215
+ async findByGatewayOrderId(gatewayOrderId) {
216
+ const snap = await this.getCollection()
217
+ .where(GATEWAY_EVENT_FIELDS.GATEWAY_ORDER_ID, "==", gatewayOrderId)
218
+ .orderBy(GATEWAY_EVENT_FIELDS.RECEIVED_AT, "desc")
219
+ .limit(50)
220
+ .get();
221
+ return snap.docs.map((d) => this.mapDoc(d));
222
+ }
223
+ /**
224
+ * Retention: refs for rows past `expiresAt`, for the caller's batch delete.
225
+ * Mirrors `sessionRepository.getExpiredRefs` so `dailyDataCleanup` composes
226
+ * it the same way it composes sessions and tokens.
227
+ */
228
+ async getExpiredRefs(now, limit = 500) {
229
+ const snap = await this.getCollection()
230
+ .where(GATEWAY_EVENT_FIELDS.EXPIRES_AT, "<", now)
231
+ .limit(limit)
232
+ .get();
233
+ return snap.docs.map((d) => d.ref);
234
+ }
235
+ async list(model) {
236
+ return applySieveToFirestore({
237
+ baseQuery: this.getCollection(),
238
+ model,
239
+ fields: GatewayEventsRepository.SIEVE_FIELDS,
240
+ });
241
+ }
242
+ }
243
+ /**
244
+ * 🛑 Every date field carries `parseValue: parseSieveDateValue`, and it is not
245
+ * optional: these are stored Firestore Timestamps, and sievejs' default
246
+ * `convertValue()` only coerces `"true"`/`"false"`/numeric strings. An ISO
247
+ * string therefore reaches the adapter unchanged and becomes
248
+ * `.where("receivedAt", ">=", "<iso-string>")` — a type mismatch against a
249
+ * Timestamp, which matches **zero documents with no error at all**
250
+ * (Root Cause #47). `audit-sieve-date-fields` blocks the omission.
251
+ */
252
+ GatewayEventsRepository.SIEVE_FIELDS = {
253
+ gateway: { canFilter: true, canSort: false },
254
+ rawEvent: { canFilter: true, canSort: false },
255
+ kind: { canFilter: true, canSort: false },
256
+ status: { canFilter: true, canSort: false },
257
+ terminal: { canFilter: true, canSort: false },
258
+ providerEventId: { canFilter: true, canSort: false },
259
+ gatewayOrderId: { canFilter: true, canSort: false },
260
+ gatewayPaymentId: { canFilter: true, canSort: false },
261
+ attempts: { canFilter: true, canSort: true },
262
+ receivedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
263
+ claimedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
264
+ leaseExpiresAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
265
+ processedAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
266
+ expiresAt: { canFilter: true, canSort: true, parseValue: parseSieveDateValue },
267
+ };
268
+ let cached = null;
269
+ /** Lazy singleton — avoids cold-start admin SDK init when nothing is ingesting. */
270
+ export function gatewayEventsRepository() {
271
+ if (!cached)
272
+ cached = new GatewayEventsRepository();
273
+ return cached;
274
+ }
@@ -0,0 +1,217 @@
1
+ /**
2
+ * `gatewayEvents` — the durable inbox for every payment-gateway webhook.
3
+ *
4
+ * ## Why this collection exists
5
+ *
6
+ * Before it, a webhook was a request and nothing else. If the handler threw, or
7
+ * the Lambda died mid-dispatch, or the event type was one we had not written a
8
+ * `case` for, **the event was gone** — there was no record it had ever arrived.
9
+ * That is what made the 2026-10-21 incident undiagnosable (₹2,511.80 captured,
10
+ * no order, a manual refund): the only trace was a `serverLogger.warn` in a log
11
+ * buffer that drops at ~4 KB/s, and a Server Action's throw never reaches
12
+ * `onRequestError` because `wrapAction` returns rather than throws
13
+ * (Root Cause #87).
14
+ *
15
+ * The inbox inverts that. Persist, then act, then ack — so a crash leaves a row
16
+ * with an expired lease that a reconciler finds within 5 minutes, instead of
17
+ * leaving nothing at all.
18
+ *
19
+ * ## The name
20
+ *
21
+ * 🛑 Not `paymentEvents` — that collides with `RTDB_PATHS.PAYMENT_EVENTS`, a
22
+ * short-lived Realtime Database signal channel that is a completely different
23
+ * thing (a browser-facing ping, pruned every 15 minutes). Not `disputes` or
24
+ * `incidents` either: both names are taken, by a buyer-contests-auto-approval
25
+ * flow and a `scammerProfiles` subcollection respectively.
26
+ *
27
+ * ## Dedupe: the document id IS the key
28
+ *
29
+ * `${gateway}_${providerEventId ?? bodySha256.slice(0,32)}`, written with
30
+ * Firestore's `.create()`, which **fails if the document exists**. That is the
31
+ * same at-most-once primitive `gatewayOrderClaims` and `refundClaims` already
32
+ * use, and it needs no transaction and no read.
33
+ *
34
+ * 🛑 **The `bodySha256` fallback is load-bearing, not a nicety.** Razorpay
35
+ * sends `x-razorpay-event-id` and it is believed stable across redeliveries —
36
+ * but that has NOT been verified against a live delivery, and verifying it
37
+ * needs a real webhook. So the fallback means a missing or unstable header
38
+ * degrades to body-identity dedupe rather than to *no* dedupe. PhonePe needs
39
+ * that branch regardless: it documents no event id, and its bodies carry
40
+ * `merchantOrderId` + `state`, so two identical bodies genuinely are the same
41
+ * logical transition.
42
+ *
43
+ * ## Write amplification
44
+ *
45
+ * 2 writes + 0 reads for a new event; 1 failed create for a duplicate. At 100
46
+ * events/day that is ~1% of the free daily write budget.
47
+ *
48
+ * 🛑 **Do not "optimise" this with an allowlist of event types that get a
49
+ * durable row.** That reintroduces the exact gap this collection closes — the
50
+ * unhandled event is the one you most want a record of, because it is the one
51
+ * no code path is watching. The correct lever for volume is unsubscribing
52
+ * unwanted types in the gateway's own dashboard.
53
+ */
54
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
55
+ import type { FirestoreDocument } from "../../../schemas/types";
56
+ export declare const GATEWAY_EVENTS_COLLECTION = "gatewayEvents";
57
+ /**
58
+ * What the event is about, with the gateway's vocabulary already resolved.
59
+ *
60
+ * Deliberately the same five values the webhook route's own `NormalisedEvent`
61
+ * uses, so the route classifies once and both the inbox and the dispatcher read
62
+ * the same answer. `"dispute"` and `"refund"` have no producer until Phase 3
63
+ * widens `normaliseRazorpayEvent` — they are declared here first **on purpose**:
64
+ * a `payment.dispute.created` arriving today lands as `kind: "other"` with its
65
+ * `rawEvent` intact and is therefore recoverable, rather than vanishing.
66
+ */
67
+ export type GatewayEventKind = "paid" | "failed" | "dispute" | "refund" | "other";
68
+ /**
69
+ * Lifecycle. Every value is reachable and each means something distinct:
70
+ *
71
+ * | value | meaning |
72
+ * |---|---|
73
+ * | `received` | persisted and claimed; dispatch has not returned yet |
74
+ * | `processing` | re-dispatched by the stuck-event sweep (attempt ≥ 2) |
75
+ * | `processed` | the handler succeeded |
76
+ * | `ignored` | an event type we do not handle — recorded verbatim, not dropped |
77
+ * | `conflict` | a LATE event whose transition would regress the order |
78
+ * | `failed` | the handler threw; `terminal` says whether a retry can help |
79
+ *
80
+ * 🛑 `conflict` is not an error state. A late `order.paid` arriving after the
81
+ * order shipped is not *wrong*, it is *out of date* — and asking the gateway to
82
+ * retry a regression it can never win is the pathology the webhook route's own
83
+ * header warns about. It acks 200 and records the conflict for a human.
84
+ */
85
+ export type GatewayEventStatus = "received" | "processing" | "processed" | "ignored" | "conflict" | "failed";
86
+ export interface GatewayEventDocument extends BaseDocument {
87
+ /** `payment.name` — "razorpay" | "phonepe" | "manual". */
88
+ gateway: string;
89
+ /** The gateway's own event string, verbatim, e.g. `payment.dispute.created`. */
90
+ rawEvent: string;
91
+ kind: GatewayEventKind;
92
+ status: GatewayEventStatus;
93
+ /**
94
+ * Set with `status: "failed"` to mean "a retry cannot help" — a 4xx-class
95
+ * fault, a validation refusal, an exhausted attempt budget. Absent means
96
+ * unknown, which the sweep treats as retryable.
97
+ */
98
+ terminal?: boolean;
99
+ /** `x-razorpay-event-id` when the gateway sent one. Absent for PhonePe. */
100
+ providerEventId?: string;
101
+ /**
102
+ * sha256 of the raw body. Always present, even when `providerEventId` is —
103
+ * it is the dedupe fallback AND the integrity check that survives payload
104
+ * redaction, so the row can prove what arrived without storing it.
105
+ */
106
+ bodySha256: string;
107
+ gatewayOrderId?: string;
108
+ gatewayPaymentId?: string;
109
+ /**
110
+ * Decimal RUPEES, never subunits. Converted at the provider boundary with
111
+ * `paiseToRupees` — `audit-money-units` blocks both the raw arithmetic and
112
+ * the word for the subunit appearing in a comment or a label.
113
+ */
114
+ amount?: number;
115
+ /**
116
+ * The reconciliation join key: which of OUR orders this event produced or
117
+ * concerns. Empty on an `ignored` row and on a `failed` one that never got
118
+ * far enough to place anything.
119
+ */
120
+ orderIds?: string[];
121
+ receivedAt: Date;
122
+ /**
123
+ * 🛑 `claimedAt`, `leaseExpiresAt` and `expiresAt` are all REQUIRED, and that
124
+ * is a correctness requirement rather than tidiness — Root Cause #100.
125
+ *
126
+ * The stuck-event sweep queries `leaseExpiresAt < now`, and the retention
127
+ * sweep queries `expiresAt < now`. **A Firestore inequality excludes every
128
+ * document that LACKS the field**, so an optional lease would make the
129
+ * detector structurally unable to see exactly the rows it exists to find:
130
+ * an event that crashed before claiming would be invisible to the thing
131
+ * watching for events that crashed. Same for retention — an optional
132
+ * `expiresAt` means rows that accumulate forever while the sweep reports
133
+ * success.
134
+ *
135
+ * The create therefore always sets all three. There is no "unclaimed" state.
136
+ */
137
+ claimedAt: Date;
138
+ leaseExpiresAt: Date;
139
+ processedAt?: Date;
140
+ /** 1 on create; incremented by each re-dispatch. */
141
+ attempts: number;
142
+ /** Truncated. Never the raw body — that is what `bodySha256` is for. */
143
+ lastError?: string;
144
+ /** Retention anchor. 90 days — see `GATEWAY_EVENT_RETENTION_DAYS`. */
145
+ expiresAt: Date;
146
+ /**
147
+ * A REDACTED projection of the body, never the body itself.
148
+ *
149
+ * Razorpay payment entities carry `email`, `contact`, `card.last4`, `vpa` and
150
+ * `bank`. `redactGatewayPayload` strips those recursively and caps the
151
+ * result; `bodySha256` preserves integrity regardless, so nothing is lost
152
+ * that a diagnosis actually needs.
153
+ */
154
+ payload?: FirestoreDocument;
155
+ /** True when redaction hit the size cap, so a reader knows it is partial. */
156
+ payloadTruncated?: boolean;
157
+ }
158
+ export declare const GATEWAY_EVENT_FIELDS: {
159
+ readonly ID: "id";
160
+ readonly GATEWAY: "gateway";
161
+ readonly RAW_EVENT: "rawEvent";
162
+ readonly KIND: "kind";
163
+ readonly STATUS: "status";
164
+ readonly TERMINAL: "terminal";
165
+ readonly PROVIDER_EVENT_ID: "providerEventId";
166
+ readonly BODY_SHA256: "bodySha256";
167
+ readonly GATEWAY_ORDER_ID: "gatewayOrderId";
168
+ readonly GATEWAY_PAYMENT_ID: "gatewayPaymentId";
169
+ readonly AMOUNT: "amount";
170
+ readonly ORDER_IDS: "orderIds";
171
+ readonly RECEIVED_AT: "receivedAt";
172
+ readonly CLAIMED_AT: "claimedAt";
173
+ readonly LEASE_EXPIRES_AT: "leaseExpiresAt";
174
+ readonly PROCESSED_AT: "processedAt";
175
+ readonly ATTEMPTS: "attempts";
176
+ readonly LAST_ERROR: "lastError";
177
+ readonly EXPIRES_AT: "expiresAt";
178
+ };
179
+ /**
180
+ * 90 days, deliberately longer than `serverErrors`' 30.
181
+ *
182
+ * A chargeback can arrive 120+ days after the payment it concerns, and the
183
+ * first thing anyone wants then is the original `order.paid` event. 90 days
184
+ * does not cover the full chargeback horizon — nothing short of indefinite
185
+ * would — but it covers the window in which an event is still the cheapest way
186
+ * to answer "what did the gateway actually tell us", and a row referenced by an
187
+ * open case is excluded from the sweep regardless.
188
+ */
189
+ export declare const GATEWAY_EVENT_RETENTION_DAYS = 90;
190
+ /**
191
+ * How long a dispatch may hold its claim before the stuck-event sweep assumes
192
+ * the worker died.
193
+ *
194
+ * 🛑 Must exceed the route's own `maxDuration` (60s), or the sweep re-dispatches
195
+ * an event that is still legitimately in flight — which, for a `paid` event,
196
+ * means two concurrent order placements. The placement claim makes that a no-op
197
+ * rather than a double order, but relying on a downstream guard to cover a
198
+ * timing bug we chose is the wrong order of defences.
199
+ */
200
+ export declare const GATEWAY_EVENT_LEASE_SECONDS = 120;
201
+ /** Attempts after which the sweep stops re-dispatching and opens a case. */
202
+ export declare const GATEWAY_EVENT_MAX_ATTEMPTS = 5;
203
+ /** Byte budget for the redacted payload. */
204
+ export declare const GATEWAY_EVENT_PAYLOAD_MAX_BYTES = 32768;
205
+ /** Byte budget for `lastError`. */
206
+ export declare const GATEWAY_EVENT_ERROR_MAX_BYTES = 2048;
207
+ /**
208
+ * Build the dedupe id. Exported so the route, the ingest helper and any future
209
+ * reconciler all derive it the same way — two spellings of a dedupe key is a
210
+ * dedupe that silently does not work.
211
+ *
212
+ * `providerEventId` is preferred because it is stable across redeliveries of
213
+ * the SAME event even when the body is re-serialised; the digest is the
214
+ * fallback. Both are prefixed with the gateway so two providers cannot collide
215
+ * on a shared id format.
216
+ */
217
+ export declare function createGatewayEventId(gateway: string, providerEventId: string | undefined, bodySha256: string): string;
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `gatewayEvents` — the durable inbox for every payment-gateway webhook.
3
+ *
4
+ * ## Why this collection exists
5
+ *
6
+ * Before it, a webhook was a request and nothing else. If the handler threw, or
7
+ * the Lambda died mid-dispatch, or the event type was one we had not written a
8
+ * `case` for, **the event was gone** — there was no record it had ever arrived.
9
+ * That is what made the 2026-10-21 incident undiagnosable (₹2,511.80 captured,
10
+ * no order, a manual refund): the only trace was a `serverLogger.warn` in a log
11
+ * buffer that drops at ~4 KB/s, and a Server Action's throw never reaches
12
+ * `onRequestError` because `wrapAction` returns rather than throws
13
+ * (Root Cause #87).
14
+ *
15
+ * The inbox inverts that. Persist, then act, then ack — so a crash leaves a row
16
+ * with an expired lease that a reconciler finds within 5 minutes, instead of
17
+ * leaving nothing at all.
18
+ *
19
+ * ## The name
20
+ *
21
+ * 🛑 Not `paymentEvents` — that collides with `RTDB_PATHS.PAYMENT_EVENTS`, a
22
+ * short-lived Realtime Database signal channel that is a completely different
23
+ * thing (a browser-facing ping, pruned every 15 minutes). Not `disputes` or
24
+ * `incidents` either: both names are taken, by a buyer-contests-auto-approval
25
+ * flow and a `scammerProfiles` subcollection respectively.
26
+ *
27
+ * ## Dedupe: the document id IS the key
28
+ *
29
+ * `${gateway}_${providerEventId ?? bodySha256.slice(0,32)}`, written with
30
+ * Firestore's `.create()`, which **fails if the document exists**. That is the
31
+ * same at-most-once primitive `gatewayOrderClaims` and `refundClaims` already
32
+ * use, and it needs no transaction and no read.
33
+ *
34
+ * 🛑 **The `bodySha256` fallback is load-bearing, not a nicety.** Razorpay
35
+ * sends `x-razorpay-event-id` and it is believed stable across redeliveries —
36
+ * but that has NOT been verified against a live delivery, and verifying it
37
+ * needs a real webhook. So the fallback means a missing or unstable header
38
+ * degrades to body-identity dedupe rather than to *no* dedupe. PhonePe needs
39
+ * that branch regardless: it documents no event id, and its bodies carry
40
+ * `merchantOrderId` + `state`, so two identical bodies genuinely are the same
41
+ * logical transition.
42
+ *
43
+ * ## Write amplification
44
+ *
45
+ * 2 writes + 0 reads for a new event; 1 failed create for a duplicate. At 100
46
+ * events/day that is ~1% of the free daily write budget.
47
+ *
48
+ * 🛑 **Do not "optimise" this with an allowlist of event types that get a
49
+ * durable row.** That reintroduces the exact gap this collection closes — the
50
+ * unhandled event is the one you most want a record of, because it is the one
51
+ * no code path is watching. The correct lever for volume is unsubscribing
52
+ * unwanted types in the gateway's own dashboard.
53
+ */
54
+ export const GATEWAY_EVENTS_COLLECTION = "gatewayEvents";
55
+ export const GATEWAY_EVENT_FIELDS = {
56
+ ID: "id",
57
+ GATEWAY: "gateway",
58
+ RAW_EVENT: "rawEvent",
59
+ KIND: "kind",
60
+ STATUS: "status",
61
+ TERMINAL: "terminal",
62
+ PROVIDER_EVENT_ID: "providerEventId",
63
+ BODY_SHA256: "bodySha256",
64
+ GATEWAY_ORDER_ID: "gatewayOrderId",
65
+ GATEWAY_PAYMENT_ID: "gatewayPaymentId",
66
+ AMOUNT: "amount",
67
+ ORDER_IDS: "orderIds",
68
+ RECEIVED_AT: "receivedAt",
69
+ CLAIMED_AT: "claimedAt",
70
+ LEASE_EXPIRES_AT: "leaseExpiresAt",
71
+ PROCESSED_AT: "processedAt",
72
+ ATTEMPTS: "attempts",
73
+ LAST_ERROR: "lastError",
74
+ EXPIRES_AT: "expiresAt",
75
+ };
76
+ /**
77
+ * 90 days, deliberately longer than `serverErrors`' 30.
78
+ *
79
+ * A chargeback can arrive 120+ days after the payment it concerns, and the
80
+ * first thing anyone wants then is the original `order.paid` event. 90 days
81
+ * does not cover the full chargeback horizon — nothing short of indefinite
82
+ * would — but it covers the window in which an event is still the cheapest way
83
+ * to answer "what did the gateway actually tell us", and a row referenced by an
84
+ * open case is excluded from the sweep regardless.
85
+ */
86
+ export const GATEWAY_EVENT_RETENTION_DAYS = 90;
87
+ /**
88
+ * How long a dispatch may hold its claim before the stuck-event sweep assumes
89
+ * the worker died.
90
+ *
91
+ * 🛑 Must exceed the route's own `maxDuration` (60s), or the sweep re-dispatches
92
+ * an event that is still legitimately in flight — which, for a `paid` event,
93
+ * means two concurrent order placements. The placement claim makes that a no-op
94
+ * rather than a double order, but relying on a downstream guard to cover a
95
+ * timing bug we chose is the wrong order of defences.
96
+ */
97
+ export const GATEWAY_EVENT_LEASE_SECONDS = 120;
98
+ /** Attempts after which the sweep stops re-dispatching and opens a case. */
99
+ export const GATEWAY_EVENT_MAX_ATTEMPTS = 5;
100
+ /** Byte budget for the redacted payload. */
101
+ export const GATEWAY_EVENT_PAYLOAD_MAX_BYTES = 32768;
102
+ /** Byte budget for `lastError`. */
103
+ export const GATEWAY_EVENT_ERROR_MAX_BYTES = 2048;
104
+ /**
105
+ * Build the dedupe id. Exported so the route, the ingest helper and any future
106
+ * reconciler all derive it the same way — two spellings of a dedupe key is a
107
+ * dedupe that silently does not work.
108
+ *
109
+ * `providerEventId` is preferred because it is stable across redeliveries of
110
+ * the SAME event even when the body is re-serialised; the digest is the
111
+ * fallback. Both are prefixed with the gateway so two providers cannot collide
112
+ * on a shared id format.
113
+ */
114
+ export function createGatewayEventId(gateway, providerEventId, bodySha256) {
115
+ const key = providerEventId?.trim() || bodySha256.slice(0, 32);
116
+ /*
117
+ * Firestore ids may not contain "/" and must not be "." or "..". A gateway
118
+ * name is ours and safe, but a provider event id is THEIRS — so it is
119
+ * sanitised rather than trusted. Anything outside the safe set collapses to
120
+ * "_", which can at worst merge two events that differ only by an unsafe
121
+ * character; that is strictly better than a write that throws on the one
122
+ * path whose whole job is to not lose the event.
123
+ */
124
+ return `${gateway}_${key}`.replace(/[^A-Za-z0-9_.:-]/g, "_").slice(0, 1500);
125
+ }