@mohasinac/appkit 3.4.8 → 3.5.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 (605) hide show
  1. package/dist/_internal/client/features/classified/ClassifiedDetailView.js +1 -1
  2. package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +1 -1
  3. package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +1 -1
  4. package/dist/_internal/client/features/filters/filter-load-options.js +10 -9
  5. package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
  6. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +11 -4
  7. package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
  8. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +10 -3
  9. package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +2 -2
  10. package/dist/_internal/client/scaffolds/DashboardScaffold.js +3 -1
  11. package/dist/_internal/server/features/checkout/actions.d.ts +16 -0
  12. package/dist/_internal/server/features/checkout/actions.js +149 -35
  13. package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +31 -0
  14. package/dist/_internal/server/features/checkout/bundle-expansion.js +41 -0
  15. package/dist/_internal/server/features/lottery/actions.js +14 -4
  16. package/dist/_internal/server/features/maintenance/analyze.js +4 -2
  17. package/dist/_internal/server/features/orders/actions.js +9 -0
  18. package/dist/_internal/server/features/orders/adapters.js +19 -0
  19. package/dist/_internal/server/features/seo/robots.js +1 -1
  20. package/dist/_internal/server/functions/firestore.d.ts +47 -1
  21. package/dist/_internal/server/functions/firestore.js +56 -1
  22. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  23. package/dist/_internal/server/functions/scheduled.js +9 -1
  24. package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.d.ts +10 -0
  25. package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.js +49 -0
  26. package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +32 -0
  27. package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +26 -0
  28. package/dist/_internal/server/jobs/core/hardBanCascade.js +181 -0
  29. package/dist/_internal/server/jobs/core/index.d.ts +4 -1
  30. package/dist/_internal/server/jobs/core/index.js +4 -1
  31. package/dist/_internal/server/jobs/core/jobRunners.d.ts +28 -0
  32. package/dist/_internal/server/jobs/core/jobRunners.js +37 -0
  33. package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +15 -0
  34. package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +38 -0
  35. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +22 -0
  36. package/dist/_internal/server/jobs/core/onJobCreated.js +59 -0
  37. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.d.ts +6 -1
  38. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -2
  39. package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.d.ts +2 -0
  40. package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.js +2 -0
  41. package/dist/_internal/server/jobs/handlers/index.d.ts +6 -0
  42. package/dist/_internal/server/jobs/handlers/index.js +8 -0
  43. package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.d.ts +12 -0
  44. package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.js +20 -0
  45. package/dist/_internal/server/jobs/handlers/onJobCreated.d.ts +3 -0
  46. package/dist/_internal/server/jobs/handlers/onJobCreated.js +9 -0
  47. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +25 -0
  48. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +71 -0
  49. package/dist/_internal/server/jobs/handlers/onShipmentDeleted.d.ts +14 -0
  50. package/dist/_internal/server/jobs/handlers/onShipmentDeleted.js +23 -0
  51. package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +17 -0
  52. package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +26 -0
  53. package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +3 -1
  54. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  55. package/dist/_internal/shared/actions/action-registry.js +136 -0
  56. package/dist/_internal/shared/features/blog/schema.d.ts +8 -8
  57. package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
  58. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +8 -8
  59. package/dist/_internal/shared/features/events/schema.d.ts +4 -4
  60. package/dist/_internal/shared/features/products/schema.d.ts +8 -8
  61. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  62. package/dist/_internal/shared/features/reviews/schema.d.ts +4 -4
  63. package/dist/client/api/useFeatureFlags.d.ts +22 -0
  64. package/dist/client/api/useFeatureFlags.js +27 -0
  65. package/dist/client/observability/reportClientError.js +3 -2
  66. package/dist/client.d.ts +4 -2
  67. package/dist/client.js +2 -1
  68. package/dist/configs/next.js +1 -0
  69. package/dist/constants/api-endpoints.d.ts +279 -3
  70. package/dist/constants/api-endpoints.js +130 -2
  71. package/dist/core/hooks/useSyncManager.js +5 -4
  72. package/dist/errors/conflict-error.d.ts +4 -0
  73. package/dist/errors/conflict-error.js +6 -0
  74. package/dist/errors/index.d.ts +1 -0
  75. package/dist/errors/index.js +1 -0
  76. package/dist/features/about/components/FeesView.js +2 -2
  77. package/dist/features/about/components/HelpPageView.js +2 -2
  78. package/dist/features/about/components/HowAuctionsWorkView.js +2 -2
  79. package/dist/features/about/components/HowCheckoutWorksView.js +2 -2
  80. package/dist/features/about/components/HowEmiWorksView.js +2 -2
  81. package/dist/features/about/components/HowOffersWorkView.js +3 -3
  82. package/dist/features/about/components/HowOrdersWorkView.js +3 -3
  83. package/dist/features/about/components/HowPayoutsWorkView.js +2 -2
  84. package/dist/features/about/components/HowPreOrdersWorkView.js +2 -2
  85. package/dist/features/about/components/HowReviewsWorkView.js +2 -2
  86. package/dist/features/about/components/PublicProfileView.d.ts +8 -1
  87. package/dist/features/about/components/PublicProfileView.js +11 -9
  88. package/dist/features/about/components/SecurityPrivacyView.js +2 -2
  89. package/dist/features/about/components/UnauthorizedView.js +2 -2
  90. package/dist/features/account/components/AddressBook.js +1 -1
  91. package/dist/features/account/components/AddressesIndexListing.js +1 -1
  92. package/dist/features/account/components/NotificationBell.js +5 -5
  93. package/dist/features/account/components/NotificationPreferencesPanel.js +5 -2
  94. package/dist/features/account/components/UserOffersPanel.js +5 -4
  95. package/dist/features/account/components/UserSidebar.js +2 -2
  96. package/dist/features/account/components/UserSupportView.js +3 -3
  97. package/dist/features/account/schemas/index.d.ts +12 -12
  98. package/dist/features/addresses/schemas/index.d.ts +6 -6
  99. package/dist/features/admin/components/AdminAdEditorView.js +3 -3
  100. package/dist/features/admin/components/AdminAddressEditorView.js +3 -3
  101. package/dist/features/admin/components/AdminAdsView.js +3 -3
  102. package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
  103. package/dist/features/admin/components/AdminBlogView.js +12 -15
  104. package/dist/features/admin/components/AdminBrandEditorView.js +1 -1
  105. package/dist/features/admin/components/AdminBrandsView.js +12 -13
  106. package/dist/features/admin/components/AdminBundleEditorView.js +5 -4
  107. package/dist/features/admin/components/AdminBundlesView.js +32 -23
  108. package/dist/features/admin/components/AdminCarouselEditorView.js +5 -5
  109. package/dist/features/admin/components/AdminCarouselView.js +2 -2
  110. package/dist/features/admin/components/AdminCatalogGuideView.js +1 -1
  111. package/dist/features/admin/components/AdminCategoriesView.js +12 -13
  112. package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
  113. package/dist/features/admin/components/AdminContactEditorView.js +2 -2
  114. package/dist/features/admin/components/AdminCouponEditorView.d.ts +10 -1
  115. package/dist/features/admin/components/AdminCouponEditorView.js +7 -2
  116. package/dist/features/admin/components/AdminCouponsView.js +32 -27
  117. package/dist/features/admin/components/AdminEmployeeEditorView.js +3 -3
  118. package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
  119. package/dist/features/admin/components/AdminFaqsView.js +20 -20
  120. package/dist/features/admin/components/AdminFeatureEditorView.js +5 -5
  121. package/dist/features/admin/components/AdminFeaturesView.js +9 -10
  122. package/dist/features/admin/components/AdminFilterBar.js +1 -1
  123. package/dist/features/admin/components/AdminFulfillmentView.js +4 -4
  124. package/dist/features/admin/components/AdminGuideHubView.js +2 -2
  125. package/dist/features/admin/components/AdminMediaView.js +3 -2
  126. package/dist/features/admin/components/AdminNavigationView.js +1 -1
  127. package/dist/features/admin/components/AdminOrderEditorView.js +3 -3
  128. package/dist/features/admin/components/AdminOrdersView.js +21 -30
  129. package/dist/features/admin/components/AdminPageHeader.js +3 -3
  130. package/dist/features/admin/components/AdminPayoutsView.js +8 -8
  131. package/dist/features/admin/components/AdminPrizeDrawsView.js +8 -9
  132. package/dist/features/admin/components/AdminProductEditorView.d.ts +9 -1
  133. package/dist/features/admin/components/AdminProductEditorView.js +7 -4
  134. package/dist/features/admin/components/AdminProductsView.js +30 -41
  135. package/dist/features/admin/components/AdminReviewsView.js +14 -17
  136. package/dist/features/admin/components/AdminScammerEditorView.js +5 -5
  137. package/dist/features/admin/components/AdminSectionsView.js +3 -3
  138. package/dist/features/admin/components/AdminSessionsView.js +8 -10
  139. package/dist/features/admin/components/AdminSidebar.js +2 -2
  140. package/dist/features/admin/components/AdminSiteSettingsView.js +10 -3
  141. package/dist/features/admin/components/AdminStoreEditorView.js +4 -5
  142. package/dist/features/admin/components/AdminStoresView.js +18 -13
  143. package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
  144. package/dist/features/admin/components/AdminTeamView.js +9 -5
  145. package/dist/features/admin/components/AdminUsersView.js +19 -15
  146. package/dist/features/admin/components/AdminViewCards.js +5 -5
  147. package/dist/features/admin/components/DashboardStats.js +1 -1
  148. package/dist/features/admin/components/DataListingView.js +2 -2
  149. package/dist/features/admin/components/DataTable.js +2 -2
  150. package/dist/features/admin/components/DrawerFormFooter.js +1 -1
  151. package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +2 -2
  152. package/dist/features/admin/components/analytics/AdminStatCard.js +1 -1
  153. package/dist/features/admin/hooks/useAdminListing.d.ts +3 -2
  154. package/dist/features/admin/hooks/useAdminListing.js +8 -2
  155. package/dist/features/admin/permission-map.js +2 -0
  156. package/dist/features/admin/schemas/firestore.d.ts +7 -0
  157. package/dist/features/admin/schemas/firestore.js +4 -0
  158. package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
  159. package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
  160. package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
  161. package/dist/features/auctions/components/MarketplaceAuctionGrid.js +4 -4
  162. package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
  163. package/dist/features/auctions/schemas/index.d.ts +16 -16
  164. package/dist/features/auth/permissions/constants.d.ts +1 -1
  165. package/dist/features/auth/permissions/constants.js +2 -0
  166. package/dist/features/auth/schemas/index.d.ts +6 -6
  167. package/dist/features/before-after/schemas/index.d.ts +3 -3
  168. package/dist/features/blog/actions/blog-actions.d.ts +32 -32
  169. package/dist/features/blog/components/BlogFeaturedCard.js +2 -2
  170. package/dist/features/blog/components/BlogIndexListing.js +2 -2
  171. package/dist/features/blog/components/BlogListView.js +4 -4
  172. package/dist/features/blog/components/BlogPostView.js +4 -4
  173. package/dist/features/blog/schemas/index.d.ts +77 -77
  174. package/dist/features/cart/components/CartDrawer.js +2 -2
  175. package/dist/features/catalogue/actions/approve-catalogue-listing.d.ts +12 -0
  176. package/dist/features/catalogue/actions/approve-catalogue-listing.js +50 -0
  177. package/dist/features/catalogue/actions/list-from-catalogue.d.ts +17 -0
  178. package/dist/features/catalogue/actions/list-from-catalogue.js +50 -0
  179. package/dist/features/catalogue/actions/submit-for-approval.d.ts +8 -0
  180. package/dist/features/catalogue/actions/submit-for-approval.js +30 -0
  181. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.d.ts +2 -0
  182. package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +53 -0
  183. package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +7 -0
  184. package/dist/features/catalogue/components/CatalogueItemEditorView.js +79 -0
  185. package/dist/features/catalogue/components/PublicCatalogueView.d.ts +5 -0
  186. package/dist/features/catalogue/components/PublicCatalogueView.js +22 -0
  187. package/dist/features/catalogue/components/UserCatalogueView.d.ts +12 -0
  188. package/dist/features/catalogue/components/UserCatalogueView.js +51 -0
  189. package/dist/features/catalogue/index.d.ts +12 -0
  190. package/dist/features/catalogue/index.js +9 -0
  191. package/dist/features/catalogue/repository/catalogue.repository.d.ts +39 -0
  192. package/dist/features/catalogue/repository/catalogue.repository.js +68 -0
  193. package/dist/features/catalogue/schemas/firestore.d.ts +47 -0
  194. package/dist/features/catalogue/schemas/firestore.js +22 -0
  195. package/dist/features/catalogue/schemas/index.d.ts +2 -0
  196. package/dist/features/catalogue/schemas/index.js +2 -0
  197. package/dist/features/catalogue/schemas/validation.d.ts +71 -0
  198. package/dist/features/catalogue/schemas/validation.js +25 -0
  199. package/dist/features/catalogue/utils/freshness.d.ts +10 -0
  200. package/dist/features/catalogue/utils/freshness.js +15 -0
  201. package/dist/features/catalogue/utils/product-from-item.d.ts +15 -0
  202. package/dist/features/catalogue/utils/product-from-item.js +34 -0
  203. package/dist/features/categories/components/BrandDetailPageView.js +1 -1
  204. package/dist/features/categories/components/BrandDetailTabs.js +2 -2
  205. package/dist/features/categories/components/BundleCollage.js +2 -2
  206. package/dist/features/categories/components/BundleItemsPicker.js +3 -2
  207. package/dist/features/categories/components/CategoriesIndexListing.js +8 -6
  208. package/dist/features/categories/components/CategoryBundlesListing.js +10 -4
  209. package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
  210. package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
  211. package/dist/features/categories/components/CategoryGrid.js +3 -3
  212. package/dist/features/categories/components/CategoryProductsListing.js +1 -1
  213. package/dist/features/categories/components/CategorySortSelect.js +1 -1
  214. package/dist/features/categories/components/CategoryStoresListing.js +1 -1
  215. package/dist/features/categories/components/CategoryTableColumns.js +1 -1
  216. package/dist/features/categories/components/CategoryTree.js +2 -2
  217. package/dist/features/categories/components/ConcernCard.js +1 -1
  218. package/dist/features/categories/hooks/useCategories.js +1 -1
  219. package/dist/features/categories/schemas/index.d.ts +32 -32
  220. package/dist/features/classified/components/ClassifiedFilters.js +2 -2
  221. package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
  222. package/dist/features/collections/schemas/index.d.ts +2 -2
  223. package/dist/features/consultation/components/ConsultationForm.js +1 -1
  224. package/dist/features/consultation/schemas/index.d.ts +10 -10
  225. package/dist/features/contact/components/ContactForm.js +4 -4
  226. package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
  227. package/dist/features/contact/components/ContactPageView.js +2 -1
  228. package/dist/features/copilot/components/AdminCopilotView.js +5 -4
  229. package/dist/features/corporate/schemas/index.d.ts +2 -2
  230. package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +3 -3
  231. package/dist/features/events/components/AdminEventEditorView.js +4 -4
  232. package/dist/features/events/components/AdminEventEntriesView.js +2 -2
  233. package/dist/features/events/components/AdminEventsView.js +8 -8
  234. package/dist/features/events/components/EventBanner.js +1 -1
  235. package/dist/features/events/components/EventCard.js +3 -3
  236. package/dist/features/events/components/EventLeaderboard.js +1 -1
  237. package/dist/features/events/components/EventOfferCard.js +1 -1
  238. package/dist/features/events/components/EventPollWidget.js +6 -5
  239. package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
  240. package/dist/features/events/components/EventRaffleWinnerView.js +5 -5
  241. package/dist/features/events/components/EventRafflesSection.js +1 -1
  242. package/dist/features/events/components/EventSaleBanner.js +1 -1
  243. package/dist/features/events/components/EventsIndexListing.js +4 -2
  244. package/dist/features/events/components/EventsListView.js +2 -2
  245. package/dist/features/events/components/SpinWheelView.js +11 -5
  246. package/dist/features/events/schemas/index.d.ts +100 -100
  247. package/dist/features/faq/actions/faq-actions.d.ts +6 -6
  248. package/dist/features/faq/components/ContactCTA.js +3 -3
  249. package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
  250. package/dist/features/faq/components/FAQHelpfulButtons.js +3 -3
  251. package/dist/features/faq/schemas/index.d.ts +12 -12
  252. package/dist/features/filters/AsyncFacetSection.js +4 -4
  253. package/dist/features/filters/FilterFacetSection.js +8 -8
  254. package/dist/features/filters/RangeFilter.js +2 -2
  255. package/dist/features/filters/SwitchFilter.js +1 -1
  256. package/dist/features/forms/Checkbox.js +2 -8
  257. package/dist/features/forms/Input.js +2 -1
  258. package/dist/features/forms/Radio.js +3 -3
  259. package/dist/features/forms/Select.d.ts +1 -1
  260. package/dist/features/forms/Select.js +3 -2
  261. package/dist/features/forms/Slider.js +5 -11
  262. package/dist/features/forms/Textarea.js +2 -1
  263. package/dist/features/grouped/schemas/index.d.ts +6 -6
  264. package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
  265. package/dist/features/homepage/components/AdvertisementBanner.js +4 -4
  266. package/dist/features/homepage/components/AnnouncementBar.js +3 -3
  267. package/dist/features/homepage/components/BeforeAfterCard.js +1 -1
  268. package/dist/features/homepage/components/BrandsSection.js +9 -9
  269. package/dist/features/homepage/components/CTABannerSection.js +1 -1
  270. package/dist/features/homepage/components/CharacterHotspot.js +4 -4
  271. package/dist/features/homepage/components/CharacterHotspotForm.js +15 -13
  272. package/dist/features/homepage/components/CollectionCardsSection.js +1 -1
  273. package/dist/features/homepage/components/CustomCardsSection.js +6 -6
  274. package/dist/features/homepage/components/CustomerReviewsSection.js +2 -2
  275. package/dist/features/homepage/components/FAQSection.js +2 -2
  276. package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -3
  277. package/dist/features/homepage/components/FeaturedResultsSection.js +2 -2
  278. package/dist/features/homepage/components/GoogleReviewsSection.js +6 -6
  279. package/dist/features/homepage/components/HeroBanner.js +1 -1
  280. package/dist/features/homepage/components/HeroCarousel.js +5 -4
  281. package/dist/features/homepage/components/HeroSection.js +1 -7
  282. package/dist/features/homepage/components/HomepageSkeleton.js +1 -1
  283. package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
  284. package/dist/features/homepage/components/HowItWorksSection.js +2 -2
  285. package/dist/features/homepage/components/NewsletterBanner.js +2 -2
  286. package/dist/features/homepage/components/NewsletterSection.js +1 -1
  287. package/dist/features/homepage/components/PromoGrid.js +1 -1
  288. package/dist/features/homepage/components/SectionCarousel.js +6 -6
  289. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  290. package/dist/features/homepage/components/ShopByCategorySection.js +10 -10
  291. package/dist/features/homepage/components/SiteFeaturesSection.js +2 -2
  292. package/dist/features/homepage/components/SocialFeedSection.js +5 -5
  293. package/dist/features/homepage/components/SocialPostCard.js +1 -1
  294. package/dist/features/homepage/components/StatsCounterSection.js +1 -1
  295. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  296. package/dist/features/homepage/components/TrustBadges.js +1 -1
  297. package/dist/features/homepage/components/TrustFeaturesSection.js +2 -2
  298. package/dist/features/homepage/components/TrustIndicatorsSection.js +2 -2
  299. package/dist/features/homepage/components/WelcomeSection.js +2 -2
  300. package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
  301. package/dist/features/homepage/hooks/useActiveAd.js +2 -1
  302. package/dist/features/homepage/schemas/firestore.d.ts +10 -0
  303. package/dist/features/homepage/schemas/index.d.ts +116 -116
  304. package/dist/features/jobs/actions/enqueue-job.d.ts +24 -0
  305. package/dist/features/jobs/actions/enqueue-job.js +44 -0
  306. package/dist/features/jobs/repository/jobs.repository.d.ts +21 -0
  307. package/dist/features/jobs/repository/jobs.repository.js +48 -0
  308. package/dist/features/jobs/schemas/firestore.d.ts +54 -0
  309. package/dist/features/jobs/schemas/firestore.js +24 -0
  310. package/dist/features/layout/AppLayoutShell.js +17 -11
  311. package/dist/features/layout/AutoBreadcrumbs.js +1 -1
  312. package/dist/features/layout/BackToTop.js +2 -2
  313. package/dist/features/layout/BottomActions.js +7 -7
  314. package/dist/features/layout/BottomNavItem.js +2 -2
  315. package/dist/features/layout/BottomNavLayout.js +13 -4
  316. package/dist/features/layout/BottomNavbar.d.ts +9 -1
  317. package/dist/features/layout/BottomNavbar.js +12 -5
  318. package/dist/features/layout/BottomSheet.js +1 -1
  319. package/dist/features/layout/Breadcrumbs.js +1 -1
  320. package/dist/features/layout/FooterLayout.js +2 -2
  321. package/dist/features/layout/NavItem.js +3 -3
  322. package/dist/features/layout/NavbarLayout.js +6 -6
  323. package/dist/features/layout/SidebarLayout.d.ts +3 -0
  324. package/dist/features/layout/SidebarLayout.js +3 -3
  325. package/dist/features/layout/TitleBarLayout.js +4 -4
  326. package/dist/features/live/components/LiveItemFilters.js +2 -2
  327. package/dist/features/live/components/LiveItemsIndexListing.js +3 -3
  328. package/dist/features/lottery/types/index.d.ts +3 -1
  329. package/dist/features/lottery/types/index.js +16 -3
  330. package/dist/features/loyalty/components/CoinsDisplay.js +2 -2
  331. package/dist/features/media/MediaImage.d.ts +6 -1
  332. package/dist/features/media/MediaImage.js +10 -4
  333. package/dist/features/media/MediaLightbox.js +1 -1
  334. package/dist/features/media/MediaPickerModal.js +4 -3
  335. package/dist/features/media/MediaVideo.js +1 -1
  336. package/dist/features/media/modals/ImageCropModal.js +1 -1
  337. package/dist/features/media/modals/ImageEditor.js +1 -1
  338. package/dist/features/media/repository/media-assets.repository.d.ts +9 -0
  339. package/dist/features/media/types/index.d.ts +4 -4
  340. package/dist/features/media/upload/MediaUploadField.js +3 -3
  341. package/dist/features/media/upload/MediaUploadList.js +1 -1
  342. package/dist/features/messages/hooks/useConversation.js +4 -3
  343. package/dist/features/messages/hooks/useConversations.js +2 -1
  344. package/dist/features/messages/schemas/index.d.ts +6 -6
  345. package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
  346. package/dist/features/orders/components/OrderPaymentSummary.d.ts +16 -0
  347. package/dist/features/orders/components/OrderPaymentSummary.js +32 -0
  348. package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
  349. package/dist/features/orders/components/OrdersList.d.ts +7 -2
  350. package/dist/features/orders/components/OrdersList.js +5 -5
  351. package/dist/features/orders/components/RefundHistoryTable.js +1 -1
  352. package/dist/features/orders/components/RefundRequestView.js +1 -1
  353. package/dist/features/orders/components/index.d.ts +2 -0
  354. package/dist/features/orders/components/index.js +1 -0
  355. package/dist/features/orders/repository/orders.repository.d.ts +8 -0
  356. package/dist/features/orders/repository/orders.repository.js +24 -0
  357. package/dist/features/orders/schemas/firestore.d.ts +59 -0
  358. package/dist/features/orders/schemas/firestore.js +5 -0
  359. package/dist/features/orders/schemas/index.d.ts +91 -40
  360. package/dist/features/orders/schemas/index.js +10 -0
  361. package/dist/features/orders/types/index.d.ts +15 -0
  362. package/dist/features/payments/schemas/index.d.ts +12 -12
  363. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -5
  364. package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
  365. package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
  366. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +7 -7
  367. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +3 -3
  368. package/dist/features/pre-orders/schemas/index.d.ts +12 -12
  369. package/dist/features/products/columns/productTableColumns.js +2 -2
  370. package/dist/features/products/components/AuctionsIndexListing.js +3 -3
  371. package/dist/features/products/components/CompareOverlay.js +15 -10
  372. package/dist/features/products/components/CustomFieldsEditor.js +2 -2
  373. package/dist/features/products/components/CustomSectionsEditor.js +3 -3
  374. package/dist/features/products/components/FeatureBadge.js +2 -2
  375. package/dist/features/products/components/GroupSettingsPanel.js +5 -4
  376. package/dist/features/products/components/MakeOfferButton.js +4 -4
  377. package/dist/features/products/components/MarketplaceBundleCard.js +3 -2
  378. package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
  379. package/dist/features/products/components/PrizeDrawCollage.js +6 -6
  380. package/dist/features/products/components/PrizeDrawDetailPageView.js +5 -5
  381. package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
  382. package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -4
  383. package/dist/features/products/components/PrizeDrawsIndexListing.js +11 -4
  384. package/dist/features/products/components/PrizeDrawsSection.js +1 -1
  385. package/dist/features/products/components/PrizeRevealModal.js +9 -4
  386. package/dist/features/products/components/ProductDetailActions.js +2 -1
  387. package/dist/features/products/components/ProductDetailPageView.js +16 -16
  388. package/dist/features/products/components/ProductFeaturesSelector.js +5 -5
  389. package/dist/features/products/components/ProductForm.js +1 -1
  390. package/dist/features/products/components/ProductGalleryClient.js +5 -3
  391. package/dist/features/products/components/ProductGrid.js +11 -11
  392. package/dist/features/products/components/ProductTabs.js +2 -2
  393. package/dist/features/products/components/ProductTabsShell.js +2 -1
  394. package/dist/features/products/components/ProductsIndexListing.js +6 -1
  395. package/dist/features/products/components/ShareButton.js +2 -1
  396. package/dist/features/products/components/ShowGroupSection.js +9 -5
  397. package/dist/features/products/components/SublistingCarouselSection.js +8 -4
  398. package/dist/features/products/constants/action-defs.d.ts +10 -2
  399. package/dist/features/products/constants/action-defs.js +20 -2
  400. package/dist/features/products/schemas/firestore.d.ts +5 -0
  401. package/dist/features/products/schemas/index.d.ts +40 -40
  402. package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
  403. package/dist/features/promotions/components/CouponCard.js +13 -7
  404. package/dist/features/promotions/components/CouponsIndexListing.js +4 -6
  405. package/dist/features/promotions/components/PromotionsView.js +2 -2
  406. package/dist/features/promotions/schemas/index.d.ts +26 -26
  407. package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
  408. package/dist/features/reviews/components/ReviewDetailShell.js +11 -11
  409. package/dist/features/reviews/components/ReviewModal.js +1 -1
  410. package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
  411. package/dist/features/reviews/components/ReviewsList.js +2 -2
  412. package/dist/features/reviews/schemas/index.d.ts +22 -22
  413. package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
  414. package/dist/features/scams/components/ScamProfileView.js +3 -3
  415. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  416. package/dist/features/scams/schemas/index.d.ts +20 -20
  417. package/dist/features/search/components/Search.js +9 -9
  418. package/dist/features/search/components/SearchFiltersRow.js +1 -1
  419. package/dist/features/search/components/SearchResultsSection.js +3 -3
  420. package/dist/features/search/components/SearchView.js +1 -1
  421. package/dist/features/search/hooks/useNavSuggestions.js +2 -1
  422. package/dist/features/search/hooks/useSearch.js +2 -2
  423. package/dist/features/search/schemas/index.d.ts +3 -3
  424. package/dist/features/seller/components/BrandInlineSelect.js +2 -2
  425. package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
  426. package/dist/features/seller/components/QuickProductForm.js +1 -1
  427. package/dist/features/seller/components/SellerAddressesView.js +4 -4
  428. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +3 -3
  429. package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
  430. package/dist/features/seller/components/SellerArtView.js +11 -11
  431. package/dist/features/seller/components/SellerAuctionsView.js +11 -11
  432. package/dist/features/seller/components/SellerBidsView.js +3 -3
  433. package/dist/features/seller/components/SellerBundlesView.js +12 -12
  434. package/dist/features/seller/components/SellerClassifiedView.js +11 -11
  435. package/dist/features/seller/components/SellerCouponEditorView.js +2 -2
  436. package/dist/features/seller/components/SellerDigitalCodesView.js +11 -11
  437. package/dist/features/seller/components/SellerFeaturesView.js +4 -4
  438. package/dist/features/seller/components/SellerLiveView.js +11 -11
  439. package/dist/features/seller/components/SellerOffersPanel.js +3 -2
  440. package/dist/features/seller/components/SellerOrdersView.js +2 -2
  441. package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
  442. package/dist/features/seller/components/SellerPayoutRequestView.js +6 -5
  443. package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -4
  444. package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
  445. package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
  446. package/dist/features/seller/components/SellerProductShell.js +20 -6
  447. package/dist/features/seller/components/SellerProductsCards.js +3 -3
  448. package/dist/features/seller/components/SellerProductsView.js +4 -4
  449. package/dist/features/seller/components/SellerReviewsView.js +7 -6
  450. package/dist/features/seller/components/SellerShippingView.js +2 -1
  451. package/dist/features/seller/components/SellerSidebar.js +5 -5
  452. package/dist/features/seller/components/SellerStickersView.js +11 -11
  453. package/dist/features/seller/components/SellerTemplatesView.js +1 -1
  454. package/dist/features/seller/schemas/index.d.ts +20 -20
  455. package/dist/features/server-errors/schemas/index.d.ts +6 -6
  456. package/dist/features/shell/CommandPalette.d.ts +27 -0
  457. package/dist/features/shell/CommandPalette.js +92 -0
  458. package/dist/features/shell/FormShell.js +4 -3
  459. package/dist/features/shell/QuickFormDrawer.js +3 -2
  460. package/dist/features/shell/StepForm.js +2 -2
  461. package/dist/features/shell/index.d.ts +2 -0
  462. package/dist/features/shell/index.js +1 -0
  463. package/dist/features/shipments/components/AdminShipmentEditorView.d.ts +7 -0
  464. package/dist/features/shipments/components/AdminShipmentEditorView.js +123 -0
  465. package/dist/features/shipments/components/AdminShipmentLotItemsView.d.ts +6 -0
  466. package/dist/features/shipments/components/AdminShipmentLotItemsView.js +96 -0
  467. package/dist/features/shipments/components/AdminShipmentProjectionsView.d.ts +9 -0
  468. package/dist/features/shipments/components/AdminShipmentProjectionsView.js +44 -0
  469. package/dist/features/shipments/components/AdminShipmentsView.d.ts +8 -0
  470. package/dist/features/shipments/components/AdminShipmentsView.js +82 -0
  471. package/dist/features/shipments/components/ShipmentItemLinkModal.d.ts +15 -0
  472. package/dist/features/shipments/components/ShipmentItemLinkModal.js +37 -0
  473. package/dist/features/shipments/hooks/useShipments.d.ts +69 -0
  474. package/dist/features/shipments/hooks/useShipments.js +96 -0
  475. package/dist/features/shipments/index.d.ts +10 -0
  476. package/dist/features/shipments/index.js +7 -0
  477. package/dist/features/shipments/manifest.d.ts +2 -0
  478. package/dist/features/shipments/manifest.js +26 -0
  479. package/dist/features/shipments/repository/shipment-items.repository.d.ts +56 -0
  480. package/dist/features/shipments/repository/shipment-items.repository.js +78 -0
  481. package/dist/features/shipments/repository/shipment-lots.repository.d.ts +48 -0
  482. package/dist/features/shipments/repository/shipment-lots.repository.js +55 -0
  483. package/dist/features/shipments/repository/shipments.repository.d.ts +50 -0
  484. package/dist/features/shipments/repository/shipments.repository.js +77 -0
  485. package/dist/features/shipments/schemas/firestore.d.ts +150 -0
  486. package/dist/features/shipments/schemas/firestore.js +76 -0
  487. package/dist/features/shipments/schemas/index.d.ts +2 -0
  488. package/dist/features/shipments/schemas/index.js +2 -0
  489. package/dist/features/shipments/schemas/validation.d.ts +350 -0
  490. package/dist/features/shipments/schemas/validation.js +96 -0
  491. package/dist/features/shipments/utils/cost-allocation.d.ts +25 -0
  492. package/dist/features/shipments/utils/cost-allocation.js +83 -0
  493. package/dist/features/site-settings/components/ActionPermissionsManager.js +2 -2
  494. package/dist/features/stores/components/InteractiveStoreCard.js +2 -2
  495. package/dist/features/stores/components/StoreAboutView.js +1 -1
  496. package/dist/features/stores/components/StoreAuctionsListing.js +3 -3
  497. package/dist/features/stores/components/StoreAuctionsView.js +1 -1
  498. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
  499. package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
  500. package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
  501. package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
  502. package/dist/features/stores/components/StoreFinanceGuideView.js +2 -2
  503. package/dist/features/stores/components/StoreGuideHubView.js +2 -2
  504. package/dist/features/stores/components/StoreHeader.js +4 -4
  505. package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
  506. package/dist/features/stores/components/StoreNavTabs.js +2 -2
  507. package/dist/features/stores/components/StoreOrdersGuideView.js +1 -1
  508. package/dist/features/stores/components/StorePreOrdersListing.js +3 -3
  509. package/dist/features/stores/components/StoreProductsListing.js +1 -1
  510. package/dist/features/stores/components/StoreReviewsListing.js +2 -2
  511. package/dist/features/stores/components/StoreReviewsView.js +1 -1
  512. package/dist/features/stores/components/StoreSettingsGuideView.js +1 -1
  513. package/dist/features/stores/components/StoresIndexListing.js +9 -3
  514. package/dist/features/stores/schemas/index.d.ts +10 -10
  515. package/dist/features/support/schemas/index.d.ts +22 -22
  516. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +3 -3
  517. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +1 -1
  518. package/dist/features/wishlist/hooks/useWishlistCount.js +1 -2
  519. package/dist/index.d.ts +44 -1
  520. package/dist/index.js +37 -1
  521. package/dist/next/routing/route-map.d.ts +18 -0
  522. package/dist/next/routing/route-map.js +9 -0
  523. package/dist/react/hooks/useVisualViewportInset.d.ts +1 -0
  524. package/dist/react/hooks/useVisualViewportInset.js +59 -0
  525. package/dist/react/index.d.ts +1 -0
  526. package/dist/react/index.js +1 -0
  527. package/dist/repositories/index.d.ts +5 -0
  528. package/dist/repositories/index.js +5 -0
  529. package/dist/schemas/registry.d.ts +398 -364
  530. package/dist/schemas/sieve.d.ts +2 -2
  531. package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
  532. package/dist/schemas/webhooks/razorpay.d.ts +100 -100
  533. package/dist/seed/_helpers/media.js +1 -0
  534. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  535. package/dist/seed/catalogue-seed-data.d.ts +2 -0
  536. package/dist/seed/catalogue-seed-data.js +112 -0
  537. package/dist/seed/grouped-listings-seed-data.d.ts +5 -0
  538. package/dist/seed/homepage-sections-seed-data.js +0 -1
  539. package/dist/seed/index.d.ts +2 -0
  540. package/dist/seed/index.js +2 -0
  541. package/dist/seed/manifest.js +6 -0
  542. package/dist/seed/products-preorders-seed-data.d.ts +5 -0
  543. package/dist/seed/shipments-seed-data.d.ts +5 -0
  544. package/dist/seed/shipments-seed-data.js +185 -0
  545. package/dist/server.d.ts +4 -0
  546. package/dist/server.js +5 -0
  547. package/dist/styles.css +75 -19
  548. package/dist/tailwind-utilities.css +1 -1
  549. package/dist/tokens/index.d.ts +0 -2
  550. package/dist/tokens/index.js +0 -2
  551. package/dist/tokens/tokens.css +12 -2
  552. package/dist/ui/DataTable.js +4 -3
  553. package/dist/ui/components/Button.d.ts +4 -1
  554. package/dist/ui/components/Button.js +11 -5
  555. package/dist/ui/components/Checkbox.d.ts +9 -1
  556. package/dist/ui/components/Checkbox.js +5 -2
  557. package/dist/ui/components/ClaimCouponButton.js +2 -1
  558. package/dist/ui/components/ConfirmDeleteModal.style.css +1 -1
  559. package/dist/ui/components/Drawer.style.css +13 -1
  560. package/dist/ui/components/Dropdown.style.css +2 -2
  561. package/dist/ui/components/FilterDrawer.d.ts +4 -1
  562. package/dist/ui/components/FilterDrawer.js +8 -2
  563. package/dist/ui/components/Form.d.ts +1 -1
  564. package/dist/ui/components/Form.js +2 -2
  565. package/dist/ui/components/FormActionBar.style.css +6 -1
  566. package/dist/ui/components/IconButton.d.ts +6 -1
  567. package/dist/ui/components/IconButton.js +5 -2
  568. package/dist/ui/components/IconButton.style.css +11 -0
  569. package/dist/ui/components/ImageGallery.style.css +2 -0
  570. package/dist/ui/components/ImageLightbox.style.css +1 -0
  571. package/dist/ui/components/ListingFilterDrawer.d.ts +4 -1
  572. package/dist/ui/components/ListingFilterDrawer.js +4 -3
  573. package/dist/ui/components/ListingLayout.style.css +2 -2
  574. package/dist/ui/components/Modal.style.css +1 -1
  575. package/dist/ui/components/Pagination.d.ts +5 -1
  576. package/dist/ui/components/Pagination.js +4 -2
  577. package/dist/ui/components/RowActionMenu.js +1 -1
  578. package/dist/ui/components/RowActionMenu.style.css +1 -1
  579. package/dist/ui/components/Select.d.ts +6 -1
  580. package/dist/ui/components/Select.js +18 -13
  581. package/dist/ui/components/Select.style.css +1 -1
  582. package/dist/ui/components/Semantic.d.ts +13 -0
  583. package/dist/ui/components/Semantic.js +16 -3
  584. package/dist/ui/components/SideDrawer.style.css +16 -4
  585. package/dist/ui/components/SideModal.style.css +1 -1
  586. package/dist/ui/components/StickyToolbar.d.ts +3 -2
  587. package/dist/ui/components/StickyToolbar.js +1 -1
  588. package/dist/ui/components/Textarea.d.ts +5 -0
  589. package/dist/ui/components/Textarea.js +8 -4
  590. package/dist/ui/components/Toast.style.css +3 -0
  591. package/dist/ui/components/UnsavedChangesModal.style.css +1 -1
  592. package/dist/ui/components/surface-tokens.d.ts +121 -113
  593. package/dist/ui/components/surface-tokens.js +110 -104
  594. package/dist/ui/forms/FormShell.d.ts +8 -27
  595. package/dist/ui/forms/FormShell.js +1 -194
  596. package/dist/ui/forms/index.d.ts +2 -2
  597. package/dist/ui/forms/index.js +1 -1
  598. package/dist/ui/index.d.ts +8 -4
  599. package/dist/ui/index.js +4 -2
  600. package/dist/utils/id-generators.d.ts +27 -0
  601. package/dist/utils/id-generators.js +45 -0
  602. package/dist/utils/number.formatter.d.ts +7 -0
  603. package/dist/utils/number.formatter.js +9 -0
  604. package/dist/validation/schemas.d.ts +5 -5
  605. package/package.json +1 -1
