@mohasinac/appkit 4.59.0 → 4.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +62 -5
  3. package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -2
  4. package/dist/_internal/server/features/brands/actions.js +78 -4
  5. package/dist/_internal/server/features/checkout/actions.d.ts +36 -13
  6. package/dist/_internal/server/features/checkout/actions.js +668 -183
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +18 -1
  8. package/dist/_internal/server/features/gateway-events/index.d.ts +10 -0
  9. package/dist/_internal/server/features/gateway-events/index.js +10 -0
  10. package/dist/_internal/server/features/gateway-events/ingest.d.ts +127 -0
  11. package/dist/_internal/server/features/gateway-events/ingest.js +188 -0
  12. package/dist/_internal/server/features/gateway-events/redact.d.ts +66 -0
  13. package/dist/_internal/server/features/gateway-events/redact.js +151 -0
  14. package/dist/_internal/server/features/grievance/actions.d.ts +63 -0
  15. package/dist/_internal/server/features/grievance/actions.js +173 -0
  16. package/dist/_internal/server/features/grievance/index.d.ts +8 -0
  17. package/dist/_internal/server/features/grievance/index.js +8 -0
  18. package/dist/_internal/server/features/grouped/data.js +28 -3
  19. package/dist/_internal/server/features/lottery/actions.js +99 -4
  20. package/dist/_internal/server/features/order-completion/actions.d.ts +92 -0
  21. package/dist/_internal/server/features/order-completion/actions.js +336 -0
  22. package/dist/_internal/server/features/order-completion/index.d.ts +7 -0
  23. package/dist/_internal/server/features/order-completion/index.js +7 -0
  24. package/dist/_internal/server/features/orders/actions.d.ts +13 -0
  25. package/dist/_internal/server/features/orders/actions.js +56 -2
  26. package/dist/_internal/server/features/orders/adapters.js +26 -0
  27. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
  28. package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
  29. package/dist/_internal/server/features/orders/index.d.ts +2 -1
  30. package/dist/_internal/server/features/orders/index.js +1 -1
  31. package/dist/_internal/server/features/orders/service.d.ts +60 -0
  32. package/dist/_internal/server/features/orders/service.js +74 -0
  33. package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
  34. package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
  35. package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
  36. package/dist/_internal/server/features/payment-cases/index.js +9 -0
  37. package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
  38. package/dist/_internal/server/features/payouts/actions.js +84 -10
  39. package/dist/_internal/server/features/points/adjust.d.ts +61 -0
  40. package/dist/_internal/server/features/points/adjust.js +121 -0
  41. package/dist/_internal/server/features/points/award.d.ts +65 -0
  42. package/dist/_internal/server/features/points/award.js +145 -0
  43. package/dist/_internal/server/features/price-index/market.d.ts +33 -0
  44. package/dist/_internal/server/features/price-index/market.js +54 -1
  45. package/dist/_internal/server/features/products/data.js +40 -22
  46. package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
  47. package/dist/_internal/server/features/protection-claims/actions.js +228 -0
  48. package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
  49. package/dist/_internal/server/features/protection-claims/index.js +8 -0
  50. package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
  51. package/dist/_internal/server/features/refunds/actions.js +259 -17
  52. package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
  53. package/dist/_internal/server/features/refunds/capacity.js +37 -0
  54. package/dist/_internal/server/features/reviews/actions.js +3 -2
  55. package/dist/_internal/server/features/search/index-build/sources.js +20 -1
  56. package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
  57. package/dist/_internal/server/features/shipping/reconcile.js +34 -3
  58. package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
  59. package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
  60. package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
  61. package/dist/_internal/server/features/stores/tabs.js +24 -4
  62. package/dist/_internal/server/functions/https.d.ts +31 -1
  63. package/dist/_internal/server/functions/https.js +52 -1
  64. package/dist/_internal/server/functions/scheduled.d.ts +72 -1
  65. package/dist/_internal/server/functions/scheduled.js +124 -1
  66. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
  67. package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
  68. package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
  69. package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
  70. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
  71. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
  72. package/dist/_internal/server/jobs/core/index.d.ts +2 -0
  73. package/dist/_internal/server/jobs/core/index.js +2 -0
  74. package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
  75. package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
  76. package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
  77. package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
  78. package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
  79. package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
  80. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
  81. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
  82. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
  83. package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
  84. package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
  85. package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
  86. package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
  87. package/dist/_internal/server/jobs/handlers/index.js +5 -0
  88. package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
  89. package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
  90. package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
  91. package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
  92. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
  93. package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
  94. package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
  95. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  96. package/dist/_internal/shared/actions/action-registry.js +71 -0
  97. package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
  98. package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
  99. package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
  100. package/dist/_internal/shared/checkout/lanes.js +46 -0
  101. package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
  102. package/dist/_internal/shared/checkout/order-math.js +251 -3
  103. package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
  104. package/dist/_internal/shared/checkout/refundable-base.js +122 -0
  105. package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
  106. package/dist/_internal/shared/features/auctions/config.js +30 -1
  107. package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
  108. package/dist/_internal/shared/features/brands/schema.js +18 -0
  109. package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
  110. package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
  111. package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
  112. package/dist/_internal/shared/features/print/label-profiles.js +350 -0
  113. package/dist/_internal/shared/features/products/to-product-item.js +33 -5
  114. package/dist/_internal/shared/fees/calculator.d.ts +31 -2
  115. package/dist/_internal/shared/fees/calculator.js +103 -5
  116. package/dist/_internal/shared/fees/india-states.d.ts +195 -0
  117. package/dist/_internal/shared/fees/india-states.js +190 -0
  118. package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
  119. package/dist/_internal/shared/fees/payout-hold.js +74 -0
  120. package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
  121. package/dist/_internal/shared/obligations/deadlines.js +155 -0
  122. package/dist/_internal/shared/shipping/quote.d.ts +96 -0
  123. package/dist/_internal/shared/shipping/quote.js +67 -0
  124. package/dist/_internal/shared/time/business-days.d.ts +91 -0
  125. package/dist/_internal/shared/time/business-days.js +185 -0
  126. package/dist/cli/index.js +0 -2
  127. package/dist/client.d.ts +9 -4
  128. package/dist/client.js +26 -3
  129. package/dist/configs/tailwind.d.ts +0 -12
  130. package/dist/configs/tailwind.js +28 -15
  131. package/dist/constants/api-endpoints.d.ts +51 -9
  132. package/dist/constants/api-endpoints.js +23 -7
  133. package/dist/constants/index.d.ts +1 -1
  134. package/dist/constants/index.js +1 -1
  135. package/dist/contracts/index.d.ts +1 -1
  136. package/dist/contracts/payment.d.ts +131 -0
  137. package/dist/features/about/components/AboutView.js +1 -1
  138. package/dist/features/about/components/DeveloperView.js +5 -2
  139. package/dist/features/about/components/FAQPageView.js +2 -1
  140. package/dist/features/about/components/FeesView.js +2 -1
  141. package/dist/features/about/components/HelpPageView.js +2 -1
  142. package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
  143. package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
  144. package/dist/features/about/components/HowEmiWorksView.js +2 -1
  145. package/dist/features/about/components/HowOffersWorkView.js +2 -1
  146. package/dist/features/about/components/HowOrdersWorkView.js +2 -1
  147. package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
  148. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
  149. package/dist/features/about/components/HowReviewsWorkView.js +2 -1
  150. package/dist/features/about/components/PolicyPageView.js +2 -1
  151. package/dist/features/about/components/ProseHero.d.ts +73 -0
  152. package/dist/features/about/components/ProseHero.js +18 -0
  153. package/dist/features/about/components/SecurityPrivacyView.js +2 -1
  154. package/dist/features/about/components/ShippingPolicyView.js +2 -1
  155. package/dist/features/about/components/TrackOrderView.js +2 -1
  156. package/dist/features/about/components/UnauthorizedView.js +1 -1
  157. package/dist/features/about/index.d.ts +2 -0
  158. package/dist/features/about/index.js +5 -0
  159. package/dist/features/account/actions/address-actions.d.ts +26 -2
  160. package/dist/features/account/actions/address-actions.js +25 -1
  161. package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
  162. package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
  163. package/dist/features/account/components/UserOrdersView.js +17 -0
  164. package/dist/features/account/components/UserSidebar.js +1 -1
  165. package/dist/features/account/hooks/useNotifications.js +29 -0
  166. package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
  167. package/dist/features/admin/components/AdminBeysView.js +2 -2
  168. package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
  169. package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
  170. package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
  171. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  172. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  173. package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
  174. package/dist/features/admin/components/AdminContactEditorView.js +1 -1
  175. package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
  176. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  177. package/dist/features/admin/components/AdminFaqsView.js +2 -2
  178. package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
  179. package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
  180. package/dist/features/admin/components/AdminGuideHubView.js +1 -1
  181. package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
  182. package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
  183. package/dist/features/admin/components/AdminPartsView.js +2 -2
  184. package/dist/features/admin/components/AdminProductsView.js +75 -4
  185. package/dist/features/admin/components/AdminSidebar.js +2 -2
  186. package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
  187. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
  188. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  189. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
  190. package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
  191. package/dist/features/admin/components/AdminUsersView.js +72 -1
  192. package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
  193. package/dist/features/admin/components/AdminViewCards.js +4 -4
  194. package/dist/features/admin/components/DataListingView.d.ts +28 -0
  195. package/dist/features/admin/components/DataListingView.js +175 -14
  196. package/dist/features/admin/components/DataTable.d.ts +12 -1
  197. package/dist/features/admin/components/DataTable.js +3 -3
  198. package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
  199. package/dist/features/admin/components/OwnerQuickActions.js +60 -2
  200. package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
  201. package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
  202. package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
  203. package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
  204. package/dist/features/admin/components/index.d.ts +4 -0
  205. package/dist/features/admin/components/index.js +6 -0
  206. package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
  207. package/dist/features/admin/constants/filter-tabs.js +106 -0
  208. package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
  209. package/dist/features/admin/repository/site-settings.repository.js +82 -1
  210. package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
  211. package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
  212. package/dist/features/admin/schemas/firestore.js +5 -1
  213. package/dist/features/admin/schemas/site-settings-form.js +30 -1
  214. package/dist/features/auctions/actions/bid-actions.js +13 -1
  215. package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
  216. package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
  217. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
  218. package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
  219. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
  220. package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
  221. package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
  222. package/dist/features/audit-log/schemas/firestore.js +14 -0
  223. package/dist/features/auth/permissions/constants.d.ts +17 -1
  224. package/dist/features/auth/permissions/constants.js +18 -0
  225. package/dist/features/blog/components/BlogPostView.js +1 -1
  226. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
  227. package/dist/features/categories/api/[id]/description-template/route.js +107 -1
  228. package/dist/features/categories/components/BrandDetailPageView.js +2 -2
  229. package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
  230. package/dist/features/categories/components/BundleDetailView.js +1 -1
  231. package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
  232. package/dist/features/categories/components/CategoryForm.js +12 -1
  233. package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
  234. package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
  235. package/dist/features/categories/repository/market-price-index.repository.js +105 -0
  236. package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
  237. package/dist/features/categories/repository/price-observation.repository.js +132 -0
  238. package/dist/features/events/components/EventSaleBanner.js +1 -1
  239. package/dist/features/events/components/EventStatusBadge.js +1 -1
  240. package/dist/features/faq/components/FAQAccordion.js +2 -1
  241. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  242. package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
  243. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  244. package/dist/features/filters/FilterFacetSection.js +1 -1
  245. package/dist/features/filters/SwitchFilter.js +1 -1
  246. package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
  247. package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
  248. package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
  249. package/dist/features/gateway-events/schemas/firestore.js +125 -0
  250. package/dist/features/gateway-events/schemas/index.d.ts +81 -0
  251. package/dist/features/gateway-events/schemas/index.js +79 -0
  252. package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
  253. package/dist/features/homepage/components/AnnouncementBar.js +37 -1
  254. package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
  255. package/dist/features/homepage/components/BrandsSection.js +1 -1
  256. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  257. package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
  258. package/dist/features/homepage/components/HeroCarousel.js +2 -2
  259. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  260. package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
  261. package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
  262. package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
  263. package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
  264. package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
  265. package/dist/features/inventory/components/ReceiveStationView.js +413 -0
  266. package/dist/features/inventory/components/operator-message.d.ts +29 -0
  267. package/dist/features/inventory/components/operator-message.js +41 -0
  268. package/dist/features/inventory/index.d.ts +13 -0
  269. package/dist/features/inventory/index.js +28 -0
  270. package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
  271. package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
  272. package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
  273. package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
  274. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
  275. package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
  276. package/dist/features/inventory/schemas/firestore.d.ts +197 -0
  277. package/dist/features/inventory/schemas/firestore.js +159 -0
  278. package/dist/features/layout/AppLayoutShell.d.ts +12 -1
  279. package/dist/features/layout/AppLayoutShell.js +25 -12
  280. package/dist/features/layout/AutoBreadcrumbs.js +162 -3
  281. package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
  282. package/dist/features/layout/BottomNavbar.d.ts +1 -1
  283. package/dist/features/layout/BottomNavbar.js +2 -2
  284. package/dist/features/media/MediaAvatar.js +1 -1
  285. package/dist/features/media/MediaImage.d.ts +24 -4
  286. package/dist/features/media/MediaImage.js +44 -4
  287. package/dist/features/media/MediaLightbox.js +1 -1
  288. package/dist/features/media/modals/ImageCropModal.js +1 -1
  289. package/dist/features/media/modals/ImageEditor.js +1 -1
  290. package/dist/features/media/upload/MediaUploadField.js +91 -3
  291. package/dist/features/obligations/constants/policies.d.ts +92 -0
  292. package/dist/features/obligations/constants/policies.js +378 -0
  293. package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
  294. package/dist/features/obligations/repository/obligations.repository.js +158 -0
  295. package/dist/features/obligations/schemas/firestore.d.ts +160 -0
  296. package/dist/features/obligations/schemas/firestore.js +87 -0
  297. package/dist/features/orders/actions/order-actions.d.ts +43 -4
  298. package/dist/features/orders/actions/order-actions.js +60 -3
  299. package/dist/features/orders/actions/refund-actions.js +70 -10
  300. package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
  301. package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
  302. package/dist/features/orders/components/OrdersList.js +2 -2
  303. package/dist/features/orders/components/RefundHistoryTable.js +3 -1
  304. package/dist/features/orders/components/index.d.ts +2 -0
  305. package/dist/features/orders/components/index.js +6 -0
  306. package/dist/features/orders/constants/transitions.d.ts +59 -0
  307. package/dist/features/orders/constants/transitions.js +104 -0
  308. package/dist/features/orders/repository/orders.repository.d.ts +109 -6
  309. package/dist/features/orders/repository/orders.repository.js +464 -21
  310. package/dist/features/orders/schemas/firestore.d.ts +270 -0
  311. package/dist/features/orders/schemas/firestore.js +24 -0
  312. package/dist/features/orders/schemas/index.d.ts +61 -0
  313. package/dist/features/orders/schemas/index.js +22 -0
  314. package/dist/features/orders/types/index.d.ts +79 -0
  315. package/dist/features/parts/components/PartsIndexPageView.js +8 -1
  316. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
  317. package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
  318. package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
  319. package/dist/features/payment-cases/schemas/firestore.js +105 -0
  320. package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
  321. package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
  322. package/dist/features/payments/repository/payout.repository.d.ts +0 -1
  323. package/dist/features/payments/repository/payout.repository.js +0 -1
  324. package/dist/features/points/repository/points.repository.d.ts +122 -0
  325. package/dist/features/points/repository/points.repository.js +304 -1
  326. package/dist/features/points/schemas/adjust-form.d.ts +58 -0
  327. package/dist/features/points/schemas/adjust-form.js +63 -0
  328. package/dist/features/points/schemas/firestore.d.ts +108 -1
  329. package/dist/features/points/schemas/firestore.js +84 -0
  330. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
  331. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  332. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
  333. package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
  334. package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
  335. package/dist/features/price-index/market-stats.d.ts +82 -0
  336. package/dist/features/price-index/market-stats.js +230 -0
  337. package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
  338. package/dist/features/print/components/BoxLabelPrintView.js +66 -0
  339. package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
  340. package/dist/features/print/components/LabelProfilePicker.js +38 -0
  341. package/dist/features/print/components/labels.d.ts +117 -0
  342. package/dist/features/print/components/labels.js +258 -0
  343. package/dist/features/print/components/labels.style.css +46 -0
  344. package/dist/features/print/index.d.ts +6 -0
  345. package/dist/features/print/index.js +16 -0
  346. package/dist/features/products/columns/productTableColumns.js +5 -4
  347. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  348. package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
  349. package/dist/features/products/components/PrizeDrawCollage.js +1 -1
  350. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  351. package/dist/features/products/components/PrizeRevealModal.js +2 -2
  352. package/dist/features/products/components/ProductDetailPageView.js +18 -4
  353. package/dist/features/products/components/ProductForm.js +34 -23
  354. package/dist/features/products/components/ProductGrid.js +86 -62
  355. package/dist/features/products/constants/card-badges.d.ts +97 -0
  356. package/dist/features/products/constants/card-badges.js +100 -0
  357. package/dist/features/products/repository/products.repository.js +34 -1
  358. package/dist/features/products/schemas/firestore.d.ts +46 -3
  359. package/dist/features/products/schemas/firestore.js +21 -0
  360. package/dist/features/promotions/components/PromotionsView.js +1 -1
  361. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
  362. package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
  363. package/dist/features/promotions/schemas/firestore.js +30 -3
  364. package/dist/features/promotions/schemas/index.d.ts +6 -6
  365. package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
  366. package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
  367. package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
  368. package/dist/features/protection-claims/schemas/firestore.js +130 -0
  369. package/dist/features/reviews/actions/review-actions.js +3 -2
  370. package/dist/features/reviews/components/ReviewModal.js +1 -1
  371. package/dist/features/reviews/components/ReviewsList.js +1 -1
  372. package/dist/features/reviews/schemas/firestore.d.ts +20 -1
  373. package/dist/features/scams/constants/scam-types.d.ts +2 -0
  374. package/dist/features/scams/constants/scam-types.js +18 -0
  375. package/dist/features/scams/schemas/report-form.d.ts +3 -3
  376. package/dist/features/scams/schemas/report-form.js +26 -1
  377. package/dist/features/search/components/Search.js +9 -9
  378. package/dist/features/search/components/SearchResultsClient.js +18 -3
  379. package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
  380. package/dist/features/search/components/SearchResultsPageView.js +2 -2
  381. package/dist/features/seller/actions/offer-actions.js +16 -1
  382. package/dist/features/seller/actions/seller-actions.js +14 -3
  383. package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
  384. package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
  385. package/dist/features/seller/components/PrintCenterView.js +41 -30
  386. package/dist/features/seller/components/SellerOrdersView.js +1 -1
  387. package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
  388. package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
  389. package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
  390. package/dist/features/seller/components/SellerProductShell.js +123 -13
  391. package/dist/features/seller/components/SellerReviewsView.js +4 -2
  392. package/dist/features/seller/components/SellerSidebar.js +1 -1
  393. package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
  394. package/dist/features/seller/schemas/coupon-form.js +27 -0
  395. package/dist/features/seller/schemas/product-form.d.ts +3 -0
  396. package/dist/features/seller/schemas/product-form.js +5 -0
  397. package/dist/features/shell/FormShell.js +2 -2
  398. package/dist/features/shell/QuickFormDrawer.js +14 -0
  399. package/dist/features/shell/SectionForm.d.ts +19 -0
  400. package/dist/features/shell/SectionForm.js +133 -9
  401. package/dist/features/shell/SectionForm.style.css +54 -0
  402. package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
  403. package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
  404. package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
  405. package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
  406. package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
  407. package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
  408. package/dist/features/stores/components/StoreGuideHubView.js +1 -1
  409. package/dist/features/stores/components/StoreHeader.js +1 -1
  410. package/dist/features/support/schemas/firestore.d.ts +73 -2
  411. package/dist/features/support/schemas/firestore.js +59 -0
  412. package/dist/index.d.ts +16 -24
  413. package/dist/index.js +38 -47
  414. package/dist/next/ErrorBoundary.js +1 -1
  415. package/dist/next/routing/route-map.d.ts +24 -0
  416. package/dist/next/routing/route-map.js +40 -0
  417. package/dist/providers/payment-manual/index.d.ts +15 -1
  418. package/dist/providers/payment-manual/index.js +37 -0
  419. package/dist/providers/payment-phonepe/index.d.ts +14 -1
  420. package/dist/providers/payment-phonepe/index.js +36 -0
  421. package/dist/providers/payment-razorpay/index.d.ts +44 -1
  422. package/dist/providers/payment-razorpay/index.js +99 -0
  423. package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
  424. package/dist/providers/shipping-shiprocket/index.js +18 -0
  425. package/dist/schemas/registry.d.ts +44 -11
  426. package/dist/server-entry.d.ts +2 -0
  427. package/dist/server-entry.js +27 -0
  428. package/dist/server.d.ts +42 -0
  429. package/dist/server.js +93 -0
  430. package/dist/styles.css +418 -149
  431. package/dist/tailwind-utilities.css +1 -1
  432. package/dist/tokens/themes/default-dark.js +15 -12
  433. package/dist/tokens/themes/default-light.js +14 -11
  434. package/dist/tokens/tokens.css +106 -23
  435. package/dist/ui/DataTable.style.css +4 -4
  436. package/dist/ui/columns/cell-renderers.d.ts +20 -0
  437. package/dist/ui/columns/cell-renderers.js +26 -1
  438. package/dist/ui/columns/index.d.ts +1 -1
  439. package/dist/ui/columns/index.js +4 -1
  440. package/dist/ui/components/Badge.style.css +1 -1
  441. package/dist/ui/components/Breadcrumb.js +19 -1
  442. package/dist/ui/components/BulkActionBar.style.css +4 -4
  443. package/dist/ui/components/Button.style.css +1 -1
  444. package/dist/ui/components/Checkbox.style.css +1 -1
  445. package/dist/ui/components/FallbackShell.js +1 -1
  446. package/dist/ui/components/Form.d.ts +14 -1
  447. package/dist/ui/components/Form.js +2 -2
  448. package/dist/ui/components/FormField.js +18 -4
  449. package/dist/ui/components/FormField.style.css +43 -3
  450. package/dist/ui/components/GatedPrice.style.css +1 -1
  451. package/dist/ui/components/IconButton.style.css +1 -1
  452. package/dist/ui/components/Input.js +22 -1
  453. package/dist/ui/components/Input.style.css +38 -22
  454. package/dist/ui/components/ListingFilterDrawer.js +1 -1
  455. package/dist/ui/components/ListingToolbar.js +1 -1
  456. package/dist/ui/components/PaginatedSelect.js +0 -0
  457. package/dist/ui/components/Radio.style.css +1 -1
  458. package/dist/ui/components/Repeater.d.ts +53 -0
  459. package/dist/ui/components/Repeater.js +7 -0
  460. package/dist/ui/components/RichTextEditor.d.ts +20 -1
  461. package/dist/ui/components/RichTextEditor.js +23 -2
  462. package/dist/ui/components/Select.style.css +7 -21
  463. package/dist/ui/components/Semantic.js +27 -3
  464. package/dist/ui/components/TagInput.style.css +4 -9
  465. package/dist/ui/components/Textarea.style.css +4 -18
  466. package/dist/ui/components/Toggle.style.css +1 -1
  467. package/dist/ui/components/Typography.d.ts +3 -3
  468. package/dist/ui/components/Typography.js +15 -15
  469. package/dist/ui/components/ViewToggle.style.css +4 -4
  470. package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
  471. package/dist/ui/forms/AddAnotherToggle.js +56 -0
  472. package/dist/ui/forms/ColorPickerField.js +15 -2
  473. package/dist/ui/forms/FieldCheckbox.js +15 -2
  474. package/dist/ui/forms/FieldInput.d.ts +22 -1
  475. package/dist/ui/forms/FieldInput.js +19 -5
  476. package/dist/ui/forms/FieldLabel.d.ts +35 -0
  477. package/dist/ui/forms/FieldLabel.js +70 -0
  478. package/dist/ui/forms/FieldSelect.d.ts +4 -1
  479. package/dist/ui/forms/FieldSelect.js +27 -5
  480. package/dist/ui/forms/FieldTextarea.d.ts +4 -1
  481. package/dist/ui/forms/FieldTextarea.js +22 -5
  482. package/dist/ui/forms/FormShell.d.ts +17 -1
  483. package/dist/ui/forms/FormShell.js +36 -2
  484. package/dist/ui/forms/FormShell.style.css +41 -33
  485. package/dist/ui/forms/index.d.ts +5 -1
  486. package/dist/ui/forms/index.js +2 -0
  487. package/dist/ui/icons/icon-registry.d.ts +1 -0
  488. package/dist/ui/icons/icon-registry.js +17 -1
  489. package/dist/utils/id-generators.d.ts +80 -0
  490. package/dist/utils/id-generators.js +93 -0
  491. package/dist/utils/search-txt-builders.d.ts +12 -0
  492. package/dist/utils/search-txt-builders.js +17 -0
  493. package/package.json +1 -1
  494. package/scripts/seed-cli.mjs +106 -5
  495. package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
  496. package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
  497. package/dist/features/loyalty/api/balance/route.d.ts +0 -12
  498. package/dist/features/loyalty/api/balance/route.js +0 -41
  499. package/dist/features/loyalty/api/earn/route.d.ts +0 -12
  500. package/dist/features/loyalty/api/earn/route.js +0 -38
  501. package/dist/features/loyalty/api/history/route.d.ts +0 -12
  502. package/dist/features/loyalty/api/history/route.js +0 -58
  503. package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
  504. package/dist/features/loyalty/api/redeem/route.js +0 -38
  505. package/dist/features/loyalty/columns/index.d.ts +0 -17
  506. package/dist/features/loyalty/columns/index.js +0 -40
  507. package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
  508. package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
  509. package/dist/features/loyalty/components/index.d.ts +0 -1
  510. package/dist/features/loyalty/components/index.js +0 -1
  511. package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
  512. package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
  513. package/dist/features/loyalty/index.d.ts +0 -6
  514. package/dist/features/loyalty/index.js +0 -6
  515. package/dist/features/loyalty/manifest.d.ts +0 -2
  516. package/dist/features/loyalty/manifest.js +0 -16
  517. package/dist/features/loyalty/messages/en.json +0 -19
  518. package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
  519. package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
  520. package/dist/features/loyalty/schemas/index.d.ts +0 -85
  521. package/dist/features/loyalty/schemas/index.js +0 -40
  522. package/dist/features/loyalty/server.d.ts +0 -6
  523. package/dist/features/loyalty/server.js +0 -6
  524. package/dist/features/loyalty/types/index.d.ts +0 -31
  525. package/dist/features/loyalty/types/index.js +0 -1
  526. package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
  527. package/dist/features/loyalty/types/loyalty-config.js +0 -1
  528. package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
  529. package/dist/features/loyalty/types/loyalty-math.js +0 -27
  530. package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
  531. package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
