@mohasinac/appkit 3.8.2 → 3.9.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 (479) hide show
  1. package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
  2. package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +4 -4
  3. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +8 -8
  4. package/dist/_internal/client/features/lottery/LotteryAdminSlotView.d.ts +1 -1
  5. package/dist/_internal/client/features/lottery/LotteryAdminSlotView.js +2 -2
  6. package/dist/_internal/server/features/bundles/actions.js +2 -2
  7. package/dist/_internal/server/features/bundles/og.d.ts +1 -1
  8. package/dist/_internal/server/features/bundles/og.js +4 -5
  9. package/dist/_internal/server/features/checkout/actions.js +57 -21
  10. package/dist/_internal/server/features/checkout/stock-restore.d.ts +19 -0
  11. package/dist/_internal/server/features/checkout/stock-restore.js +80 -0
  12. package/dist/_internal/server/features/checkout/upi-resolution.d.ts +11 -0
  13. package/dist/_internal/server/features/checkout/upi-resolution.js +28 -0
  14. package/dist/_internal/server/features/classified/og.js +1 -1
  15. package/dist/_internal/server/features/digital-code/og.js +1 -1
  16. package/dist/_internal/server/features/item-requests/og.d.ts +2 -2
  17. package/dist/_internal/server/features/item-requests/og.js +4 -5
  18. package/dist/_internal/server/features/live/og.js +1 -1
  19. package/dist/_internal/server/features/lottery/adapters.d.ts +2 -2
  20. package/dist/_internal/server/features/lottery/adapters.js +1 -1
  21. package/dist/_internal/server/features/orders/actions.d.ts +28 -0
  22. package/dist/_internal/server/features/orders/actions.js +239 -4
  23. package/dist/_internal/server/features/orders/adapters.js +3 -0
  24. package/dist/_internal/server/features/payments/data.js +3 -2
  25. package/dist/_internal/server/features/payouts/actions.d.ts +2 -2
  26. package/dist/_internal/server/features/payouts/actions.js +4 -3
  27. package/dist/_internal/server/features/pre-orders/service.d.ts +1 -1
  28. package/dist/_internal/server/features/pre-orders/service.js +3 -2
  29. package/dist/_internal/server/features/prize-draws/og.js +5 -5
  30. package/dist/_internal/server/features/products/og.js +1 -1
  31. package/dist/_internal/server/features/promotions/service.js +3 -1
  32. package/dist/_internal/server/features/refunds/actions.d.ts +2 -2
  33. package/dist/_internal/server/features/refunds/actions.js +7 -6
  34. package/dist/_internal/server/functions/firestore.js +1 -1
  35. package/dist/_internal/server/functions/scheduled.d.ts +4 -1
  36. package/dist/_internal/server/functions/scheduled.js +26 -2
  37. package/dist/_internal/server/jobs/core/emiInstallmentReminder.js +1 -1
  38. package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +4 -0
  39. package/dist/_internal/server/jobs/core/hardBanCascade.js +15 -4
  40. package/dist/_internal/server/jobs/core/hardBanReinstatement.d.ts +16 -0
  41. package/dist/_internal/server/jobs/core/hardBanReinstatement.js +63 -0
  42. package/dist/_internal/server/jobs/core/jobRunners.js +3 -1
  43. package/dist/_internal/server/jobs/core/onScamReportCreate.js +1 -1
  44. package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +10 -0
  45. package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +60 -0
  46. package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +15 -0
  47. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +59 -0
  48. package/dist/_internal/server/jobs/core/pendingOrderTimeout.d.ts +7 -0
  49. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +32 -6
  50. package/dist/_internal/server/jobs/handlers/hardBanReinstatement.d.ts +2 -0
  51. package/dist/_internal/server/jobs/handlers/hardBanReinstatement.js +2 -0
  52. package/dist/_internal/server/jobs/handlers/index.d.ts +3 -0
  53. package/dist/_internal/server/jobs/handlers/index.js +3 -0
  54. package/dist/_internal/server/jobs/handlers/messages.d.ts +4 -0
  55. package/dist/_internal/server/jobs/handlers/messages.js +4 -0
  56. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +3 -3
  57. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +12 -12
  58. package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +1 -1
  59. package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +5 -5
  60. package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.d.ts +2 -0
  61. package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.js +2 -0
  62. package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.d.ts +2 -0
  63. package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.js +2 -0
  64. package/dist/_internal/shared/actions/action-registry.js +27 -0
  65. package/dist/_internal/shared/checkout/order-math.js +3 -2
  66. package/dist/_internal/shared/checkout/rules/_defaults.js +1 -0
  67. package/dist/_internal/shared/checkout/rules/preorder.rule.js +7 -0
  68. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +7 -0
  69. package/dist/_internal/shared/checkout/rules/types.d.ts +11 -0
  70. package/dist/_internal/shared/features/auctions/errors.js +1 -1
  71. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +0 -1
  72. package/dist/_internal/shared/features/categories/bundle-copy.js +0 -1
  73. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +6 -6
  74. package/dist/_internal/shared/features/categories/bundle-schemas.js +2 -2
  75. package/dist/_internal/shared/features/checkout/config.d.ts +3 -3
  76. package/dist/_internal/shared/features/checkout/config.js +3 -3
  77. package/dist/_internal/shared/features/emi/schedule.d.ts +6 -6
  78. package/dist/_internal/shared/features/emi/schedule.js +10 -9
  79. package/dist/_internal/shared/features/promotions/errors.js +1 -1
  80. package/dist/_internal/shared/fees/calculator.d.ts +5 -5
  81. package/dist/_internal/shared/fees/calculator.js +19 -19
  82. package/dist/client.d.ts +1 -1
  83. package/dist/client.js +1 -1
  84. package/dist/constants/api-endpoints.d.ts +9 -0
  85. package/dist/constants/api-endpoints.js +3 -0
  86. package/dist/constants/field-names.d.ts +4 -0
  87. package/dist/constants/field-names.js +4 -0
  88. package/dist/features/admin/components/AdminArtView.js +2 -2
  89. package/dist/features/admin/components/AdminBidsView.js +2 -2
  90. package/dist/features/admin/components/AdminBundleEditorView.d.ts +1 -1
  91. package/dist/features/admin/components/AdminBundleEditorView.js +8 -8
  92. package/dist/features/admin/components/AdminBundlesView.js +6 -6
  93. package/dist/features/admin/components/AdminClassifiedView.js +2 -2
  94. package/dist/features/admin/components/AdminDigitalCodesView.js +2 -2
  95. package/dist/features/admin/components/AdminLiveView.js +2 -2
  96. package/dist/features/admin/components/AdminOrderEditorView.d.ts +6 -1
  97. package/dist/features/admin/components/AdminOrderEditorView.js +45 -5
  98. package/dist/features/admin/components/AdminOrdersView.js +8 -3
  99. package/dist/features/admin/components/AdminPayoutsView.js +2 -2
  100. package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -2
  101. package/dist/features/admin/components/AdminReturnRequestsView.js +2 -2
  102. package/dist/features/admin/components/AdminSiteSettingsView.js +11 -11
  103. package/dist/features/admin/components/AdminStickersView.js +2 -2
  104. package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
  105. package/dist/features/admin/hooks/useAdminListingData.d.ts +1 -1
  106. package/dist/features/admin/hooks/useAdminListingData.js +3 -2
  107. package/dist/features/admin/schemas/firestore.d.ts +9 -7
  108. package/dist/features/admin/schemas/firestore.js +4 -3
  109. package/dist/features/auctions/components/AuctionBidsTable.js +3 -3
  110. package/dist/features/auth/checkout-value-otp.d.ts +46 -0
  111. package/dist/features/auth/checkout-value-otp.js +73 -0
  112. package/dist/features/auth/repository/user.repository.d.ts +6 -0
  113. package/dist/features/auth/repository/user.repository.js +19 -0
  114. package/dist/features/auth/schemas/firestore.d.ts +10 -0
  115. package/dist/features/auth/schemas/firestore.js +2 -0
  116. package/dist/features/cart/actions/cart-actions.d.ts +1 -1
  117. package/dist/features/cart/actions/cart-actions.js +4 -4
  118. package/dist/features/cart/components/CartView.d.ts +2 -2
  119. package/dist/features/cart/components/ShippingPicker.d.ts +4 -4
  120. package/dist/features/cart/components/ShippingPicker.js +11 -11
  121. package/dist/features/cart/repository/cart.repository.d.ts +1 -1
  122. package/dist/features/cart/repository/cart.repository.js +2 -2
  123. package/dist/features/cart/schemas/firestore.d.ts +2 -2
  124. package/dist/features/catalogue/components/CatalogueItemEditorView.js +3 -3
  125. package/dist/features/catalogue/components/PublicCatalogueView.js +2 -2
  126. package/dist/features/catalogue/schemas/validation.js +1 -1
  127. package/dist/features/categories/components/BundleCollage.js +2 -2
  128. package/dist/features/categories/components/BundleDetailView.js +2 -2
  129. package/dist/features/categories/components/BundleItemsPicker.d.ts +1 -1
  130. package/dist/features/categories/components/BundleItemsPicker.js +2 -2
  131. package/dist/features/categories/components/CategoryBundlesListing.js +2 -2
  132. package/dist/features/categories/schemas/firestore.d.ts +1 -1
  133. package/dist/features/categories/schemas/index.d.ts +3 -3
  134. package/dist/features/categories/schemas/index.js +2 -2
  135. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +16 -0
  136. package/dist/features/checkout/actions/checkout-value-otp-actions.js +83 -0
  137. package/dist/features/checkout/actions/index.d.ts +1 -0
  138. package/dist/features/checkout/actions/index.js +1 -0
  139. package/dist/features/checkout/schemas/firestore.d.ts +1 -1
  140. package/dist/features/classified/components/index.d.ts +0 -4
  141. package/dist/features/classified/components/index.js +0 -2
  142. package/dist/features/digital-codes/components/index.d.ts +0 -4
  143. package/dist/features/digital-codes/components/index.js +0 -2
  144. package/dist/features/events/schemas/index.d.ts +1 -1
  145. package/dist/features/events/schemas/index.js +1 -1
  146. package/dist/features/homepage/components/FeaturedBundlesSection.js +2 -2
  147. package/dist/features/live/components/index.d.ts +0 -4
  148. package/dist/features/live/components/index.js +0 -2
  149. package/dist/features/lottery/types/index.d.ts +3 -3
  150. package/dist/features/lottery/types/index.js +5 -5
  151. package/dist/features/orders/components/OrderPaymentSummary.js +2 -2
  152. package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
  153. package/dist/features/orders/components/RefundHistoryTable.js +1 -1
  154. package/dist/features/orders/components/RefundRequestView.js +1 -1
  155. package/dist/features/orders/constants/payment-window.d.ts +10 -0
  156. package/dist/features/orders/constants/payment-window.js +10 -0
  157. package/dist/features/orders/repository/orders.repository.d.ts +25 -0
  158. package/dist/features/orders/repository/orders.repository.js +50 -1
  159. package/dist/features/orders/schemas/firestore.d.ts +50 -2
  160. package/dist/features/orders/schemas/index.d.ts +24 -24
  161. package/dist/features/orders/schemas/index.js +20 -20
  162. package/dist/features/orders/types/index.d.ts +4 -0
  163. package/dist/features/orders/utils/bundle-grouping.d.ts +1 -1
  164. package/dist/features/orders/utils/bundle-grouping.js +1 -1
  165. package/dist/features/payments/schemas/index.d.ts +10 -10
  166. package/dist/features/payments/schemas/index.js +9 -9
  167. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -2
  168. package/dist/features/products/components/ArtStickersListView.d.ts +7 -0
  169. package/dist/features/products/components/ArtStickersListView.js +57 -0
  170. package/dist/features/products/components/GroupSettingsPanel.js +1 -1
  171. package/dist/features/products/components/MakeOfferButton.js +3 -3
  172. package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
  173. package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
  174. package/dist/features/products/components/PrizeDrawCollage.js +2 -2
  175. package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
  176. package/dist/features/products/components/PrizeRevealModal.js +1 -1
  177. package/dist/features/products/components/ProductDetailPageView.js +2 -9
  178. package/dist/features/products/components/ProductForm.js +2 -2
  179. package/dist/features/products/components/ProductGrid.js +2 -2
  180. package/dist/features/products/components/ProductsIndexListing.d.ts +13 -1
  181. package/dist/features/products/components/ProductsIndexListing.js +7 -5
  182. package/dist/features/products/components/ProductsIndexPageView.js +6 -1
  183. package/dist/features/products/constants/listing-tabs.d.ts +42 -17
  184. package/dist/features/products/constants/listing-tabs.js +25 -6
  185. package/dist/features/products/schemas/catalog-product.d.ts +5 -5
  186. package/dist/features/products/schemas/catalog-product.js +1 -1
  187. package/dist/features/products/schemas/firestore.d.ts +5 -5
  188. package/dist/features/products/schemas/firestore.js +2 -2
  189. package/dist/features/products/types/index.d.ts +5 -2
  190. package/dist/features/promotions/components/CouponCard.js +2 -2
  191. package/dist/features/promotions/schemas/firestore.d.ts +2 -0
  192. package/dist/features/promotions/schemas/firestore.js +1 -0
  193. package/dist/features/promotions/schemas/index.d.ts +14 -14
  194. package/dist/features/promotions/schemas/index.js +6 -6
  195. package/dist/features/scams/components/ScamProfileView.js +3 -7
  196. package/dist/features/scams/components/ScamRegistryView.js +2 -6
  197. package/dist/features/scams/schemas/firestore.d.ts +1 -1
  198. package/dist/features/search/components/Search.d.ts +1 -1
  199. package/dist/features/seller/actions/offer-actions.js +1 -1
  200. package/dist/features/seller/components/PrintCenterView.js +2 -2
  201. package/dist/features/seller/components/QuickProductForm.js +5 -5
  202. package/dist/features/seller/components/SellerArtView.js +2 -2
  203. package/dist/features/seller/components/SellerAuctionsView.js +2 -2
  204. package/dist/features/seller/components/SellerBidsView.js +2 -2
  205. package/dist/features/seller/components/SellerBundlesView.js +6 -6
  206. package/dist/features/seller/components/SellerClassifiedView.js +2 -2
  207. package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
  208. package/dist/features/seller/components/SellerLiveView.js +2 -2
  209. package/dist/features/seller/components/SellerOffersView.js +2 -2
  210. package/dist/features/seller/components/SellerOrdersView.js +3 -3
  211. package/dist/features/seller/components/SellerPayoutRequestView.js +2 -2
  212. package/dist/features/seller/components/SellerPayoutSettingsView.js +2 -2
  213. package/dist/features/seller/components/SellerPayoutsView.js +2 -2
  214. package/dist/features/seller/components/SellerPreOrdersView.js +2 -2
  215. package/dist/features/seller/components/SellerPrizeDrawsView.js +2 -2
  216. package/dist/features/seller/components/SellerProductShell.js +8 -8
  217. package/dist/features/seller/components/SellerProductsView.js +1 -1
  218. package/dist/features/seller/components/SellerShippingView.js +6 -6
  219. package/dist/features/seller/components/SellerStickersView.js +2 -2
  220. package/dist/features/seller/hooks/useSellerListingData.d.ts +1 -1
  221. package/dist/features/seller/hooks/useSellerListingData.js +3 -2
  222. package/dist/features/shipments/components/AdminShipmentEditorView.js +10 -10
  223. package/dist/features/shipments/components/AdminShipmentLotItemsView.js +4 -4
  224. package/dist/features/shipments/components/AdminShipmentProjectionsView.js +5 -5
  225. package/dist/features/shipments/components/AdminShipmentsView.js +4 -4
  226. package/dist/features/shipments/repository/shipment-lots.repository.d.ts +2 -2
  227. package/dist/features/shipments/repository/shipment-lots.repository.js +8 -8
  228. package/dist/features/shipments/schemas/firestore.d.ts +21 -21
  229. package/dist/features/shipments/schemas/firestore.js +9 -9
  230. package/dist/features/shipments/schemas/validation.d.ts +30 -30
  231. package/dist/features/shipments/schemas/validation.js +6 -6
  232. package/dist/features/shipments/utils/cost-allocation.d.ts +5 -5
  233. package/dist/features/shipments/utils/cost-allocation.js +39 -38
  234. package/dist/features/store-extensions/schemas/firestore.d.ts +5 -5
  235. package/dist/features/stores/components/StoreDetailLayoutView.js +9 -13
  236. package/dist/features/stores/schemas/firestore.d.ts +7 -7
  237. package/dist/features/stores/schemas/index.d.ts +84 -84
  238. package/dist/features/stores/schemas/index.js +5 -5
  239. package/dist/features/tester/seed-data/categories-tester-seed-data.js +1 -1
  240. package/dist/features/tester/seed-data/products-tester-seed-data.js +6 -6
  241. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +9 -2
  242. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +8 -1
  243. package/dist/features/whatsapp-bot/helpers/whatsapp.js +13 -2
  244. package/dist/features/whatsapp-bot/types/index.d.ts +9 -1
  245. package/dist/index.d.ts +3 -7
  246. package/dist/index.js +7 -5
  247. package/dist/next/routing/route-map.d.ts +2 -0
  248. package/dist/next/routing/route-map.js +6 -0
  249. package/dist/schemas/firestore-helpers.d.ts +2 -2
  250. package/dist/schemas/firestore-helpers.js +2 -2
  251. package/dist/schemas/registry.d.ts +73 -73
  252. package/dist/seed/bids-seed-data.js +6 -6
  253. package/dist/seed/blog-posts-seed-data.js +1 -0
  254. package/dist/seed/cart-seed-data.js +13 -13
  255. package/dist/seed/catalogue-seed-data.js +6 -6
  256. package/dist/seed/categories-seed-data.js +5 -5
  257. package/dist/seed/claimed-coupons-seed-data.js +3 -3
  258. package/dist/seed/coupons-seed-data.js +20 -20
  259. package/dist/seed/events-seed-data.js +27 -27
  260. package/dist/seed/factories/bid.factory.js +1 -1
  261. package/dist/seed/faq-seed-data.js +20 -1
  262. package/dist/seed/grouped-listings-seed-data.d.ts +2 -2
  263. package/dist/seed/grouped-listings-seed-data.js +3 -3
  264. package/dist/seed/offers-seed-data.js +19 -19
  265. package/dist/seed/orders-seed-data.js +29 -29
  266. package/dist/seed/payouts-seed-data.js +7 -7
  267. package/dist/seed/products-auctions-seed-data.js +6 -6
  268. package/dist/seed/products-preorders-seed-data.d.ts +2 -2
  269. package/dist/seed/products-preorders-seed-data.js +1 -1
  270. package/dist/seed/products-standard-seed-data.js +8 -8
  271. package/dist/seed/scammers-seed-data.js +2 -2
  272. package/dist/seed/shipments-seed-data.js +29 -29
  273. package/dist/seed/site-settings-seed-data.js +3 -2
  274. package/dist/seed/store-extensions-seed-data.js +8 -8
  275. package/dist/seed/stores-seed-data.js +37 -8
  276. package/dist/seed/users-seed-data.js +38 -1
  277. package/dist/server-entry.d.ts +1 -3
  278. package/dist/server-entry.js +1 -3
  279. package/dist/server.d.ts +2 -1
  280. package/dist/server.js +3 -1
  281. package/dist/ui/components/PriceDisplay.js +3 -12
  282. package/dist/utils/number.formatter.d.ts +2 -7
  283. package/dist/utils/number.formatter.js +3 -8
  284. package/package.json +1 -1
  285. package/scripts/seed-cli.mjs +8 -3
  286. package/dist/_internal/client/scaffolds/DashboardScaffold.d.ts +0 -34
  287. package/dist/_internal/client/scaffolds/DashboardScaffold.js +0 -26
  288. package/dist/_internal/client/theme/__tests__/ThemeProvider.test.d.ts +0 -1
  289. package/dist/_internal/client/theme/__tests__/ThemeProvider.test.js +0 -109
  290. package/dist/_internal/server/features/auctions/__tests__/service.test.d.ts +0 -1
  291. package/dist/_internal/server/features/auctions/__tests__/service.test.js +0 -140
  292. package/dist/_internal/server/features/checkout/__tests__/actions.test.d.ts +0 -1
  293. package/dist/_internal/server/features/checkout/__tests__/actions.test.js +0 -600
  294. package/dist/_internal/server/features/refunds/__tests__/actions.test.d.ts +0 -1
  295. package/dist/_internal/server/features/refunds/__tests__/actions.test.js +0 -263
  296. package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.d.ts +0 -1
  297. package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.js +0 -249
  298. package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.d.ts +0 -1
  299. package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.js +0 -65
  300. package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.d.ts +0 -1
  301. package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.js +0 -163
  302. package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.d.ts +0 -1
  303. package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.js +0 -115
  304. package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.d.ts +0 -1
  305. package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.js +0 -201
  306. package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.d.ts +0 -1
  307. package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.js +0 -169
  308. package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.d.ts +0 -1
  309. package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.js +0 -148
  310. package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.d.ts +0 -1
  311. package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.js +0 -210
  312. package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.d.ts +0 -1
  313. package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.js +0 -190
  314. package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.d.ts +0 -1
  315. package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.js +0 -161
  316. package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.d.ts +0 -1
  317. package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.js +0 -302
  318. package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.d.ts +0 -1
  319. package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.js +0 -96
  320. package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.d.ts +0 -1
  321. package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.js +0 -252
  322. package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.d.ts +0 -1
  323. package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.js +0 -129
  324. package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +0 -15
  325. package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +0 -38
  326. package/dist/_internal/server/providers/index.d.ts +0 -11
  327. package/dist/_internal/server/providers/index.js +0 -11
  328. package/dist/_internal/server/providers/payment/razorpay-mock.d.ts +0 -52
  329. package/dist/_internal/server/providers/payment/razorpay-mock.js +0 -118
  330. package/dist/_internal/server/providers/resolve.d.ts +0 -36
  331. package/dist/_internal/server/providers/resolve.js +0 -31
  332. package/dist/_internal/server/providers/shipping/shiprocket-mock.d.ts +0 -29
  333. package/dist/_internal/server/providers/shipping/shiprocket-mock.js +0 -152
  334. package/dist/_internal/shared/types/__tests__/action-result.test.d.ts +0 -1
  335. package/dist/_internal/shared/types/__tests__/action-result.test.js +0 -65
  336. package/dist/errors/__tests__/error-mapping.test.d.ts +0 -1
  337. package/dist/errors/__tests__/error-mapping.test.js +0 -122
  338. package/dist/errors/__tests__/safe-read.test.d.ts +0 -1
  339. package/dist/errors/__tests__/safe-read.test.js +0 -39
  340. package/dist/features/addresses/repository/__tests__/addresses.repository.test.d.ts +0 -1
  341. package/dist/features/addresses/repository/__tests__/addresses.repository.test.js +0 -386
  342. package/dist/features/admin/components/AdminListingScaffold.d.ts +0 -41
  343. package/dist/features/admin/components/AdminListingScaffold.js +0 -68
  344. package/dist/features/admin/components/QuickActionsPanel.d.ts +0 -15
  345. package/dist/features/admin/components/QuickActionsPanel.js +0 -5
  346. package/dist/features/admin/repository/__tests__/notification.repository.test.d.ts +0 -1
  347. package/dist/features/admin/repository/__tests__/notification.repository.test.js +0 -356
  348. package/dist/features/admin/repository/__tests__/site-settings.repository.test.d.ts +0 -1
  349. package/dist/features/admin/repository/__tests__/site-settings.repository.test.js +0 -298
  350. package/dist/features/auctions/repository/__tests__/bid.repository.test.d.ts +0 -1
  351. package/dist/features/auctions/repository/__tests__/bid.repository.test.js +0 -290
  352. package/dist/features/auctions/repository/auctions.repository.d.ts +0 -12
  353. package/dist/features/auctions/repository/auctions.repository.js +0 -42
  354. package/dist/features/auth/repository/__tests__/session.repository.test.d.ts +0 -1
  355. package/dist/features/auth/repository/__tests__/session.repository.test.js +0 -310
  356. package/dist/features/auth/repository/__tests__/session.test.d.ts +0 -1
  357. package/dist/features/auth/repository/__tests__/session.test.js +0 -146
  358. package/dist/features/auth/repository/__tests__/sms-counter.repository.test.d.ts +0 -1
  359. package/dist/features/auth/repository/__tests__/sms-counter.repository.test.js +0 -171
  360. package/dist/features/auth/repository/__tests__/sms-counter.test.d.ts +0 -1
  361. package/dist/features/auth/repository/__tests__/sms-counter.test.js +0 -88
  362. package/dist/features/auth/repository/__tests__/token.repository.test.d.ts +0 -1
  363. package/dist/features/auth/repository/__tests__/token.repository.test.js +0 -260
  364. package/dist/features/auth/repository/__tests__/token.test.d.ts +0 -1
  365. package/dist/features/auth/repository/__tests__/token.test.js +0 -140
  366. package/dist/features/auth/repository/__tests__/user.repository.test.d.ts +0 -1
  367. package/dist/features/auth/repository/__tests__/user.repository.test.js +0 -352
  368. package/dist/features/auth/repository/__tests__/user.test.d.ts +0 -1
  369. package/dist/features/auth/repository/__tests__/user.test.js +0 -226
  370. package/dist/features/before-after/repository/before-after.repository.d.ts +0 -13
  371. package/dist/features/before-after/repository/before-after.repository.js +0 -36
  372. package/dist/features/before-after/server.d.ts +0 -6
  373. package/dist/features/before-after/server.js +0 -6
  374. package/dist/features/cart/repository/__tests__/cart.repository.test.d.ts +0 -1
  375. package/dist/features/cart/repository/__tests__/cart.repository.test.js +0 -371
  376. package/dist/features/categories/repository/__tests__/categories.repository.test.d.ts +0 -1
  377. package/dist/features/categories/repository/__tests__/categories.repository.test.js +0 -813
  378. package/dist/features/collections/repository/collections.repository.d.ts +0 -8
  379. package/dist/features/collections/repository/collections.repository.js +0 -16
  380. package/dist/features/collections/server.d.ts +0 -6
  381. package/dist/features/collections/server.js +0 -6
  382. package/dist/features/events/repository/__tests__/event.repository.test.d.ts +0 -1
  383. package/dist/features/events/repository/__tests__/event.repository.test.js +0 -299
  384. package/dist/features/faq/repository/__tests__/faqs.repository.test.d.ts +0 -1
  385. package/dist/features/faq/repository/__tests__/faqs.repository.test.js +0 -311
  386. package/dist/features/forms/Form.d.ts +0 -25
  387. package/dist/features/forms/Form.js +0 -37
  388. package/dist/features/history/repository/__tests__/user-history.repository.test.d.ts +0 -1
  389. package/dist/features/history/repository/__tests__/user-history.repository.test.js +0 -180
  390. package/dist/features/homepage/repository/__tests__/carousel.repository.test.d.ts +0 -1
  391. package/dist/features/homepage/repository/__tests__/carousel.repository.test.js +0 -182
  392. package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.d.ts +0 -1
  393. package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.js +0 -185
  394. package/dist/features/layout/ListingLayout.d.ts +0 -34
  395. package/dist/features/layout/ListingLayout.js +0 -103
  396. package/dist/features/messages/repository/__tests__/conversations.repository.test.d.ts +0 -1
  397. package/dist/features/messages/repository/__tests__/conversations.repository.test.js +0 -257
  398. package/dist/features/orders/repository/__tests__/orders.repository.test.d.ts +0 -1
  399. package/dist/features/orders/repository/__tests__/orders.repository.test.js +0 -211
  400. package/dist/features/payments/repository/__tests__/payout.repository.test.d.ts +0 -1
  401. package/dist/features/payments/repository/__tests__/payout.repository.test.js +0 -292
  402. package/dist/features/pre-orders/repository/preorders.repository.d.ts +0 -8
  403. package/dist/features/pre-orders/repository/preorders.repository.js +0 -25
  404. package/dist/features/products/repository/__tests__/product-features.repository.test.d.ts +0 -1
  405. package/dist/features/products/repository/__tests__/product-features.repository.test.js +0 -329
  406. package/dist/features/products/repository/__tests__/products.repository.test.d.ts +0 -1
  407. package/dist/features/products/repository/__tests__/products.repository.test.js +0 -607
  408. package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.d.ts +0 -1
  409. package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.js +0 -219
  410. package/dist/features/promotions/repository/__tests__/coupons.repository.test.d.ts +0 -1
  411. package/dist/features/promotions/repository/__tests__/coupons.repository.test.js +0 -480
  412. package/dist/features/promotions/repository/promotions.repository.d.ts +0 -14
  413. package/dist/features/promotions/repository/promotions.repository.js +0 -43
  414. package/dist/features/reviews/repository/__tests__/reviews.repository.test.d.ts +0 -1
  415. package/dist/features/reviews/repository/__tests__/reviews.repository.test.js +0 -327
  416. package/dist/features/scams/repository/__tests__/scammer.repository.test.d.ts +0 -1
  417. package/dist/features/scams/repository/__tests__/scammer.repository.test.js +0 -385
  418. package/dist/features/search/repository/__tests__/search.repository.test.d.ts +0 -1
  419. package/dist/features/search/repository/__tests__/search.repository.test.js +0 -369
  420. package/dist/features/seller/components/SellerStatCard.d.ts +0 -14
  421. package/dist/features/seller/components/SellerStatCard.js +0 -6
  422. package/dist/features/seller/components/seller-products-styles.d.ts +0 -7
  423. package/dist/features/seller/components/seller-products-styles.js +0 -14
  424. package/dist/features/seller/repository/__tests__/offer.repository.test.d.ts +0 -1
  425. package/dist/features/seller/repository/__tests__/offer.repository.test.js +0 -458
  426. package/dist/features/seller/repository/seller.repository.d.ts +0 -22
  427. package/dist/features/seller/repository/seller.repository.js +0 -72
  428. package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.d.ts +0 -1
  429. package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.js +0 -37
  430. package/dist/features/stores/repository/__tests__/store.repository.test.d.ts +0 -1
  431. package/dist/features/stores/repository/__tests__/store.repository.test.js +0 -261
  432. package/dist/features/stores/repository/stores.repository.d.ts +0 -11
  433. package/dist/features/stores/repository/stores.repository.js +0 -37
  434. package/dist/features/support/repository/__tests__/support.repository.test.d.ts +0 -1
  435. package/dist/features/support/repository/__tests__/support.repository.test.js +0 -312
  436. package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.d.ts +0 -1
  437. package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.js +0 -139
  438. package/dist/features/wishlist/repository/wishlist.repository.d.ts +0 -13
  439. package/dist/features/wishlist/repository/wishlist.repository.js +0 -31
  440. package/dist/providers/db-firebase/__tests__/filter-aliases.test.d.ts +0 -1
  441. package/dist/providers/db-firebase/__tests__/filter-aliases.test.js +0 -93
  442. package/dist/providers/shipping-shiprocket/index.d.ts +0 -297
  443. package/dist/providers/shipping-shiprocket/index.js +0 -194
  444. package/dist/providers/shipping-shiprocket/shiprocket-provider.d.ts +0 -45
  445. package/dist/providers/shipping-shiprocket/shiprocket-provider.js +0 -168
  446. package/dist/react/contexts/ThemeContext.d.ts +0 -13
  447. package/dist/react/contexts/ThemeContext.js +0 -64
  448. package/dist/schemas/webhooks/shiprocket.d.ts +0 -30
  449. package/dist/schemas/webhooks/shiprocket.js +0 -22
  450. package/dist/seed/actions/demo-seed-actions.d.ts +0 -42
  451. package/dist/seed/actions/demo-seed-actions.js +0 -36
  452. package/dist/seed/actions/index.d.ts +0 -1
  453. package/dist/seed/actions/index.js +0 -1
  454. package/dist/seed/sub-listings-seed-data.d.ts +0 -123
  455. package/dist/seed/sub-listings-seed-data.js +0 -447
  456. package/dist/seed/tester-checklist-seed-data.d.ts +0 -2
  457. package/dist/seed/tester-checklist-seed-data.js +0 -248
  458. package/dist/ui/components/DashboardStatsCard.d.ts +0 -15
  459. package/dist/ui/components/DashboardStatsCard.js +0 -27
  460. package/dist/ui/components/DashboardStatsCard.style.css +0 -68
  461. package/dist/ui/components/DynamicSelect.d.ts +0 -23
  462. package/dist/ui/components/DynamicSelect.js +0 -77
  463. package/dist/ui/components/DynamicSelect.style.css +0 -101
  464. package/dist/ui/components/InlineCreateSelect.d.ts +0 -48
  465. package/dist/ui/components/InlineCreateSelect.js +0 -75
  466. package/dist/ui/components/ListingViewShell.d.ts +0 -37
  467. package/dist/ui/components/ListingViewShell.js +0 -9
  468. package/dist/ui/components/PaginatedMultiSelect.d.ts +0 -28
  469. package/dist/ui/components/PaginatedMultiSelect.js +0 -141
  470. package/dist/ui/components/PaginatedMultiSelect.style.css +0 -272
  471. package/dist/ui/components/SectionTabs.d.ts +0 -19
  472. package/dist/ui/components/SectionTabs.js +0 -66
  473. package/dist/ui/components/SectionTabs.style.css +0 -164
  474. package/dist/ui/components/__tests__/BulkActionBar.test.d.ts +0 -1
  475. package/dist/ui/components/__tests__/BulkActionBar.test.js +0 -96
  476. package/dist/ui/components/__tests__/ListingToolbar.test.d.ts +0 -1
  477. package/dist/ui/components/__tests__/ListingToolbar.test.js +0 -125
  478. package/dist/ui/components/__tests__/new-primitives.test.d.ts +0 -1
  479. package/dist/ui/components/__tests__/new-primitives.test.js +0 -187