@@ -55,3 +55,34 @@ export interface StockShortfall {
55
55
  * that product, not just this item's slice.
56
56
  */
57
57
  export declare function validateCartItemStock(item: CartItemDocument, productById: Map<string, ProductDocument>, decrements: Map<string, number>): StockShortfall | null;
58
+ /**
59
+ * Result of bucketing a cart into stock-satisfiable vs. stock-short lines.
60
+ * Shared shape consumed by both checkout entry points (COD/UPI transaction
61
+ * path and Razorpay post-payment path) so "what happens when an item is
62
+ * unavailable" (skip it vs. cancel the whole checkout) is decided ONCE, by
63
+ * the caller, from the same bucketing logic.
64
+ */
65
+ export interface StockBucketResult {
66
+ available: {
67
+ item: CartItemDocument;
68
+ product: ProductDocument;
69
+ }[];
70
+ unavailable: {
71
+ productId: string;
72
+ productTitle: string;
73
+ requestedQty: number;
74
+ availableQty: number;
75
+ }[];
76
+ }
77
+ /**
78
+ * For every cart item: bucket into `available` (with its resolved
79
+ * "representative" product attached) or `unavailable` (with the shortfall
80
+ * detail). Pure stock bucketing only — callers are responsible for any
81
+ * extra per-item side effects (sync preflight checks, business-rule caps,
82
+ * etc.) they want to run over the `available` bucket.
83
+ *
84
+ * `resolveRepresentative` lets each call site supply its own "which product
85
+ * represents this cart line" logic (both current call sites use the first
86
+ * bundle member / the plain productId) without duplicating that lookup here.
87
+ */
88
+ export declare function bucketCartItemsByStock(cartItems: CartItemDocument[], productById: Map<string, ProductDocument>, decrements: Map<string, number>, resolveRepresentative: (item: CartItemDocument) => ProductDocument | null): StockBucketResult;
@@ -68,3 +68,44 @@ export function validateCartItemStock(item, productById, decrements) {
68
68
  }
69
69
  return null;
70
70
  }
