@mohasinac/appkit 4.2.0 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/dist/_internal/client/features/layout/navActive.d.ts +17 -0
  2. package/dist/_internal/client/features/layout/navActive.js +33 -0
  3. package/dist/_internal/server/features/auth/actions.d.ts +0 -1
  4. package/dist/_internal/server/features/auth/actions.js +0 -1
  5. package/dist/_internal/server/features/bundles/data.d.ts +22 -4
  6. package/dist/_internal/server/features/bundles/data.js +41 -4
  7. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  8. package/dist/_internal/server/features/bundles/index.js +1 -1
  9. package/dist/_internal/server/features/checkout/actions.js +7 -78
  10. package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +5 -16
  11. package/dist/_internal/server/features/checkout/prize-bundle-gates.js +5 -30
  12. package/dist/_internal/server/features/orders/adapters.js +1 -14
  13. package/dist/_internal/server/features/products/actions.js +8 -3
  14. package/dist/_internal/server/features/products/service.d.ts +15 -0
  15. package/dist/_internal/server/features/products/service.js +41 -0
  16. package/dist/_internal/server/functions/firestore.d.ts +3 -1
  17. package/dist/_internal/server/functions/firestore.js +17 -1
  18. package/dist/_internal/server/functions/scheduled.d.ts +2 -5
  19. package/dist/_internal/server/functions/scheduled.js +6 -30
  20. package/dist/_internal/server/jobs/core/bundleStockSync.js +25 -7
  21. package/dist/_internal/server/jobs/core/countersReconcile.js +7 -1
  22. package/dist/_internal/server/jobs/core/index.d.ts +4 -4
  23. package/dist/_internal/server/jobs/core/index.js +4 -4
  24. package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.d.ts +19 -0
  25. package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.js +30 -0
  26. package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +2 -2
  27. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +2 -2
  28. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.d.ts +20 -0
  29. package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +113 -0
  30. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.d.ts +14 -0
  31. package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +74 -0
  32. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.d.ts +22 -0
  33. package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +68 -0
  34. package/dist/_internal/server/jobs/handlers/index.d.ts +3 -4
  35. package/dist/_internal/server/jobs/handlers/index.js +8 -6
  36. package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.d.ts +3 -0
  37. package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.js +11 -0
  38. package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.d.ts +2 -0
  39. package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.js +2 -0
  40. package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.d.ts +3 -0
  41. package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.js +4 -0
  42. package/dist/_internal/shared/actions/action-registry.js +40 -10
  43. package/dist/_internal/shared/checkout/rules/_defaults.js +1 -2
  44. package/dist/_internal/shared/checkout/rules/_limits.d.ts +3 -0
  45. package/dist/_internal/shared/checkout/rules/_limits.js +3 -0
  46. package/dist/_internal/shared/checkout/rules/_registry.d.ts +2 -1
  47. package/dist/_internal/shared/checkout/rules/_registry.js +2 -2
  48. package/dist/_internal/shared/checkout/rules/classified.rule.js +0 -1
  49. package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
  50. package/dist/_internal/shared/checkout/rules/index.js +1 -1
  51. package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +20 -1
  52. package/dist/_internal/shared/checkout/rules/types.d.ts +17 -7
  53. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +2 -0
  54. package/dist/_internal/shared/features/categories/bundle-copy.js +2 -0
  55. package/dist/_internal/shared/features/categories/bundle-pricing.d.ts +23 -0
  56. package/dist/_internal/shared/features/categories/bundle-pricing.js +25 -0
  57. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  58. package/dist/constants/api-endpoints.d.ts +6 -9
  59. package/dist/constants/api-endpoints.js +5 -5
  60. package/dist/constants/field-names.d.ts +17 -1
  61. package/dist/constants/field-names.js +17 -1
  62. package/dist/features/account/components/UserSidebar.js +21 -9
  63. package/dist/features/account/hooks/useNotifications.js +5 -0
  64. package/dist/features/admin/actions/admin-actions.js +6 -0
  65. package/dist/features/admin/actions/notification-actions.js +1 -2
  66. package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
  67. package/dist/features/admin/components/AdminGuideHubView.js +15 -1
  68. package/dist/features/admin/components/AdminPaymentsGuideView.d.ts +2 -0
  69. package/dist/features/admin/components/AdminPaymentsGuideView.js +36 -0
  70. package/dist/features/admin/components/AdminPrizeDrawsView.js +3 -3
  71. package/dist/features/admin/components/AdminSidebar.js +18 -9
  72. package/dist/features/admin/components/AdminSiteSettingsView.js +33 -6
  73. package/dist/features/admin/components/AdminTesterChecklistView.js +74 -22
  74. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +2 -0
  75. package/dist/features/admin/components/AdminWhatsAppGuideView.js +35 -0
  76. package/dist/features/admin/hooks/useAdminListing.d.ts +4 -0
  77. package/dist/features/admin/hooks/useAdminListing.js +4 -2
  78. package/dist/features/admin/schemas/firestore.d.ts +13 -5
  79. package/dist/features/admin/schemas/firestore.js +1 -2
  80. package/dist/features/auctions/actions/bid-actions.js +3 -1
  81. package/dist/features/auctions/components/AuctionBidsTable.d.ts +6 -1
  82. package/dist/features/auctions/components/AuctionBidsTable.js +8 -4
  83. package/dist/features/auctions/components/AuctionDetailPageView.js +10 -13
  84. package/dist/features/auctions/components/CollapsibleBidHistory.d.ts +23 -2
  85. package/dist/features/auctions/components/CollapsibleBidHistory.js +22 -3
  86. package/dist/features/auctions/components/LiveBidPrice.d.ts +19 -0
  87. package/dist/features/auctions/components/LiveBidPrice.js +17 -0
  88. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -1
  89. package/dist/features/auctions/components/PlaceBidFormClient.js +16 -1
  90. package/dist/features/auctions/hooks/useBids.d.ts +33 -0
  91. package/dist/features/auctions/hooks/useBids.js +32 -0
  92. package/dist/features/auctions/hooks/useLiveAuctionBid.d.ts +20 -0
  93. package/dist/features/auctions/hooks/useLiveAuctionBid.js +23 -0
  94. package/dist/features/auth/checkout-value-otp.d.ts +7 -10
  95. package/dist/features/auth/checkout-value-otp.js +14 -10
  96. package/dist/features/auth/server.d.ts +0 -1
  97. package/dist/features/auth/server.js +0 -1
  98. package/dist/features/blog/api/[slug]/route.d.ts +5 -0
  99. package/dist/features/blog/api/[slug]/route.js +12 -3
  100. package/dist/features/blog/components/BlogPostView.d.ts +2 -0
  101. package/dist/features/blog/components/BlogPostView.js +5 -4
  102. package/dist/features/blog/hooks/useBlog.d.ts +2 -0
  103. package/dist/features/blog/hooks/useBlog.js +2 -0
  104. package/dist/features/blog/repository/blog.repository.d.ts +7 -0
  105. package/dist/features/blog/repository/blog.repository.js +44 -0
  106. package/dist/features/blog/schemas/firestore.d.ts +3 -0
  107. package/dist/features/blog/schemas/firestore.js +1 -0
  108. package/dist/features/blog/types/index.d.ts +2 -0
  109. package/dist/features/cart/components/index.d.ts +0 -2
  110. package/dist/features/cart/components/index.js +0 -1
  111. package/dist/features/cart/hooks/useCartCount.js +22 -5
  112. package/dist/features/cart/hooks/useGuestCart.js +11 -1
  113. package/dist/features/cart/utils/guest-cart.d.ts +4 -0
  114. package/dist/features/cart/utils/guest-cart.js +10 -0
  115. package/dist/features/cart/utils/pending-ops.d.ts +17 -0
  116. package/dist/features/cart/utils/pending-ops.js +46 -5
  117. package/dist/features/categories/components/BrandDetailPageView.js +6 -2
  118. package/dist/features/categories/components/BundleDetailView.js +4 -2
  119. package/dist/features/categories/components/CategoryDetailPageView.js +10 -2
  120. package/dist/features/categories/schemas/firestore.d.ts +7 -0
  121. package/dist/features/checkout/actions/index.d.ts +0 -1
  122. package/dist/features/checkout/actions/index.js +0 -1
  123. package/dist/features/checkout/schemas/firestore.d.ts +2 -2
  124. package/dist/features/events/actions/event-actions.d.ts +2 -0
  125. package/dist/features/events/actions/event-actions.js +5 -0
  126. package/dist/features/events/components/EventCard.js +2 -3
  127. package/dist/features/events/components/RelatedEventsCarousel.d.ts +15 -0
  128. package/dist/features/events/components/RelatedEventsCarousel.js +13 -0
  129. package/dist/features/events/components/index.d.ts +2 -0
  130. package/dist/features/events/components/index.js +1 -0
  131. package/dist/features/events/repository/events.repository.d.ts +6 -0
  132. package/dist/features/events/repository/events.repository.js +21 -0
  133. package/dist/features/history/repository/user-history.repository.d.ts +1 -1
  134. package/dist/features/history/utils/guest-history.d.ts +1 -1
  135. package/dist/features/homepage/components/FeaturedBundlesSection.js +4 -2
  136. package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
  137. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  138. package/dist/features/homepage/components/WelcomeSection.js +1 -1
  139. package/dist/features/layout/AppLayoutShell.js +44 -10
  140. package/dist/features/layout/NavbarLayout.js +1 -1
  141. package/dist/features/layout/TitleBarLayout.js +2 -2
  142. package/dist/features/media/MediaVideo.d.ts +7 -0
  143. package/dist/features/media/MediaVideo.js +36 -5
  144. package/dist/features/orders/components/OrdersList.js +1 -5
  145. package/dist/features/orders/schemas/firestore.d.ts +2 -8
  146. package/dist/features/orders/schemas/index.d.ts +3 -32
  147. package/dist/features/orders/schemas/index.js +1 -4
  148. package/dist/features/orders/types/index.d.ts +6 -9
  149. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
  150. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
  151. package/dist/features/products/actions/product-actions.js +13 -10
  152. package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
  153. package/dist/features/products/components/MarketplaceBundleCard.js +7 -4
  154. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  155. package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
  156. package/dist/features/products/components/PrizeDrawWinnerMappingView.d.ts +14 -0
  157. package/dist/features/products/components/PrizeDrawWinnerMappingView.js +37 -0
  158. package/dist/features/products/components/PrizeRevealModal.d.ts +10 -23
  159. package/dist/features/products/components/PrizeRevealModal.js +18 -147
  160. package/dist/features/products/components/ProductDetailPageView.js +72 -30
  161. package/dist/features/products/components/ProductForm.js +7 -14
  162. package/dist/features/products/components/ProductGalleryClient.d.ts +10 -1
  163. package/dist/features/products/components/ProductGalleryClient.js +29 -10
  164. package/dist/features/products/components/ProductsIndexListing.js +2 -1
  165. package/dist/features/products/components/RelatedProductsCarousel.js +2 -2
  166. package/dist/features/products/components/ShowGroupSection.js +2 -2
  167. package/dist/features/products/components/SublistingCarouselSection.js +1 -1
  168. package/dist/features/products/components/index.d.ts +4 -2
  169. package/dist/features/products/components/index.js +1 -0
  170. package/dist/features/products/constants/action-defs.d.ts +1 -3
  171. package/dist/features/products/constants/action-defs.js +0 -5
  172. package/dist/features/products/repository/products.repository.d.ts +6 -0
  173. package/dist/features/products/repository/products.repository.js +20 -1
  174. package/dist/features/products/schemas/firestore.d.ts +28 -3
  175. package/dist/features/products/schemas/index.d.ts +11 -3
  176. package/dist/features/products/schemas/index.js +10 -2
  177. package/dist/features/products/types/index.d.ts +2 -1
  178. package/dist/features/reviews/actions/review-actions.js +1 -0
  179. package/dist/features/reviews/components/ReviewDetailPageView.js +8 -1
  180. package/dist/features/reviews/components/ReviewDetailShell.js +2 -1
  181. package/dist/features/reviews/components/ReviewsList.js +2 -1
  182. package/dist/features/reviews/schemas/firestore.d.ts +3 -0
  183. package/dist/features/reviews/schemas/index.d.ts +6 -0
  184. package/dist/features/reviews/schemas/index.js +2 -0
  185. package/dist/features/reviews/types/index.d.ts +3 -0
  186. package/dist/features/scams/actions/scam-actions.d.ts +3 -0
  187. package/dist/features/scams/actions/scam-actions.js +3 -2
  188. package/dist/features/scams/components/ScamProfileView.d.ts +2 -1
  189. package/dist/features/scams/components/ScamProfileView.js +2 -2
  190. package/dist/features/scams/repository/scammer.repository.d.ts +6 -0
  191. package/dist/features/scams/repository/scammer.repository.js +24 -0
  192. package/dist/features/seller/actions/seller-actions.js +8 -0
  193. package/dist/features/seller/components/SellerPrizeDrawsView.js +4 -0
  194. package/dist/features/seller/components/SellerSidebar.js +20 -9
  195. package/dist/features/stores/components/StoreDetailLayoutView.js +6 -6
  196. package/dist/features/stores/components/StoreGuideHubView.js +7 -1
  197. package/dist/features/stores/components/StoreNavTabs.d.ts +10 -1
  198. package/dist/features/stores/components/StoreNavTabs.js +22 -9
  199. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +3 -0
  200. package/dist/features/stores/components/StoreWhatsAppGuideView.js +12 -0
  201. package/dist/features/stores/components/index.d.ts +2 -0
  202. package/dist/features/stores/components/index.js +1 -0
  203. package/dist/features/tester/actions/index.d.ts +1 -0
  204. package/dist/features/tester/actions/index.js +1 -0
  205. package/dist/features/tester/actions/leaderboard-actions.d.ts +3 -0
  206. package/dist/features/tester/actions/leaderboard-actions.js +5 -0
  207. package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +26 -4
  208. package/dist/features/tester/components/AdminTesterFeedbackListView.js +13 -0
  209. package/dist/features/tester/components/BugHunterLeaderboardView.d.ts +23 -0
  210. package/dist/features/tester/components/BugHunterLeaderboardView.js +18 -0
  211. package/dist/features/tester/components/index.d.ts +2 -0
  212. package/dist/features/tester/components/index.js +1 -0
  213. package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +12 -1
  214. package/dist/features/tester/repository/tester-checklist-item.repository.js +80 -0
  215. package/dist/features/tester/repository/tester-checklist-response.repository.d.ts +4 -0
  216. package/dist/features/tester/repository/tester-checklist-response.repository.js +4 -0
  217. package/dist/features/tester/schemas/firestore.d.ts +22 -1
  218. package/dist/features/tester/schemas/firestore.js +8 -0
  219. package/dist/features/tester/seed-data/categories-tester-seed-data.js +42 -7
  220. package/dist/features/tester/seed-data/events-tester-seed-data.js +23 -0
  221. package/dist/features/tester/seed-data/orders-tester-seed-data.js +69 -31
  222. package/dist/features/tester/seed-data/products-tester-seed-data.js +154 -9
  223. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +252 -15
  224. package/dist/features/wishlist/hooks/useGuestWishlist.js +11 -1
  225. package/dist/features/wishlist/hooks/useWishlistCount.js +16 -2
  226. package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -0
  227. package/dist/features/wishlist/utils/guest-wishlist.js +11 -0
  228. package/dist/index.d.ts +23 -22
  229. package/dist/index.js +31 -58
  230. package/dist/jobs.d.ts +1 -1
  231. package/dist/jobs.js +2 -2
  232. package/dist/next/routing/route-map.d.ts +9 -2
  233. package/dist/next/routing/route-map.js +4 -1
  234. package/dist/schemas/registry.d.ts +6 -26
  235. package/dist/seed/bids-seed-data.js +14 -2
  236. package/dist/seed/blog-posts-seed-data.js +2 -1
  237. package/dist/seed/categories-seed-data.js +11 -2
  238. package/dist/seed/events-seed-data.js +11 -11
  239. package/dist/seed/faq-seed-data.js +5 -1
  240. package/dist/seed/products-auctions-seed-data.js +2 -2
  241. package/dist/seed/products-preorders-seed-data.d.ts +2 -1
  242. package/dist/seed/products-prize-draws-seed-data.js +56 -10
  243. package/dist/seed/products-standard-seed-data.js +80 -3
  244. package/dist/seed/scammers-seed-data.js +75 -2
  245. package/dist/seed/site-settings-seed-data.js +5 -2
  246. package/dist/server-entry.d.ts +0 -1
  247. package/dist/server-entry.js +0 -1
  248. package/dist/server.d.ts +4 -20
  249. package/dist/server.js +10 -57
  250. package/dist/styles.css +1 -277
  251. package/dist/tailwind-utilities.css +1 -1
  252. package/dist/ui/components/BaseListingCard.js +1 -1
  253. package/dist/ui/components/ImageLightbox.d.ts +9 -0
  254. package/dist/ui/components/ImageLightbox.js +6 -3
  255. package/dist/ui/components/ListingToolbar.d.ts +18 -1
  256. package/dist/ui/components/ListingToolbar.js +5 -2
  257. package/dist/ui/components/StickyToolbar.js +13 -8
  258. package/package.json +1 -1
