@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,68 @@
1
+ import type { DocumentReference } from "firebase-admin/firestore";
2
+ import { BaseRepository } from "../../../providers/db-firebase";
3
+ import { type ObligationDocument, type ObligationKind, type ObligationState } from "../schemas/firestore";
4
+ export interface OpenObligationInput {
5
+ kind: ObligationKind;
6
+ subjectCollection: string;
7
+ subjectId: string;
8
+ dueAt: Date;
9
+ isTestData?: boolean;
10
+ note?: string;
11
+ now?: Date;
12
+ }
13
+ export interface CloseObligationInput {
14
+ state: Exclude<ObligationState, "open">;
15
+ closeReason: string;
16
+ now?: Date;
17
+ }
18
+ export declare class ObligationsRepository extends BaseRepository<ObligationDocument> {
19
+ constructor();
20
+ /**
21
+ * Open an obligation, or leave an existing open one exactly as it is.
22
+ *
23
+ * 🛑 `.create()`, fails-if-exists — which gives the invariant **at most one
24
+ * open obligation per (subject, kind)**. That is what makes it safe to
25
+ * reconcile obligations on EVERY order write, including the great majority
26
+ * that change nothing relevant: a double create is a no-op, not a second
27
+ * timer.
28
+ *
29
+ * 🛑 It deliberately does NOT update the `dueAt` of an existing row. The
30
+ * clock starts once, at the anchoring event, and a later write re-deriving a
31
+ * slightly different deadline must not quietly extend it — that would let a
32
+ * seller refresh their own dispatch deadline by touching the order.
33
+ */
34
+ open(input: OpenObligationInput): Promise<{
35
+ id: string;
36
+ created: boolean;
37
+ }>;
38
+ /** Close one, with a reason. Never throws — see `open`. */
39
+ close(subjectId: string, kind: ObligationKind, input: CloseObligationInput): Promise<void>;
40
+ /**
41
+ * The sweep's ONE query: open obligations past due.
42
+ *
43
+ * 🛑 One equality (`state`) and one inequality (`dueAt`), ordered by `dueAt`
44
+ * — the only shape Firestore serves without demanding the inequality field
45
+ * lead the sort (Root Cause #59). **ONE composite index for every kind**,
46
+ * which is the whole reason `kind` is a field rather than named deadline
47
+ * columns on the order: fifteen named deadline fields would mean fifteen
48
+ * queries per tick and fifteen new composite indexes on a collection that
49
+ * already carries 55. The two orphan `prizeRevealDeadline` indexes — on a
50
+ * field that exists in no TypeScript file — are a preview of that failure.
51
+ */
52
+ listDue(now: Date, limit?: number): Promise<ObligationDocument[]>;
53
+ /** Open obligations approaching their deadline, for the warning pass. */
54
+ listUpcoming(horizon: Date, now: Date, limit?: number): Promise<ObligationDocument[]>;
55
+ /**
56
+ * Every open obligation for one subject — the quiet-period check.
57
+ *
58
+ * 🛑 This is the QUIET PERIOD invariant's query, and the payout path must
59
+ * call it at BOTH batch-creation and settlement time. A refund posted between
60
+ * the two would otherwise silently shrink a payout an admin had already sent.
61
+ */
62
+ listOpenForSubject(subjectId: string): Promise<ObligationDocument[]>;
63
+ /** Record that a warning was sent, so a re-run does not re-warn. */
64
+ recordWarning(id: string, at: Date): Promise<void>;
65
+ /** Refs for a subject's obligations — used when an order is hard-deleted. */
66
+ refsForSubject(subjectId: string): Promise<DocumentReference[]>;
67
+ }
68
+ export declare function obligationsRepository(): ObligationsRepository;
@@ -0,0 +1,158 @@
1
+ import { BaseRepository, prepareForFirestore } from "../../../providers/db-firebase/index.js";
2
+ import { normalizeError } from "../../../errors/normalize.js";
3
+ import { OBLIGATIONS_COLLECTION, OBLIGATION_ACTIVE_STATES, OBLIGATION_FIELDS, createObligationId, } from "../schemas/firestore.js";
4
+ export class ObligationsRepository extends BaseRepository {
5
+ /*
6
+ * 🛑 NO `SIEVE_FIELDS`, deliberately.
7
+ *
8
+ * `audit-sieve-field-coverage` targets every `*.repository.ts` defining one,
9
+ * and this collection has no filterable admin list to justify it: the sweep
10
+ * uses exactly one query shape, and an operator looking at a deadline looks
11
+ * at the ORDER, not at the index row. Declaring a Sieve surface nothing calls
12
+ * is the speculative-infra pattern — the `route-schema-registry` lesson, 576
13
+ * keys into a layer with no readers.
14
+ */
15
+ constructor() {
16
+ super(OBLIGATIONS_COLLECTION);
17
+ }
18
+ /**
19
+ * Open an obligation, or leave an existing open one exactly as it is.
20
+ *
21
+ * 🛑 `.create()`, fails-if-exists — which gives the invariant **at most one
22
+ * open obligation per (subject, kind)**. That is what makes it safe to
23
+ * reconcile obligations on EVERY order write, including the great majority
24
+ * that change nothing relevant: a double create is a no-op, not a second
25
+ * timer.
26
+ *
27
+ * 🛑 It deliberately does NOT update the `dueAt` of an existing row. The
28
+ * clock starts once, at the anchoring event, and a later write re-deriving a
29
+ * slightly different deadline must not quietly extend it — that would let a
30
+ * seller refresh their own dispatch deadline by touching the order.
31
+ */
32
+ async open(input) {
33
+ const now = input.now ?? new Date();
34
+ const id = createObligationId(input.subjectId, input.kind);
35
+ const doc = {
36
+ id,
37
+ kind: input.kind,
38
+ subjectCollection: input.subjectCollection,
39
+ subjectId: input.subjectId,
40
+ dueAt: input.dueAt,
41
+ state: "open",
42
+ ...(input.isTestData ? { isTestData: true } : {}),
43
+ ...(input.note ? { note: input.note } : {}),
44
+ createdAt: now,
45
+ updatedAt: now,
46
+ };
47
+ try {
48
+ await this.getCollection().doc(id).create(prepareForFirestore(doc));
49
+ return { id, created: true };
50
+ }
51
+ catch (err) {
52
+ /*
53
+ * Any failure is treated as "already there". Unlike the gateway-event
54
+ * inbox — which must fail OPEN because a lost event is unrecoverable —
55
+ * an obligation is a derived hint: the next order write reconciles again,
56
+ * and the subject itself still carries the facts. Rethrowing here would
57
+ * let a transient Firestore blip fail the ORDER WRITE that triggered the
58
+ * reconcile, which is the one thing that must not happen.
59
+ */
60
+ void normalizeError(err);
61
+ return { id, created: false };
62
+ }
63
+ }
64
+ /** Close one, with a reason. Never throws — see `open`. */
65
+ async close(subjectId, kind, input) {
66
+ const now = input.now ?? new Date();
67
+ try {
68
+ await this.getCollection()
69
+ .doc(createObligationId(subjectId, kind))
70
+ .update({
71
+ state: input.state,
72
+ closeReason: input.closeReason,
73
+ closedAt: now,
74
+ updatedAt: now,
75
+ });
76
+ }
77
+ catch (err) {
78
+ // Closing one that does not exist is the normal case, not a fault.
79
+ void normalizeError(err);
80
+ }
81
+ }
82
+ /**
83
+ * The sweep's ONE query: open obligations past due.
84
+ *
85
+ * 🛑 One equality (`state`) and one inequality (`dueAt`), ordered by `dueAt`
86
+ * — the only shape Firestore serves without demanding the inequality field
87
+ * lead the sort (Root Cause #59). **ONE composite index for every kind**,
88
+ * which is the whole reason `kind` is a field rather than named deadline
89
+ * columns on the order: fifteen named deadline fields would mean fifteen
90
+ * queries per tick and fifteen new composite indexes on a collection that
91
+ * already carries 55. The two orphan `prizeRevealDeadline` indexes — on a
92
+ * field that exists in no TypeScript file — are a preview of that failure.
93
+ */
94
+ async listDue(now, limit = 100) {
95
+ const snap = await this.getCollection()
96
+ .where(OBLIGATION_FIELDS.STATE, "in", [...OBLIGATION_ACTIVE_STATES])
97
+ .where(OBLIGATION_FIELDS.DUE_AT, "<=", now)
98
+ .orderBy(OBLIGATION_FIELDS.DUE_AT, "asc")
99
+ .limit(limit)
100
+ .get();
101
+ return snap.docs.map((d) => this.mapDoc(d));
102
+ }
103
+ /** Open obligations approaching their deadline, for the warning pass. */
104
+ async listUpcoming(horizon, now, limit = 100) {
105
+ const snap = await this.getCollection()
106
+ .where(OBLIGATION_FIELDS.STATE, "in", [...OBLIGATION_ACTIVE_STATES])
107
+ .where(OBLIGATION_FIELDS.DUE_AT, "<=", horizon)
108
+ .orderBy(OBLIGATION_FIELDS.DUE_AT, "asc")
109
+ .limit(limit)
110
+ .get();
111
+ return snap.docs
112
+ .map((d) => this.mapDoc(d))
113
+ .filter((o) => o.dueAt.getTime() > now.getTime());
114
+ }
115
+ /**
116
+ * Every open obligation for one subject — the quiet-period check.
117
+ *
118
+ * 🛑 This is the QUIET PERIOD invariant's query, and the payout path must
119
+ * call it at BOTH batch-creation and settlement time. A refund posted between
120
+ * the two would otherwise silently shrink a payout an admin had already sent.
121
+ */
122
+ async listOpenForSubject(subjectId) {
123
+ const snap = await this.getCollection()
124
+ .where(OBLIGATION_FIELDS.SUBJECT_ID, "==", subjectId)
125
+ .where(OBLIGATION_FIELDS.STATE, "in", [...OBLIGATION_ACTIVE_STATES])
126
+ .get();
127
+ return snap.docs.map((d) => this.mapDoc(d));
128
+ }
129
+ /** Record that a warning was sent, so a re-run does not re-warn. */
130
+ async recordWarning(id, at) {
131
+ try {
132
+ const existing = await this.findById(id);
133
+ await this.getCollection()
134
+ .doc(id)
135
+ .update({
136
+ warnedAt: [...(existing?.warnedAt ?? []), at],
137
+ updatedAt: at,
138
+ });
139
+ }
140
+ catch (err) {
141
+ void normalizeError(err);
142
+ }
143
+ }
144
+ /** Refs for a subject's obligations — used when an order is hard-deleted. */
145
+ async refsForSubject(subjectId) {
146
+ const snap = await this.getCollection()
147
+ .where(OBLIGATION_FIELDS.SUBJECT_ID, "==", subjectId)
148
+ .limit(50)
149
+ .get();
150
+ return snap.docs.map((d) => d.ref);
151
+ }
152
+ }
153
+ let cached = null;
154
+ export function obligationsRepository() {
155
+ if (!cached)
156
+ cached = new ObligationsRepository();
157
+ return cached;
158
+ }
@@ -0,0 +1,160 @@
1
+ /**
2
+ * `obligations` — deadlines with money consequences.
3
+ *
4
+ * ## Why a mechanism rather than more cron jobs
5
+ *
6
+ * The order lifecycle has roughly seventy timer-driven scenarios ("seller never
7
+ * accepts → auto-cancel + full refund at 3 days", "buyer cancels before
8
+ * shipping", "return approved but never posted"…). The approach before this was
9
+ * eight hand-written sweeps whose coverage could only be established by
10
+ * checking that every pair of `.filter()` predicates agreed — and
11
+ * Root Cause #27 is that reasoning having already failed at n=3: an order in
12
+ * `reupload_requested` was excluded by `getExpiredPaymentDeadlines` (it HAS a
13
+ * proof), by `getUnreviewedProofPastDeadline` (it HAS an outcome) and by
14
+ * `runPendingOrderTimeout` (it HAS a deadline). Three sweeps, pairwise
15
+ * disjoint, and the order held stock forever with no terminal state.
16
+ *
17
+ * This collection makes "which sweep owns this order" answerable by
18
+ * construction instead of by three filters happening to agree.
19
+ *
20
+ * ## 🛑 IT IS A DUE-DATE INDEX, NOT TRUTH
21
+ *
22
+ * The order is authoritative. An obligation row exists so the sweep can FIND
23
+ * candidates cheaply with one indexed query; having found one it **re-reads the
24
+ * subject and re-evaluates the policy's `precondition`**, and a row whose
25
+ * premise no longer holds closes as `superseded` rather than acting.
26
+ *
27
+ * That is what keeps this out of the stored-mirror drift class (Root Cause
28
+ * #42). A row saying "cancel this order at 15:00" is a HINT; the order saying
29
+ * "I was paid at 14:58" is the fact, and the fact wins.
30
+ *
31
+ * ## 🛑 NOT A FIRESTORE TRIGGER
32
+ *
33
+ * An `onOrderWrite` trigger that wrote `obligations`, whose sweep then wrote
34
+ * `orders`, is Root Cause #92's self-write loop exactly — the one that cost
35
+ * 1,017,548 invocations in 24 hours against a 2M/month free quota, plus a
36
+ * sibling function woken a million times just to return. Obligations are
37
+ * reconciled **inside the order's own write**, in `updateWithHistory`, where
38
+ * the current document is already in hand.
39
+ */
40
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
41
+ export declare const OBLIGATIONS_COLLECTION = "obligations";
42
+ /**
43
+ * Every kind of deadline the system owes somebody.
44
+ *
45
+ * 🛑 A `Record<ObligationKind, ObligationPolicy>` in `constants/policies.ts`
46
+ * consumes this union, so **adding a kind without declaring its anchor,
47
+ * duration and guardrail tier is a compile error.** That is the property that
48
+ * makes the Nth scenario cheap instead of another bespoke cron job.
49
+ */
50
+ export type ObligationKind = "seller-accept" | "seller-dispatch" | "proof-reupload" | "delivery-confirm" | "return-respond" | "return-post" | "return-receive" | "return-inspect" | "claim-shipping" | "claim-sale"
51
+ /**
52
+ * The order is COMPLETE: 7 days have passed since delivery with no issue
53
+ * raised, so points are awarded and no new dispute may be opened.
54
+ *
55
+ * 🛑 Owner's requirement, 2026-10-21, verbatim: *"points only get issued on
56
+ * successful purchases after buyer put reviews, then only, if no review no
57
+ * points, that marks the complete order, they are also assigned if the user
58
+ * no issues or updates after 7 days of delivery — no further disputes should
59
+ * be entertained as well."*
60
+ *
61
+ * So completion has TWO triggers and this is the second: the first is the
62
+ * buyer posting a review (event-driven, no timer needed), and this is the
63
+ * silence fallback. Whichever fires first completes the order; the award must
64
+ * therefore be IDEMPOTENT, which is why it is keyed on the order in the
65
+ * points ledger rather than appended blindly.
66
+ *
67
+ * It is also the dispute cutoff, which is the part with teeth: after this
68
+ * fires, a new dispute is refused. Existing ones are unaffected — see the
69
+ * policy's own note on why "no further disputes" cannot mean "everything
70
+ * closes at 7 days".
71
+ */
72
+ | "order-complete" | "payout-release";
73
+ /**
74
+ * Lifecycle of one obligation.
75
+ *
76
+ * | state | meaning |
77
+ * |---|---|
78
+ * | `open` | the clock is running |
79
+ * | `met` | the thing happened in time — closed by the order's own write |
80
+ * | `acted` | the deadline passed and the sweep did what the policy says |
81
+ * | `escalated` | the deadline passed and a human was asked instead |
82
+ * | `superseded` | the premise no longer holds; nothing was owed after all |
83
+ *
84
+ * 🛑 `superseded` is not a failure and must not be reported as one. It is the
85
+ * normal outcome of the index disagreeing with the subject, which is exactly
86
+ * the case the re-read exists to catch.
87
+ */
88
+ export type ObligationState = "open" | "met" | "acted" | "escalated" | "superseded";
89
+ /**
90
+ * What the sweep is allowed to do when a deadline passes.
91
+ *
92
+ * 🛑 THIS LIVES IN THE TYPE, not in the sweep's code, and that is deliberate:
93
+ * the guardrail tier is a property of the SCENARIO, so it belongs beside the
94
+ * duration rather than in a conditional somebody can quietly widen.
95
+ *
96
+ * - `act` — the ceiling is an amount we captured, the recipient is the payer,
97
+ * and no counterparty is debited. A pre-dispatch cancellation with a full
98
+ * refund qualifies; so does writing an anchor, closing a window, or
99
+ * BLOCKING a payout (withholding is always safe).
100
+ * - `escalate` — goods have left the seller, or somebody other than the payer
101
+ * is debited, or a prior refund exists. Open a case; a human decides.
102
+ */
103
+ export type ObligationDueAction = "act" | "escalate";
104
+ export interface ObligationDocument extends BaseDocument {
105
+ kind: ObligationKind;
106
+ /** Collection the subject lives in — `orders` for all of today's kinds. */
107
+ subjectCollection: string;
108
+ subjectId: string;
109
+ /**
110
+ * When it comes due. The ONE field the sweep queries on.
111
+ *
112
+ * 🛑 Required, not optional. The sweep filters `dueAt <= now`, and a
113
+ * Firestore inequality **excludes every document that lacks the field**
114
+ * (Root Cause #100) — so an optional `dueAt` would make the sweep
115
+ * structurally unable to see exactly the rows that failed to compute one.
116
+ */
117
+ dueAt: Date;
118
+ state: ObligationState;
119
+ /** Why it closed. Free text for a human; never parsed. */
120
+ closeReason?: string;
121
+ closedAt?: Date;
122
+ /** Warnings already sent, so a re-run does not re-warn. */
123
+ warnedAt?: Date[];
124
+ /**
125
+ * Mirrors the subject's own flag so the sweep can compress deadlines for a
126
+ * test fixture **without reading the subject first**.
127
+ *
128
+ * 🛑 Per-subject, never global. A global compression would shorten every
129
+ * live buyer's deadline the moment someone ran the tester.
130
+ */
131
+ isTestData?: boolean;
132
+ /** For the admin detail view, and for a case opened from here. */
133
+ note?: string;
134
+ }
135
+ export declare const OBLIGATION_FIELDS: {
136
+ readonly ID: "id";
137
+ readonly KIND: "kind";
138
+ readonly SUBJECT_COLLECTION: "subjectCollection";
139
+ readonly SUBJECT_ID: "subjectId";
140
+ readonly DUE_AT: "dueAt";
141
+ readonly STATE: "state";
142
+ readonly CLOSE_REASON: "closeReason";
143
+ readonly CLOSED_AT: "closedAt";
144
+ readonly IS_TEST_DATA: "isTestData";
145
+ };
146
+ /** States from which the sweep still has work to do. */
147
+ export declare const OBLIGATION_ACTIVE_STATES: readonly ObligationState[];
148
+ /**
149
+ * 🛑 THE IDEMPOTENCY KEY, and the invariant it buys.
150
+ *
151
+ * Deterministic `${subjectId}__${kind}` means **at most one open obligation per
152
+ * (subject, kind)**. A double create is a no-op write rather than a second
153
+ * timer, which is what makes it safe to reconcile obligations on EVERY order
154
+ * write — including the many writes that change nothing relevant.
155
+ *
156
+ * Double underscore, matching `createClaimedCouponId`'s convention, so a
157
+ * subject id containing a single underscore cannot collide with a kind.
158
+ */
159
+ export declare function createObligationId(subjectId: string, kind: ObligationKind): string;
160
+ export declare const ALL_OBLIGATION_KINDS: ObligationKind[];
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `obligations` — deadlines with money consequences.
3
+ *
4
+ * ## Why a mechanism rather than more cron jobs
5
+ *
6
+ * The order lifecycle has roughly seventy timer-driven scenarios ("seller never
7
+ * accepts → auto-cancel + full refund at 3 days", "buyer cancels before
8
+ * shipping", "return approved but never posted"…). The approach before this was
9
+ * eight hand-written sweeps whose coverage could only be established by
10
+ * checking that every pair of `.filter()` predicates agreed — and
11
+ * Root Cause #27 is that reasoning having already failed at n=3: an order in
12
+ * `reupload_requested` was excluded by `getExpiredPaymentDeadlines` (it HAS a
13
+ * proof), by `getUnreviewedProofPastDeadline` (it HAS an outcome) and by
14
+ * `runPendingOrderTimeout` (it HAS a deadline). Three sweeps, pairwise
15
+ * disjoint, and the order held stock forever with no terminal state.
16
+ *
17
+ * This collection makes "which sweep owns this order" answerable by
18
+ * construction instead of by three filters happening to agree.
19
+ *
20
+ * ## 🛑 IT IS A DUE-DATE INDEX, NOT TRUTH
21
+ *
22
+ * The order is authoritative. An obligation row exists so the sweep can FIND
23
+ * candidates cheaply with one indexed query; having found one it **re-reads the
24
+ * subject and re-evaluates the policy's `precondition`**, and a row whose
25
+ * premise no longer holds closes as `superseded` rather than acting.
26
+ *
27
+ * That is what keeps this out of the stored-mirror drift class (Root Cause
28
+ * #42). A row saying "cancel this order at 15:00" is a HINT; the order saying
29
+ * "I was paid at 14:58" is the fact, and the fact wins.
30
+ *
31
+ * ## 🛑 NOT A FIRESTORE TRIGGER
32
+ *
33
+ * An `onOrderWrite` trigger that wrote `obligations`, whose sweep then wrote
34
+ * `orders`, is Root Cause #92's self-write loop exactly — the one that cost
35
+ * 1,017,548 invocations in 24 hours against a 2M/month free quota, plus a
36
+ * sibling function woken a million times just to return. Obligations are
37
+ * reconciled **inside the order's own write**, in `updateWithHistory`, where
38
+ * the current document is already in hand.
39
+ */
40
+ export const OBLIGATIONS_COLLECTION = "obligations";
41
+ export const OBLIGATION_FIELDS = {
42
+ ID: "id",
43
+ KIND: "kind",
44
+ SUBJECT_COLLECTION: "subjectCollection",
45
+ SUBJECT_ID: "subjectId",
46
+ DUE_AT: "dueAt",
47
+ STATE: "state",
48
+ CLOSE_REASON: "closeReason",
49
+ CLOSED_AT: "closedAt",
50
+ IS_TEST_DATA: "isTestData",
51
+ };
52
+ /** States from which the sweep still has work to do. */
53
+ export const OBLIGATION_ACTIVE_STATES = ["open"];
54
+ /**
55
+ * 🛑 THE IDEMPOTENCY KEY, and the invariant it buys.
56
+ *
57
+ * Deterministic `${subjectId}__${kind}` means **at most one open obligation per
58
+ * (subject, kind)**. A double create is a no-op write rather than a second
59
+ * timer, which is what makes it safe to reconcile obligations on EVERY order
60
+ * write — including the many writes that change nothing relevant.
61
+ *
62
+ * Double underscore, matching `createClaimedCouponId`'s convention, so a
63
+ * subject id containing a single underscore cannot collide with a kind.
64
+ */
65
+ export function createObligationId(subjectId, kind) {
66
+ return `${subjectId}__${kind}`.replace(/[^A-Za-z0-9_.:-]/g, "_").slice(0, 1500);
67
+ }
68
+ /**
69
+ * Runtime companion, keyed `Record<Union, true>` so both mistakes are compile
70
+ * errors: a kind added to the union and forgotten here, and a key here that is
71
+ * not a real kind. An array literal catches neither (Root Cause #61).
72
+ */
73
+ const OBLIGATION_KIND_MAP = {
74
+ "seller-accept": true,
75
+ "seller-dispatch": true,
76
+ "proof-reupload": true,
77
+ "delivery-confirm": true,
78
+ "return-respond": true,
79
+ "return-post": true,
80
+ "return-receive": true,
81
+ "return-inspect": true,
82
+ "claim-shipping": true,
83
+ "claim-sale": true,
84
+ "order-complete": true,
85
+ "payout-release": true,
86
+ };
87
+ export const ALL_OBLIGATION_KINDS = Object.keys(OBLIGATION_KIND_MAP);
@@ -4,9 +4,25 @@
4
4
  * Pure business functions — auth, rate-limiting, and Next.js specifics
5
5
  * are handled by the calling server action in the consumer.
6
6
  */
7
- import type { OrderDocument } from "../schemas";
7
+ import type { OrderDocument, OrderPlain } from "../schemas";
8
+ import type { CancellationRefundOutcome } from "../types/index";
8
9
  import type { TrackingInfo } from "../../../contracts/shipping";
9
- export declare function cancelOrderForUser(userId: string, orderId: string, reason: string): Promise<void>;
10
+ /**
11
+ * Cancel a whole order on the buyer's own request.
12
+ *
13
+ * 🛑 **Returns the refund outcome now, and used to return `void` (D14).** This
14
+ * called `orderRepository.cancelOrder(orderId, reason)` — omitting the optional
15
+ * third argument, as all four callers did — so a *paid* order was cancelled,
16
+ * its stock restored, and **the money kept**, while
17
+ * `previewCancellationRefund` had already shown the buyer a figure nothing
18
+ * honoured.
19
+ *
20
+ * Both halves live in `cancelOrderWithRefund`, deliberately not here: passing
21
+ * the amount alone would only record an intent `cancelOrder` has no code to
22
+ * settle, which reads in the database as a refund on its way and is worse than
23
+ * the honest silence it replaces. See that module's header for the full table.
24
+ */
25
+ export declare function cancelOrderForUser(userId: string, orderId: string, reason: string): Promise<CancellationRefundOutcome>;
10
26
  /**
11
27
  * Cancels a subset of line items on an already-placed order and lets the rest
12
28
  * proceed. Matches today's whole-order cancellation behavior: marks the items
@@ -15,10 +31,33 @@ export declare function cancelOrderForUser(userId: string, orderId: string, reas
15
31
  * the order ends up cancelled, falls through to the same whole-order
16
32
  * `cancelOrder` path `cancelOrderForUser` uses, rather than leaving a
17
33
  * zero-item live order.
34
+ *
35
+ * 🛑 Returns `null` on the genuinely-partial path, and an outcome only when it
36
+ * fell through to cancelling the whole order. That is not a convenience: a
37
+ * partial cancellation's add-on and per-item refund arithmetic is **D15/D16**
38
+ * and is not built — it still sets `refundPending: true` and leaves the money
39
+ * to the admin refund flow, exactly as before. Returning a zero-amount outcome
40
+ * here would claim a decision had been made about money when none has.
18
41
  */
19
- export declare function cancelOrderItemsForUser(userId: string, orderId: string, itemIds: string[], reason: string): Promise<void>;
42
+ export declare function cancelOrderItemsForUser(userId: string, orderId: string, itemIds: string[], reason: string): Promise<CancellationRefundOutcome | null>;
20
43
  export declare function listOrdersForUser(userId: string): Promise<OrderDocument[]>;
21
- export declare function getOrderByIdForUser(userId: string, orderId: string): Promise<OrderDocument>;
44
+ /**
45
+ * One order, for the buyer who placed it.
46
+ *
47
+ * 🛑 RETURNS PLAINTEXT, and the return TYPE says so. See
48
+ * `getAddressByIdForUser` for the full reasoning — same defect, same shape.
49
+ *
50
+ * `OrderRepository.mapDoc` does not decrypt, so this returned `enc:v1:` blobs
51
+ * for `userName`, `userEmail` and the `shippingAddress` name and phone, to
52
+ * the buyer, about their own order. Its caller is a server action that hands
53
+ * the result straight to the client.
54
+ *
55
+ * Revealing here rather than at the caller, because this function is what
56
+ * knows the read is owner-scoped: it throws `NotFoundError` — not Forbidden,
57
+ * deliberately, so the response cannot confirm an order exists — for any
58
+ * order whose `userId` is not the caller's.
59
+ */
60
+ export declare function getOrderByIdForUser(userId: string, orderId: string): Promise<OrderPlain>;
22
61
  /**
23
62
  * Retrieve live tracking info for an order via the registered IShippingProvider.
24
63
  * Returns null when no shipping provider is registered or no trackingNumber exists.
@@ -9,12 +9,28 @@ import { serverLogger } from "../../../monitoring/index.js";
9
9
  import { getProviders } from "../../../contracts/index.js";
10
10
  import { orderRepository } from "../repository/orders.repository.js";
11
11
  import { ORDER_CANCELLABLE_STATUSES } from "../../../_internal/shared/features/orders/config.js";
12
+ import { cancelOrderWithRefund } from "../../../_internal/server/features/orders/cancellation-refund.js";
12
13
  const ERR_ORDER_NOT_FOUND = "Order not found";
13
14
  function assertCancellable(order) {
14
15
  if (!ORDER_CANCELLABLE_STATUSES.includes(order.status)) {
15
16
  throw new ValidationError("Only pending or confirmed orders can be cancelled");
16
17
  }
17
18
  }
19
+ /**
20
+ * Cancel a whole order on the buyer's own request.
21
+ *
22
+ * 🛑 **Returns the refund outcome now, and used to return `void` (D14).** This
23
+ * called `orderRepository.cancelOrder(orderId, reason)` — omitting the optional
24
+ * third argument, as all four callers did — so a *paid* order was cancelled,
25
+ * its stock restored, and **the money kept**, while
26
+ * `previewCancellationRefund` had already shown the buyer a figure nothing
27
+ * honoured.
28
+ *
29
+ * Both halves live in `cancelOrderWithRefund`, deliberately not here: passing
30
+ * the amount alone would only record an intent `cancelOrder` has no code to
31
+ * settle, which reads in the database as a refund on its way and is worse than
32
+ * the honest silence it replaces. See that module's header for the full table.
33
+ */
18
34
  export async function cancelOrderForUser(userId, orderId, reason) {
19
35
  const order = await orderRepository.findById(orderId);
20
36
  if (!order)
@@ -22,8 +38,20 @@ export async function cancelOrderForUser(userId, orderId, reason) {
22
38
  if (order.userId !== userId)
23
39
  throw new AuthorizationError("You are not authorised to cancel this order");
24
40
  assertCancellable(order);
25
- await orderRepository.cancelOrder(orderId, reason);
26
- serverLogger.info("Order cancelled by user", { userId, orderId, reason });
41
+ const { refund } = await cancelOrderWithRefund(order, {
42
+ reason,
43
+ actorUid: userId,
44
+ actorRole: "buyer",
45
+ trigger: "cancelOrderForUser",
46
+ });
47
+ serverLogger.info("Order cancelled by user", {
48
+ userId,
49
+ orderId,
50
+ reason,
51
+ refundMoved: refund.moved,
52
+ refundAmount: refund.amount,
53
+ });
54
+ return refund;
27
55
  }
28
56
  /**
29
57
  * Cancels a subset of line items on an already-placed order and lets the rest
@@ -33,6 +61,13 @@ export async function cancelOrderForUser(userId, orderId, reason) {
33
61
  * the order ends up cancelled, falls through to the same whole-order
34
62
  * `cancelOrder` path `cancelOrderForUser` uses, rather than leaving a
35
63
  * zero-item live order.
64
+ *
65
+ * 🛑 Returns `null` on the genuinely-partial path, and an outcome only when it
66
+ * fell through to cancelling the whole order. That is not a convenience: a
67
+ * partial cancellation's add-on and per-item refund arithmetic is **D15/D16**
68
+ * and is not built — it still sets `refundPending: true` and leaves the money
69
+ * to the admin refund flow, exactly as before. Returning a zero-amount outcome
70
+ * here would claim a decision had been made about money when none has.
36
71
  */
37
72
  export async function cancelOrderItemsForUser(userId, orderId, itemIds, reason) {
38
73
  if (itemIds.length === 0) {
@@ -74,17 +109,39 @@ export async function cancelOrderItemsForUser(userId, orderId, itemIds, reason)
74
109
  itemIds: [...matchedIds],
75
110
  reason,
76
111
  });
112
+ /*
113
+ * Explicit, because the declared return type is a union and an implicit
114
+ * `undefined` is not a member of it. It also says the thing worth saying:
115
+ * no refund decision was taken here.
116
+ */
117
+ return null;
77
118
  }
78
119
  export async function listOrdersForUser(userId) {
79
120
  return orderRepository.findByUser(userId);
80
121
  }
122
+ /**
123
+ * One order, for the buyer who placed it.
124
+ *
125
+ * 🛑 RETURNS PLAINTEXT, and the return TYPE says so. See
126
+ * `getAddressByIdForUser` for the full reasoning — same defect, same shape.
127
+ *
128
+ * `OrderRepository.mapDoc` does not decrypt, so this returned `enc:v1:` blobs
129
+ * for `userName`, `userEmail` and the `shippingAddress` name and phone, to
130
+ * the buyer, about their own order. Its caller is a server action that hands
131
+ * the result straight to the client.
132
+ *
133
+ * Revealing here rather than at the caller, because this function is what
134
+ * knows the read is owner-scoped: it throws `NotFoundError` — not Forbidden,
135
+ * deliberately, so the response cannot confirm an order exists — for any
136
+ * order whose `userId` is not the caller's.
137
+ */
81
138
  export async function getOrderByIdForUser(userId, orderId) {
82
139
  const order = await orderRepository.findById(orderId);
83
140
  if (!order)
84
141
  throw new NotFoundError(ERR_ORDER_NOT_FOUND);
85
142
  if (order.userId !== userId)
86
143
  throw new NotFoundError(ERR_ORDER_NOT_FOUND);
87
- return order;
144
+ return orderRepository.revealOrder(order);
88
145
  }
89
146
  /**
90
147
  * Retrieve live tracking info for an order via the registered IShippingProvider.