71
+ /**
72
+ * For every cart item: bucket into `available` (with its resolved
73
+ * "representative" product attached) or `unavailable` (with the shortfall
74
+ * detail). Pure stock bucketing only — callers are responsible for any
75
+ * extra per-item side effects (sync preflight checks, business-rule caps,
76
+ * etc.) they want to run over the `available` bucket.
77
+ *
78
+ * `resolveRepresentative` lets each call site supply its own "which product
79
+ * represents this cart line" logic (both current call sites use the first
80
+ * bundle member / the plain productId) without duplicating that lookup here.
81
+ */
82
+ export function bucketCartItemsByStock(cartItems, productById, decrements, resolveRepresentative) {
83
+ const available = [];
84
+ const unavailable = [];
85
+ for (const item of cartItems) {
86
+ const shortfall = validateCartItemStock(item, productById, decrements);
87
+ if (shortfall) {
88
+ unavailable.push({
89
+ productId: shortfall.productId,
90
+ productTitle: item.productTitle,
91
+ requestedQty: item.quantity,
92
+ availableQty: shortfall.availableQty,
93
+ });
94
+ continue;
95
+ }
96
+ const representative = resolveRepresentative(item);
97
+ if (!representative) {
98
+ // Defensive — validateCartItemStock already confirmed every member
99
+ // product exists + is published, so this should be unreachable.
100
+ unavailable.push({
101
+ productId: item.productId,
102
+ productTitle: item.productTitle,
103
+ requestedQty: item.quantity,
104
+ availableQty: 0,
105
+ });
106
+ continue;
107
+ }
108
+ available.push({ item, product: representative });
109
+ }
110
+ return { available, unavailable };
111
+ }
@@ -1,7 +1,7 @@
1
1
  "use server";