@@ -38,13 +38,15 @@ export { onStoreWriteHandler } from "./onStoreWrite";
38
38
  export { adminAnalyticsHandler } from "./adminAnalytics";
39
39
  export { storeAnalyticsHandler, } from "./storeAnalytics";
40
40
  export { listingProcessorHandler, supportedListingCollections, } from "./listingProcessor";
41
- // SB1-L (S7-PrizeDraws) — 7 functions covering prize draws, bundle sync,
42
- // event raffles, and spin-the-wheel.
43
- export { prizeRevealOpenHandler } from "./prizeRevealOpen";
44
- export { prizeRevealCloseHandler } from "./prizeRevealClose";
45
- export { prizeRevealExpiryHandler } from "./prizeRevealExpiry";
46
- export { prizeRevealReminderHandler } from "./prizeRevealReminder";
41
+ // SB1-L (S7-PrizeDraws) — bundle sync, event raffles, and spin-the-wheel.
42
+ // Prize-draw reveal itself was redesigned to a fully-automatic model — see
43
+ // prizeDrawAssignWinner.ts (shared core), onPrizeDrawPaymentConfirmed
44
+ // (instant mode), prizeDrawSoldOutReveal (scheduled mode, sellout half), and
45
+ // prizeDrawExpiryReveal (scheduled mode, expiry half) below.
47
46
  export { bundleStockSyncHandler } from "./bundleStockSync";