@@ -303,6 +303,44 @@ export interface OrderRefundEvent {
303
303
  reasonCode?: ReturnReason;
304
304
  refundedAt: Date;
305
305
  refundedBy: string;
306
+ /**
307
+ * Lifecycle of this refund entry. **Optional on purpose** — every row
308
+ * written before the two-phase scheme (2026-10-21) has none, and those are
309
+ * all committed refunds, so a missing status must COUNT as committed.
310
+ *
311
+ * · `reserved` a slot was claimed and the provider call is in flight. The
312
+ * amount is already spoken for, so it counts toward the
313
+ * cumulative cap — that is what closes the TOCTOU.
314
+ * · `processed` the provider confirmed. Money moved.
315
+ * · `failed` the provider refused. The reservation is RELEASED simply by
316
+ * being skipped in the cumulative sum, which is why there is
317
+ * no explicit release step to forget.
318
+ *
319
+ * A `reserved` entry that never settles is a crash between the provider call
320
+ * and our write — detectable, and exactly what the reconciler looks for.
321
+ */
322
+ status?: "reserved" | "processed" | "failed";
323
+ /** Why the provider refused, when `status === "failed"`. */
324
+ failureReason?: string;
325
+ /**
326
+ * The gateway's own refund reference, whichever gateway ran.
327
+ *
328
+ * 🛑 ADDED 2026-10-21 because reconciliation was impossible (D7). Razorpay's
329
+ * refund id was written to **`phonepeRefundId`** unconditionally — the
330
+ * action did `phonepeRefundId = result.id` with no branch on provider — while
331
+ * the declared `razorpayRefundId` was written by NOTHING, and
332
+ * `RefundHistoryTable` rendered no reference at all for a Razorpay refund.
333
+ * So a refund existed in Razorpay's dashboard with no way to tie it to ours.
334
+ *
335
+ * This is the field a reconciler reads, and it is gateway-BLIND on purpose:
336
+ * a reconciler that has to know which provider ran before it can find the id
337
+ * is a reconciler that breaks on the next provider. The two
338
+ * provider-specific fields below stay, populated only by the provider that
339
+ * actually produced the id, for operators who search a specific dashboard.
340
+ */
341
+ gatewayRefundId?: string;
342
+ /** Which gateway produced `gatewayRefundId` (`payment.name`). */
343
+ gateway?: string;
306
344
  /** Set when PhonePe processed the refund. */
307
345
  phonepeRefundId?: string;
308
346
  /** Set when Razorpay processed the refund (`rfnd_…`). Mutually exclusive with `phonepeRefundId` — one online gateway runs at a time. */
@@ -371,8 +409,78 @@ export interface OrderDocument extends BaseDocument {
371
409
  trackingNumber?: string;
372
410
  notes?: string;
373
411
  orderDate: Date;
412
+ /**
413
+ * When the SELLER accepted the order — the first fact in the fulfilment
414
+ * lifecycle, and it did not exist before Phase 5b.
415
+ *
416
+ * 🛑 D30: there was no seller-acceptance step at all. `customShipOrder`
417
+ * requires `status === "confirmed"` and **nothing ever set `confirmed` on a
418
+ * paid order** except an admin PATCH, while `onOrderCreate` wrote one admin
419
+ * notification and stopped. So a seller could silently ignore a paid order
420
+ * forever and no clock anywhere noticed.
421
+ *
422
+ * Its presence is what distinguishes "the seller has not looked at this yet"
423
+ * from "the seller accepted it and has not packed it" — two different
424
+ * obligations with two different deadlines (`seller-accept` then
425
+ * `seller-dispatch`), which is unexpressible with a single status field.
426
+ */
427
+ acceptedAt?: Date;
374
428
  shippingDate?: Date;
375
429
  deliveryDate?: Date;
430
+ /**
431
+ * When the order was marked COMPLETE — the fact that awards points and
432
+ * closes the dispute window.
433
+ *
434
+ * 🛑 Owner's rule, 2026-10-21: *"auto assigned after 7 days of delivery, when
435
+ * order is marked complete; if review is given and order marked complete by
436
+ * the buyer before — immediate disburse."*
437
+ *
438
+ * So there are two writers and they are not equivalent:
439
+ *
440
+ * | writer | when | `completedBy` |
441
+ * |---|---|---|
442
+ * | `obligationSweep` | 7 days after delivery, nothing contested | `"system"` |
443
+ * | `markOrderCompleteAction` | the buyer, having left a review | their uid |
444
+ *
445
+ * The buyer's path is the FAST one — it skips the remaining wait, which is
446
+ * what "immediate disburse" asks for. And because `payout-release` is
447
+ * `blockedBy: ["order-complete", …]`, an early completion opens the seller's
448
+ * payout gate early **with no extra mechanism**: the buyer confirming
449
+ * satisfaction is exactly the signal a quiet period exists to wait for.
450
+ *
451
+ * A FACT, never a deadline — the 7-day deadline itself stays derived
452
+ * (`deadlinesFor`), so changing the period does not need a backfill.
453
+ */
454
+ completedAt?: Date;
455
+ /** `"system"` for the timer, or the buyer's uid for the fast path. */
456
+ completedBy?: string;
457
+ /**
458
+ * When purchase points were credited for this order.
459
+ *
460
+ * ## 🛑 THE IDEMPOTENCY KEY, and it is the whole reason the award exists
461
+ *
462
+ * `pointsLedger` is append-only and `pointsRepository.append` takes no key,
463
+ * so an append does not deduplicate itself. Completion has TWO triggers —
464
+ * the buyer's fast path and the 7-day `order-complete` sweep — and a double
465
+ * fire would credit twice **permanently, with no way to net it off.**
466
+ *
467
+ * Both triggers check this field before awarding and write it after, which
468
+ * is the same mechanism `order.shippingReconciliation` already provides for
469
+ * the points credit on shipping savings: the marker is written in the same
470
+ * step as the credit precisely so it can be the key.
471
+ *
472
+ * It is also set on an order that earned ZERO (fully cancelled, zero value),
473
+ * so the sweep stops revisiting it — "we looked and there was nothing to
474
+ * give" is a decision, and leaving it unmarked re-reads that order on every
475
+ * tick forever.
476
+ */
477
+ pointsAwardedAt?: Date;
478
+ /**
479
+ * How many points were credited. Recorded for the seller's payout deduction
480
+ * and for explaining a balance, so neither has to re-derive a percentage of a
481
+ * figure the order may since have changed.
482
+ */
483
+ pointsAwarded?: number;
376
484
  cancellationDate?: Date;
377
485
  cancellationReason?: string;
378
486
  /**
@@ -414,6 +522,21 @@ export interface OrderDocument extends BaseDocument {
414
522
  returnDestination?: "warehouse" | "seller";
415
523
  /** The address the buyer was given, resolved once and recorded verbatim. */
416
524
  returnAddress?: string;
525
+ /**
526
+ * When the seller APPROVED the return — the anchor the buyer's posting
527
+ * deadline is measured from.
528
+ *
529
+ * 🛑 Added for Phase 5b, and its absence was load-bearing: without it, "the
530
+ * buyer has 7 days to post an approved return" had nothing to count from, so
531
+ * the only available anchor was `returnRequestedAt` — which starts the
532
+ * buyer's clock while the seller is still deciding, i.e. a seller who takes
533
+ * 48 hours to approve silently eats two days of the buyer's window.
534
+ *
535
+ * A FACT, never a deadline. Deadlines are derived (`deadlinesFor`), never
536
+ * stored — a stored deadline needs a backfill and drifts from the policy the
537
+ * day somebody edits one (Root Cause #42).
538
+ */
539
+ returnApprovedAt?: Date;
417
540
  /** Set when the buyer marks it posted; `in_transit` without one is a bug. */
418
541
  returnPostedAt?: Date;
419
542
  returnReceivedAt?: Date;
@@ -448,6 +571,37 @@ export interface OrderDocument extends BaseDocument {
448
571
  /** Full list of all applied coupons/discounts for this order group */
449
572
  appliedDiscounts?: AppliedOrderDiscount[];
450
573
  platformFee?: number;
574
+ /**
575
+ * GST charged on the platform fee, in decimal rupees.
576
+ *
577
+ * 🛑 ADDED 2026-10-21 because its ABSENCE made a refund over-deduct by ~10x.
578
+ *
579
+ * This was computed at checkout (`gstOnFee`), charged to the buyer as its own
580
+ * term in `orderTotal`, and then folded into `gstAmount` — so the order
581
+ * recorded the combined figure and no field held the fee's own tax. The
582
+ * platform fee is non-refundable by policy, so a refund has to withhold
583
+ * `platformFee + its GST`, and with the second half unavailable
584
+ * `previewCancellationRefund` re-derived BOTH from live percentages:
585
+ *
586
+ * effectiveRate = platformFeePercent × (1 + gstPercent / 100)
587
+ * feeDeducted = grossRefund × effectiveRate / 100
588
+ *
589
+ * That ignores `commissions.platformFeeMax` (default **₹10**) entirely, so on
590
+ * a ₹5,000 order it withheld **₹118** from a buyer who had paid **₹11.80** —
591
+ * keeping ~₹106 of their goods money and calling it a platform fee. The
592
+ * error grows with order value.
593
+ *
594
+ * Stored rather than re-derived for the same reason every other agreed term
595
+ * is: the rate in force when the order was placed is the rate that governs
596
+ * it. `platformFeeWithheld()` reads this field and falls back to deriving it
597
+ * only for orders written before it existed.
598
+ *
599
+ * 🛑 Note the ASYMMETRY with product GST, which is deliberate: product
600
+ * prices are tax-INCLUSIVE so their tax is backed out for reporting, while
601
+ * this is GST on OUR service fee charged to the buyer ON TOP of the fee. See
602
+ * the note above `orderTotal` in `createOrderForGroup`.
603
+ */
604
+ platformFeeGst?: number;
451
605
  depositAmount?: number;
452
606
  codRemainingAmount?: number;
453
607
  /** COD handling fee charged to the buyer: min(subtotal × codHandlingFeePercent / 100, codHandlingFeeCap). Only set when paymentMethod === "cod". */
@@ -542,6 +696,26 @@ export interface OrderDocument extends BaseDocument {
542
696
  emiTokenAmount?: number;
543
697
  /** Extra cost of choosing EMI over full payment, in decimal rupees — split between platform and seller. */
544
698
  emiSurchargeAmount?: number;
699
+ /**
700
+ * The SELLER's share of the EMI surcharge, in decimal rupees.
701
+ *
702
+ * 🛑 D45, the half that is a data gap rather than a commercial decision.
703
+ * `computeEmiSchedule` computes `surchargeSellerShare` (from
704
+ * `emi.surchargeSellerSharePercent`, seeded at 50) and it was **persisted
705
+ * nowhere** — so the split existed as a setting, a form field and a returned
706
+ * value with no field to land in and therefore no reader in the payout path.
707
+ * The platform kept 100% of a surcharge it had already decided to split.
708
+ *
709
+ * 🛑 Persisting it moves NO money on its own, and that is deliberate.
710
+ * Whether the seller is actually PAID this — along with shipping and the COD
711
+ * handling fee, the other two D45 terms — is a commercial decision about who
712
+ * keeps which revenue, and it is the owner's to make, not a defect to quietly
713
+ * fix. What was broken is that the decision had already been made (the
714
+ * setting exists, defaulted to 50%) and the number was then thrown away. Now
715
+ * it is recorded, so honouring it is a payout change rather than an
716
+ * archaeology exercise.
717
+ */
718
+ emiSurchargeSellerShare?: number;
545
719
  emiInstallments?: EmiInstallment[];
546
720
  /** Sum of unpaid installment amounts, in decimal rupees. 0 once all installments are paid. */
547
721
  emiRemainingBalance?: number;
@@ -588,6 +762,56 @@ export interface OrderDocument extends BaseDocument {
588
762
  shippingReconciliation?: ShippingReconciliation & {
589
763
  reconciledAt: Date;
590
764
  };
765
+ /**
766
+ * Did WE book this shipment through the Shiprocket integration?
767
+ *
768
+ * 🛑 The discriminator for whether postage may be reimbursed at all, and it
769
+ * must be a fact about the BOOKING rather than about the evidence — see
770
+ * `isReimbursableShipment`. If reimbursement were gated on "a receipt
771
+ * exists", a seller could upload a receipt for a parcel the platform paid
772
+ * for and be reimbursed for our spend.
773
+ *
774
+ * Written by the integration at booking time. Absent means nobody recorded a
775
+ * platform booking, which for a self-shipped parcel is correct and still
776
+ * requires evidence and approval before anything is paid.
777
+ */
778
+ platformBookedShipment?: boolean;
779
+ /**
780
+ * The self-shipped reimbursement workflow: evidence in, approved amount out.
781
+ *
782
+ * ## 🛑 `declaredAmount` is an ESTIMATE; `approvedAmount` is the entitlement
783
+ *
784
+ * Owner, 2026-10-21: *"The seller may set an initial value of shipping but
785
+ * the only approved amount will be given to them."* So a seller who quotes
786
+ * ₹120 and posts for ₹80 is reimbursed ₹80 — the two numbers are different
787
+ * things and must never be conflated, which is why they are separate fields
788
+ * rather than one that gets overwritten.
789
+ *
790
+ * `approvedAmount` is absent until an admin approves. A missing value means
791
+ * "not yet decided", never zero: defaulting it to 0 would make an
792
+ * un-reviewed claim indistinguishable from a rejected one, and the payout
793
+ * base reads this field.
794
+ *
795
+ * 🛑 **`approvedBy` must never be `"system"`.** Approving a reimbursement
796
+ * moves money to a seller on the strength of a document a human has to look
797
+ * at. Same rule, and the same reason, as `paymentCases.resolve()` refusing a
798
+ * system resolver.
799
+ */
800
+ shippingReimbursement?: {
801
+ /** What the seller says it cost. An estimate, not an entitlement. */
802
+ declaredAmount: number;
803
+ /** Receipt / postage slip. Uploaded by the seller. */
804
+ evidenceUrl?: string;
805
+ /** The tracking number on that receipt — ties the evidence to the parcel. */
806
+ trackingNumber?: string;
807
+ submittedAt: Date;
808
+ /** Present only once an admin has decided. Absent ≠ zero. */
809
+ approvedAmount?: number;
810
+ approvedBy?: string;
811
+ approvedAt?: Date;
812
+ /** Required when the approved amount differs from the declared one. */
813
+ approvalNote?: string;
814
+ };
591
815
  /**
592
816
  * The carrier's label PDF, once a shipment has been booked.
593
817
  *
@@ -778,6 +1002,28 @@ export interface OrderDocument extends BaseDocument {
778
1002
  }[];
779
1003
  /** Set true only when an automatic partial refund (for dropped Razorpay items) failed and needs manual follow-up. */
780
1004
  refundPending?: boolean;
1005
+ /**
1006
+ * Marks an order created by the tester harness.
1007
+ *
1008
+ * 🛑 DECLARED LATE: three readers already depended on it —
1009
+ * `deadlinesFor()`, `protection-claims/actions.ts` and
1010
+ * `orders.repository.ts` — while `OrderDocument` never carried the field,
1011
+ * so all three were type errors. The intent is documented in
1012
+ * `obligations/deadlines.ts`: a test order COMPRESSES its obligation
1013
+ * windows, so a tester can watch a deadline lapse inside one run instead of
1014
+ * waiting the real number of days.
1015
+ *
1016
+ * 🛑 This does NOT enrol orders in the test-data purge. `runTestDataCleanup`
1017
+ * deliberately leaves `orders`/`reviews`/`wishlists`/`history` alone — they
1018
+ * denormalise what they display, so a swept order would leave a
1019
+ * half-rendered row rather than disappear. The flag is read for timing, not
1020
+ * for deletion, and adding it to `TEST_DATA_COLLECTIONS` would be a
1021
+ * different and much larger decision.
1022
+ *
1023
+ * Optional, so no migration: every existing order reads `undefined`, which
1024
+ * `deadlinesFor` tests with `=== true`.
1025
+ */
1026
+ isTestData?: boolean;
781
1027
  }
782
1028
  export type OrderPaymentRecordMethod = "manual" | "phonepe" | "razorpay" | "cod";
783
1029
  export type OrderPaymentVerificationMethod = "manual_review" | "webhook" | "cod_collection" | "order_status";
@@ -810,6 +1056,30 @@ export interface OrderPaymentRecord {
810
1056
  };
811
1057
  }
812
1058
  export declare const ORDER_COLLECTION: "orders";
1059
+ /**
1060
+ * At-most-once gate for refunds. Document id = `sha256(idempotencyKey)`,
1061
+ * claimed with `.create()` BEFORE any provider call.
1062
+ *
1063
+ * 🛑 A claim is deliberately NOT released on failure. Surviving a crash is the
1064
+ * whole point: it stops a retry from issuing a second provider call for a
1065
+ * refund that may already have succeeded at the gateway. An unsettled claim
1066
+ * older than an hour is a crash between "provider called" and "entry settled",
1067
+ * and resolving it means READING the gateway, never guessing — that is Phase
1068
+ * 4's R3 reconciler.
1069
+ *
1070
+ * Classified **PRESERVE** in the tester tier (`tester/scripts/lib/collections.mjs`)
1071
+ * because it is the only record that a refund was attempted and wiping it
1072
+ * would let a replay re-refund.
1073
+ *
1074
+ * 🛑 It deliberately gets NO `SEED_COLLECTION_PURPOSE` entry, and that is not
1075
+ * an oversight. `audit-seed-purpose`'s R1 requires that registry to match
1076
+ * `COLLECTION_MAP` EXACTLY in both directions — a key for a collection the
1077
+ * seeder never writes is a DEAD entry, the same shape as the `offers` entry in
1078
+ * `TEST_DATA_COLLECTIONS` that could only ever match zero rows while reading
1079
+ * as coverage. This collection has no seed data, so the tester tier is the
1080
+ * only list it belongs in. (I added it to both first; R1 would have failed.)
1081
+ */
1082
+ export declare const REFUND_CLAIMS_COLLECTION: "refundClaims";
813
1083
  export declare const ORDER_INDEXED_FIELDS: readonly ["searchTxt", "userId", "productId", "storeId", "status", "paymentStatus", "payoutStatus", "shippingMethod", "orderDate", "createdAt", "assignedWorkerId", "pickedAt", "packedAt"];
814
1084
  export declare const DEFAULT_ORDER_DATA: Partial<OrderDocument>;
815
1085
  export declare const ORDER_PUBLIC_FIELDS: readonly ["id", "productId", "productTitle", "quantity", "unitPrice", "totalPrice", "currency", "status", "paymentStatus", "shippingAddress", "trackingNumber", "notes", "orderDate", "shippingDate", "deliveryDate", "createdAt"];
@@ -49,6 +49,30 @@ export const RefundStatusValues = {
49
49
  REJECTED: "rejected",
50
50
  };
51
51
  export const ORDER_COLLECTION = "orders";
52
+ /**
53
+ * At-most-once gate for refunds. Document id = `sha256(idempotencyKey)`,
54
+ * claimed with `.create()` BEFORE any provider call.
55
+ *
56
+ * 🛑 A claim is deliberately NOT released on failure. Surviving a crash is the
57
+ * whole point: it stops a retry from issuing a second provider call for a
58
+ * refund that may already have succeeded at the gateway. An unsettled claim
59
+ * older than an hour is a crash between "provider called" and "entry settled",
60
+ * and resolving it means READING the gateway, never guessing — that is Phase
61
+ * 4's R3 reconciler.
62
+ *
63
+ * Classified **PRESERVE** in the tester tier (`tester/scripts/lib/collections.mjs`)
64
+ * because it is the only record that a refund was attempted and wiping it
65
+ * would let a replay re-refund.
66
+ *
67
+ * 🛑 It deliberately gets NO `SEED_COLLECTION_PURPOSE` entry, and that is not
68
+ * an oversight. `audit-seed-purpose`'s R1 requires that registry to match
69
+ * `COLLECTION_MAP` EXACTLY in both directions — a key for a collection the
70
+ * seeder never writes is a DEAD entry, the same shape as the `offers` entry in
71
+ * `TEST_DATA_COLLECTIONS` that could only ever match zero rows while reading
72
+ * as coverage. This collection has no seed data, so the tester tier is the
73
+ * only list it belongs in. (I added it to both first; R1 would have failed.)
74
+ */
75
+ export const REFUND_CLAIMS_COLLECTION = "refundClaims";
52
76
  export const ORDER_INDEXED_FIELDS = [
53
77
  "searchTxt",
54
78
  "userId",
@@ -107,12 +107,26 @@ export declare const orderDocumentItemSchema: z.ZodObject<{
107
107
  listingType?: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live" | undefined;
108
108
  prizeRevealStatus?: "closed" | "open" | "pending" | "revealed" | undefined;
109
109
  }>;
110
+ /**
111
+ * Mirror of `OrderRefundEvent`.
112
+ *
113
+ * 🛑 THIS HAD ALREADY DRIFTED, and silently in the dangerous direction.
114
+ * `z.object()` STRIPS unknown keys, so a field present on the interface and
115
+ * absent here is **removed on parse** — it does not error, it vanishes. Before
116
+ * 2026-10-21 it was missing `reasonCode` AND `razorpayRefundId`, which means a
117
+ * Razorpay refund reference would have been discarded by the very schema meant
118
+ * to validate it.
119
+ *
120
+ * Keep this in lockstep with the interface. When adding a field there, add it
121
+ * here in the same change.
122
+ */
110
123
  export declare const orderRefundEventSchema: z.ZodObject<{
111
124
  refundId: z.ZodString;
112
125
  type: z.ZodEnum<["full", "partial"]>;
113
126
  amount: z.ZodEffects<z.ZodNumber, number, number>;
114
127
  itemIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
115
128
  reason: z.ZodString;
129
+ reasonCode: z.ZodOptional<z.ZodString>;
116
130
  refundedAt: z.ZodUnion<[z.ZodDate, z.ZodString, z.ZodObject<{
117
131
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
118
132
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
@@ -121,7 +135,12 @@ export declare const orderRefundEventSchema: z.ZodObject<{
121
135
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
122
136
  }, z.ZodTypeAny, "passthrough">>]>;
123
137
  refundedBy: z.ZodString;
138
+ status: z.ZodOptional<z.ZodEnum<["reserved", "processed", "failed"]>>;
139
+ failureReason: z.ZodOptional<z.ZodString>;
140
+ gatewayRefundId: z.ZodOptional<z.ZodString>;
141
+ gateway: z.ZodOptional<z.ZodString>;
124
142
  phonepeRefundId: z.ZodOptional<z.ZodString>;
143
+ razorpayRefundId: z.ZodOptional<z.ZodString>;
125
144
  manualTransactionId: z.ZodOptional<z.ZodString>;
126
145
  proofDocumentUrl: z.ZodOptional<z.ZodString>;
127
146
  proofDocumentMimeType: z.ZodOptional<z.ZodString>;
@@ -135,8 +154,14 @@ export declare const orderRefundEventSchema: z.ZodObject<{
135
154
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
136
155
  }, z.ZodTypeAny, "passthrough">;
137
156
  refundedBy: string;
157
+ status?: "failed" | "processed" | "reserved" | undefined;
158
+ failureReason?: string | undefined;
159
+ gateway?: string | undefined;
138
160
  itemIds?: string[] | undefined;
161
+ reasonCode?: string | undefined;
162
+ gatewayRefundId?: string | undefined;
139
163
  phonepeRefundId?: string | undefined;
164
+ razorpayRefundId?: string | undefined;
140
165
  manualTransactionId?: string | undefined;
141
166
  proofDocumentUrl?: string | undefined;
142
167
  proofDocumentMimeType?: string | undefined;
@@ -150,8 +175,14 @@ export declare const orderRefundEventSchema: z.ZodObject<{
150
175
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
151
176
  }, z.ZodTypeAny, "passthrough">;
152
177
  refundedBy: string;
178
+ status?: "failed" | "processed" | "reserved" | undefined;
179
+ failureReason?: string | undefined;
180
+ gateway?: string | undefined;
153
181
  itemIds?: string[] | undefined;
182
+ reasonCode?: string | undefined;
183
+ gatewayRefundId?: string | undefined;
154
184
  phonepeRefundId?: string | undefined;
185
+ razorpayRefundId?: string | undefined;
155
186
  manualTransactionId?: string | undefined;
156
187
  proofDocumentUrl?: string | undefined;
157
188
  proofDocumentMimeType?: string | undefined;
@@ -449,6 +480,7 @@ export declare const orderFirestoreSchema: z.ZodObject<{
449
480
  amount: z.ZodEffects<z.ZodNumber, number, number>;
450
481
  itemIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
451
482
  reason: z.ZodString;
483
+ reasonCode: z.ZodOptional<z.ZodString>;
452
484
  refundedAt: z.ZodUnion<[z.ZodDate, z.ZodString, z.ZodObject<{
453
485
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
454
486
  }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
@@ -457,7 +489,12 @@ export declare const orderFirestoreSchema: z.ZodObject<{
457
489
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
458
490
  }, z.ZodTypeAny, "passthrough">>]>;
459
491
  refundedBy: z.ZodString;
492
+ status: z.ZodOptional<z.ZodEnum<["reserved", "processed", "failed"]>>;
493
+ failureReason: z.ZodOptional<z.ZodString>;
494
+ gatewayRefundId: z.ZodOptional<z.ZodString>;
495
+ gateway: z.ZodOptional<z.ZodString>;
460
496
  phonepeRefundId: z.ZodOptional<z.ZodString>;
497
+ razorpayRefundId: z.ZodOptional<z.ZodString>;
461
498
  manualTransactionId: z.ZodOptional<z.ZodString>;
462
499
  proofDocumentUrl: z.ZodOptional<z.ZodString>;
463
500
  proofDocumentMimeType: z.ZodOptional<z.ZodString>;
@@ -471,8 +508,14 @@ export declare const orderFirestoreSchema: z.ZodObject<{
471
508
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
472
509
  }, z.ZodTypeAny, "passthrough">;
473
510
  refundedBy: string;
511
+ status?: "failed" | "processed" | "reserved" | undefined;
512
+ failureReason?: string | undefined;
513
+ gateway?: string | undefined;
474
514
  itemIds?: string[] | undefined;
515
+ reasonCode?: string | undefined;
516
+ gatewayRefundId?: string | undefined;
475
517
  phonepeRefundId?: string | undefined;
518
+ razorpayRefundId?: string | undefined;
476
519
  manualTransactionId?: string | undefined;
477
520
  proofDocumentUrl?: string | undefined;
478
521
  proofDocumentMimeType?: string | undefined;
@@ -486,8 +529,14 @@ export declare const orderFirestoreSchema: z.ZodObject<{
486
529
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
487
530
  }, z.ZodTypeAny, "passthrough">;
488
531
  refundedBy: string;
532
+ status?: "failed" | "processed" | "reserved" | undefined;
533
+ failureReason?: string | undefined;
534
+ gateway?: string | undefined;
489
535
  itemIds?: string[] | undefined;
536
+ reasonCode?: string | undefined;
537
+ gatewayRefundId?: string | undefined;
490
538
  phonepeRefundId?: string | undefined;
539
+ razorpayRefundId?: string | undefined;
491
540
  manualTransactionId?: string | undefined;
492
541
  proofDocumentUrl?: string | undefined;
493
542
  proofDocumentMimeType?: string | undefined;
@@ -661,8 +710,14 @@ export declare const orderFirestoreSchema: z.ZodObject<{
661
710
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
662
711
  }, z.ZodTypeAny, "passthrough">;
663
712
  refundedBy: string;
713
+ status?: "failed" | "processed" | "reserved" | undefined;
714
+ failureReason?: string | undefined;
715
+ gateway?: string | undefined;
664
716
  itemIds?: string[] | undefined;
717
+ reasonCode?: string | undefined;
718
+ gatewayRefundId?: string | undefined;
665
719
  phonepeRefundId?: string | undefined;
720
+ razorpayRefundId?: string | undefined;
666
721
  manualTransactionId?: string | undefined;
667
722
  proofDocumentUrl?: string | undefined;
668
723
  proofDocumentMimeType?: string | undefined;
@@ -809,8 +864,14 @@ export declare const orderFirestoreSchema: z.ZodObject<{
809
864
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
810
865
  }, z.ZodTypeAny, "passthrough">;
811
866
  refundedBy: string;
867
+ status?: "failed" | "processed" | "reserved" | undefined;
868
+ failureReason?: string | undefined;
869
+ gateway?: string | undefined;
812
870
  itemIds?: string[] | undefined;
871
+ reasonCode?: string | undefined;
872
+ gatewayRefundId?: string | undefined;
813
873
  phonepeRefundId?: string | undefined;
874
+ razorpayRefundId?: string | undefined;
814
875
  manualTransactionId?: string | undefined;
815
876
  proofDocumentUrl?: string | undefined;
816
877
  proofDocumentMimeType?: string | undefined;
@@ -52,15 +52,37 @@ export const orderDocumentItemSchema = z.object({
52
52
  listingType: orderListingTypeSchema.optional(),
53
53
  prizeRevealStatus: z.enum(["pending", "open", "closed", "revealed"]).optional(),
54
54
  });
55
+ /**
56
+ * Mirror of `OrderRefundEvent`.
57
+ *
58
+ * 🛑 THIS HAD ALREADY DRIFTED, and silently in the dangerous direction.
59
+ * `z.object()` STRIPS unknown keys, so a field present on the interface and
60
+ * absent here is **removed on parse** — it does not error, it vanishes. Before
61
+ * 2026-10-21 it was missing `reasonCode` AND `razorpayRefundId`, which means a
62
+ * Razorpay refund reference would have been discarded by the very schema meant
63
+ * to validate it.
64
+ *
65
+ * Keep this in lockstep with the interface. When adding a field there, add it
66
+ * here in the same change.
67
+ */
55
68
  export const orderRefundEventSchema = z.object({
56
69
  refundId: z.string(),
57
70
  type: orderRefundTypeSchema,
58
71
  amount: rupeesSchema,
59
72
  itemIds: z.array(z.string()).optional(),
60
73
  reason: z.string(),
74
+ reasonCode: z.string().optional(),
61
75
  refundedAt: firestoreDateSchema,
62
76
  refundedBy: z.string(),
77
+ // Two-phase lifecycle. Optional because pre-2026-10-21 rows carry none, and
78
+ // a missing status means "committed" to every reader.
79
+ status: z.enum(["reserved", "processed", "failed"]).optional(),
80
+ failureReason: z.string().optional(),
81
+ // Gateway-blind reference, the one a reconciler reads.
82
+ gatewayRefundId: z.string().optional(),
83
+ gateway: z.string().optional(),
63
84
  phonepeRefundId: z.string().optional(),
85
+ razorpayRefundId: z.string().optional(),
64
86
  manualTransactionId: z.string().optional(),
65
87
  proofDocumentUrl: z.string().optional(),
66
88
  proofDocumentMimeType: z.string().optional(),
@@ -277,6 +277,44 @@ export interface Order {
277
277
  autoApproved?: boolean;
278
278
  disputeRaised?: boolean;
279
279
  disputeStatus?: "open" | "resolved";
280
+ /**
281
+ * Completion — the owner's rule, and both writers of one fact.
282
+ *
283
+ * 🛑 Added to the CLIENT type and the adapter together, because adding it to
284
+ * one alone is Root Cause #57 and the symptom is invisible: with
285
+ * `completedAt` undefined, `OrderCompletionPanel` renders its rating UI
286
+ * forever and never shows the "this order is complete" confirmation — which
287
+ * reads as correct behaviour rather than as a dropped field. That is exactly
288
+ * how the whole manual-payment flow sat dead for every buyer: the page gated
289
+ * its render on `paymentMethod`, the adapter mapped only `paymentStatus`, and
290
+ * the result was a polite "this order does not require manual payment".
291
+ *
292
+ * `completedBy` distinguishes the two paths, and they are not the same
293
+ * signal: `"system"` means nobody complained for seven days, a buyer's uid
294
+ * means they said they were happy. Same effect, different fact — so the
295
+ * confirmation copy says which one happened.
296
+ */
297
+ completedAt?: string;
298
+ completedBy?: string;
299
+ /**
300
+ * Anchors the panel needs to decide whether anything is contested.
301
+ *
302
+ * `returnRequestedAt` is load-bearing beyond the status check: a return can
303
+ * be requested and then the status moved on, so the status alone is not a
304
+ * complete answer to "is there a live return".
305
+ */
306
+ returnRequestedAt?: string;
307
+ /**
308
+ * Refund COUNT only, never the events.
309
+ *
310
+ * 🛑 Deliberately not `refunds[]`. The panel needs one bit — "has any money
311
+ * already moved on this order" — and the events carry `refundedBy` (a staff
312
+ * uid), `gatewayRefundId` and a `reason` string assembled for operators.
313
+ * Publishing all that to a buyer's page to answer a yes/no question is the
314
+ * spread-and-publish shape (Root Cause #70); a count answers it and leaks
315
+ * nothing.
316
+ */
317
+ refundCount?: number;
280
318
  /**
281
319
  * Manual-payment (cash / UPI / EMI) fields. Every one of these already
282
320
  * existed on `OrderDocument` but was dropped by `orderDocumentToOrder`,
@@ -320,6 +358,47 @@ export interface Order {
320
358
  /** Denormalized from the product at order-creation time — drives PrizeRevealModal copy. */
321
359
  prizeRevealMode?: "instant" | "scheduled";
322
360
  }
361
+ /**
362
+ * What happened to the buyer's money when their order was cancelled.
363
+ *
364
+ * 🛑 Lives HERE, not beside the function that produces it
365
+ * (`_internal/server/features/orders/cancellation-refund.ts`), for one concrete
366
+ * reason: appkit publishes no `./_internal/*` subpath, so a type declared there
367
+ * is unreachable from the consumer — and the consumer is exactly who needs to
368
+ * name it, because the API route and the buyer's cancel page both return and
369
+ * render this value.
370
+ *
371
+ * It is returned rather than swallowed because *"₹2,499 is on its way back"* and
372
+ * *"we owe you ₹2,499 and someone will send it"* are different sentences, and
373
+ * a buyer who has just cancelled a paid order is entitled to the right one.
374
+ * Before D14 the answer was always a bare 200 and `"Order cancelled"` — true,
375
+ * and silent about the money, which is the defect.
376
+ */
377
+ export type CancellationRefundOutcome =
378
+ /** Nothing to refund: never captured, or already returned in full. */
379
+ {
380
+ moved: "none";
381
+ why: "not-paid" | "nothing-refundable";
382
+ amount: 0;
383
+ }
384
+ /** Refunded through the gateway, once, keyed on the order. */
385
+ | {
386
+ moved: "gateway";
387
+ amount: number;
388
+ refundId: string;
389
+ }
390
+ /**
391
+ * Owed and recorded, but no automatic rail could move it — a manual payment
392
+ * method, a post-dispatch cancellation, or a gateway refusal. A
393
+ * `manual_refund_due` case carries it to an operator; `caseId` is absent only
394
+ * if that write itself failed, which never blocks the cancellation.
395
+ */
396
+ | {
397
+ moved: "owed";
398
+ amount: number;
399
+ why: "post-dispatch" | "manual-payment" | "gateway-failed" | "no-gateway-reference";
400
+ caseId?: string;
401
+ };
323
402
  export interface OrderListResponse {
324
403
  items: Order[];
325
404
  total: number;
@@ -1,6 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Section, Container, Stack, Row, Div, Grid, Heading, Text, Span, TextLink, Badge, } from "../../../ui/index.js";
3
3
  import { ALL_PART_SLOTS, PART_SLOT_LABEL, } from "../schemas/firestore.js";
4
+ /*
5
+ * 🛑 Rendered as JSX from a Server Component, which is the normal RSC
6
+ * boundary and is fine — the trap Root Cause #76 describes is CALLING a
7
+ * `/client` runtime value or reading a property off it, not rendering a
8
+ * client component. The toolbar needs the session, so it owns that itself.
9
+ */
10
+ import { RecordOwnerQuickActions } from "../../admin/components/RecordOwnerQuickActions.js";
4
11
  export function PartsIndexPageView({ hrefForClassification, renderSearch, }) {
5
12
  return (_jsx(Section, { padding: "y-lg", children: _jsx(Container, { size: "lg", children: _jsxs(Stack, { gap: "lg", className: "min-w-0", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 1, children: "Beyblade parts gallery" }), _jsxs(Text, { color: "muted", children: ["Every component we have a record of, by what it is. A code like", " ", _jsx(Span, { weight: "semibold", children: "RF" }), " or ", _jsx(Span, { weight: "semibold", children: "105" }), " means different things in different generations, so parts are grouped by their classification rather than by code."] })] }), renderSearch?.(), _jsx(Grid, { cols: "navTiles", gap: "sm", className: "min-w-0", children: ALL_PART_SLOTS.map((slot) => (_jsx(Div, { surface: "card", padding: "sm", rounded: "md", border: "subtle", className: "min-w-0", children: _jsx(TextLink, { href: hrefForClassification(slot), children: PART_SLOT_LABEL[slot] }) }, slot))) })] }) }) }));
6
13
  }
@@ -13,5 +20,5 @@ export function PartClassificationPageView({ slot, parts, truncated, hrefForPart
13
20
  const label = PART_SLOT_LABEL[slot] ?? slot;
14
21
  return (_jsx(Section, { padding: "y-lg", children: _jsx(Container, { size: "lg", children: _jsxs(Stack, { gap: "lg", className: "min-w-0", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", color: "muted", children: _jsx(TextLink, { href: partsIndexHref, children: "Parts" }) }), _jsx(Heading, { level: 1, children: label }), _jsx(Text, { color: "muted", size: "sm", children: parts.length === 0
15
22
  ? "No parts recorded in this classification yet."
16
- : `${parts.length}${truncated ? "+" : ""} recorded.` })] }), parts.length > 0 && (_jsx(Stack, { gap: "xs", className: "min-w-0", children: parts.map((p) => (_jsxs(Row, { gap: "sm", align: "center", padding: "inline", surface: "card", rounded: "md", border: "subtle", className: "min-w-0", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(TextLink, { href: hrefForPart(p.slot, tailOf(p.id)), children: p.name }), typeof p.weightG === "number" && (_jsxs(Span, { size: "xs", color: "muted", children: [" ", "\u00B7 ", p.weightG, " g"] }))] }), p.code && (_jsx(Badge, { variant: "info", className: "flex-shrink-0", children: p.code }))] }, p.id))) }))] }) }) }));
23
+ : `${parts.length}${truncated ? "+" : ""} recorded.` })] }), parts.length > 0 && (_jsx(Stack, { gap: "xs", className: "min-w-0", children: parts.map((p) => (_jsxs(Row, { gap: "sm", align: "center", padding: "inline", surface: "card", rounded: "md", border: "subtle", className: "min-w-0", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(TextLink, { href: hrefForPart(p.slot, tailOf(p.id)), children: p.name }), typeof p.weightG === "number" && (_jsxs(Span, { size: "xs", color: "muted", children: [" ", "\u00B7 ", p.weightG, " g"] }))] }), p.code && (_jsx(Badge, { variant: "info", className: "flex-shrink-0", children: p.code })), _jsx(RecordOwnerQuickActions, { resource: "PART", recordId: p.id, placement: "detail", recordLabel: p.name })] }, p.id))) }))] }) }) }));
17
24
  }