2
2
  import { wrapAction } from "@mohasinac/appkit/server";
3
3
  import { getAdminDb } from "../../../../providers/db-firebase";
4
- import { eventRepository } from "../../../../repositories";
4
+ import { eventRepository, productRepository } from "../../../../repositories";
5
5
  import { lotteryEntryRepository } from "../../../../features/lottery/repository/lottery-entry.repository";
6
6
  import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
7
7
  import { ValidationError } from "../../../shared/errors/index";
@@ -52,8 +52,17 @@ export async function submitLotteryPullAction(input) {
52
52
  lotteryConfig = event.lotteryConfig;
53
53
  }
54
54
  else {
55
- // Product lottery load via product repository (not implemented here; caller ensures correct source)
56
- throw new ValidationError("Product lottery pull must go through the product lottery pull route.");
55
+ const product = await productRepository.findById(sourceId).catch(() => null);
56
+ if (!product || product.listingType !== "prize-draw") {
57
+ throw new LotteryError("LOTTERY_WINDOW_CLOSED", "Prize-draw product not found.");
58
+ }
59
+ if (product.status !== "published") {
60
+ throw new LotteryError("LOTTERY_WINDOW_CLOSED", "This prize draw is not currently active.");
61
+ }
62
+ if (product.prizeDrawMode !== "lottery" || !product.lotteryConfig) {
63
+ throw new LotteryError("LOTTERY_WINDOW_CLOSED", "Lottery config not found on product.");
64
+ }
65
+ lotteryConfig = product.lotteryConfig;
57
66
  }