47
+ export { onPrizeDrawPaymentConfirmedHandler } from "./onPrizeDrawPaymentConfirmed";
48
+ export { prizeDrawSoldOutRevealHandler } from "./prizeDrawSoldOutReveal";
49
+ export { prizeDrawExpiryRevealHandler } from "./prizeDrawExpiryReveal";
48
50
  // SB-UNI-V — Firestore onWrite trigger for product stock changes (recomputes
49
51
  // bundleStockStatus on categoryType:"bundle" rows + activeMemberCount on
50
52
  // groupedListings).
@@ -0,0 +1,3 @@
1
+ import type { FirestoreTriggerHandler } from "../runtime/types";
2
+ import { type PrizeDrawOrderSnapshot } from "../core/onPrizeDrawPaymentConfirmed";
3
+ export declare const onPrizeDrawPaymentConfirmedHandler: FirestoreTriggerHandler<PrizeDrawOrderSnapshot, PrizeDrawOrderSnapshot>;
@@ -0,0 +1,11 @@
1
+ import { handlePrizeDrawPaymentConfirmed, } from "../core/onPrizeDrawPaymentConfirmed";
2
+ export const onPrizeDrawPaymentConfirmedHandler = async (event, ctx) => {
3
+ const before = event.before;
4
+ const after = event.after;
5
+ if (!after)
6
+ return;
7
+ // Only act on the paid transition — avoids re-firing on every other order write.
8
+ if (before?.paymentStatus === "paid" || after.paymentStatus !== "paid")
9
+ return;
10
+ await handlePrizeDrawPaymentConfirmed({ orderId: event.params.orderId, order: after }, ctx);
11
+ };
@@ -0,0 +1,2 @@
1
+ import type { ScheduleHandler } from "../runtime/types";
2
+ export declare const prizeDrawExpiryRevealHandler: ScheduleHandler;
@@ -0,0 +1,2 @@
1
+ import { runPrizeDrawExpiryReveal } from "../core/prizeDrawExpiryReveal";
2
+ export const prizeDrawExpiryRevealHandler = runPrizeDrawExpiryReveal;
@@ -0,0 +1,3 @@
1
+ import type { FirestoreTriggerHandler } from "../runtime/types";
2
+ import { type PrizeDrawStockSnapshot } from "../core/prizeDrawSoldOutReveal";
3
+ export declare const prizeDrawSoldOutRevealHandler: FirestoreTriggerHandler<PrizeDrawStockSnapshot, PrizeDrawStockSnapshot>;
@@ -0,0 +1,4 @@
1
+ import { handlePrizeDrawSoldOut, } from "../core/prizeDrawSoldOutReveal";
2
+ export const prizeDrawSoldOutRevealHandler = async (event, ctx) => {
3
+ await handlePrizeDrawSoldOut({ productId: event.params.productId, before: event.before, after: event.after }, ctx);
4
+ };
@@ -747,6 +747,14 @@ export const ACTIONS = {
747
747
  kind: "ghost",
748
748
  },
