@mohasinac/appkit 3.4.8 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +1 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +1 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +1 -1
- package/dist/_internal/client/features/filters/filter-load-options.js +10 -9
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +11 -4
- package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
- package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +10 -3
- package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +2 -2
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +3 -1
- package/dist/_internal/server/features/checkout/actions.d.ts +16 -0
- package/dist/_internal/server/features/checkout/actions.js +149 -35
- package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +31 -0
- package/dist/_internal/server/features/checkout/bundle-expansion.js +41 -0
- package/dist/_internal/server/features/lottery/actions.js +14 -4
- package/dist/_internal/server/features/maintenance/analyze.js +4 -2
- package/dist/_internal/server/features/orders/actions.js +9 -0
- package/dist/_internal/server/features/orders/adapters.js +19 -0
- package/dist/_internal/server/features/seo/robots.js +1 -1
- package/dist/_internal/server/functions/firestore.d.ts +47 -1
- package/dist/_internal/server/functions/firestore.js +56 -1
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +9 -1
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.d.ts +10 -0
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.js +49 -0
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +32 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +26 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +179 -0
- package/dist/_internal/server/jobs/core/index.d.ts +4 -1
- package/dist/_internal/server/jobs/core/index.js +4 -1
- package/dist/_internal/server/jobs/core/jobRunners.d.ts +28 -0
- package/dist/_internal/server/jobs/core/jobRunners.js +37 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +15 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +38 -0
- package/dist/_internal/server/jobs/core/onJobCreated.d.ts +22 -0
- package/dist/_internal/server/jobs/core/onJobCreated.js +59 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.d.ts +6 -1
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -2
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +6 -0
- package/dist/_internal/server/jobs/handlers/index.js +8 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.d.ts +12 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.js +20 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.js +9 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +25 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +71 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.d.ts +14 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.js +23 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +17 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +26 -0
- package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +3 -1
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +136 -0
- package/dist/_internal/shared/features/blog/schema.d.ts +8 -8
- package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +8 -8
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/_internal/shared/features/products/schema.d.ts +8 -8
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +4 -4
- package/dist/client/api/useFeatureFlags.d.ts +22 -0
- package/dist/client/api/useFeatureFlags.js +27 -0
- package/dist/client/observability/reportClientError.js +3 -2
- package/dist/client.d.ts +4 -2
- package/dist/client.js +2 -1
- package/dist/configs/next.js +1 -0
- package/dist/constants/api-endpoints.d.ts +279 -3
- package/dist/constants/api-endpoints.js +130 -2
- package/dist/core/hooks/useSyncManager.js +5 -4
- package/dist/errors/conflict-error.d.ts +4 -0
- package/dist/errors/conflict-error.js +6 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/features/about/components/FeesView.js +2 -2
- package/dist/features/about/components/HelpPageView.js +2 -2
- package/dist/features/about/components/HowAuctionsWorkView.js +2 -2
- package/dist/features/about/components/HowCheckoutWorksView.js +2 -2
- package/dist/features/about/components/HowEmiWorksView.js +2 -2
- package/dist/features/about/components/HowOffersWorkView.js +3 -3
- package/dist/features/about/components/HowOrdersWorkView.js +3 -3
- package/dist/features/about/components/HowPayoutsWorkView.js +2 -2
- package/dist/features/about/components/HowPreOrdersWorkView.js +2 -2
- package/dist/features/about/components/HowReviewsWorkView.js +2 -2
- package/dist/features/about/components/PublicProfileView.d.ts +8 -1
- package/dist/features/about/components/PublicProfileView.js +11 -9
- package/dist/features/about/components/SecurityPrivacyView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +2 -2
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/NotificationBell.js +5 -5
- package/dist/features/account/components/NotificationPreferencesPanel.js +5 -2
- package/dist/features/account/components/UserOffersPanel.js +5 -4
- package/dist/features/account/components/UserSidebar.js +2 -2
- package/dist/features/account/components/UserSupportView.js +3 -3
- package/dist/features/account/schemas/index.d.ts +12 -12
- package/dist/features/addresses/schemas/index.d.ts +6 -6
- package/dist/features/admin/components/AdminAdEditorView.js +3 -3
- package/dist/features/admin/components/AdminAddressEditorView.js +3 -3
- package/dist/features/admin/components/AdminAdsView.js +3 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBlogView.js +12 -15
- package/dist/features/admin/components/AdminBrandEditorView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +12 -13
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -4
- package/dist/features/admin/components/AdminBundlesView.js +32 -23
- package/dist/features/admin/components/AdminCarouselEditorView.js +5 -5
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCatalogGuideView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +12 -13
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminContactEditorView.js +2 -2
- package/dist/features/admin/components/AdminCouponEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +7 -2
- package/dist/features/admin/components/AdminCouponsView.js +32 -27
- package/dist/features/admin/components/AdminEmployeeEditorView.js +3 -3
- package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +20 -20
- package/dist/features/admin/components/AdminFeatureEditorView.js +5 -5
- package/dist/features/admin/components/AdminFeaturesView.js +9 -10
- package/dist/features/admin/components/AdminFilterBar.js +1 -1
- package/dist/features/admin/components/AdminFulfillmentView.js +4 -4
- package/dist/features/admin/components/AdminGuideHubView.js +2 -2
- package/dist/features/admin/components/AdminMediaView.js +3 -2
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +3 -3
- package/dist/features/admin/components/AdminOrdersView.js +21 -30
- package/dist/features/admin/components/AdminPageHeader.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +8 -8
- package/dist/features/admin/components/AdminPrizeDrawsView.js +8 -9
- package/dist/features/admin/components/AdminProductEditorView.d.ts +9 -1
- package/dist/features/admin/components/AdminProductEditorView.js +7 -4
- package/dist/features/admin/components/AdminProductsView.js +30 -41
- package/dist/features/admin/components/AdminReviewsView.js +14 -17
- package/dist/features/admin/components/AdminScammerEditorView.js +5 -5
- package/dist/features/admin/components/AdminSectionsView.js +3 -3
- package/dist/features/admin/components/AdminSessionsView.js +8 -10
- package/dist/features/admin/components/AdminSidebar.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +10 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +4 -5
- package/dist/features/admin/components/AdminStoresView.js +18 -13
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamView.js +9 -5
- package/dist/features/admin/components/AdminUsersView.js +19 -15
- package/dist/features/admin/components/AdminViewCards.js +5 -5
- package/dist/features/admin/components/DashboardStats.js +1 -1
- package/dist/features/admin/components/DataListingView.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/DrawerFormFooter.js +1 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +2 -2
- package/dist/features/admin/components/analytics/AdminStatCard.js +1 -1
- package/dist/features/admin/hooks/useAdminListing.d.ts +3 -2
- package/dist/features/admin/hooks/useAdminListing.js +8 -2
- package/dist/features/admin/permission-map.js +2 -0
- package/dist/features/admin/schemas/firestore.d.ts +7 -0
- package/dist/features/admin/schemas/firestore.js +4 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +4 -4
- package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
- package/dist/features/auctions/schemas/index.d.ts +16 -16
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +2 -0
- package/dist/features/auth/schemas/index.d.ts +6 -6
- package/dist/features/before-after/schemas/index.d.ts +3 -3
- package/dist/features/blog/actions/blog-actions.d.ts +32 -32
- package/dist/features/blog/components/BlogFeaturedCard.js +2 -2
- package/dist/features/blog/components/BlogIndexListing.js +2 -2
- package/dist/features/blog/components/BlogListView.js +4 -4
- package/dist/features/blog/components/BlogPostView.js +4 -4
- package/dist/features/blog/schemas/index.d.ts +77 -77
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/catalogue/actions/approve-catalogue-listing.d.ts +12 -0
- package/dist/features/catalogue/actions/approve-catalogue-listing.js +50 -0
- package/dist/features/catalogue/actions/list-from-catalogue.d.ts +17 -0
- package/dist/features/catalogue/actions/list-from-catalogue.js +50 -0
- package/dist/features/catalogue/actions/submit-for-approval.d.ts +8 -0
- package/dist/features/catalogue/actions/submit-for-approval.js +30 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.d.ts +2 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +53 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +7 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +79 -0
- package/dist/features/catalogue/components/PublicCatalogueView.d.ts +5 -0
- package/dist/features/catalogue/components/PublicCatalogueView.js +22 -0
- package/dist/features/catalogue/components/UserCatalogueView.d.ts +12 -0
- package/dist/features/catalogue/components/UserCatalogueView.js +51 -0
- package/dist/features/catalogue/index.d.ts +12 -0
- package/dist/features/catalogue/index.js +9 -0
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +39 -0
- package/dist/features/catalogue/repository/catalogue.repository.js +68 -0
- package/dist/features/catalogue/schemas/firestore.d.ts +47 -0
- package/dist/features/catalogue/schemas/firestore.js +22 -0
- package/dist/features/catalogue/schemas/index.d.ts +2 -0
- package/dist/features/catalogue/schemas/index.js +2 -0
- package/dist/features/catalogue/schemas/validation.d.ts +71 -0
- package/dist/features/catalogue/schemas/validation.js +25 -0
- package/dist/features/catalogue/utils/freshness.d.ts +10 -0
- package/dist/features/catalogue/utils/freshness.js +15 -0
- package/dist/features/catalogue/utils/product-from-item.d.ts +15 -0
- package/dist/features/catalogue/utils/product-from-item.js +34 -0
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/BrandDetailTabs.js +2 -2
- package/dist/features/categories/components/BundleCollage.js +2 -2
- package/dist/features/categories/components/BundleItemsPicker.js +3 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +8 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +10 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
- package/dist/features/categories/components/CategoryGrid.js +3 -3
- package/dist/features/categories/components/CategoryProductsListing.js +1 -1
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +1 -1
- package/dist/features/categories/components/CategoryTableColumns.js +1 -1
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/hooks/useCategories.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +32 -32
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/consultation/components/ConsultationForm.js +1 -1
- package/dist/features/consultation/schemas/index.d.ts +10 -10
- package/dist/features/contact/components/ContactForm.js +4 -4
- package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +2 -1
- package/dist/features/copilot/components/AdminCopilotView.js +5 -4
- package/dist/features/corporate/schemas/index.d.ts +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +3 -3
- package/dist/features/events/components/AdminEventEditorView.js +4 -4
- package/dist/features/events/components/AdminEventEntriesView.js +2 -2
- package/dist/features/events/components/AdminEventsView.js +8 -8
- package/dist/features/events/components/EventBanner.js +1 -1
- package/dist/features/events/components/EventCard.js +3 -3
- package/dist/features/events/components/EventLeaderboard.js +1 -1
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +5 -5
- package/dist/features/events/components/EventRafflesSection.js +1 -1
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/events/components/EventsIndexListing.js +4 -2
- package/dist/features/events/components/EventsListView.js +2 -2
- package/dist/features/events/components/SpinWheelView.js +11 -5
- package/dist/features/events/schemas/index.d.ts +100 -100
- package/dist/features/faq/actions/faq-actions.d.ts +6 -6
- package/dist/features/faq/components/ContactCTA.js +3 -3
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +3 -3
- package/dist/features/faq/schemas/index.d.ts +12 -12
- package/dist/features/filters/AsyncFacetSection.js +4 -4
- package/dist/features/filters/FilterFacetSection.js +8 -8
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +2 -8
- package/dist/features/forms/Input.js +2 -1
- package/dist/features/forms/Radio.js +3 -3
- package/dist/features/forms/Select.d.ts +1 -1
- package/dist/features/forms/Select.js +3 -2
- package/dist/features/forms/Slider.js +5 -11
- package/dist/features/forms/Textarea.js +2 -1
- package/dist/features/grouped/schemas/index.d.ts +6 -6
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +4 -4
- package/dist/features/homepage/components/AnnouncementBar.js +3 -3
- package/dist/features/homepage/components/BeforeAfterCard.js +1 -1
- package/dist/features/homepage/components/BrandsSection.js +9 -9
- package/dist/features/homepage/components/CTABannerSection.js +1 -1
- package/dist/features/homepage/components/CharacterHotspot.js +4 -4
- package/dist/features/homepage/components/CharacterHotspotForm.js +15 -13
- package/dist/features/homepage/components/CollectionCardsSection.js +1 -1
- package/dist/features/homepage/components/CustomCardsSection.js +6 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +2 -2
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -3
- package/dist/features/homepage/components/FeaturedResultsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +6 -6
- package/dist/features/homepage/components/HeroBanner.js +1 -1
- package/dist/features/homepage/components/HeroCarousel.js +5 -4
- package/dist/features/homepage/components/HeroSection.js +1 -7
- package/dist/features/homepage/components/HomepageSkeleton.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/NewsletterBanner.js +2 -2
- package/dist/features/homepage/components/NewsletterSection.js +1 -1
- package/dist/features/homepage/components/PromoGrid.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +6 -6
- package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -10
- package/dist/features/homepage/components/SiteFeaturesSection.js +2 -2
- package/dist/features/homepage/components/SocialFeedSection.js +5 -5
- package/dist/features/homepage/components/SocialPostCard.js +1 -1
- package/dist/features/homepage/components/StatsCounterSection.js +1 -1
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/TrustBadges.js +1 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +2 -2
- package/dist/features/homepage/components/TrustIndicatorsSection.js +2 -2
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/hooks/useActiveAd.js +2 -1
- package/dist/features/homepage/schemas/firestore.d.ts +10 -0
- package/dist/features/homepage/schemas/index.d.ts +116 -116
- package/dist/features/jobs/actions/enqueue-job.d.ts +24 -0
- package/dist/features/jobs/actions/enqueue-job.js +44 -0
- package/dist/features/jobs/repository/jobs.repository.d.ts +21 -0
- package/dist/features/jobs/repository/jobs.repository.js +48 -0
- package/dist/features/jobs/schemas/firestore.d.ts +54 -0
- package/dist/features/jobs/schemas/firestore.js +24 -0
- package/dist/features/layout/AppLayoutShell.js +17 -11
- package/dist/features/layout/AutoBreadcrumbs.js +1 -1
- package/dist/features/layout/BackToTop.js +2 -2
- package/dist/features/layout/BottomActions.js +7 -7
- package/dist/features/layout/BottomNavItem.js +2 -2
- package/dist/features/layout/BottomNavLayout.js +13 -4
- package/dist/features/layout/BottomNavbar.d.ts +9 -1
- package/dist/features/layout/BottomNavbar.js +12 -5
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/Breadcrumbs.js +1 -1
- package/dist/features/layout/FooterLayout.js +2 -2
- package/dist/features/layout/NavItem.js +3 -3
- package/dist/features/layout/NavbarLayout.js +6 -6
- package/dist/features/layout/SidebarLayout.d.ts +3 -0
- package/dist/features/layout/SidebarLayout.js +3 -3
- package/dist/features/layout/TitleBarLayout.js +4 -4
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +3 -3
- package/dist/features/lottery/types/index.d.ts +3 -1
- package/dist/features/lottery/types/index.js +16 -3
- package/dist/features/loyalty/components/CoinsDisplay.js +2 -2
- package/dist/features/media/MediaImage.d.ts +6 -1
- package/dist/features/media/MediaImage.js +10 -4
- package/dist/features/media/MediaLightbox.js +1 -1
- package/dist/features/media/MediaPickerModal.js +4 -3
- package/dist/features/media/MediaVideo.js +1 -1
- package/dist/features/media/modals/ImageCropModal.js +1 -1
- package/dist/features/media/modals/ImageEditor.js +1 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +9 -0
- package/dist/features/media/types/index.d.ts +4 -4
- package/dist/features/media/upload/MediaUploadField.js +3 -3
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +4 -3
- package/dist/features/messages/hooks/useConversations.js +2 -1
- package/dist/features/messages/schemas/index.d.ts +6 -6
- package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
- package/dist/features/orders/components/OrderPaymentSummary.d.ts +16 -0
- package/dist/features/orders/components/OrderPaymentSummary.js +32 -0
- package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
- package/dist/features/orders/components/OrdersList.d.ts +7 -2
- package/dist/features/orders/components/OrdersList.js +5 -5
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/repository/orders.repository.d.ts +8 -0
- package/dist/features/orders/repository/orders.repository.js +24 -0
- package/dist/features/orders/schemas/firestore.d.ts +59 -0
- package/dist/features/orders/schemas/firestore.js +5 -0
- package/dist/features/orders/schemas/index.d.ts +91 -40
- package/dist/features/orders/schemas/index.js +10 -0
- package/dist/features/orders/types/index.d.ts +15 -0
- package/dist/features/payments/schemas/index.d.ts +12 -12
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -5
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +7 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +3 -3
- package/dist/features/pre-orders/schemas/index.d.ts +12 -12
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +3 -3
- package/dist/features/products/components/CompareOverlay.js +15 -10
- package/dist/features/products/components/CustomFieldsEditor.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -3
- package/dist/features/products/components/FeatureBadge.js +2 -2
- package/dist/features/products/components/GroupSettingsPanel.js +5 -4
- package/dist/features/products/components/MakeOfferButton.js +4 -4
- package/dist/features/products/components/MarketplaceBundleCard.js +3 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -6
- package/dist/features/products/components/PrizeDrawDetailPageView.js +5 -5
- package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -4
- package/dist/features/products/components/PrizeDrawsIndexListing.js +11 -4
- package/dist/features/products/components/PrizeDrawsSection.js +1 -1
- package/dist/features/products/components/PrizeRevealModal.js +9 -4
- package/dist/features/products/components/ProductDetailActions.js +2 -1
- package/dist/features/products/components/ProductDetailPageView.js +16 -16
- package/dist/features/products/components/ProductFeaturesSelector.js +5 -5
- package/dist/features/products/components/ProductForm.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +5 -3
- package/dist/features/products/components/ProductGrid.js +11 -11
- package/dist/features/products/components/ProductTabs.js +2 -2
- package/dist/features/products/components/ProductTabsShell.js +2 -1
- package/dist/features/products/components/ProductsIndexListing.js +6 -1
- package/dist/features/products/components/ShareButton.js +2 -1
- package/dist/features/products/components/ShowGroupSection.js +9 -5
- package/dist/features/products/components/SublistingCarouselSection.js +8 -4
- package/dist/features/products/constants/action-defs.d.ts +10 -2
- package/dist/features/products/constants/action-defs.js +20 -2
- package/dist/features/products/schemas/firestore.d.ts +5 -0
- package/dist/features/products/schemas/index.d.ts +40 -40
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/promotions/components/CouponCard.js +13 -7
- package/dist/features/promotions/components/CouponsIndexListing.js +4 -6
- package/dist/features/promotions/components/PromotionsView.js +2 -2
- package/dist/features/promotions/schemas/index.d.ts +26 -26
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +11 -11
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewsList.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +22 -22
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/schemas/index.d.ts +20 -20
- package/dist/features/search/components/Search.js +9 -9
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +3 -3
- package/dist/features/search/components/SearchView.js +1 -1
- package/dist/features/search/hooks/useNavSuggestions.js +2 -1
- package/dist/features/search/hooks/useSearch.js +2 -2
- package/dist/features/search/schemas/index.d.ts +3 -3
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/QuickProductForm.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +4 -4
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +3 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerArtView.js +11 -11
- package/dist/features/seller/components/SellerAuctionsView.js +11 -11
- package/dist/features/seller/components/SellerBidsView.js +3 -3
- package/dist/features/seller/components/SellerBundlesView.js +12 -12
- package/dist/features/seller/components/SellerClassifiedView.js +11 -11
- package/dist/features/seller/components/SellerCouponEditorView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +11 -11
- package/dist/features/seller/components/SellerFeaturesView.js +4 -4
- package/dist/features/seller/components/SellerLiveView.js +11 -11
- package/dist/features/seller/components/SellerOffersPanel.js +3 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
- package/dist/features/seller/components/SellerPayoutRequestView.js +6 -5
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +20 -6
- package/dist/features/seller/components/SellerProductsCards.js +3 -3
- package/dist/features/seller/components/SellerProductsView.js +4 -4
- package/dist/features/seller/components/SellerReviewsView.js +7 -6
- package/dist/features/seller/components/SellerShippingView.js +2 -1
- package/dist/features/seller/components/SellerSidebar.js +5 -5
- package/dist/features/seller/components/SellerStickersView.js +11 -11
- package/dist/features/seller/components/SellerTemplatesView.js +1 -1
- package/dist/features/seller/schemas/index.d.ts +20 -20
- package/dist/features/server-errors/schemas/index.d.ts +6 -6
- package/dist/features/shell/CommandPalette.d.ts +27 -0
- package/dist/features/shell/CommandPalette.js +92 -0
- package/dist/features/shell/FormShell.js +4 -3
- package/dist/features/shell/QuickFormDrawer.js +3 -2
- package/dist/features/shell/StepForm.js +2 -2
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.d.ts +7 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.js +123 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.d.ts +6 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +96 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.d.ts +9 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +44 -0
- package/dist/features/shipments/components/AdminShipmentsView.d.ts +8 -0
- package/dist/features/shipments/components/AdminShipmentsView.js +82 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.d.ts +15 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.js +37 -0
- package/dist/features/shipments/hooks/useShipments.d.ts +69 -0
- package/dist/features/shipments/hooks/useShipments.js +96 -0
- package/dist/features/shipments/index.d.ts +10 -0
- package/dist/features/shipments/index.js +7 -0
- package/dist/features/shipments/manifest.d.ts +2 -0
- package/dist/features/shipments/manifest.js +26 -0
- package/dist/features/shipments/repository/shipment-items.repository.d.ts +56 -0
- package/dist/features/shipments/repository/shipment-items.repository.js +78 -0
- package/dist/features/shipments/repository/shipment-lots.repository.d.ts +48 -0
- package/dist/features/shipments/repository/shipment-lots.repository.js +55 -0
- package/dist/features/shipments/repository/shipments.repository.d.ts +50 -0
- package/dist/features/shipments/repository/shipments.repository.js +77 -0
- package/dist/features/shipments/schemas/firestore.d.ts +150 -0
- package/dist/features/shipments/schemas/firestore.js +76 -0
- package/dist/features/shipments/schemas/index.d.ts +2 -0
- package/dist/features/shipments/schemas/index.js +2 -0
- package/dist/features/shipments/schemas/validation.d.ts +350 -0
- package/dist/features/shipments/schemas/validation.js +96 -0
- package/dist/features/shipments/utils/cost-allocation.d.ts +25 -0
- package/dist/features/shipments/utils/cost-allocation.js +83 -0
- package/dist/features/site-settings/components/ActionPermissionsManager.js +2 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +2 -2
- package/dist/features/stores/components/StoreAboutView.js +1 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +3 -3
- package/dist/features/stores/components/StoreAuctionsView.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
- package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
- package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
- package/dist/features/stores/components/StoreFinanceGuideView.js +2 -2
- package/dist/features/stores/components/StoreGuideHubView.js +2 -2
- package/dist/features/stores/components/StoreHeader.js +4 -4
- package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
- package/dist/features/stores/components/StoreNavTabs.js +2 -2
- package/dist/features/stores/components/StoreOrdersGuideView.js +1 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +3 -3
- package/dist/features/stores/components/StoreProductsListing.js +1 -1
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoreReviewsView.js +1 -1
- package/dist/features/stores/components/StoreSettingsGuideView.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +9 -3
- package/dist/features/stores/schemas/index.d.ts +10 -10
- package/dist/features/support/schemas/index.d.ts +22 -22
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +3 -3
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +1 -1
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -2
- package/dist/index.d.ts +44 -1
- package/dist/index.js +37 -1
- package/dist/next/routing/route-map.d.ts +18 -0
- package/dist/next/routing/route-map.js +9 -0
- package/dist/react/hooks/useVisualViewportInset.d.ts +1 -0
- package/dist/react/hooks/useVisualViewportInset.js +59 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/repositories/index.d.ts +5 -0
- package/dist/repositories/index.js +5 -0
- package/dist/schemas/registry.d.ts +398 -364
- package/dist/schemas/sieve.d.ts +2 -2
- package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
- package/dist/schemas/webhooks/razorpay.d.ts +100 -100
- package/dist/seed/_helpers/media.js +1 -0
- package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
- package/dist/seed/catalogue-seed-data.d.ts +2 -0
- package/dist/seed/catalogue-seed-data.js +112 -0
- package/dist/seed/grouped-listings-seed-data.d.ts +5 -0
- package/dist/seed/homepage-sections-seed-data.js +0 -1
- package/dist/seed/index.d.ts +2 -0
- package/dist/seed/index.js +2 -0
- package/dist/seed/manifest.js +6 -0
- package/dist/seed/products-preorders-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.js +185 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +5 -0
- package/dist/styles.css +75 -19
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +0 -2
- package/dist/tokens/index.js +0 -2
- package/dist/tokens/tokens.css +12 -2
- package/dist/ui/DataTable.js +4 -3
- package/dist/ui/components/Button.d.ts +4 -1
- package/dist/ui/components/Button.js +11 -5
- package/dist/ui/components/Checkbox.d.ts +9 -1
- package/dist/ui/components/Checkbox.js +5 -2
- package/dist/ui/components/ClaimCouponButton.js +2 -1
- package/dist/ui/components/ConfirmDeleteModal.style.css +1 -1
- package/dist/ui/components/Drawer.style.css +13 -1
- package/dist/ui/components/Dropdown.style.css +2 -2
- package/dist/ui/components/FilterDrawer.d.ts +4 -1
- package/dist/ui/components/FilterDrawer.js +8 -2
- package/dist/ui/components/Form.d.ts +1 -1
- package/dist/ui/components/Form.js +2 -2
- package/dist/ui/components/FormActionBar.style.css +6 -1
- package/dist/ui/components/IconButton.d.ts +6 -1
- package/dist/ui/components/IconButton.js +5 -2
- package/dist/ui/components/IconButton.style.css +11 -0
- package/dist/ui/components/ImageGallery.style.css +2 -0
- package/dist/ui/components/ImageLightbox.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.d.ts +4 -1
- package/dist/ui/components/ListingFilterDrawer.js +4 -3
- package/dist/ui/components/ListingLayout.style.css +2 -2
- package/dist/ui/components/Modal.style.css +1 -1
- package/dist/ui/components/Pagination.d.ts +5 -1
- package/dist/ui/components/Pagination.js +4 -2
- package/dist/ui/components/RowActionMenu.js +1 -1
- package/dist/ui/components/RowActionMenu.style.css +1 -1
- package/dist/ui/components/Select.d.ts +6 -1
- package/dist/ui/components/Select.js +18 -13
- package/dist/ui/components/Select.style.css +1 -1
- package/dist/ui/components/Semantic.d.ts +13 -0
- package/dist/ui/components/Semantic.js +16 -3
- package/dist/ui/components/SideDrawer.style.css +16 -4
- package/dist/ui/components/SideModal.style.css +1 -1
- package/dist/ui/components/StickyToolbar.d.ts +3 -2
- package/dist/ui/components/StickyToolbar.js +1 -1
- package/dist/ui/components/Textarea.d.ts +5 -0
- package/dist/ui/components/Textarea.js +8 -4
- package/dist/ui/components/Toast.style.css +3 -0
- package/dist/ui/components/UnsavedChangesModal.style.css +1 -1
- package/dist/ui/components/surface-tokens.d.ts +121 -113
- package/dist/ui/components/surface-tokens.js +110 -104
- package/dist/ui/forms/FormShell.d.ts +8 -27
- package/dist/ui/forms/FormShell.js +1 -194
- package/dist/ui/forms/index.d.ts +2 -2
- package/dist/ui/forms/index.js +1 -1
- package/dist/ui/index.d.ts +8 -4
- package/dist/ui/index.js +4 -2
- package/dist/utils/id-generators.d.ts +27 -0
- package/dist/utils/id-generators.js +45 -0
- package/dist/utils/number.formatter.d.ts +7 -0
- package/dist/utils/number.formatter.js +9 -0
- package/dist/validation/schemas.d.ts +5 -5
- 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
|
-
|
|
56
|
-
|
|
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
|
|
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 ===
|
|
157
|
+
if (topRoutes.find((r) => r.route === CLIENT_ERROR_ENDPOINTS.REPORT &&
|
|
157
158
|
topCodes[0]?.code === "NETWORK_ERROR")) {
|
|
158
|
-
|
|
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
|
}
|
|
@@ -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
|
|
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>;
|