58
67
  // Check draw window
59
68
  if (!isDrawWindowOpen(lotteryConfig)) {
@@ -71,7 +80,8 @@ export async function submitLotteryPullAction(input) {
71
80
  }
72
81
  // Atomically: pick slot + create entry + mark slot booked
73
82
  const db = getAdminDb();
74
- const sourceDocRef = db.collection("events").doc(sourceId);
83
+ const sourceCollectionName = data.sourceType === "event" ? "events" : "products";
84
+ const sourceDocRef = db.collection(sourceCollectionName).doc(sourceId);
75
85
  const { assignedSlot, userLotteryNumber } = await db.runTransaction(async (tx) => {
76
86
  // Re-read lotteryConfig inside transaction for freshness
77
87
  const sourceSnap = await tx.get(sourceDocRef);
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { getAdminDb } from "../../../../providers/db-firebase/admin";
12
12
  import { SERVER_ERRORS_COLLECTION, } from "../../../../features/server-errors/schemas/firestore";
13
+ import { CLIENT_ERROR_ENDPOINTS } from "../../../../constants/api-endpoints";
13
14
  function topFrames(stack, n) {
14
15
  if (!stack)
15
16
  return [];
@@ -153,9 +154,10 @@ export async function analyzeLogs(opts) {
153
154
  if (topCodes.find((c) => c.code.startsWith("PAYMENT_ROLLBACK"))) {
154
155
  recommendations.push("PAYMENT_ROLLBACK_* observed — verify Razorpay webhook health and check the refund-rollback path.");
155
156
  }
156
- if (topRoutes.find((r) => r.route === "/api/client-errors" &&
157
+ if (topRoutes.find((r) => r.route === CLIENT_ERROR_ENDPOINTS.REPORT &&
157
158
  topCodes[0]?.code === "NETWORK_ERROR")) {
158
- recommendations.push("/api/client-errors itself is failing ingestion endpoint may be down; client errors are being lost.");
159
+ // audit-hardcoded-api-routes-ok: human-readable diagnostic message, not a call site
160
+ recommendations.push(`${CLIENT_ERROR_ENDPOINTS.REPORT} itself is failing — ingestion endpoint may be down; client errors are being lost.`);
159
161
  }
160
162
  if (recommendations.length === 0) {
161
163
  recommendations.push("No anomaly heuristics triggered — failures are within expected distribution.");
@@ -97,6 +97,15 @@ export async function adminVerifyPaymentAction(orderId) {
97
97
  paymentStatus: "paid",
98
98
  paymentId: order.paymentTransactionId ?? order.paymentId ?? `manual-${orderId}`,
99
99
  status: "processing",
100
+ paymentRecord: {
101
+ method: "manual",
102
+ transactionId: order.paymentTransactionId,
103
+ proofUrl: order.paymentProofUrl,
104
+ amountPaise: order.totalPrice,
105
+ paidAt: new Date(),
106
+ verifiedBy: user.uid,
107
+ verificationMethod: "manual_review",
108
+ },
100
109
  });
101
110
  });
102
111
  }
@@ -64,5 +64,24 @@ export function orderDocumentToOrder(doc) {
64
64
  updatedAt: doc.updatedAt instanceof Date
65
65
  ? doc.updatedAt.toISOString()
66
66
  : String(doc.updatedAt),
67
+ ...(doc.prizeWon
68
+ ? {
69
+ prizeWon: {
70
+ ...doc.prizeWon,
71
+ wonAt: doc.prizeWon.wonAt instanceof Date
72
+ ? doc.prizeWon.wonAt.toISOString()
73
+ : String(doc.prizeWon.wonAt),
74
+ },
75
+ }
76
+ : {}),
77
+ ...(doc.prizeRevealDeadline
78
+ ? {
79
+ prizeRevealDeadline: doc.prizeRevealDeadline instanceof Date
80
+ ? doc.prizeRevealDeadline.toISOString()
81
+ : String(doc.prizeRevealDeadline),
82
+ }
83
+ : {}),
84
+ ...(doc.prizeRevealExpired !== undefined ? { prizeRevealExpired: doc.prizeRevealExpired } : {}),
85
+ ...(doc.prizeDrawProductId ? { prizeDrawProductId: doc.prizeDrawProductId } : {}),
67
86
  };
68
87
  }
@@ -6,7 +6,7 @@ export function buildRobots({ siteUrl }) {
6
6
  allow: "/",
7
7
  disallow: [
8
8
  "/admin/",
9
- "/api/",
9
+ "/api/", // audit-hardcoded-api-routes-ok: robots.txt disallow prefix, not an endpoint reference
10
10
  "/seller/",
11
11
  "/user/",
12
12
  "/auth/",
@@ -23,8 +23,54 @@ export declare const onSupportTicketUpdate: import("./types").DocumentTriggerFun
23
23
  export declare const onUserBanChange: import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>;
24
24
  export declare const onScamReportCreate: import("./types").DocumentTriggerFunctionDefinition<null, Record<string, import("../../..").JsonValue>>;
25
25
  export declare const onScamReportUpdate: import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>;
26
+ export declare const onShipmentItemWrite: import("./types").DocumentTriggerFunctionDefinition<{
27
+ [x: string]: import("../../..").JsonValue;
28
+ }, {
29
+ [x: string]: import("../../..").JsonValue;
30
+ }>;
31
+ export declare const onShipmentLotWrite: import("./types").DocumentTriggerFunctionDefinition<{
32
+ [x: string]: import("../../..").JsonValue;
33
+ }, {
34
+ [x: string]: import("../../..").JsonValue;
35
+ }>;
36
+ export declare const onShipmentHeaderWrite: import("./types").DocumentTriggerFunctionDefinition<{
37
+ [x: string]: import("../../..").JsonValue;
38
+ }, {
39
+ [x: string]: import("../../..").JsonValue;
40
+ }>;
41
+ export declare const onShipmentDeleted: import("./types").DocumentTriggerFunctionDefinition<{
42
+ [x: string]: import("../../..").JsonValue;
43
+ }, {
44
+ [x: string]: import("../../..").JsonValue;
45
+ }>;
46
+ export declare const onCatalogueSubmittedForApproval: import("./types").DocumentTriggerFunctionDefinition<{
47
+ [x: string]: import("../../..").JsonValue;
48
+ }, {
49
+ [x: string]: import("../../..").JsonValue;
50
+ }>;
51
+ export declare const onJobCreated: import("./types").DocumentTriggerFunctionDefinition<null, import("../../../server").JobDocument>;
26
52
  export declare const FIRESTORE_TRIGGER_FUNCTIONS: readonly [import("./types").DocumentTriggerFunctionDefinition<null, import("../jobs").NewBid>, import("./types").DocumentTriggerFunctionDefinition<null, import("../jobs").NewOrder>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").OrderBefore, import("../jobs").OrderAfter>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").ProductDoc, import("../jobs").ProductDoc>, import("./types").DocumentTriggerFunctionDefinition<{
27
53
  [x: string]: import("../../..").JsonValue;
28
54
  }, {
29
55
  [x: string]: import("../../..").JsonValue;
30
- }>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").CategoryDoc, import("../jobs").CategoryDoc>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").StoreDoc, import("../jobs").StoreDoc>, import("./types").DocumentTriggerFunctionDefinition<null, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<null, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>];
56
+ }>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").CategoryDoc, import("../jobs").CategoryDoc>, import("./types").DocumentTriggerFunctionDefinition<import("../jobs").StoreDoc, import("../jobs").StoreDoc>, import("./types").DocumentTriggerFunctionDefinition<null, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<null, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<Record<string, import("../../..").JsonValue>, Record<string, import("../../..").JsonValue>>, import("./types").DocumentTriggerFunctionDefinition<{
57
+ [x: string]: import("../../..").JsonValue;
58
+ }, {
59
+ [x: string]: import("../../..").JsonValue;
60
+ }>, import("./types").DocumentTriggerFunctionDefinition<{
61
+ [x: string]: import("../../..").JsonValue;
62
+ }, {
63
+ [x: string]: import("../../..").JsonValue;
64
+ }>, import("./types").DocumentTriggerFunctionDefinition<{
65
+ [x: string]: import("../../..").JsonValue;
66
+ }, {
67
+ [x: string]: import("../../..").JsonValue;
68
+ }>, import("./types").DocumentTriggerFunctionDefinition<{
69
+ [x: string]: import("../../..").JsonValue;
70
+ }, {
71
+ [x: string]: import("../../..").JsonValue;
72
+ }>, import("./types").DocumentTriggerFunctionDefinition<{
73
+ [x: string]: import("../../..").JsonValue;
74
+ }, {
75
+ [x: string]: import("../../..").JsonValue;
76
+ }>, import("./types").DocumentTriggerFunctionDefinition<null, import("../../../server").JobDocument>];
@@ -6,7 +6,7 @@
6
6
  * The path patterns mirror the original `functions/src/index.ts` declarations