749
749
  // ── Order lifecycle ─────────────────────────────────────────────────
750
+ "view-order": {
751
+ id: "user.view-order",
752
+ label: "View Details",
753
+ ariaLabel: "View order details",
754
+ description: "Open the full details of this order.",
755
+ kind: "ghost",
756
+ iconKey: "Eye",
757
+ },
750
758
  "track-order": {
751
759
  id: "user.track-order",
752
760
  label: "Track Order",
@@ -1346,6 +1354,34 @@ export const ACTIONS = {
1346
1354
  confirmKind: "danger",
1347
1355
  },
1348
1356
  },
1357
+ "confirm-bug": {
1358
+ id: "admin.confirm-bug",
1359
+ label: "Mark as Bug",
1360
+ ariaLabel: "Confirm this as a real bug and credit the reporting tester",
1361
+ description: "Confirms this reported issue as a real bug, credits the reporting tester as the bug hunter, and disables the case for all other testers.",
1362
+ kind: "danger",
1363
+ permissions: ["admin"],
1364
+ confirmation: {
1365
+ title: "Confirm this bug?",
1366
+ body: "This credits the reporting tester as the bug hunter for this case and disables it so no other tester can answer it. This can't be undone from the UI.",
1367
+ confirmLabel: "Mark as Bug",
1368
+ confirmKind: "danger",
1369
+ },
1370
+ },
1371
+ "reopen-checklist-item": {
1372
+ id: "admin.reopen-checklist-item",
1373
+ label: "Reopen as New Test Case",
1374
+ ariaLabel: "Reopen this fixed case as a new version for retest",
1375
+ description: "Once a confirmed bug is fixed, reopen it as a new version (v+1) for testers to retest — the old disabled case stays in the database with its bug-hunter credit intact.",
1376
+ kind: "secondary",
1377
+ permissions: ["admin"],
1378
+ confirmation: {
1379
+ title: "Reopen this case for retest?",
1380
+ body: "This creates a new, active version of this test case for testers to answer again. The old case stays disabled in the database — its bug-hunter credit is not affected.",
1381
+ confirmLabel: "Reopen",
1382
+ confirmKind: "primary",
1383
+ },
1384
+ },
1349
1385
  "resend-notification": {
1350
1386
  id: "admin.resend-notification",
1351
1387
  label: "Resend",
@@ -1930,26 +1966,20 @@ export const ACTIONS = {
1930
1966
  },
1931
1967
  "continue-to-verification": {
1932
1968
  id: "checkout.continue-to-verification",
1933
- label: "Continue to Verification",
1934
- description: "Advance from address selection to identity verification step.",
1935
- kind: "primary",
1936
- },
1937
- "send-otp": {
1938
- id: "checkout.send-otp",
1939
- label: "Send verification code",
1940
- description: "Send a one-time code to the buyer's registered email to verify identity before checkout.",
1969
+ label: "Continue",
1970
+ description: "Advance from address selection to the payment step.",
1941
1971
  kind: "primary",
1942
1972
  },
1943
1973
  "verify-otp": {
1944
1974
  id: "checkout.verify-otp",
1945
1975
  label: "Verify & Continue",
1946
- description: "Submit the one-time code and proceed to payment selection.",
1976
+ description: "Submit the high-value-order one-time code and proceed to payment.",
1947
1977
  kind: "primary",
1948
1978
  },
1949
1979
  "resend-otp": {
1950
1980
  id: "checkout.resend-otp",
1951
1981
  label: "Resend code",
1952
- description: "Re-send the verification code to the buyer's registered email.",
1982
+ description: "Re-send the high-value-order verification code to the buyer's registered email.",
1953
1983
  kind: "ghost",
1954
1984
  },
1955
1985
  "pay-online": {
@@ -5,7 +5,6 @@ export const DEFAULT_LISTING_RULE = {
5
5
  cartEligible: true,
6
6
  cartIneligibleHint: "This listing type cannot be added to the cart.",
7
7
  requiresShippingAddress: true,
8
- requiresConsentOtp: true,
9
8
  nonRefundable: false,
10
9
  maxQuantityPerLine: STANDARD_MAX_QTY_PER_LINE,
11
10
  canMergeWithSameProduct: true,
@@ -13,7 +12,7 @@ export const DEFAULT_LISTING_RULE = {
13
12
  refundPolicy: { full: true, partial: true, partialGranularity: "item" },
14
13
  splitKey: (item) => `standard:${item.storeId ?? "unknown"}`,
15
14
  splitMultipleOrders: (item) => [item],
16
- preflightChecks: (_pairs) => { },
15
+ preflightChecks: (_pairs, _paymentMethod) => { },
17
16
  stockDecrementExtras: (_product, _qty) => ({}),
18
17
  stockIncrementExtras: (_product, _qty) => ({}),
19
18
  decorateOrderItem: (line, product) => ({
@@ -13,6 +13,9 @@ export declare const CHECKOUT_MAX_ORDERS_PER_TX = 20;
13
13
  * reveal flow.
14
14
  */
15
15
  export declare const PRIZE_DRAW_MAX_REVEALS_PER_ORDER = 3;
16
+ /** Seller-facing prize-draw duration cap, in days — enforced by the Zod schema and the seller form. */
17
+ export declare const PRIZE_DRAW_DURATION_DAYS_MIN = 1;
18
+ export declare const PRIZE_DRAW_DURATION_DAYS_MAX = 15;
16
19
  /** Maximum qty per bundle purchase (bundles are always single-shot direct buys). */
17
20
  export declare const BUNDLE_MAX_QTY_PER_TX = 1;
18
21
  /** Standard / pre-order max qty per cart line (enforced at addToCart). */
@@ -13,6 +13,9 @@ export const CHECKOUT_MAX_ORDERS_PER_TX = 20;
13
13
  * reveal flow.
14
14
  */
15
15
  export const PRIZE_DRAW_MAX_REVEALS_PER_ORDER = 3;
16
+ /** Seller-facing prize-draw duration cap, in days — enforced by the Zod schema and the seller form. */
17
+ export const PRIZE_DRAW_DURATION_DAYS_MIN = 1;
18
+ export const PRIZE_DRAW_DURATION_DAYS_MAX = 15;
16
19
  /** Maximum qty per bundle purchase (bundles are always single-shot direct buys). */
17
20
  export const BUNDLE_MAX_QTY_PER_TX = 1;
18
21
  /** Standard / pre-order max qty per cart line (enforced at addToCart). */
@@ -12,6 +12,7 @@ import type { ListingType } from "../../../../features/products/types/index";
12
12
  import type { CartItemDocument } from "../../../../features/cart/schemas/firestore";
13
13
  import type { ListingCheckoutRule, CategoryCheckoutRule, CartItemProductPair } from "./types";
14
14
  import type { OrderType } from "../../../../features/orders/utils/order-splitter";
15
+ import type { CheckoutPaymentMethod } from "../../features/checkout/config";
15
16
  export declare const CHECKOUT_RULES: Record<ListingType, ListingCheckoutRule>;
16
17
  export declare const CATEGORY_CHECKOUT_RULES: Record<string, CategoryCheckoutRule>;
17
18
  /**
@@ -41,4 +42,4 @@ export declare function getSplitKey(item: CartItemDocument): string;
41
42
  * Note: the async maxPerUser cap check remains in the server-only
42
43
  * `enforceMaxPerUserForCart` (prize-bundle-gates.ts) and runs separately.
43
44
  */
44
- export declare function runSyncPreflight(pairs: CartItemProductPair[]): void;
45
+ export declare function runSyncPreflight(pairs: CartItemProductPair[], paymentMethod?: CheckoutPaymentMethod): void;
@@ -74,7 +74,7 @@ export function getSplitKey(item) {
74
74
  * Note: the async maxPerUser cap check remains in the server-only
75
75
  * `enforceMaxPerUserForCart` (prize-bundle-gates.ts) and runs separately.
76
76
  */
77
- export function runSyncPreflight(pairs) {
77
+ export function runSyncPreflight(pairs, paymentMethod) {
78
78
  const byType = new Map();
79
79
  for (const pair of pairs) {
80
80
  if (pair.item.bundleProductIds?.length)
@@ -86,6 +86,6 @@ export function runSyncPreflight(pairs) {
86
86
  }
87
87
  for (const [lt, ltPairs] of byType) {
88
88
  const rule = CHECKOUT_RULES[lt] ?? CHECKOUT_RULES.standard;
89
- rule.preflightChecks(ltPairs);
89
+ rule.preflightChecks(ltPairs, paymentMethod);
90
90
  }
91
91
  }
@@ -6,5 +6,4 @@ export const classifiedRule = {
6
6
  cartEligible: false,
7
7
  cartIneligibleHint: 'Use "Contact Seller" to arrange a meetup.',
8
8
  requiresShippingAddress: false,
9
- requiresConsentOtp: false,
10
9
  };
@@ -1,6 +1,6 @@
1
1
  export type { ListingCheckoutRule, CategoryCheckoutRule, CartItemProductPair, OrderItemInput, RefundPolicy, } from "./types";
2
2
  export { CHECKOUT_RULES, CATEGORY_CHECKOUT_RULES, getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPreflight, } from "./_registry";
3
- export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits";
3
+ export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, PRIZE_DRAW_DURATION_DAYS_MIN, PRIZE_DRAW_DURATION_DAYS_MAX, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits";
4
4
  export { standardRule } from "./standard.rule";
5
5
  export { auctionRule } from "./auction.rule";
6
6
  export { preOrderRule } from "./preorder.rule";
@@ -1,5 +1,5 @@
1
1
  export { CHECKOUT_RULES, CATEGORY_CHECKOUT_RULES, getListingRule, getCategoryRule, pickOrderType, getSplitKey, runSyncPreflight, } from "./_registry";
2
- export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits";
2
+ export { CART_MAX_ITEMS, CHECKOUT_MAX_ORDERS_PER_TX, PRIZE_DRAW_MAX_REVEALS_PER_ORDER, PRIZE_DRAW_DURATION_DAYS_MIN, PRIZE_DRAW_DURATION_DAYS_MAX, BUNDLE_MAX_QTY_PER_TX, STANDARD_MAX_QTY_PER_LINE, } from "./_limits";
3
3
  // Individual rules — exported for tests and direct access.
4
4
  export { standardRule } from "./standard.rule";
5
5
  export { auctionRule } from "./auction.rule";
@@ -1,6 +1,15 @@
1
1
  import { ValidationError } from "../../../../errors";
2
2
  import { DEFAULT_LISTING_RULE } from "./_defaults";
3
3
  import { PRIZE_DRAW_MAX_REVEALS_PER_ORDER } from "./_limits";
4
+ /**
5
+ * Deferred/unconfirmed-payment methods are not allowed for prize-draw
6
+ * checkout — instant-mode winner assignment triggers on the order's payment
7
+ * actually being confirmed, which cod/cash/emi don't guarantee happens (or
8
+ * happens promptly). Only "upi_manual" (bank/UPI transfer, confirmed later by
9
+ * seller/admin) and "online" (Razorpay, confirms near-instantly) are allowed;
10
+ * "admin_bypass" stays usable for QA regardless.
11
+ */
12
+ const PRIZE_DRAW_BLOCKED_PAYMENT_METHODS = ["cod", "cash", "emi"];
4
13
  export const prizeDrawRule = {
5
14
  ...DEFAULT_LISTING_RULE,
6
15
  orderType: "prize-draw",
@@ -9,6 +18,7 @@ export const prizeDrawRule = {
9
18
  canMergeWithSameProduct: false,
10
19
  maxLinesPerOrder: PRIZE_DRAW_MAX_REVEALS_PER_ORDER,
11
20
  refundPolicy: { full: false, partial: false, partialGranularity: "none" },
21
+ blockedPaymentMethods: PRIZE_DRAW_BLOCKED_PAYMENT_METHODS,
12
22
  splitKey: (item) => `prize-draw:${item.itemId}`,
13
23
  /**
14
24
  * Slice a high-quantity prize-draw entry into chunks of
@@ -33,7 +43,13 @@ export const prizeDrawRule = {
33
43
  }
34
44
  return chunks;
35
45
  },
36
- preflightChecks: (pairs) => {
46
+ preflightChecks: (pairs, paymentMethod) => {
47
+ if (paymentMethod && PRIZE_DRAW_BLOCKED_PAYMENT_METHODS.includes(paymentMethod)) {
48
+ const hasPrizeDraw = pairs.some((p) => p.product.listingType === "prize-draw");
49
+ if (hasPrizeDraw) {
50
+ throw Object.assign(new ValidationError("Prize-draw entries can only be paid by manual bank/UPI transfer or Razorpay — cash on delivery and EMI are not available for this listing type."), { code: "PRIZE_DRAW_PAYMENT_METHOD_BLOCKED" });
51
+ }
52
+ }
37
53
  for (const { item, product } of pairs) {
38
54
  if (product.listingType !== "prize-draw")
39
55
  continue;
@@ -68,5 +84,8 @@ export const prizeDrawRule = {
68
84
  decorateOrderDoc: (_groupFirstItem, groupFirstProduct) => ({
69
85
  prizeDrawProductId: groupFirstProduct.id,
70
86
  isNonRefundable: true,
87
+ ...(groupFirstProduct.prizeRevealMode
88
+ ? { prizeRevealMode: groupFirstProduct.prizeRevealMode }
89
+ : {}),
71
90
  }),
72
91
  };
@@ -15,6 +15,7 @@ import type { JsonValue } from "@mohasinac/appkit";
15
15
  import type { ProductDocument } from "../../../../features/products/schemas/firestore";
16
16
  import type { OrderDocumentItem } from "../../../../features/orders/schemas/firestore";
17
17
  import type { OrderType } from "../../../../features/orders/utils/order-splitter";
18
+ import type { CheckoutPaymentMethod } from "../../features/checkout/config";
18
19
  export interface CartItemProductPair {
19
20
  item: CartItemDocument;
20
21
  product: ProductDocument;
@@ -56,8 +57,6 @@ export interface ListingCheckoutRule {
56
57
  * delivery) and classified (meetup-arranged locally).
57
58
  */
58
59
  requiresShippingAddress: boolean;
59
- /** Does checkout require the consent-OTP gate? */
60
- requiresConsentOtp: boolean;
61
60
  /**
62
61
  * Is this order non-refundable? Blocks the refund API for orders of this type.
63
62
  * Set true for prize-draw entries.
@@ -79,6 +78,13 @@ export interface ListingCheckoutRule {
79
78
  maxLinesPerOrder: number;
80
79
  /** Full/partial refund capabilities per type. */
81
80
  refundPolicy: RefundPolicy;
81
+ /**
82
+ * Payment methods this listing type cannot be paid with. Undefined/empty =
83
+ * all methods allowed. Prize-draw blocks cod/cash/emi — winner assignment
84
+ * depends on the order's payment actually being confirmed, which those
85
+ * deferred-payment methods don't guarantee.
86
+ */
87
+ blockedPaymentMethods?: CheckoutPaymentMethod[];
82
88
  /**
83
89
  * Return the grouping key used by the order splitter. Items with the same
84
90
  * key land in the same OrderGroup and produce one order document.
@@ -95,10 +101,14 @@ export interface ListingCheckoutRule {
95
101
  * Throws ValidationError on violation; returns void on pass.
96
102
  * Receives only data already in memory (no IO needed).
97
103
  *
98
- * Pre-order checks reservationCap. Prize-draw checks prizeMaxEntries.
99
- * Future `live` checks jurisdiction from product + buyer state.
104
+ * Pre-order checks reservationCap. Prize-draw checks prizeMaxEntries +
105
+ * blockedPaymentMethods. Future `live` checks jurisdiction from product +
106
+ * buyer state.
107
+ *
108
+ * `paymentMethod` is optional so existing rules that don't need it (every
109
+ * type except prize-draw today) don't have to accept/ignore the param.
100
110
  */
101
- preflightChecks(pairs: CartItemProductPair[]): void;
111
+ preflightChecks(pairs: CartItemProductPair[], paymentMethod?: CheckoutPaymentMethod): void;
102
112
  /**
103
113
  * Return extra Firestore field updates to merge alongside the standard
104
114
  * `availableQuantity` decrement. Pure — works from product data already
@@ -121,13 +131,13 @@ export interface ListingCheckoutRule {
121
131
  /**
122
132
  * Transform a raw order-line input (built from cart item data) before it
123
133
  * is written to the OrderDocument. Adds type-specific fields such as
124
- * prize-draw reveal status and deadline.
134
+ * prize-draw reveal status.
125
135
  */
126
136
  decorateOrderItem(line: OrderItemInput, product: ProductDocument): OrderItemInput;
127
137
  /**
128
138
  * Return extra fields to spread onto the created OrderDocument.
129
139
  * Used for prize-draw-specific fields (prizeDrawProductId, isNonRefundable,
130
- * prizeRevealDeadline).
140
+ * prizeRevealMode).
131
141
  */
132
142
  decorateOrderDoc(groupFirstItem: CartItemDocument, groupFirstProduct: ProductDocument): Record<string, JsonValue>;
133
143
  }
@@ -28,6 +28,8 @@ export declare const BUNDLE_COPY: {
28
28
  readonly priceFallback: "—";
29
29
  readonly itemCount: (n: number) => string;
30
30
  readonly emptyMembers: "Bundle contents are being updated. Check back shortly.";
31
+ readonly discountBadge: (percent: number) => string;
32
+ readonly savingsLabel: (formattedSavings: string) => string;
31
33
  readonly ctaDisabled: "Add to cart coming soon";
32
34
  readonly ctaHint: "Bundle checkout is being wired up — buyers can browse contents now and the buy flow ships in the next release.";
33
35
  readonly ctaAddToCart: "Add bundle to cart";
@@ -30,6 +30,8 @@ export const BUNDLE_COPY = {
30
30
  priceFallback: "—",
31
31
  itemCount: (n) => `${n} item${n !== 1 ? "s" : ""}`,
32
32
  emptyMembers: "Bundle contents are being updated. Check back shortly.",
33
+ discountBadge: (percent) => `${percent}% OFF`,
34
+ savingsLabel: (formattedSavings) => `You save ${formattedSavings}`,
33
35
  // SB-UNI-5 2026-05-13 — CTA functional. Disabled-CTA copy retained for
34
36
  // consumers that opt out of the wired CTA (the new client island reads
35
37
  // the active strings below).
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bundle discount math — single source of truth for turning
3
+ * `bundlePrice` + `bundleOriginalTotal` (sum of member products' individual
4
+ * prices, denormalised onto the bundle doc at write time — see
5
+ * `resolveBundleOriginalTotal` in `_internal/server/features/bundles/data.ts`)
6
+ * into a displayable "X% OFF" figure.
7
+ *
8
+ * Pure — no React, no Firestore. Safe to import from any bundle view.
9
+ */
10
+ export interface BundleDiscount {
11
+ /** Sum of member products' individual prices (decimal rupees). */
12
+ originalTotal: number;
13
+ /** originalTotal - bundlePrice (decimal rupees). */
14
+ savings: number;
15
+ /** Rounded whole-number percentage off, e.g. 25 for "25% OFF". */
16
+ percent: number;
17
+ }
18
+ /**
19
+ * Returns null when there's nothing genuine to show — either total is
20
+ * missing/zero, or the bundle price isn't actually cheaper than buying the
21
+ * parts separately (a mispriced bundle is not "a discount").
22
+ */
23
+ export declare function computeBundleDiscount(bundlePrice?: number, bundleOriginalTotal?: number): BundleDiscount | null;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Bundle discount math — single source of truth for turning
3
+ * `bundlePrice` + `bundleOriginalTotal` (sum of member products' individual
4
+ * prices, denormalised onto the bundle doc at write time — see
5
+ * `resolveBundleOriginalTotal` in `_internal/server/features/bundles/data.ts`)
6
+ * into a displayable "X% OFF" figure.
7
+ *
8
+ * Pure — no React, no Firestore. Safe to import from any bundle view.
9
+ */
10
+ /**
11
+ * Returns null when there's nothing genuine to show — either total is
12
+ * missing/zero, or the bundle price isn't actually cheaper than buying the
13
+ * parts separately (a mispriced bundle is not "a discount").
14
+ */
15
+ export function computeBundleDiscount(bundlePrice, bundleOriginalTotal) {
16
+ if (!bundlePrice || !bundleOriginalTotal)
17
+ return null;
18
+ if (bundleOriginalTotal <= bundlePrice)
19
+ return null;
20
+ const savings = bundleOriginalTotal - bundlePrice;
21
+ const percent = Math.round((savings / bundleOriginalTotal) * 100);
22
+ if (percent <= 0)
23
+ return null;
24
+ return { originalTotal: bundleOriginalTotal, savings, percent };
25
+ }
@@ -6,7 +6,7 @@ export const config = {
6
6
  listingType: LISTING_TYPE,
7
7
  slugPrefix: "prizedraw-",
8
8
  cartLine: "single-product",
9
- detailRoute: (idOrSlug) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(idOrSlug)),
9
+ detailRoute: (idOrSlug) => String(ROUTES.PUBLIC.PRIZE_DRAW_DETAIL(idOrSlug)),
10
10
  badge: undefined,
11
11
  priceLabel: "Price (₹)",
12
12
  typeLabel: "Prize Draw",
@@ -118,10 +118,12 @@ export declare const ADMIN_ENDPOINTS: {
118
118
  readonly FAQ_BY_ID: (id: string) => string;
119
119
  readonly TESTER_CHECKLIST_ITEMS: "/api/admin/tester-checklist-items";
120
120
  readonly TESTER_CHECKLIST_ITEM_BY_ID: (id: string) => string;
121
+ readonly TESTER_CHECKLIST_ITEM_REOPEN: (id: string) => string;
121
122
  readonly TESTER_FEEDBACK: "/api/admin/tester-feedback";
122
123
  readonly TESTER_FEEDBACK_BY_ID: (id: string) => string;
123
124
  readonly TESTER_FEEDBACK_REPORT: "/api/admin/tester-feedback/report";
124
125
  readonly TESTER_FEEDBACK_EXPORT: "/api/admin/tester-feedback/export";
126
+ readonly TESTER_FEEDBACK_CONFIRM_BUG: (id: string) => string;
125
127
  readonly STORES: "/api/admin/stores";
126
128
  readonly STORE_BY_ID: (uid: string) => string;
127
129
  readonly PAYOUTS: "/api/admin/payouts";
@@ -331,9 +333,6 @@ export declare const PRODUCT_ENDPOINTS: {
331
333
  readonly BY_IDS: (ids: string) => string;
332
334
  readonly GROUP_BY_ID: (groupId: string) => string;
333
335
  };
334
- export declare const PRIZE_DRAW_ENDPOINTS: {
335
- readonly REVEAL: (productId: string) => string;
336
- };
337
336
  export declare const SUBLISTING_CATEGORY_ENDPOINTS: {
338
337
  readonly BY_ID: (id: string) => string;
339
338
  };
@@ -566,10 +565,12 @@ export declare const API_ENDPOINTS: {
566
565
  readonly FAQ_BY_ID: (id: string) => string;
567
566
  readonly TESTER_CHECKLIST_ITEMS: "/api/admin/tester-checklist-items";
568
567
  readonly TESTER_CHECKLIST_ITEM_BY_ID: (id: string) => string;
568
+ readonly TESTER_CHECKLIST_ITEM_REOPEN: (id: string) => string;
569
569
  readonly TESTER_FEEDBACK: "/api/admin/tester-feedback";
570
570
  readonly TESTER_FEEDBACK_BY_ID: (id: string) => string;
571
571
  readonly TESTER_FEEDBACK_REPORT: "/api/admin/tester-feedback/report";
572
572
  readonly TESTER_FEEDBACK_EXPORT: "/api/admin/tester-feedback/export";
573
+ readonly TESTER_FEEDBACK_CONFIRM_BUG: (id: string) => string;
573
574
  readonly STORES: "/api/admin/stores";
574
575
  readonly STORE_BY_ID: (uid: string) => string;
575
576
  readonly PAYOUTS: "/api/admin/payouts";
@@ -782,9 +783,6 @@ export declare const API_ENDPOINTS: {
782
783
  readonly BY_IDS: (ids: string) => string;
783
784
  readonly GROUP_BY_ID: (groupId: string) => string;
784
785
  };
785
- readonly PRIZE_DRAWS: {
786
- readonly REVEAL: (productId: string) => string;
787
- };
788
786
  readonly PROMOTIONS: {
789
787
  readonly LIST: "/api/coupons";
790
788
  readonly COUPON_BY_CODE: (code: string) => string;
@@ -1016,10 +1014,12 @@ export declare const API_ROUTES: {
1016
1014
  readonly FAQ_BY_ID: (id: string) => string;
1017
1015
  readonly TESTER_CHECKLIST_ITEMS: "/api/admin/tester-checklist-items";
1018
1016
  readonly TESTER_CHECKLIST_ITEM_BY_ID: (id: string) => string;
1017
+ readonly TESTER_CHECKLIST_ITEM_REOPEN: (id: string) => string;
1019
1018
  readonly TESTER_FEEDBACK: "/api/admin/tester-feedback";
1020
1019
  readonly TESTER_FEEDBACK_BY_ID: (id: string) => string;
1021
1020
  readonly TESTER_FEEDBACK_REPORT: "/api/admin/tester-feedback/report";
1022
1021
  readonly TESTER_FEEDBACK_EXPORT: "/api/admin/tester-feedback/export";
1022
+ readonly TESTER_FEEDBACK_CONFIRM_BUG: (id: string) => string;
1023
1023
  readonly STORES: "/api/admin/stores";
1024
1024
  readonly STORE_BY_ID: (uid: string) => string;
1025
1025
  readonly PAYOUTS: "/api/admin/payouts";
@@ -1232,9 +1232,6 @@ export declare const API_ROUTES: {
1232
1232
  readonly BY_IDS: (ids: string) => string;
1233
1233
  readonly GROUP_BY_ID: (groupId: string) => string;
1234
1234
  };
1235
- readonly PRIZE_DRAWS: {
1236
- readonly REVEAL: (productId: string) => string;
1237
- };
1238
1235
  readonly PROMOTIONS: {
1239
1236
  readonly LIST: "/api/coupons";
1240
1237
  readonly COUPON_BY_CODE: (code: string) => string;
@@ -145,10 +145,12 @@ export const ADMIN_ENDPOINTS = {
145
145
  FAQ_BY_ID: (id) => `/api/admin/faqs/${id}`,
146
146
  TESTER_CHECKLIST_ITEMS: "/api/admin/tester-checklist-items",
147
147
  TESTER_CHECKLIST_ITEM_BY_ID: (id) => `/api/admin/tester-checklist-items/${id}`,
148
+ TESTER_CHECKLIST_ITEM_REOPEN: (id) => `/api/admin/tester-checklist-items/${id}/reopen`,
148
149
  TESTER_FEEDBACK: "/api/admin/tester-feedback",
149
150
  TESTER_FEEDBACK_BY_ID: (id) => `/api/admin/tester-feedback/${id}`,
150
151
  TESTER_FEEDBACK_REPORT: "/api/admin/tester-feedback/report",
151
152
  TESTER_FEEDBACK_EXPORT: "/api/admin/tester-feedback/export",
153
+ TESTER_FEEDBACK_CONFIRM_BUG: (id) => `/api/admin/tester-feedback/${id}/confirm-bug`,
152
154
  STORES: "/api/admin/stores",
153
155
  STORE_BY_ID: (uid) => `/api/admin/stores/${uid}`,
154
156
  PAYOUTS: "/api/admin/payouts",
@@ -432,11 +434,10 @@ export const PRODUCT_ENDPOINTS = {
432
434
  GROUP_BY_ID: (groupId) => `/api/products/group/${encodeURIComponent(groupId)}`,
433
435
  };
434
436
  // ---------------------------------------------------------------------------
435
- // Prize Draws
437
+ // Prize Draws — no client-callable endpoints. Reveal is fully automatic
438
+ // (assignPrizeDrawWinner, triggered by payment confirmation / sellout /
439
+ // expiry) — there is no buyer-facing reveal action to call anymore.
436
440
  // ---------------------------------------------------------------------------
437
- export const PRIZE_DRAW_ENDPOINTS = {
438
- REVEAL: (productId) => `/api/prize-draws/${encodeURIComponent(productId)}/reveal`,
439
- };
440
441
  // ---------------------------------------------------------------------------
441
442
  // Sublisting Categories (public)
442
443
  // ---------------------------------------------------------------------------
@@ -641,7 +642,6 @@ export const API_ENDPOINTS = {
641
642
  ORDERS: ORDER_ENDPOINTS,
642
643
  PREORDERS: PREORDER_ENDPOINTS,
643
644
  PRODUCTS: PRODUCT_ENDPOINTS,
644
- PRIZE_DRAWS: PRIZE_DRAW_ENDPOINTS,
645
645
  PROMOTIONS: PROMOTION_ENDPOINTS,
646
646
  REVIEWS: REVIEW_ENDPOINTS,
647
647
  SEARCH: SEARCH_ENDPOINTS,
@@ -70,7 +70,11 @@ export declare const PRODUCT_FIELDS: {
70
70
  readonly PRIZE_REVEAL_STATUS: "prizeRevealStatus";
71
71
  readonly PRIZE_REVEAL_WINDOW_START: "prizeRevealWindowStart";
72
72
  readonly PRIZE_REVEAL_WINDOW_END: "prizeRevealWindowEnd";
73
- readonly PRIZE_REVEAL_DEADLINE: "prizeRevealDeadline";
73
+ readonly PRIZE_DRAW_DURATION_DAYS: "prizeDrawDurationDays";
74
+ readonly PRIZE_REVEAL_MODE: "prizeRevealMode";
75
+ readonly PRIZE_CURRENT_ENTRIES: "prizeCurrentEntries";
76
+ readonly PRIZE_MAX_ENTRIES: "prizeMaxEntries";
77
+ readonly PRIZE_DRAW_MODE: "prizeDrawMode";
74
78
  readonly IS_PART_OF_BUNDLE: "isPartOfBundle";
75
79
  readonly SEARCH_TOKENS: "searchTokens";
76
80
  readonly CREATED_AT: "createdAt";
@@ -111,6 +115,14 @@ export declare const PRODUCT_FIELDS: {
111
115
  readonly OPEN: "open";
112
116
  readonly CLOSED: "closed";
113
117
  };
118
+ readonly PRIZE_REVEAL_MODE_VALUES: {
119
+ readonly INSTANT: "instant";
120
+ readonly SCHEDULED: "scheduled";
121
+ };
122
+ readonly PRIZE_DRAW_MODE_VALUES: {
123
+ readonly REVEAL: "reveal";
124
+ readonly LOTTERY: "lottery";
125
+ };
114
126
  readonly IS_ACTIVE: "isActive";
115
127
  readonly DISPLAY_ORDER: "displayOrder";
116
128
  readonly LISTING_TYPE_VALUES: {
@@ -172,6 +184,9 @@ export declare const ORDER_FIELDS: {
172
184
  readonly PAYMENT_PROOF_URL: "paymentProofUrl";
173
185
  readonly PAYMENT_PROOF_UPLOADED_AT: "paymentProofUploadedAt";
174
186
  readonly PAYMENT_REVIEW_OUTCOME: "paymentReviewOutcome";
187
+ readonly PRIZE_WON: "prizeWon";
188
+ readonly PRIZE_DRAW_PRODUCT_ID: "prizeDrawProductId";
189
+ readonly PRIZE_REVEAL_MODE: "prizeRevealMode";
175
190
  readonly STATUS_VALUES: {
176
191
  readonly PENDING: "pending";
177
192
  readonly CONFIRMED: "confirmed";
@@ -425,6 +440,7 @@ export declare const CATEGORY_FIELDS: {
425
440
  readonly BUNDLE_ITEM_DETAILS: "bundleItemDetails";
426
441
  readonly BUNDLE_STOCK_STATUS: "bundleStockStatus";
427
442
  readonly BUNDLE_QUERY_RESOLVED_AT: "bundleQueryResolvedAt";
443
+ readonly BUNDLE_ORIGINAL_TOTAL: "bundleOriginalTotal";
428
444
  readonly DISPLAY: "display";
429
445
  readonly VIEW_COUNT: "viewCount";
430
446
  readonly CREATED_AT: "createdAt";
@@ -75,7 +75,11 @@ export const PRODUCT_FIELDS = {
75
75
  PRIZE_REVEAL_STATUS: "prizeRevealStatus",
76
76
  PRIZE_REVEAL_WINDOW_START: "prizeRevealWindowStart",
77
77
  PRIZE_REVEAL_WINDOW_END: "prizeRevealWindowEnd",
78
- PRIZE_REVEAL_DEADLINE: "prizeRevealDeadline",
78
+ PRIZE_DRAW_DURATION_DAYS: "prizeDrawDurationDays",
79
+ PRIZE_REVEAL_MODE: "prizeRevealMode",
80
+ PRIZE_CURRENT_ENTRIES: "prizeCurrentEntries",
81
+ PRIZE_MAX_ENTRIES: "prizeMaxEntries",
82
+ PRIZE_DRAW_MODE: "prizeDrawMode",
79
83
  IS_PART_OF_BUNDLE: "isPartOfBundle",
80
84
  SEARCH_TOKENS: "searchTokens",
81
85
  CREATED_AT: "createdAt",
@@ -116,6 +120,14 @@ export const PRODUCT_FIELDS = {
116
120
  OPEN: "open",
117
121
  CLOSED: "closed",
118
122
  },
123
+ PRIZE_REVEAL_MODE_VALUES: {
124
+ INSTANT: "instant",
125
+ SCHEDULED: "scheduled",
126
+ },
127
+ PRIZE_DRAW_MODE_VALUES: {
128
+ REVEAL: "reveal",
129
+ LOTTERY: "lottery",
130
+ },
119
131
  IS_ACTIVE: "isActive",
120
132
  DISPLAY_ORDER: "displayOrder",
121
133
  LISTING_TYPE_VALUES: {
@@ -185,6 +197,9 @@ export const ORDER_FIELDS = {
185
197
  PAYMENT_PROOF_URL: "paymentProofUrl",
186
198
  PAYMENT_PROOF_UPLOADED_AT: "paymentProofUploadedAt",
187
199
  PAYMENT_REVIEW_OUTCOME: "paymentReviewOutcome",
200
+ PRIZE_WON: "prizeWon",
201
+ PRIZE_DRAW_PRODUCT_ID: "prizeDrawProductId",
202
+ PRIZE_REVEAL_MODE: "prizeRevealMode",
188
203
  STATUS_VALUES: {
189
204
  PENDING: "pending",
190
205
  CONFIRMED: "confirmed",
@@ -466,6 +481,7 @@ export const CATEGORY_FIELDS = {
466
481
  BUNDLE_ITEM_DETAILS: "bundleItemDetails",
467
482
  BUNDLE_STOCK_STATUS: "bundleStockStatus",
468
483
  BUNDLE_QUERY_RESOLVED_AT: "bundleQueryResolvedAt",
484
+ BUNDLE_ORIGINAL_TOTAL: "bundleOriginalTotal",
469
485
  DISPLAY: "display",
470
486
  VIEW_COUNT: "viewCount",
471
487
  CREATED_AT: "createdAt",