@@ -136,7 +136,7 @@ export interface CategoryDocument extends BaseDocument {
136
136
  */
137
137
  bundleKind?: "special" | "brand";
138
138
  /** Discounted bundle price in paise. */
139
- bundlePriceInPaise?: number;
139
+ bundlePrice?: number;
140
140
  /** Rule resolving the bundle's member products — static list or live query. */
141
141
  bundleQueryRule?: BundleQueryRule;
142
142
  /** Snapshot stock state — recomputed by onProductStockChange. */
@@ -231,7 +231,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
231
231
  brandFounded: z.ZodOptional<z.ZodNumber>;
232
232
  brandBannerImage: z.ZodOptional<z.ZodString>;
233
233
  bundleKind: z.ZodOptional<z.ZodEnum<["special", "brand"]>>;
234
- bundlePriceInPaise: z.ZodOptional<z.ZodNumber>;
234
+ bundlePrice: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, number>>;
235
235
  bundleQueryRule: z.ZodOptional<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
236
236
  type: z.ZodLiteral<"static">;
237
237
  productIds: z.ZodArray<z.ZodString, "many">;
@@ -443,7 +443,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
443
443
  brandCountry?: string | undefined;
444
444
  brandFounded?: number | undefined;
445
445
  brandBannerImage?: string | undefined;
446
- bundlePriceInPaise?: number | undefined;
446
+ bundlePrice?: number | undefined;
447
447
  bundleQueryRule?: {
448
448
  type: "static";
449
449
  productIds: string[];
@@ -537,7 +537,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
537
537
  brandCountry?: string | undefined;
538
538
  brandFounded?: number | undefined;
539
539
  brandBannerImage?: string | undefined;
540
- bundlePriceInPaise?: number | undefined;
540
+ bundlePrice?: number | undefined;
541
541
  bundleQueryRule?: {
542
542
  type: "static";
543
543
  productIds: string[];
@@ -1,6 +1,6 @@
1
1
  export * from "./firestore";
2
2
  import { z } from "zod";
3
- import { auditTimestampsShape, firestoreDateSchema, paiseSchema } from "../../../schemas/firestore-helpers";
3
+ import { auditTimestampsShape, firestoreDateSchema, rupeesSchema } from "../../../schemas/firestore-helpers";
4
4
  // ─── Firestore document schema (W2) ───────────────────────────────────────────
5
5
  // Mirrors CategoryDocument + nested types in ./firestore.ts.
6
6
  // Registered into SCHEMAS.firestore.categories.
@@ -78,7 +78,7 @@ export const categoryFirestoreSchema = z.object({
78
78
  brandFounded: z.number().int().optional(),
79
79
  brandBannerImage: z.string().optional(),
80
80
  bundleKind: z.enum(["special", "brand"]).optional(),
81
- bundlePriceInPaise: paiseSchema.optional(),
81
+ bundlePrice: rupeesSchema.optional(),
82
82
  bundleQueryRule: bundleQueryRuleSchema.optional(),
83
83
  bundleStockStatus: z.enum(["in_stock", "out_of_stock"]).optional(),
84
84
  bundleQueryResolvedAt: firestoreDateSchema.optional(),
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Checkout Value OTP Actions (appkit) — Tier PP.
3
+ *
4
+ * OTP gate for placing a checkout whose total is at/above
5
+ * `siteSettings.payment.otpCheckoutThreshold` (skipped for COD). A distinct
6
+ * purpose from `checkout-actions.ts`'s third-party shipping consent OTP —
7
+ * same crypto primitives, separate Firestore namespace and copy.
8
+ */
9
+ /** Sends a checkout-value OTP to the buyer's registered email. Returns masked email so the UI can confirm which inbox to check. */
10
+ export declare function sendCheckoutValueOtp(userId: string, userEmail: string): Promise<{
11
+ maskedEmail: string;
12
+ }>;
13
+ /** Verifies the 6-digit checkout-value OTP and marks the Firestore record verified. */
14
+ export declare function verifyCheckoutValueOtp(userId: string, code: string): Promise<void>;
15
+ /** Whether the buyer has a currently-verified checkout-value OTP on file. */
16
+ export declare function isCheckoutValueOtpVerified(userId: string): Promise<boolean>;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Checkout Value OTP Actions (appkit) — Tier PP.
3
+ *
4
+ * OTP gate for placing a checkout whose total is at/above
5
+ * `siteSettings.payment.otpCheckoutThreshold` (skipped for COD). A distinct
6
+ * purpose from `checkout-actions.ts`'s third-party shipping consent OTP —
7
+ * same crypto primitives, separate Firestore namespace and copy.
8
+ */
9
+ import { timingSafeEqual } from "crypto";
10
+ import { ValidationError } from "../../../errors";
11
+ import { serverLogger } from "../../../monitoring";
12
+ import { sendEmail } from "../../contact/email";
13
+ import { getAdminDb } from "../../../providers/db-firebase";
14
+ import { resolveDate } from "../../../utils";
15
+ import { CHECKOUT_VALUE_OTP_EXPIRY_MS, CHECKOUT_VALUE_OTP_MAX_ATTEMPTS, hashOtp, generateOtpCode, checkoutValueOtpRef, enforceCheckoutValueOtpRateLimit, } from "../../auth/checkout-value-otp";
16
+ /** Sends a checkout-value OTP to the buyer's registered email. Returns masked email so the UI can confirm which inbox to check. */
17
+ export async function sendCheckoutValueOtp(userId, userEmail) {
18
+ const db = getAdminDb();
19
+ await enforceCheckoutValueOtpRateLimit(db, userId);
20
+ const code = generateOtpCode();
21
+ const codeHash = hashOtp(code);
22
+ const expiresAt = new Date(Date.now() + CHECKOUT_VALUE_OTP_EXPIRY_MS);
23
+ await checkoutValueOtpRef(db, userId).set({
24
+ codeHash,
25
+ expiresAt,
26
+ attempts: 0,
27
+ verified: false,
28
+ createdAt: new Date(),
29
+ });
30
+ const siteName = process.env.NEXT_PUBLIC_SITE_NAME || "LetItRip";
31
+ const [local, domain] = userEmail.split("@");
32
+ const maskedEmail = domain
33
+ ? `${local.length <= 2 ? "*".repeat(local.length) : local[0] + "*".repeat(local.length - 2) + local[local.length - 1]}@${domain}`
34
+ : "***";
35
+ await sendEmail({
36
+ to: userEmail,
37
+ subject: `${siteName}: Verify your order`,
38
+ html: `
39
+ <div style="font-family:sans-serif;max-width:480px;margin:0 auto;padding:24px">
40
+ <h2 style="margin-bottom:8px">Verify Your Order</h2>
41
+ <p style="color:#555">Your cart total requires verification before checkout. Enter this code to continue:</p>
42
+ <div style="font-size:36px;font-weight:bold;letter-spacing:8px;text-align:center;margin:24px 0;padding:16px;background:#f3f4f6;border-radius:8px">${code}</div>
43
+ <p style="color:#888;font-size:12px">This code expires in 10 minutes. If you did not request this, please ignore this email.</p>
44
+ </div>
45
+ `,
46
+ });
47
+ serverLogger.info(`Checkout value OTP sent: uid=${userId}`);
48
+ return { maskedEmail };
49
+ }
50
+ /** Verifies the 6-digit checkout-value OTP and marks the Firestore record verified. */
51
+ export async function verifyCheckoutValueOtp(userId, code) {
52
+ const db = getAdminDb();
53
+ const ref = checkoutValueOtpRef(db, userId);
54
+ const snap = await ref.get();
55
+ if (!snap.exists) {
56
+ throw new ValidationError("No verification code found. Please request a new code.");
57
+ }
58
+ const otpDoc = snap.data();
59
+ if (otpDoc.verified)
60
+ return;
61
+ if (otpDoc.attempts >= CHECKOUT_VALUE_OTP_MAX_ATTEMPTS) {
62
+ throw new ValidationError("Too many failed attempts. Please request a new code.");
63
+ }
64
+ if (Date.now() > (resolveDate(otpDoc.expiresAt)?.getTime() ?? 0)) {
65
+ throw new ValidationError("Code expired. Please request a new one.");
66
+ }
67
+ const inputHash = hashOtp(code);
68
+ if (!timingSafeEqual(Buffer.from(inputHash, "hex"), Buffer.from(otpDoc.codeHash, "hex"))) {
69
+ await ref.update({ attempts: otpDoc.attempts + 1 });
70
+ throw new ValidationError("Invalid code. Please check and try again.");
71
+ }
72
+ await ref.update({ verified: true, verifiedAt: new Date() });
73
+ serverLogger.info(`Checkout value OTP verified: uid=${userId}`);
74
+ }
75
+ /** Whether the buyer has a currently-verified checkout-value OTP on file. */
76
+ export async function isCheckoutValueOtpVerified(userId) {
77
+ const db = getAdminDb();
78
+ const snap = await checkoutValueOtpRef(db, userId).get();
79
+ if (!snap.exists)
80
+ return false;
81
+ const otpDoc = snap.data();
82
+ return otpDoc.verified === true;
83
+ }
@@ -1 +1,2 @@
1
1
  export * from "./checkout-actions";
2
+ export * from "./checkout-value-otp-actions";
@@ -1 +1,2 @@
1
1
  export * from "./checkout-actions";
2
+ export * from "./checkout-value-otp-actions";
@@ -21,7 +21,7 @@ export type FailedPaymentDocument = {
21
21
  uid: string;
22
22
  gatewayOrderId?: string;
23
23
  gatewayPaymentId?: string;
24
- /** Amount in smallest currency unit (e.g. paise). */
24
+ /** Amount in decimal rupees. */
25
25
  amountRs?: number;
26
26
  addressId?: string;
27
27
  reason: FailedPaymentReason;
@@ -1,6 +1,2 @@
1
- export { ClassifiedListView } from "./ClassifiedListView";
2
- export type { ClassifiedListViewProps } from "./ClassifiedListView";
3
- export { ClassifiedIndexListing } from "./ClassifiedIndexListing";
4
- export type { ClassifiedIndexListingProps } from "./ClassifiedIndexListing";
5
1
  export { ClassifiedFilters } from "./ClassifiedFilters";
6
2
  export type { ClassifiedFiltersProps } from "./ClassifiedFilters";
@@ -1,3 +1 @@
1
- export { ClassifiedListView } from "./ClassifiedListView";
2
- export { ClassifiedIndexListing } from "./ClassifiedIndexListing";
3
1
  export { ClassifiedFilters } from "./ClassifiedFilters";
@@ -1,6 +1,2 @@
1
- export { DigitalCodesListView } from "./DigitalCodesListView";
2
- export type { DigitalCodesListViewProps } from "./DigitalCodesListView";
3
- export { DigitalCodesIndexListing } from "./DigitalCodesIndexListing";
4
- export type { DigitalCodesIndexListingProps } from "./DigitalCodesIndexListing";
5
1
  export { DigitalCodeFilters } from "./DigitalCodeFilters";
6
2
  export type { DigitalCodeFiltersProps } from "./DigitalCodeFilters";
@@ -1,3 +1 @@
1
- export { DigitalCodesListView } from "./DigitalCodesListView";
2
- export { DigitalCodesIndexListing } from "./DigitalCodesIndexListing";
3
1
  export { DigitalCodeFilters } from "./DigitalCodeFilters";
@@ -348,7 +348,7 @@ export declare const spinPrizeSchema: z.ZodObject<{
348
348
  isActive: boolean;
349
349
  couponId?: string | undefined;
350
350
  }>;
351
- /** Lottery slot schema — client-safe shape (no priceInPaise/weight sent to clients). */
351
+ /** Lottery slot schema — client-safe shape (no price/weight sent to clients). */
352
352
  export declare const lotterySlotClientSchema: z.ZodObject<{
353
353
  slotNumber: z.ZodNumber;
354
354
  name: z.ZodString;
@@ -77,7 +77,7 @@ export const spinPrizeSchema = z.object({
77
77
  weight: z.number(),
78
78
  isActive: z.boolean(),
79
79
  });
80
- /** Lottery slot schema — client-safe shape (no priceInPaise/weight sent to clients). */
80
+ /** Lottery slot schema — client-safe shape (no price/weight sent to clients). */
81
81
  export const lotterySlotClientSchema = z.object({
82
82
  slotNumber: z.number().int().min(1),
83
83
  name: z.string(),
@@ -24,7 +24,7 @@ function FeaturedBundleCard({ bundle, onBuyNow }) {
24
24
  const memberCount = bundle.bundleProductIds?.length ?? 0;
25
25
  const cover = bundle.display?.coverImage;
26
26
  const href = String(ROUTES.PUBLIC.BUNDLE_DETAIL?.(bundle.slug) ?? "#");
27
- return (_jsxs(Stack, { gap: "none", surface: "default", rounded: "xl", border: "default", children: [_jsxs(Link, { href: href, className: "group block p-[var(--appkit-space-3)] hover:no-underline", children: [_jsx(Div, { className: `relative mb-2 aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: cover ? (_jsx(MediaImage, { src: cover, alt: bundle.name, size: "card", className: "transition-transform group-hover:scale-105" })) : (_jsx(Row, { textSize: "3xl", className: "h-full w-full", align: "center", justify: "center", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2", size: "sm", weight: "semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1", wrap: true, children: [_jsx(Text, { size: "sm", weight: "bold", children: bundle.bundlePriceInPaise
28
- ? formatCurrency(bundle.bundlePriceInPaise / 100, "INR")
27
+ return (_jsxs(Stack, { gap: "none", surface: "default", rounded: "xl", border: "default", children: [_jsxs(Link, { href: href, className: "group block p-[var(--appkit-space-3)] hover:no-underline", children: [_jsx(Div, { className: `relative mb-2 aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: cover ? (_jsx(MediaImage, { src: cover, alt: bundle.name, size: "card", className: "transition-transform group-hover:scale-105" })) : (_jsx(Row, { textSize: "3xl", className: "h-full w-full", align: "center", justify: "center", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2", size: "sm", weight: "semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1", wrap: true, children: [_jsx(Text, { size: "sm", weight: "bold", children: bundle.bundlePrice
28
+ ? formatCurrency(bundle.bundlePrice, "INR")
29
29
  : BUNDLE_COPY.featured.priceFallback }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.featured.itemCount(memberCount)] }), stock !== "in_stock" && (_jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: BUNDLE_COPY.stockBadge.listVariantOutOfStock }))] })] }), onBuyNow && (_jsx(Div, { border: "subtle", className: `border-t ${__P.p3}`, padding: "t-xs", children: _jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow, compact: true }) }))] }));
30
30
  }
@@ -1,6 +1,2 @@
1
- export { LiveItemsListView } from "./LiveItemsListView";
2
- export type { LiveItemsListViewProps } from "./LiveItemsListView";
3
- export { LiveItemsIndexListing } from "./LiveItemsIndexListing";
4
- export type { LiveItemsIndexListingProps } from "./LiveItemsIndexListing";
5
1
  export { LiveItemFilters } from "./LiveItemFilters";
6
2
  export type { LiveItemFiltersProps } from "./LiveItemFilters";
@@ -1,3 +1 @@
1
- export { LiveItemsListView } from "./LiveItemsListView";
2
- export { LiveItemsIndexListing } from "./LiveItemsIndexListing";
3
1
  export { LiveItemFilters } from "./LiveItemFilters";
@@ -7,7 +7,7 @@
7
7
  export interface LotterySlot {
8
8
  slotNumber: number;
9
9
  name: string;
10
- priceInPaise: number;
10
+ price: number;
11
11
  weight: number;
12
12
  isBooked: boolean;
13
13
  bookedByUserLotteryNumber?: number;
@@ -27,7 +27,7 @@ export interface LotteryConfig {
27
27
  slots: LotterySlot[];
28
28
  totalSlots: number;
29
29
  pricingMode: LotteryPricingMode;
30
- uniformPriceInPaise?: number;
30
+ uniformPrice?: number;
31
31
  drawWindowDurationMinutes: number;
32
32
  maxPullsPerTransaction: number;
33
33
  maxPullsPerUser: number;
@@ -54,7 +54,7 @@ export declare class LotteryError extends Error {
54
54
  * Weight is always at least 1 (never 0).
55
55
  * For uniform pricing: all slots get weight 50.
56
56
  */
57
- export declare function computeWeight(priceInPaise: number, maxPriceInPaise: number): number;
57
+ export declare function computeWeight(price: number, maxPrice: number): number;
58
58
  /**
59
59
  * Pick a slot using weighted random selection. Uses the Web Crypto API, not
60
60
  * `Math.random()`, so the fairness claim shown to users (PrizeRevealModal's
@@ -17,10 +17,10 @@ export class LotteryError extends Error {
17
17
  * Weight is always at least 1 (never 0).
18
18
  * For uniform pricing: all slots get weight 50.
19
19
  */
20
- export function computeWeight(priceInPaise, maxPriceInPaise) {
21
- if (maxPriceInPaise === 0)
20
+ export function computeWeight(price, maxPrice) {
21
+ if (maxPrice === 0)
22
22
  return 50;
23
- return Math.max(1, Math.round((1 - priceInPaise / maxPriceInPaise) * 99) + 1);
23
+ return Math.max(1, Math.round((1 - price / maxPrice) * 99) + 1);
24
24
  }
25
25
  /**
26
26
  * Cryptographically-random integer in [0, maxExclusive) via the Web Crypto
@@ -60,9 +60,9 @@ export function assignSlotWeights(config) {
60
60
  if (config.pricingMode === "uniform") {
61
61
  return config.slots.map((sl) => ({ ...sl, weight: 50 }));
62
62
  }
63
- const maxPrice = Math.max(...config.slots.map((sl) => sl.priceInPaise), 0);
63
+ const maxPrice = Math.max(...config.slots.map((sl) => sl.price), 0);
64
64
  return config.slots.map((sl) => ({
65
65
  ...sl,
66
- weight: computeWeight(sl.priceInPaise, maxPrice),
66
+ weight: computeWeight(sl.price, maxPrice),
67
67
  }));
68
68
  }
@@ -19,7 +19,7 @@ function legacyFallback(order) {
19
19
  method,
20
20
  transactionId: order.paymentTransactionId ?? order.paymentId,
21
21
  proofUrl: order.paymentProofUrl,
22
- amountPaise: order.totalPrice,
22
+ amount: order.totalPrice,
23
23
  verificationMethod: method === "razorpay" ? "webhook" : method === "cod" ? "cod_collection" : "manual_review",
24
24
  };
25
25
  }
@@ -28,5 +28,5 @@ export function OrderPaymentSummary({ order, className = "" }) {
28
28
  if (!record) {
29
29
  return (_jsx(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: _jsx(Text, { size: "sm", color: "muted", children: "No payment information recorded yet." }) }));
30
30
  }
31
- return (_jsxs(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsxs(Row, { justify: "between", align: "center", className: "mb-2", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Payment" }), _jsx(Badge, { variant: order.paymentStatus === "paid" ? "success" : "default", children: order.paymentStatus ?? "pending" })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Method" }), _jsx(Text, { size: "sm", weight: "medium", children: METHOD_LABEL[record.method] })] }), _jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Amount" }), _jsx(Text, { size: "sm", weight: "medium", children: formatCurrency(record.amountPaise / 100, order.currency ?? "INR") })] }), record.transactionId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Reference" }), _jsx(Text, { size: "sm", weight: "medium", children: record.transactionId })] })), record.paidAt && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Paid at" }), _jsx(Text, { size: "sm", children: new Date(record.paidAt).toLocaleString() })] })), record.verifiedBy && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Verified by" }), _jsx(Text, { size: "sm", children: record.verifiedBy })] })), record.gatewayRef?.paymentId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Gateway payment ID" }), _jsx(Text, { size: "sm", children: record.gatewayRef.paymentId })] }))] })] }));
31
+ return (_jsxs(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsxs(Row, { justify: "between", align: "center", className: "mb-2", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Payment" }), _jsx(Badge, { variant: order.paymentStatus === "paid" ? "success" : "default", children: order.paymentStatus ?? "pending" })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Method" }), _jsx(Text, { size: "sm", weight: "medium", children: METHOD_LABEL[record.method] })] }), _jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Amount" }), _jsx(Text, { size: "sm", weight: "medium", children: formatCurrency(record.amount, order.currency ?? "INR") })] }), record.transactionId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Reference" }), _jsx(Text, { size: "sm", weight: "medium", children: record.transactionId })] })), record.paidAt && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Paid at" }), _jsx(Text, { size: "sm", children: new Date(record.paidAt).toLocaleString() })] })), record.verifiedBy && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Verified by" }), _jsx(Text, { size: "sm", children: record.verifiedBy })] })), record.gatewayRef?.paymentId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Gateway payment ID" }), _jsx(Text, { size: "sm", children: record.gatewayRef.paymentId })] }))] })] }));
32
32
  }
@@ -11,6 +11,6 @@ export function OrderSiblingPayments({ siblings, currentOrderId, className = "",
11
11
  return null;
12
12
  return (_jsxs(Div, { className: `${className}`, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsx(Heading, { level: 3, className: "mb-3", color: "muted", size: "sm", weight: "semibold", children: REFUND_COPY.siblingPayments.heading(others.length) }), _jsx(Stack, { gap: "xs", children: others.map((o) => {
13
13
  const href = String(ROUTES.USER.ORDER_DETAIL(o.id));
14
- return (_jsxs(Row, { justify: "between", align: "center", gap: "sm", children: [_jsx(Link, { href: href, className: "text-[length:var(--appkit-text-sm)] font-medium text-[color:var(--appkit-color-primary)] hover:underline", children: o.id }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "xs", color: "muted", transform: "capitalize", children: o.status }), _jsx(Text, { size: "xs", weight: "semibold", children: formatCurrency(o.totalPrice / 100, o.currency ?? "INR") })] })] }, o.id));
14
+ return (_jsxs(Row, { justify: "between", align: "center", gap: "sm", children: [_jsx(Link, { href: href, className: "text-[length:var(--appkit-text-sm)] font-medium text-[color:var(--appkit-color-primary)] hover:underline", children: o.id }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "xs", color: "muted", transform: "capitalize", children: o.status }), _jsx(Text, { size: "xs", weight: "semibold", children: formatCurrency(o.totalPrice, o.currency ?? "INR") })] })] }, o.id));
15
15
  }) })] }));
16
16
  }
@@ -10,7 +10,7 @@ function formatDate(d) {
10
10
  return dt.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
11
11
  }
12
12
  function RefundRow({ event, currency }) {
13
- return (_jsxs(Row, { border: "subtle", justify: "between", align: "start", gap: "sm", className: "border-b last:border-0", padding: "y-sm", children: [_jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Badge, { variant: event.type === "full" ? "danger" : "warning", children: event.type === "full" ? REFUND_COPY.history.badgeFull : REFUND_COPY.history.badgePartial }), _jsx(Text, { size: "xs", color: "muted", children: formatDate(event.refundedAt) })] }), _jsx(Text, { size: "sm", children: event.reason }), event.manualTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelTxn, " ", event.manualTransactionId] })), event.razorpayRefundId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelRazorpay, " ", event.razorpayRefundId] }))] }), _jsx(Text, { size: "sm", weight: "semibold", className: "shrink-0", children: formatCurrency(event.amount / 100, currency) })] }));
13
+ return (_jsxs(Row, { border: "subtle", justify: "between", align: "start", gap: "sm", className: "border-b last:border-0", padding: "y-sm", children: [_jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Badge, { variant: event.type === "full" ? "danger" : "warning", children: event.type === "full" ? REFUND_COPY.history.badgeFull : REFUND_COPY.history.badgePartial }), _jsx(Text, { size: "xs", color: "muted", children: formatDate(event.refundedAt) })] }), _jsx(Text, { size: "sm", children: event.reason }), event.manualTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelTxn, " ", event.manualTransactionId] })), event.razorpayRefundId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelRazorpay, " ", event.razorpayRefundId] }))] }), _jsx(Text, { size: "sm", weight: "semibold", className: "shrink-0", children: formatCurrency(event.amount, currency) })] }));
14
14
  }
15
15
  /** Warning triangle icon — inline SVG kept here since it's a single-use decorative element. */
16
16
  function WarningIcon() {
@@ -41,5 +41,5 @@ export function RefundRequestView({ order, onSubmitRequest, isLoading = false, c
41
41
  setError(err instanceof Error ? err.message : REFUND_COPY.request.errorFallback);
42
42
  }
43
43
  };
44
- return (_jsxs(Stack, { gap: "md", className: className, children: [_jsxs(Text, { size: "sm", color: "muted", children: [REFUND_COPY.request.orderTotalLabel, " ", _jsx(Span, { weight: "bold", children: formatCurrency(order.totalPrice / 100, order.currency ?? "INR") })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", weight: "semibold", children: [REFUND_COPY.request.reasonLabel, " ", _jsx(Span, { "aria-hidden": true, children: "*" })] }), _jsx(Textarea, { value: reason, onChange: (e) => setReason(e.target.value), placeholder: REFUND_COPY.request.reasonPlaceholder, rows: 3, "aria-required": "true", "aria-label": REFUND_COPY.request.reasonLabel })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", children: REFUND_COPY.request.acknowledgeHeading }), REFUND_COPY.request.acknowledgments.map((text, i) => (_jsx(Checkbox, { checked: acknowledged[i], onChange: () => handleToggle(i), label: _jsx(Text, { size: "sm", className: "leading-snug", children: text }), "aria-label": `Acknowledgment ${i + 1}` }, i)))] }), error && (_jsx(Text, { size: "sm", color: "danger", role: "alert", children: error })), _jsx(Button, { variant: "danger", onClick: handleSubmit, disabled: !canSubmit, "aria-busy": isLoading, children: isLoading ? REFUND_COPY.request.submittingLabel : REFUND_COPY.request.submitLabel })] }));
44
+ return (_jsxs(Stack, { gap: "md", className: className, children: [_jsxs(Text, { size: "sm", color: "muted", children: [REFUND_COPY.request.orderTotalLabel, " ", _jsx(Span, { weight: "bold", children: formatCurrency(order.totalPrice, order.currency ?? "INR") })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", weight: "semibold", children: [REFUND_COPY.request.reasonLabel, " ", _jsx(Span, { "aria-hidden": true, children: "*" })] }), _jsx(Textarea, { value: reason, onChange: (e) => setReason(e.target.value), placeholder: REFUND_COPY.request.reasonPlaceholder, rows: 3, "aria-required": "true", "aria-label": REFUND_COPY.request.reasonLabel })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", children: REFUND_COPY.request.acknowledgeHeading }), REFUND_COPY.request.acknowledgments.map((text, i) => (_jsx(Checkbox, { checked: acknowledged[i], onChange: () => handleToggle(i), label: _jsx(Text, { size: "sm", className: "leading-snug", children: text }), "aria-label": `Acknowledgment ${i + 1}` }, i)))] }), error && (_jsx(Text, { size: "sm", color: "danger", role: "alert", children: error })), _jsx(Button, { variant: "danger", onClick: handleSubmit, disabled: !canSubmit, "aria-busy": isLoading, children: isLoading ? REFUND_COPY.request.submittingLabel : REFUND_COPY.request.submitLabel })] }));
45
45
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 15-minute payment window shared constant — imported by the checkout action
3
+ * (stamps `order.paymentDeadline`), the buyer countdown UI, and the
4
+ * `paymentWindowTimeout` sweep job, so they can never drift out of sync.
5
+ */
6
+ export declare const PAYMENT_WINDOW_MINUTES = 15;
7
+ export declare const PAYMENT_WINDOW_MS: number;
8
+ /** Cancellation reasons this feature writes to `OrderDocument.cancellationReason` (a free-form string field). */
9
+ export declare const PAYMENT_WINDOW_EXPIRED_REASON = "payment_window_expired";
10
+ export declare const PAYMENT_FRAUD_REJECTED_REASON = "payment_fraud_rejected";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 15-minute payment window shared constant — imported by the checkout action
3
+ * (stamps `order.paymentDeadline`), the buyer countdown UI, and the
4
+ * `paymentWindowTimeout` sweep job, so they can never drift out of sync.
5
+ */
6
+ export const PAYMENT_WINDOW_MINUTES = 15;
7
+ export const PAYMENT_WINDOW_MS = PAYMENT_WINDOW_MINUTES * 60 * 1000;
8
+ /** Cancellation reasons this feature writes to `OrderDocument.cancellationReason` (a free-form string field). */
9
+ export const PAYMENT_WINDOW_EXPIRED_REASON = "payment_window_expired";
10
+ export const PAYMENT_FRAUD_REJECTED_REASON = "payment_fraud_rejected";
@@ -188,6 +188,31 @@ declare class OrderRepository extends BaseRepository<OrderDocument> {
188
188
  ref: DocumentReference;
189
189
  data: OrderDocument;
190
190
  }>>;
191
+ /**
192
+ * Cloud Functions: 15-minute payment-window sweep — orders past their
193
+ * `paymentDeadline` with no proof uploaded yet. Filters out orders that
194
+ * already have `paymentProofUrl` set in-memory (the 2-hour auto-approve
195
+ * sweep owns those instead) rather than as a Firestore inequality, since a
196
+ * `paymentProofUrl != null` filter would silently exclude every doc where
197
+ * the field isn't set at all — the opposite of what's needed here.
198
+ */
199
+ getExpiredPaymentDeadlines(): Promise<Array<{
200
+ id: string;
201
+ ref: DocumentReference;
202
+ data: OrderDocument;
203
+ }>>;
204
+ /**
205
+ * Cloud Functions: 2-hour auto-approve sweep — orders with a submitted
206
+ * proof that no admin has acted on yet (`paymentReviewOutcome` unset).
207
+ * Filters that in-memory rather than as a Firestore inequality for the
208
+ * same reason as `getExpiredPaymentDeadlines` — a `!= null` filter would
209
+ * silently exclude every doc where the field was never set at all.
210
+ */
211
+ getUnreviewedProofPastDeadline(hours?: number): Promise<Array<{
212
+ id: string;
213
+ ref: DocumentReference;
214
+ data: OrderDocument;
215
+ }>>;
191
216
  /**
192
217
  * Cloud Functions: find delivered orders eligible for the weekly payout sweep.
193
218
  *
@@ -103,7 +103,7 @@ class OrderRepository extends BaseRepository {
103
103
  paymentRecord: {
104
104
  method: "cod",
105
105
  transactionId: note,
106
- amountPaise: order.totalPrice,
106
+ amount: order.totalPrice,
107
107
  paidAt: new Date(),
108
108
  verifiedBy,
109
109
  verificationMethod: "cod_collection",
@@ -291,6 +291,55 @@ class OrderRepository extends BaseRepository {
291
291
  data: this.decryptOrder({ id: d.id, ...d.data() }),
292
292
  }));
293
293
  }
294
+ /**
295
+ * Cloud Functions: 15-minute payment-window sweep — orders past their
296
+ * `paymentDeadline` with no proof uploaded yet. Filters out orders that
297
+ * already have `paymentProofUrl` set in-memory (the 2-hour auto-approve
298
+ * sweep owns those instead) rather than as a Firestore inequality, since a
299
+ * `paymentProofUrl != null` filter would silently exclude every doc where
300
+ * the field isn't set at all — the opposite of what's needed here.
301
+ */
302
+ async getExpiredPaymentDeadlines() {
303
+ const snap = await this.db
304
+ .collection(this.collection)
305
+ .where(ORDER_FIELDS.STATUS, "==", OrderStatusValues.PENDING)
306
+ .where(ORDER_FIELDS.PAYMENT_STATUS, "==", "pending")
307
+ .where(ORDER_FIELDS.PAYMENT_DEADLINE, "<=", new Date())
308
+ .limit(500)
309
+ .get();
310
+ return snap.docs
311
+ .map((d) => ({
312
+ id: d.id,
313
+ ref: d.ref,
314
+ data: this.decryptOrder({ id: d.id, ...d.data() }),
315
+ }))
316
+ .filter((entry) => !entry.data.paymentProofUrl);
317
+ }
318
+ /**
319
+ * Cloud Functions: 2-hour auto-approve sweep — orders with a submitted
320
+ * proof that no admin has acted on yet (`paymentReviewOutcome` unset).
321
+ * Filters that in-memory rather than as a Firestore inequality for the
322
+ * same reason as `getExpiredPaymentDeadlines` — a `!= null` filter would
323
+ * silently exclude every doc where the field was never set at all.
324
+ */
325
+ async getUnreviewedProofPastDeadline(hours = 2) {
326
+ const cutoff = new Date();
327
+ cutoff.setHours(cutoff.getHours() - hours);
328
+ const snap = await this.db
329
+ .collection(this.collection)
330
+ .where(ORDER_FIELDS.STATUS, "==", OrderStatusValues.PENDING)
331
+ .where(ORDER_FIELDS.PAYMENT_STATUS, "==", "pending")
332
+ .where(ORDER_FIELDS.PAYMENT_PROOF_UPLOADED_AT, "<=", cutoff)
333
+ .limit(500)
334
+ .get();
335
+ return snap.docs
336
+ .map((d) => ({
337
+ id: d.id,
338
+ ref: d.ref,
339
+ data: this.decryptOrder({ id: d.id, ...d.data() }),
340
+ }))
341
+ .filter((entry) => !!entry.data.paymentProofUrl && !entry.data.paymentReviewOutcome);
342
+ }
294
343
  /**
295
344
  * Cloud Functions: find delivered orders eligible for the weekly payout sweep.
296
345
  *
@@ -100,6 +100,9 @@ export interface OrderDocumentItem {
100
100
  cancelledQuantity?: number;
101
101
  cancelledAt?: Date;
102
102
  cancelledReason?: string;
103
+ /** SB-UNI-5 — forwarded from the cart line when this order item is an expanded bundle, so the order-detail UI can collapse it back under a "Bundle: <name>" header and stock-restore logic can fan back out to member products. */
104
+ bundleCategorySlug?: string;
105
+ bundleProductIds?: string[];
103
106
  /** P-8 GST — snapshotted from the product at order time so the invoice stays accurate even if the product's HSN/rate later changes. */
104
107
  hsnCode?: string;
105
108
  gstRate?: 0 | 5 | 12 | 18 | 28;
@@ -178,7 +181,7 @@ export interface OrderDocument extends BaseDocument {
178
181
  platformFee?: number;
179
182
  depositAmount?: number;
180
183
  codRemainingAmount?: number;
181
- /** COD handling fee charged to the buyer: max(codHandlingFeeMinInPaise, subtotal × codHandlingFeePercent / 100). Only set when paymentMethod === "cod". */
184
+ /** COD handling fee charged to the buyer: max(codHandlingFeeMin, subtotal × codHandlingFeePercent / 100). Only set when paymentMethod === "cod". */
182
185
  codHandlingFee?: number;
183
186
  /** Order subtotal before GST — the amount GST is computed on. */
184
187
  taxableAmount?: number;
@@ -274,6 +277,51 @@ export interface OrderDocument extends BaseDocument {
274
277
  paymentProofMimeType?: string;
275
278
  /** When the buyer submitted the proof. */
276
279
  paymentProofUploadedAt?: Date;
280
+ /**
281
+ * Deadline for the buyer to pay/upload proof. Set only at creation for
282
+ * `upi_manual`/`cash`/`emi` orders — never for `cod`, `razorpay`, or
283
+ * `admin_bypass` (those either pay before order creation or have no proof
284
+ * step). `paymentWindowTimeout` cancels + restocks any order still
285
+ * `pending`/`pending` with no `paymentProofUrl` past this timestamp.
286
+ * Extended by 15 more minutes when admin requests a proof re-upload.
287
+ */
288
+ paymentDeadline?: Date;
289
+ /** True once a cancellation path has restored `availableQuantity` for this order's items. Guards against double-restock. */
290
+ stockRestored?: boolean;
291
+ stockRestoredAt?: Date;
292
+ /**
293
+ * UPI VPA resolved and shown to the buyer at order-creation time — the
294
+ * seller's own `payoutDetails.upiId` for seller-owned stores (falling back
295
+ * to `siteSettings.contact.upiVpa` if unconfigured), or the site UPI
296
+ * directly for admin-owned stores. Immutable "ground truth" for the
297
+ * cross-check below; never client-supplied.
298
+ */
299
+ displayedUpiId?: string;
300
+ /** UPI VPA the buyer says they actually paid from/to, per their own UPI app — the real cross-check signal against `displayedUpiId`. */
301
+ buyerReportedUpiId?: string;
302
+ /** True when `buyerReportedUpiId` doesn't match `displayedUpiId` — surfaced prominently in the admin review UI. */
303
+ paymentUpiMismatch?: boolean;
304
+ /** Buyer's explicit "I have paid" declaration, distinct from admin's own verification. */
305
+ buyerMarkedPaid?: boolean;
306
+ buyerMarkedPaidAt?: Date;
307
+ /** Buyer's required "this payment is genuine, no fraudulent tricks/chargebacks" agreement — server-validated, not just a client-side disable. */
308
+ buyerFraudAgreementAccepted?: boolean;
309
+ buyerFraudAgreementAcceptedAt?: Date;
310
+ /** Which of the three admin review actions was taken on this order's payment proof. */
311
+ paymentReviewOutcome?: "approved" | "reupload_requested" | "rejected_fraud";
312
+ /** Admin's reason text — required for both `reupload_requested` and `rejected_fraud`. */
313
+ paymentReviewNote?: string;
314
+ paymentReviewedBy?: string;
315
+ paymentReviewedAt?: Date;
316
+ /** True when `paymentReviewAutoApprove` approved this order after 2 hours of no manual admin review. */
317
+ autoApproved?: boolean;
318
+ autoApprovedAt?: Date;
319
+ /** Buyer/seller/admin dispute raised against an auto-approved order — surfaces to the admin queue, does not itself reverse payment/order status. */
320
+ disputeRaised?: boolean;
321
+ disputeRaisedBy?: string;
322
+ disputeRaisedAt?: Date;
323
+ disputeReason?: string;
324
+ disputeStatus?: "open" | "resolved";
277
325
  /**
278
326
  * Same-shape payment record regardless of how the buyer paid — manual
279
327
  * (cash/UPI proof), Razorpay (webhook-verified), or COD (collected on
@@ -309,7 +357,7 @@ export interface OrderPaymentRecord {
309
357
  transactionId?: string;
310
358
  /** Manual proof upload | COD collection receipt photo (optional) | n/a for razorpay. */
311
359
  proofUrl?: string;
312
- amountPaise: number;
360
+ amount: number;
313
361
  paidAt?: Date;
314
362
  /** Admin/seller uid (manual/COD) | "razorpay-webhook" (razorpay, automatic). */
315
363
  verifiedBy?: string;