7
7
  * to preserve identical deploy behavior.
8
8
  */
9
- import { onBidPlacedHandler, onCategoryWriteHandler, onOrderCreateHandler, onOrderStatusChangeHandler, onProductStockChangeHandler, onProductWriteHandler, onReviewWriteHandler, onScamReportCreateHandler, onScamReportUpdateHandler, onStoreWriteHandler, onSupportTicketCreateHandler, onSupportTicketUpdateHandler, onUserBanChangeHandler, } from "../jobs/handlers";
9
+ import { onBidPlacedHandler, onCategoryWriteHandler, onOrderCreateHandler, onOrderStatusChangeHandler, onProductStockChangeHandler, onProductWriteHandler, onReviewWriteHandler, onScamReportCreateHandler, onScamReportUpdateHandler, onStoreWriteHandler, onSupportTicketCreateHandler, onSupportTicketUpdateHandler, onUserBanChangeHandler, onShipmentItemWriteHandler, onShipmentLotWriteHandler, onShipmentHeaderWriteHandler, onShipmentDeletedHandler, onCatalogueSubmittedForApprovalHandler, onJobCreatedHandler, } from "../jobs/handlers";
10
10
  import { defineFunction } from "./define";
11
11
  const REGION = "asia-south1";
12
12
  export const onBidPlaced = defineFunction({
@@ -100,6 +100,55 @@ export const onScamReportUpdate = defineFunction({
100
100
  handler: onScamReportUpdateHandler,
101
101
  options: { region: REGION },
102
102
  });
103
+ // Procurement Shipments — 3-function recompute cascade. See
104
+ // onShipmentItemWrite/onShipmentAllocationSync/onShipmentDeleted handler
105
+ // files for the full data-flow explanation.
106
+ export const onShipmentItemWrite = defineFunction({
107
+ name: "onShipmentItemWrite",
108
+ description: "Recompute a shipment lot's itemCount + mainItemsProjectedRevenuePaise on any item write.",
109
+ trigger: { kind: "documentWritten", pathPattern: "shipmentItems/{itemId}" },
110
+ handler: onShipmentItemWriteHandler,
111
+ options: { region: REGION },
112
+ });
113
+ export const onShipmentLotWrite = defineFunction({
114
+ name: "onShipmentLotWrite",
115
+ description: "Recompute cross-lot customs/shipping allocation + shipment totals on any lot write.",
116
+ trigger: { kind: "documentWritten", pathPattern: "shipmentLots/{lotId}" },
117
+ handler: onShipmentLotWriteHandler,
118
+ options: { region: REGION },
119
+ });
120
+ export const onShipmentHeaderWrite = defineFunction({
121
+ name: "onShipmentHeaderWrite",
122
+ description: "Recompute cross-lot allocation when a shipment's customs/shipping/labor/status fields change.",
123
+ trigger: { kind: "documentWritten", pathPattern: "procurementShipments/{shipmentId}" },
124
+ handler: onShipmentHeaderWriteHandler,
125
+ options: { region: REGION },
126
+ });
127
+ export const onShipmentDeleted = defineFunction({
128
+ name: "onShipmentDeleted",
129
+ description: "Cascade-delete a shipment's lots + items in batches of 500 (bound as documentWritten; handler checks for deletion).",
130
+ trigger: { kind: "documentWritten", pathPattern: "procurementShipments/{shipmentId}" },
131
+ handler: onShipmentDeletedHandler,
132
+ options: { region: REGION },
133
+ });
134
+ export const onCatalogueSubmittedForApproval = defineFunction({
135
+ name: "onCatalogueSubmittedForApproval",
136
+ description: "Notify all admins when a catalogue item's listingStatus transitions to pending_admin_approval.",
137
+ trigger: { kind: "documentUpdated", pathPattern: "catalogueItems/{itemId}" },
138
+ handler: onCatalogueSubmittedForApprovalHandler,
139
+ options: { region: REGION },
140
+ });
141
+ // Async job primitive — Vercel routes write a lightweight `jobs/{jobId}` doc
142
+ // via `enqueueJob()` and return immediately; this Function does the actual
143
+ // processing (CLAUDE.md Rule #6). Longer timeout/memory than the other
144
+ // triggers since job runners (e.g. hardBanCascade, payoutsWeekly) do real work.
145
+ export const onJobCreated = defineFunction({
146
+ name: "onJobCreated",
147
+ description: "Dispatch a jobs/{jobId} doc to its JOB_RUNNERS entry and report the result via bulk_events RTDB.",
148
+ trigger: { kind: "documentCreated", pathPattern: "jobs/{jobId}" },
149
+ handler: onJobCreatedHandler,
150
+ options: { region: REGION, timeoutSeconds: 300, memory: "512MiB" },
151
+ });
103
152
  export const FIRESTORE_TRIGGER_FUNCTIONS = [
104
153
  onBidPlaced,
105
154
  onOrderCreate,
@@ -114,4 +163,10 @@ export const FIRESTORE_TRIGGER_FUNCTIONS = [
114
163
  onUserBanChange,
115
164
  onScamReportCreate,
116
165
  onScamReportUpdate,
166
+ onShipmentItemWrite,
167
+ onShipmentLotWrite,
168
+ onShipmentHeaderWrite,
169
+ onShipmentDeleted,
170
+ onCatalogueSubmittedForApproval,
171
+ onJobCreated,
117
172
  ];
@@ -20,4 +20,5 @@ export declare const prizeRevealExpiry: import("./types").ScheduledFunctionDefin
20
20
  export declare const prizeRevealReminder: import("./types").ScheduledFunctionDefinition;
21
21
  export declare const bundleStockSync: import("./types").ScheduledFunctionDefinition;
22
22
  export declare const emiInstallmentReminder: import("./types").ScheduledFunctionDefinition;
23
- export declare const SCHEDULED_FUNCTIONS: readonly [import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition];
23
+ export declare const catalogueImageStalenessReminder: import("./types").ScheduledFunctionDefinition;
24
+ export declare const SCHEDULED_FUNCTIONS: readonly [import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition, import("./types").ScheduledFunctionDefinition];
@@ -1,6 +1,6 @@
1
1
  // Scheduled function definitions (Cloud Scheduler triggers).
2
2
  // Cron syntax accepts both Firebase shorthand and standard cron expressions.
3
- import { auctionSettlementHandler, autoPayoutEligibilityHandler, bundleStockSyncHandler, cartPruneHandler, cleanupRtdbEventsHandler, countersReconcileHandler, couponExpiryHandler, dailyDataCleanupHandler, draftPruneHandler, emiInstallmentReminderHandler, mediaTmpCleanupHandler, notificationPruneHandler, offerExpiryHandler, payoutBatchHandler, pendingOrderTimeoutHandler, positionsReconcileHandler, prizeRevealCloseHandler, prizeRevealExpiryHandler, prizeRevealOpenHandler, prizeRevealReminderHandler, productStatsSyncHandler, weeklyPayoutEligibilityHandler, } from "../jobs/handlers";
3
+ import { auctionSettlementHandler, autoPayoutEligibilityHandler, bundleStockSyncHandler, cartPruneHandler, cleanupRtdbEventsHandler, countersReconcileHandler, couponExpiryHandler, dailyDataCleanupHandler, draftPruneHandler, emiInstallmentReminderHandler, catalogueImageStalenessReminderHandler, mediaTmpCleanupHandler, notificationPruneHandler, offerExpiryHandler, payoutBatchHandler, pendingOrderTimeoutHandler, positionsReconcileHandler, prizeRevealCloseHandler, prizeRevealExpiryHandler, prizeRevealOpenHandler, prizeRevealReminderHandler, productStatsSyncHandler, weeklyPayoutEligibilityHandler, } from "../jobs/handlers";
4
4
  import { defineFunction } from "./define";
5
5
  const REGION = "asia-south1";
6
6
  const EVERY_5_MIN = "every 5 minutes";
@@ -158,6 +158,13 @@ export const emiInstallmentReminder = defineFunction({
158
158
  handler: emiInstallmentReminderHandler,
159
159
  options: { region: REGION, timeoutSeconds: 300, memory: "256MiB", maxInstances: 1 },
160
160
  });
161
+ export const catalogueImageStalenessReminder = defineFunction({
162
+ name: "catalogueImageStalenessReminder",
163
+ description: "Remind catalogue owners whose photos are nearing the 30-day freshness cutoff (daily 07:00 IST).",
164
+ trigger: { kind: "schedule", cron: "0 7 * * *", timeZone: "Asia/Kolkata" },
165
+ handler: catalogueImageStalenessReminderHandler,
166
+ options: { region: REGION, timeoutSeconds: 300, memory: "256MiB", maxInstances: 1 },
167
+ });
161
168
  export const SCHEDULED_FUNCTIONS = [
162
169
  auctionSettlement,
163
170
  pendingOrderTimeout,
@@ -181,4 +188,5 @@ export const SCHEDULED_FUNCTIONS = [
181
188
  prizeRevealReminder,
182
189
  bundleStockSync,
183
190
  emiInstallmentReminder,
191
+ catalogueImageStalenessReminder,
184
192
  ];
@@ -0,0 +1,10 @@
1
+ import type { JobContext } from "../runtime/types";
2
+ /**
3
+ * Daily sweep — nudges catalogue owners whose photos are approaching (or
4
+ * past) the freshness cutoff (`assertCatalogueImagesFresh`'s 30-day gate),
5
+ * so the "List" / "Request to sell" block doesn't come as a surprise.
6
+ * `staleReminderSentAt` gates re-notification: only fires again once
7
+ * `lastImageUpdateAt` has moved past the previous reminder (i.e. the owner
8
+ * uploaded a fresh photo and then let it go stale again).
9
+ */
10
+ export declare function runCatalogueImageStalenessReminder(ctx: JobContext): Promise<void>;
@@ -0,0 +1,49 @@
1
+ import { normalizeError } from "../../../../errors/normalize";
2
+ import { sendNotification } from "../../../../features/admin/actions/notification-actions";
3
+ import { catalogueRepository } from "../../../../repositories";
4
+ import { CATALOGUE_IMAGE_FRESHNESS_DAYS } from "../../../../features/catalogue/schemas/firestore";
5
+ const REMINDER_LEAD_DAYS = 5;
6
+ const DAY_MS = 86400000;
7
+ /**
8
+ * Daily sweep — nudges catalogue owners whose photos are approaching (or
9
+ * past) the freshness cutoff (`assertCatalogueImagesFresh`'s 30-day gate),
10
+ * so the "List" / "Request to sell" block doesn't come as a surprise.
11
+ * `staleReminderSentAt` gates re-notification: only fires again once
12
+ * `lastImageUpdateAt` has moved past the previous reminder (i.e. the owner
13
+ * uploaded a fresh photo and then let it go stale again).
14
+ */
15
+ export async function runCatalogueImageStalenessReminder(ctx) {
16
+ ctx.logger.info("Catalogue image staleness reminder sweep starting");
17
+ const reminderCutoff = new Date(ctx.now.getTime() - (CATALOGUE_IMAGE_FRESHNESS_DAYS - REMINDER_LEAD_DAYS) * DAY_MS);
18
+ const items = await catalogueRepository.listStale(reminderCutoff, 200);
19
+ let remindersSent = 0;
20
+ for (const item of items) {
21
+ if (item.listingStatus === "listed")
22
+ continue; // already listed — no gate left to hit
23
+ const lastUpdate = new Date(item.lastImageUpdateAt);
24
+ if (item.staleReminderSentAt && new Date(item.staleReminderSentAt) >= lastUpdate)
25
+ continue; // already reminded for this image set
26
+ try {
27
+ await sendNotification({
28
+ userId: item.ownerId,
29
+ type: "catalogue_images_stale",
30
+ priority: "normal",
31
+ title: "Refresh your catalogue photos",
32
+ message: `Photos for "${item.title}" are getting old — refresh them within ${CATALOGUE_IMAGE_FRESHNESS_DAYS - REMINDER_LEAD_DAYS} days or you won't be able to list it.`,
33
+ relatedId: item.id,
34
+ relatedType: "catalogueItem",
35
+ actionUrl: `/user/catalogue/${item.id}/edit`,
36
+ });
37
+ await catalogueRepository.update(item.id, { staleReminderSentAt: ctx.now });
38
+ remindersSent++;
39
+ }
40
+ catch (err) {
41
+ void normalizeError(err);
42
+ ctx.logger.warn("Catalogue staleness reminder notification failed", {
43
+ itemId: item.id,
44
+ err: err instanceof Error ? err.message : String(err),
45
+ });
46
+ }
47
+ }
48
+ ctx.logger.info("Catalogue image staleness reminder sweep complete", { remindersSent });
49
+ }
@@ -1,7 +1,11 @@
1
1
  import { normalizeError } from "../../../../errors/normalize";
2
2
  import { getAdminAuth, getAdminRealtimeDb } from "../../../../providers/db-firebase";
3
+ import { jobsRepository } from "../../../../repositories";
4
+ import { batchDelete } from "../handlers/_helpers";
3
5
  const AUTH_STALE_MS = 3 * 60 * 1000;
4
6
  const PAYMENT_STALE_MS = 15 * 60 * 1000;
7
+ const BULK_STALE_MS = 15 * 60 * 1000;
8
+ const JOBS_TTL_DAYS = 30;
5
9
  export async function runCleanupRtdbEvents(ctx) {
6
10
  ctx.logger.info("Starting RTDB events cleanup");
7
11
  const rtdb = getAdminRealtimeDb();
@@ -47,5 +51,33 @@ export async function runCleanupRtdbEvents(ctx) {
47
51
  void normalizeError(payErr);
48
52
  ctx.logger.error("Payment events cleanup failed (non-fatal)", payErr);
49
53
  }
54
+ try {
55
+ const bulkSnap = await rtdb.ref("bulk_events").get();
56
+ if (bulkSnap.exists()) {
57
+ const allBulkEvents = bulkSnap.val();
58
+ const staleBulkIds = Object.entries(allBulkEvents)
59
+ .filter(([, node]) => (node.updatedAt ?? node.createdAt ?? 0) < now - BULK_STALE_MS)
60
+ .map(([id]) => id);
61
+ if (staleBulkIds.length > 0) {
62
+ await Promise.all(staleBulkIds.map((id) => rtdb.ref(`bulk_events/${id}`).remove()));
63
+ ctx.logger.info("Bulk events removed", { count: staleBulkIds.length });
64
+ }
65
+ }
66
+ }
67
+ catch (bulkErr) {
68
+ void normalizeError(bulkErr);
69
+ ctx.logger.error("Bulk events cleanup failed (non-fatal)", bulkErr);
70
+ }
71
+ try {
72
+ const staleJobRefs = await jobsRepository.getStaleFinishedRefs(JOBS_TTL_DAYS);
73
+ if (staleJobRefs.length > 0) {
74
+ const deleted = await batchDelete(ctx, staleJobRefs);
75
+ ctx.logger.info("Stale jobs pruned", { deleted });
76
+ }
77
+ }
78
+ catch (jobsErr) {
79
+ void normalizeError(jobsErr);
80
+ ctx.logger.error("Jobs prune failed (non-fatal)", jobsErr);
81
+ }
50
82
  ctx.logger.info("RTDB events cleanup complete");
51
83
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Core: hard-ban cascade — disables Auth login, marks the user banned,
3
+ * revokes sessions, suspends any owned store + archives its products,
4
+ * cancels active bids, and cascades the ban across any address / payment
5
+ * clusters shared with other accounts (fraud-ring containment).
6
+ *
7
+ * Extracted verbatim (stage-for-stage) from the former synchronous
8
+ * `POST /api/admin/users/[uid]/hard-ban` route body — that route now only
9
+ * runs the cheap pre-flight guards (self-ban / target-exists / admin-target)
10
+ * and enqueues this as a `hardBanCascade` job (see `./jobRunners.ts`) so the
11
+ * cascade runs inside a Firebase Function instead of the Vercel 10s sync
12
+ * ceiling (CLAUDE.md Rule #6).
13
+ *
14
+ * Each stage keeps its original non-fatal try/catch-log-continue behavior,
15
+ * EXCEPT stage 2 (marking the user banned on Firestore), which is the one
16
+ * write that must succeed for the ban to take effect — if it throws, the job
17
+ * is marked failed so an admin can retry.
18
+ */
19
+ import type { JobContext } from "../runtime/types";
20
+ import type { JobRunResult } from "./jobRunners";
21
+ export interface HardBanCascadeInput {
22
+ uid: string;
23
+ reason: string;
24
+ bannedBy: string;
25
+ }
26
+ export declare function runHardBanCascade(input: HardBanCascadeInput, ctx: JobContext): Promise<JobRunResult>;