@mohasinac/appkit 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +4 -4
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +8 -8
- package/dist/_internal/client/features/lottery/LotteryAdminSlotView.d.ts +1 -1
- package/dist/_internal/client/features/lottery/LotteryAdminSlotView.js +2 -2
- package/dist/_internal/server/features/bundles/actions.js +2 -2
- package/dist/_internal/server/features/bundles/og.d.ts +1 -1
- package/dist/_internal/server/features/bundles/og.js +4 -5
- package/dist/_internal/server/features/checkout/actions.js +57 -21
- package/dist/_internal/server/features/checkout/stock-restore.d.ts +19 -0
- package/dist/_internal/server/features/checkout/stock-restore.js +80 -0
- package/dist/_internal/server/features/checkout/upi-resolution.d.ts +11 -0
- package/dist/_internal/server/features/checkout/upi-resolution.js +28 -0
- package/dist/_internal/server/features/classified/og.js +1 -1
- package/dist/_internal/server/features/digital-code/og.js +1 -1
- package/dist/_internal/server/features/item-requests/og.d.ts +2 -2
- package/dist/_internal/server/features/item-requests/og.js +4 -5
- package/dist/_internal/server/features/live/og.js +1 -1
- package/dist/_internal/server/features/lottery/adapters.d.ts +2 -2
- package/dist/_internal/server/features/lottery/adapters.js +1 -1
- package/dist/_internal/server/features/orders/actions.d.ts +28 -0
- package/dist/_internal/server/features/orders/actions.js +239 -4
- package/dist/_internal/server/features/orders/adapters.js +3 -0
- package/dist/_internal/server/features/payments/data.js +3 -2
- package/dist/_internal/server/features/payouts/actions.d.ts +2 -2
- package/dist/_internal/server/features/payouts/actions.js +4 -3
- package/dist/_internal/server/features/pre-orders/service.d.ts +1 -1
- package/dist/_internal/server/features/pre-orders/service.js +3 -2
- package/dist/_internal/server/features/prize-draws/og.js +5 -5
- package/dist/_internal/server/features/products/og.js +1 -1
- package/dist/_internal/server/features/promotions/service.js +3 -1
- package/dist/_internal/server/features/refunds/actions.d.ts +2 -2
- package/dist/_internal/server/features/refunds/actions.js +7 -6
- package/dist/_internal/server/functions/firestore.js +1 -1
- package/dist/_internal/server/functions/scheduled.d.ts +4 -1
- package/dist/_internal/server/functions/scheduled.js +26 -2
- package/dist/_internal/server/jobs/core/emiInstallmentReminder.js +1 -1
- package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +4 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +15 -4
- package/dist/_internal/server/jobs/core/hardBanReinstatement.d.ts +16 -0
- package/dist/_internal/server/jobs/core/hardBanReinstatement.js +63 -0
- package/dist/_internal/server/jobs/core/jobRunners.js +3 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +1 -1
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +10 -0
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +60 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +15 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +59 -0
- package/dist/_internal/server/jobs/core/pendingOrderTimeout.d.ts +7 -0
- package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +32 -6
- package/dist/_internal/server/jobs/handlers/hardBanReinstatement.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/hardBanReinstatement.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/index.js +3 -0
- package/dist/_internal/server/jobs/handlers/messages.d.ts +4 -0
- package/dist/_internal/server/jobs/handlers/messages.js +4 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +3 -3
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +12 -12
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +1 -1
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +5 -5
- package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/paymentReviewAutoApprove.js +2 -0
- package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/paymentWindowTimeout.js +2 -0
- package/dist/_internal/shared/actions/action-registry.js +27 -0
- package/dist/_internal/shared/checkout/order-math.js +3 -2
- package/dist/_internal/shared/checkout/rules/_defaults.js +1 -0
- package/dist/_internal/shared/checkout/rules/preorder.rule.js +7 -0
- package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +7 -0
- package/dist/_internal/shared/checkout/rules/types.d.ts +11 -0
- package/dist/_internal/shared/features/auctions/errors.js +1 -1
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +0 -1
- package/dist/_internal/shared/features/categories/bundle-copy.js +0 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +6 -6
- package/dist/_internal/shared/features/categories/bundle-schemas.js +2 -2
- package/dist/_internal/shared/features/checkout/config.d.ts +3 -3
- package/dist/_internal/shared/features/checkout/config.js +3 -3
- package/dist/_internal/shared/features/emi/schedule.d.ts +6 -6
- package/dist/_internal/shared/features/emi/schedule.js +10 -9
- package/dist/_internal/shared/features/promotions/errors.js +1 -1
- package/dist/_internal/shared/fees/calculator.d.ts +5 -5
- package/dist/_internal/shared/fees/calculator.js +19 -19
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/constants/api-endpoints.d.ts +9 -0
- package/dist/constants/api-endpoints.js +3 -0
- package/dist/constants/field-names.d.ts +4 -0
- package/dist/constants/field-names.js +4 -0
- package/dist/features/admin/components/AdminArtView.js +2 -2
- package/dist/features/admin/components/AdminBidsView.js +2 -2
- package/dist/features/admin/components/AdminBundleEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +8 -8
- package/dist/features/admin/components/AdminBundlesView.js +6 -6
- package/dist/features/admin/components/AdminClassifiedView.js +2 -2
- package/dist/features/admin/components/AdminDigitalCodesView.js +2 -2
- package/dist/features/admin/components/AdminLiveView.js +2 -2
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +6 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +45 -5
- package/dist/features/admin/components/AdminOrdersView.js +8 -3
- package/dist/features/admin/components/AdminPayoutsView.js +2 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -2
- package/dist/features/admin/components/AdminReturnRequestsView.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +11 -11
- package/dist/features/admin/components/AdminStickersView.js +2 -2
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/hooks/useAdminListingData.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminListingData.js +3 -2
- package/dist/features/admin/schemas/firestore.d.ts +9 -7
- package/dist/features/admin/schemas/firestore.js +4 -3
- package/dist/features/auctions/components/AuctionBidsTable.js +3 -3
- package/dist/features/auth/checkout-value-otp.d.ts +46 -0
- package/dist/features/auth/checkout-value-otp.js +73 -0
- package/dist/features/auth/repository/user.repository.d.ts +6 -0
- package/dist/features/auth/repository/user.repository.js +19 -0
- package/dist/features/auth/schemas/firestore.d.ts +10 -0
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/cart/actions/cart-actions.d.ts +1 -1
- package/dist/features/cart/actions/cart-actions.js +4 -4
- package/dist/features/cart/components/CartView.d.ts +2 -2
- package/dist/features/cart/components/ShippingPicker.d.ts +4 -4
- package/dist/features/cart/components/ShippingPicker.js +11 -11
- package/dist/features/cart/repository/cart.repository.d.ts +1 -1
- package/dist/features/cart/repository/cart.repository.js +2 -2
- package/dist/features/cart/schemas/firestore.d.ts +2 -2
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +3 -3
- package/dist/features/catalogue/components/PublicCatalogueView.js +2 -2
- package/dist/features/catalogue/schemas/validation.js +1 -1
- package/dist/features/categories/components/BundleCollage.js +2 -2
- package/dist/features/categories/components/BundleDetailView.js +2 -2
- package/dist/features/categories/components/BundleItemsPicker.d.ts +1 -1
- package/dist/features/categories/components/BundleItemsPicker.js +2 -2
- package/dist/features/categories/components/CategoryBundlesListing.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +1 -1
- package/dist/features/categories/schemas/index.d.ts +3 -3
- package/dist/features/categories/schemas/index.js +2 -2
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +16 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +83 -0
- package/dist/features/checkout/actions/index.d.ts +1 -0
- package/dist/features/checkout/actions/index.js +1 -0
- package/dist/features/checkout/schemas/firestore.d.ts +1 -1
- package/dist/features/classified/components/index.d.ts +0 -4
- package/dist/features/classified/components/index.js +0 -2
- package/dist/features/digital-codes/components/index.d.ts +0 -4
- package/dist/features/digital-codes/components/index.js +0 -2
- package/dist/features/events/schemas/index.d.ts +1 -1
- package/dist/features/events/schemas/index.js +1 -1
- package/dist/features/homepage/components/FeaturedBundlesSection.js +2 -2
- package/dist/features/live/components/index.d.ts +0 -4
- package/dist/features/live/components/index.js +0 -2
- package/dist/features/lottery/types/index.d.ts +3 -3
- package/dist/features/lottery/types/index.js +5 -5
- package/dist/features/orders/components/OrderPaymentSummary.js +2 -2
- package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/constants/payment-window.d.ts +10 -0
- package/dist/features/orders/constants/payment-window.js +10 -0
- package/dist/features/orders/repository/orders.repository.d.ts +25 -0
- package/dist/features/orders/repository/orders.repository.js +50 -1
- package/dist/features/orders/schemas/firestore.d.ts +50 -2
- package/dist/features/orders/schemas/index.d.ts +24 -24
- package/dist/features/orders/schemas/index.js +20 -20
- package/dist/features/orders/types/index.d.ts +4 -0
- package/dist/features/orders/utils/bundle-grouping.d.ts +1 -1
- package/dist/features/orders/utils/bundle-grouping.js +1 -1
- package/dist/features/payments/schemas/index.d.ts +10 -10
- package/dist/features/payments/schemas/index.js +9 -9
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -2
- package/dist/features/products/components/ArtStickersListView.d.ts +7 -0
- package/dist/features/products/components/ArtStickersListView.js +57 -0
- package/dist/features/products/components/GroupSettingsPanel.js +1 -1
- package/dist/features/products/components/MakeOfferButton.js +3 -3
- package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
- package/dist/features/products/components/PrizeDrawCollage.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeRevealModal.js +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +2 -9
- package/dist/features/products/components/ProductForm.js +2 -2
- package/dist/features/products/components/ProductGrid.js +2 -2
- package/dist/features/products/components/ProductsIndexListing.d.ts +13 -1
- package/dist/features/products/components/ProductsIndexListing.js +7 -5
- package/dist/features/products/components/ProductsIndexPageView.js +6 -1
- package/dist/features/products/constants/listing-tabs.d.ts +42 -17
- package/dist/features/products/constants/listing-tabs.js +25 -6
- package/dist/features/products/schemas/catalog-product.d.ts +5 -5
- package/dist/features/products/schemas/catalog-product.js +1 -1
- package/dist/features/products/schemas/firestore.d.ts +5 -5
- package/dist/features/products/schemas/firestore.js +2 -2
- package/dist/features/products/types/index.d.ts +5 -2
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/schemas/firestore.d.ts +2 -0
- package/dist/features/promotions/schemas/firestore.js +1 -0
- package/dist/features/promotions/schemas/index.d.ts +14 -14
- package/dist/features/promotions/schemas/index.js +6 -6
- package/dist/features/scams/components/ScamProfileView.js +3 -7
- package/dist/features/scams/components/ScamRegistryView.js +2 -6
- package/dist/features/scams/schemas/firestore.d.ts +1 -1
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/seller/actions/offer-actions.js +1 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -2
- package/dist/features/seller/components/QuickProductForm.js +5 -5
- package/dist/features/seller/components/SellerArtView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerBundlesView.js +6 -6
- package/dist/features/seller/components/SellerClassifiedView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +2 -2
- package/dist/features/seller/components/SellerLiveView.js +2 -2
- package/dist/features/seller/components/SellerOffersView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +3 -3
- package/dist/features/seller/components/SellerPayoutRequestView.js +2 -2
- package/dist/features/seller/components/SellerPayoutSettingsView.js +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +2 -2
- package/dist/features/seller/components/SellerProductShell.js +8 -8
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerShippingView.js +6 -6
- package/dist/features/seller/components/SellerStickersView.js +2 -2
- package/dist/features/seller/hooks/useSellerListingData.d.ts +1 -1
- package/dist/features/seller/hooks/useSellerListingData.js +3 -2
- package/dist/features/shipments/components/AdminShipmentEditorView.js +10 -10
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +4 -4
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +5 -5
- package/dist/features/shipments/components/AdminShipmentsView.js +4 -4
- package/dist/features/shipments/repository/shipment-lots.repository.d.ts +2 -2
- package/dist/features/shipments/repository/shipment-lots.repository.js +8 -8
- package/dist/features/shipments/schemas/firestore.d.ts +21 -21
- package/dist/features/shipments/schemas/firestore.js +9 -9
- package/dist/features/shipments/schemas/validation.d.ts +30 -30
- package/dist/features/shipments/schemas/validation.js +6 -6
- package/dist/features/shipments/utils/cost-allocation.d.ts +5 -5
- package/dist/features/shipments/utils/cost-allocation.js +39 -38
- package/dist/features/store-extensions/schemas/firestore.d.ts +5 -5
- package/dist/features/stores/components/StoreDetailLayoutView.js +9 -13
- package/dist/features/stores/schemas/firestore.d.ts +7 -7
- package/dist/features/stores/schemas/index.d.ts +84 -84
- package/dist/features/stores/schemas/index.js +5 -5
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +1 -1
- package/dist/features/tester/seed-data/products-tester-seed-data.js +6 -6
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +9 -2
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +8 -1
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +13 -2
- package/dist/features/whatsapp-bot/types/index.d.ts +9 -1
- package/dist/index.d.ts +4 -7
- package/dist/index.js +9 -5
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +6 -0
- package/dist/schemas/firestore-helpers.d.ts +2 -2
- package/dist/schemas/firestore-helpers.js +2 -2
- package/dist/schemas/registry.d.ts +73 -73
- package/dist/security/index.d.ts +2 -1
- package/dist/security/index.js +5 -1
- package/dist/security/pii-encrypt.d.ts +2 -53
- package/dist/security/pii-encrypt.js +19 -100
- package/dist/security/pii-mask.d.ts +67 -0
- package/dist/security/pii-mask.js +100 -0
- package/dist/seed/bids-seed-data.js +6 -6
- package/dist/seed/blog-posts-seed-data.js +1 -0
- package/dist/seed/cart-seed-data.js +13 -13
- package/dist/seed/catalogue-seed-data.js +6 -6
- package/dist/seed/categories-seed-data.js +5 -5
- package/dist/seed/claimed-coupons-seed-data.js +3 -3
- package/dist/seed/coupons-seed-data.js +20 -20
- package/dist/seed/events-seed-data.js +27 -27
- package/dist/seed/factories/bid.factory.js +1 -1
- package/dist/seed/faq-seed-data.js +20 -1
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -2
- package/dist/seed/grouped-listings-seed-data.js +3 -3
- package/dist/seed/offers-seed-data.js +19 -19
- package/dist/seed/orders-seed-data.js +29 -29
- package/dist/seed/payouts-seed-data.js +7 -7
- package/dist/seed/products-auctions-seed-data.js +6 -6
- package/dist/seed/products-preorders-seed-data.d.ts +2 -2
- package/dist/seed/products-preorders-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +8 -8
- package/dist/seed/scammers-seed-data.js +2 -2
- package/dist/seed/shipments-seed-data.js +29 -29
- package/dist/seed/site-settings-seed-data.js +3 -2
- package/dist/seed/store-extensions-seed-data.js +8 -8
- package/dist/seed/stores-seed-data.js +37 -8
- package/dist/seed/users-seed-data.js +38 -1
- package/dist/server-entry.d.ts +1 -3
- package/dist/server-entry.js +1 -3
- package/dist/server.d.ts +2 -1
- package/dist/server.js +3 -1
- package/dist/ui/components/PriceDisplay.js +3 -12
- package/dist/utils/number.formatter.d.ts +2 -7
- package/dist/utils/number.formatter.js +3 -8
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +17 -3
- package/dist/_internal/client/scaffolds/DashboardScaffold.d.ts +0 -34
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +0 -26
- package/dist/_internal/client/theme/__tests__/ThemeProvider.test.d.ts +0 -1
- package/dist/_internal/client/theme/__tests__/ThemeProvider.test.js +0 -109
- package/dist/_internal/server/features/auctions/__tests__/service.test.d.ts +0 -1
- package/dist/_internal/server/features/auctions/__tests__/service.test.js +0 -140
- package/dist/_internal/server/features/checkout/__tests__/actions.test.d.ts +0 -1
- package/dist/_internal/server/features/checkout/__tests__/actions.test.js +0 -600
- package/dist/_internal/server/features/refunds/__tests__/actions.test.d.ts +0 -1
- package/dist/_internal/server/features/refunds/__tests__/actions.test.js +0 -263
- package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/auctionSettlement.test.js +0 -249
- package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/couponExpiry.test.js +0 -65
- package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/listingProcessor.test.js +0 -163
- package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/mediaTmpCleanup.test.js +0 -115
- package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onBidPlaced.test.js +0 -201
- package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onOrderCreate.test.js +0 -169
- package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onOrderStatusChange.test.js +0 -148
- package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onProductStockChange.test.js +0 -210
- package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onReviewWrite.test.js +0 -190
- package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/onUserBanChange.test.js +0 -161
- package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/payoutBatch.test.js +0 -302
- package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/pendingOrderTimeout.test.js +0 -96
- package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/triggerEventRaffle.test.js +0 -252
- package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.d.ts +0 -1
- package/dist/_internal/server/jobs/core/__tests__/wrapJobHandler.test.js +0 -129
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +0 -15
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +0 -38
- package/dist/_internal/server/providers/index.d.ts +0 -11
- package/dist/_internal/server/providers/index.js +0 -11
- package/dist/_internal/server/providers/payment/razorpay-mock.d.ts +0 -52
- package/dist/_internal/server/providers/payment/razorpay-mock.js +0 -118
- package/dist/_internal/server/providers/resolve.d.ts +0 -36
- package/dist/_internal/server/providers/resolve.js +0 -31
- package/dist/_internal/server/providers/shipping/shiprocket-mock.d.ts +0 -29
- package/dist/_internal/server/providers/shipping/shiprocket-mock.js +0 -152
- package/dist/_internal/shared/types/__tests__/action-result.test.d.ts +0 -1
- package/dist/_internal/shared/types/__tests__/action-result.test.js +0 -65
- package/dist/errors/__tests__/error-mapping.test.d.ts +0 -1
- package/dist/errors/__tests__/error-mapping.test.js +0 -122
- package/dist/errors/__tests__/safe-read.test.d.ts +0 -1
- package/dist/errors/__tests__/safe-read.test.js +0 -39
- package/dist/features/addresses/repository/__tests__/addresses.repository.test.d.ts +0 -1
- package/dist/features/addresses/repository/__tests__/addresses.repository.test.js +0 -386
- package/dist/features/admin/components/AdminListingScaffold.d.ts +0 -41
- package/dist/features/admin/components/AdminListingScaffold.js +0 -68
- package/dist/features/admin/components/QuickActionsPanel.d.ts +0 -15
- package/dist/features/admin/components/QuickActionsPanel.js +0 -5
- package/dist/features/admin/repository/__tests__/notification.repository.test.d.ts +0 -1
- package/dist/features/admin/repository/__tests__/notification.repository.test.js +0 -356
- package/dist/features/admin/repository/__tests__/site-settings.repository.test.d.ts +0 -1
- package/dist/features/admin/repository/__tests__/site-settings.repository.test.js +0 -298
- package/dist/features/auctions/repository/__tests__/bid.repository.test.d.ts +0 -1
- package/dist/features/auctions/repository/__tests__/bid.repository.test.js +0 -290
- package/dist/features/auctions/repository/auctions.repository.d.ts +0 -12
- package/dist/features/auctions/repository/auctions.repository.js +0 -42
- package/dist/features/auth/repository/__tests__/session.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/session.repository.test.js +0 -310
- package/dist/features/auth/repository/__tests__/session.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/session.test.js +0 -146
- package/dist/features/auth/repository/__tests__/sms-counter.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/sms-counter.repository.test.js +0 -171
- package/dist/features/auth/repository/__tests__/sms-counter.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/sms-counter.test.js +0 -88
- package/dist/features/auth/repository/__tests__/token.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/token.repository.test.js +0 -260
- package/dist/features/auth/repository/__tests__/token.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/token.test.js +0 -140
- package/dist/features/auth/repository/__tests__/user.repository.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/user.repository.test.js +0 -352
- package/dist/features/auth/repository/__tests__/user.test.d.ts +0 -1
- package/dist/features/auth/repository/__tests__/user.test.js +0 -226
- package/dist/features/before-after/repository/before-after.repository.d.ts +0 -13
- package/dist/features/before-after/repository/before-after.repository.js +0 -36
- package/dist/features/before-after/server.d.ts +0 -6
- package/dist/features/before-after/server.js +0 -6
- package/dist/features/cart/repository/__tests__/cart.repository.test.d.ts +0 -1
- package/dist/features/cart/repository/__tests__/cart.repository.test.js +0 -371
- package/dist/features/categories/repository/__tests__/categories.repository.test.d.ts +0 -1
- package/dist/features/categories/repository/__tests__/categories.repository.test.js +0 -813
- package/dist/features/collections/repository/collections.repository.d.ts +0 -8
- package/dist/features/collections/repository/collections.repository.js +0 -16
- package/dist/features/collections/server.d.ts +0 -6
- package/dist/features/collections/server.js +0 -6
- package/dist/features/events/repository/__tests__/event.repository.test.d.ts +0 -1
- package/dist/features/events/repository/__tests__/event.repository.test.js +0 -299
- package/dist/features/faq/repository/__tests__/faqs.repository.test.d.ts +0 -1
- package/dist/features/faq/repository/__tests__/faqs.repository.test.js +0 -311
- package/dist/features/forms/Form.d.ts +0 -25
- package/dist/features/forms/Form.js +0 -37
- package/dist/features/history/repository/__tests__/user-history.repository.test.d.ts +0 -1
- package/dist/features/history/repository/__tests__/user-history.repository.test.js +0 -180
- package/dist/features/homepage/repository/__tests__/carousel.repository.test.d.ts +0 -1
- package/dist/features/homepage/repository/__tests__/carousel.repository.test.js +0 -182
- package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.d.ts +0 -1
- package/dist/features/homepage/repository/__tests__/homepage-sections.repository.test.js +0 -185
- package/dist/features/layout/ListingLayout.d.ts +0 -34
- package/dist/features/layout/ListingLayout.js +0 -103
- package/dist/features/messages/repository/__tests__/conversations.repository.test.d.ts +0 -1
- package/dist/features/messages/repository/__tests__/conversations.repository.test.js +0 -257
- package/dist/features/orders/repository/__tests__/orders.repository.test.d.ts +0 -1
- package/dist/features/orders/repository/__tests__/orders.repository.test.js +0 -211
- package/dist/features/payments/repository/__tests__/payout.repository.test.d.ts +0 -1
- package/dist/features/payments/repository/__tests__/payout.repository.test.js +0 -292
- package/dist/features/pre-orders/repository/preorders.repository.d.ts +0 -8
- package/dist/features/pre-orders/repository/preorders.repository.js +0 -25
- package/dist/features/products/repository/__tests__/product-features.repository.test.d.ts +0 -1
- package/dist/features/products/repository/__tests__/product-features.repository.test.js +0 -329
- package/dist/features/products/repository/__tests__/products.repository.test.d.ts +0 -1
- package/dist/features/products/repository/__tests__/products.repository.test.js +0 -607
- package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.d.ts +0 -1
- package/dist/features/promotions/repository/__tests__/claimed-coupons.repository.test.js +0 -219
- package/dist/features/promotions/repository/__tests__/coupons.repository.test.d.ts +0 -1
- package/dist/features/promotions/repository/__tests__/coupons.repository.test.js +0 -480
- package/dist/features/promotions/repository/promotions.repository.d.ts +0 -14
- package/dist/features/promotions/repository/promotions.repository.js +0 -43
- package/dist/features/reviews/repository/__tests__/reviews.repository.test.d.ts +0 -1
- package/dist/features/reviews/repository/__tests__/reviews.repository.test.js +0 -327
- package/dist/features/scams/repository/__tests__/scammer.repository.test.d.ts +0 -1
- package/dist/features/scams/repository/__tests__/scammer.repository.test.js +0 -385
- package/dist/features/search/repository/__tests__/search.repository.test.d.ts +0 -1
- package/dist/features/search/repository/__tests__/search.repository.test.js +0 -369
- package/dist/features/seller/components/SellerStatCard.d.ts +0 -14
- package/dist/features/seller/components/SellerStatCard.js +0 -6
- package/dist/features/seller/components/seller-products-styles.d.ts +0 -7
- package/dist/features/seller/components/seller-products-styles.js +0 -14
- package/dist/features/seller/repository/__tests__/offer.repository.test.d.ts +0 -1
- package/dist/features/seller/repository/__tests__/offer.repository.test.js +0 -458
- package/dist/features/seller/repository/seller.repository.d.ts +0 -22
- package/dist/features/seller/repository/seller.repository.js +0 -72
- package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.d.ts +0 -1
- package/dist/features/site-settings/components/__tests__/ThemeManagerView.test.js +0 -37
- package/dist/features/stores/repository/__tests__/store.repository.test.d.ts +0 -1
- package/dist/features/stores/repository/__tests__/store.repository.test.js +0 -261
- package/dist/features/stores/repository/stores.repository.d.ts +0 -11
- package/dist/features/stores/repository/stores.repository.js +0 -37
- package/dist/features/support/repository/__tests__/support.repository.test.d.ts +0 -1
- package/dist/features/support/repository/__tests__/support.repository.test.js +0 -312
- package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.d.ts +0 -1
- package/dist/features/wishlist/repository/__tests__/user-wishlist.repository.test.js +0 -139
- package/dist/features/wishlist/repository/wishlist.repository.d.ts +0 -13
- package/dist/features/wishlist/repository/wishlist.repository.js +0 -31
- package/dist/providers/db-firebase/__tests__/filter-aliases.test.d.ts +0 -1
- package/dist/providers/db-firebase/__tests__/filter-aliases.test.js +0 -93
- package/dist/providers/shipping-shiprocket/index.d.ts +0 -297
- package/dist/providers/shipping-shiprocket/index.js +0 -194
- package/dist/providers/shipping-shiprocket/shiprocket-provider.d.ts +0 -45
- package/dist/providers/shipping-shiprocket/shiprocket-provider.js +0 -168
- package/dist/react/contexts/ThemeContext.d.ts +0 -13
- package/dist/react/contexts/ThemeContext.js +0 -64
- package/dist/schemas/webhooks/shiprocket.d.ts +0 -30
- package/dist/schemas/webhooks/shiprocket.js +0 -22
- package/dist/seed/actions/demo-seed-actions.d.ts +0 -42
- package/dist/seed/actions/demo-seed-actions.js +0 -36
- package/dist/seed/actions/index.d.ts +0 -1
- package/dist/seed/actions/index.js +0 -1
- package/dist/seed/sub-listings-seed-data.d.ts +0 -123
- package/dist/seed/sub-listings-seed-data.js +0 -447
- package/dist/seed/tester-checklist-seed-data.d.ts +0 -2
- package/dist/seed/tester-checklist-seed-data.js +0 -248
- package/dist/ui/components/DashboardStatsCard.d.ts +0 -15
- package/dist/ui/components/DashboardStatsCard.js +0 -27
- package/dist/ui/components/DashboardStatsCard.style.css +0 -68
- package/dist/ui/components/DynamicSelect.d.ts +0 -23
- package/dist/ui/components/DynamicSelect.js +0 -77
- package/dist/ui/components/DynamicSelect.style.css +0 -101
- package/dist/ui/components/InlineCreateSelect.d.ts +0 -48
- package/dist/ui/components/InlineCreateSelect.js +0 -75
- package/dist/ui/components/ListingViewShell.d.ts +0 -37
- package/dist/ui/components/ListingViewShell.js +0 -9
- package/dist/ui/components/PaginatedMultiSelect.d.ts +0 -28
- package/dist/ui/components/PaginatedMultiSelect.js +0 -141
- package/dist/ui/components/PaginatedMultiSelect.style.css +0 -272
- package/dist/ui/components/SectionTabs.d.ts +0 -19
- package/dist/ui/components/SectionTabs.js +0 -66
- package/dist/ui/components/SectionTabs.style.css +0 -164
- package/dist/ui/components/__tests__/BulkActionBar.test.d.ts +0 -1
- package/dist/ui/components/__tests__/BulkActionBar.test.js +0 -96
- package/dist/ui/components/__tests__/ListingToolbar.test.d.ts +0 -1
- package/dist/ui/components/__tests__/ListingToolbar.test.js +0 -125
- package/dist/ui/components/__tests__/new-primitives.test.d.ts +0 -1
- package/dist/ui/components/__tests__/new-primitives.test.js +0 -187
|
@@ -7,5 +7,33 @@ export declare function attachPaymentProofAction(orderId: string, proof: {
|
|
|
7
7
|
proofUrl: string;
|
|
8
8
|
transactionId?: string;
|
|
9
9
|
mimeType?: string;
|
|
10
|
+
buyerMarkedPaid: boolean;
|
|
11
|
+
buyerFraudAgreementAccepted: boolean;
|
|
12
|
+
buyerReportedUpiId?: string;
|
|
10
13
|
}): Promise<ActionResult<void>>;
|
|
11
14
|
export declare function adminVerifyPaymentAction(orderId: string): Promise<ActionResult<void>>;
|
|
15
|
+
/**
|
|
16
|
+
* Tier PP — "honest mistake" tier of the two-tier admin review (blurry
|
|
17
|
+
* screenshot, wrong amount typed). Clears the proof so the buyer can cleanly
|
|
18
|
+
* resubmit, and extends `paymentDeadline` by another 15 minutes from now so
|
|
19
|
+
* review latency doesn't eat into the buyer's time to fix it. Order stays
|
|
20
|
+
* `pending`/`pending` — no penalty.
|
|
21
|
+
*/
|
|
22
|
+
export declare function adminRequestProofReuploadAction(orderId: string, note: string): Promise<ActionResult<void>>;
|
|
23
|
+
/**
|
|
24
|
+
* Tier PP — "fraud" tier of the two-tier admin review. Cancels the order,
|
|
25
|
+
* restores stock, and triggers a new temporary 7-day full-account hard ban
|
|
26
|
+
* (extends the existing permanent-only `hardBanCascade` job with an
|
|
27
|
+
* `expiresAt`, rather than forking a parallel cascade — see
|
|
28
|
+
* `HardBanCascadeInput.expiresAt`).
|
|
29
|
+
*/
|
|
30
|
+
export declare function adminRejectPaymentAsFraudAction(orderId: string, note: string): Promise<ActionResult<void>>;
|
|
31
|
+
/**
|
|
32
|
+
* Tier PP — raises a dispute on an auto-approved order ("the automation
|
|
33
|
+
* might be wrong"). Only valid when `autoApproved === true` — a manually
|
|
34
|
+
* reviewed order already went through human judgment and disputes on it go
|
|
35
|
+
* through the existing return/refund flow instead. Callable by the buyer,
|
|
36
|
+
* the seller (store owner), or admin/moderator. Does not itself reverse
|
|
37
|
+
* payment/order status — surfaces to the admin queue for investigation.
|
|
38
|
+
*/
|
|
39
|
+
export declare function raiseOrderDisputeAction(orderId: string, reason: string): Promise<ActionResult<void>>;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { wrapAction } from "@mohasinac/appkit/server";
|
|
3
|
-
import { orderRepository } from "../../../../repositories";
|
|
3
|
+
import { orderRepository, storeRepository, userRepository } from "../../../../repositories";
|
|
4
4
|
import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
|
|
5
5
|
import { createOrderSchema, updateOrderStatusSchema, cancelOrderSchema, } from "../../../shared/features/orders/schema";
|
|
6
6
|
import { assertOrderCancellable, assertReturnWindowOpen } from "./service";
|
|
7
7
|
import { ValidationError } from "../../../shared/errors/index";
|
|
8
8
|
import { OrderNotFoundError, OrderOwnershipError } from "../../../shared/features/orders/errors";
|
|
9
9
|
import { isAdminUser, isModeratorUser } from "../../../../features/auth/role-predicates";
|
|
10
|
+
import { sendNotification } from "../../../../features/admin/actions/notification-actions";
|
|
11
|
+
import { restoreStockForOrder } from "../checkout/stock-restore";
|
|
12
|
+
import { getAdminDb } from "../../../../providers/db-firebase";
|
|
13
|
+
import { enqueueJob } from "../../../../features/jobs/actions/enqueue-job";
|
|
14
|
+
import { PAYMENT_WINDOW_MS, PAYMENT_FRAUD_REJECTED_REASON } from "../../../../features/orders/constants/payment-window";
|
|
15
|
+
import { normalizeError } from "../../../../errors/normalize";
|
|
16
|
+
import { serverLogger } from "../../../../monitoring";
|
|
10
17
|
export async function createOrderAction(input) {
|
|
11
18
|
return wrapAction(async () => {
|
|
12
19
|
const user = await requireRoleUser(["buyer", "seller", "admin"]);
|
|
@@ -59,6 +66,63 @@ export async function updateOrderStatusAction(input) {
|
|
|
59
66
|
});
|
|
60
67
|
}
|
|
61
68
|
// ── P-1 Manual payment proof ─────────────────────────────────────────────────
|
|
69
|
+
/** Loose UPI VPA comparison — case/whitespace differences shouldn't register as a mismatch. */
|
|
70
|
+
function normalizeUpi(vpa) {
|
|
71
|
+
return (vpa ?? "").trim().toLowerCase();
|
|
72
|
+
}
|
|
73
|
+
const REASON_REQUIRED_MSG = "A reason is required";
|
|
74
|
+
/**
|
|
75
|
+
* Fast-review WhatsApp push — fans out to every configured admin number so
|
|
76
|
+
* a payment proof can be acted on within the 2-hour auto-approve window
|
|
77
|
+
* without hunting through the orders list. Fire-and-forget, non-fatal on
|
|
78
|
+
* failure (mirrors the existing `onOrderCreate.ts` purchase-announcement
|
|
79
|
+
* pattern) — skips silently if the WhatsApp Cloud API isn't configured.
|
|
80
|
+
*/
|
|
81
|
+
function notifyAdminsOfPaymentProof(order) {
|
|
82
|
+
void (async () => {
|
|
83
|
+
try {
|
|
84
|
+
const [{ resolveKeys }, { sendWhatsAppBusinessMessage, buildPaymentProofReviewMessage }] = await Promise.all([
|
|
85
|
+
import("../../../../core/integration-keys"),
|
|
86
|
+
import("../../../../features/whatsapp-bot/server"),
|
|
87
|
+
]);
|
|
88
|
+
const keys = await resolveKeys();
|
|
89
|
+
if (!keys.whatsappPhoneNumberId || !keys.whatsappCloudApiToken)
|
|
90
|
+
return;
|
|
91
|
+
const adminNumbers = keys.whatsappAdminNotifyNumbers
|
|
92
|
+
.split(",")
|
|
93
|
+
.map((n) => n.trim().replace(/\D/g, ""))
|
|
94
|
+
.filter(Boolean);
|
|
95
|
+
if (adminNumbers.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
// No hardcoded domain fallback here (audit-ssr-in-appkit) — every
|
|
98
|
+
// consumer sets NEXT_PUBLIC_SITE_URL; skip the review link rather than
|
|
99
|
+
// guessing a brand-specific domain from inside appkit/_internal/.
|
|
100
|
+
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? "";
|
|
101
|
+
const message = buildPaymentProofReviewMessage({
|
|
102
|
+
orderId: order.id,
|
|
103
|
+
buyerName: order.userName,
|
|
104
|
+
productTitle: order.productTitle,
|
|
105
|
+
totalAmount: order.totalPrice,
|
|
106
|
+
reviewUrl: `${baseUrl}/admin/orders`,
|
|
107
|
+
});
|
|
108
|
+
await Promise.allSettled(adminNumbers.map((toPhone) => sendWhatsAppBusinessMessage({
|
|
109
|
+
toPhone,
|
|
110
|
+
message,
|
|
111
|
+
phoneNumberId: keys.whatsappPhoneNumberId,
|
|
112
|
+
accessToken: keys.whatsappCloudApiToken,
|
|
113
|
+
})));
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
void normalizeError(err);
|
|
117
|
+
// Non-fatal — the order itself already saved successfully; a WhatsApp
|
|
118
|
+
// Cloud API hiccup here must never surface as a proof-upload failure.
|
|
119
|
+
serverLogger.warn("Payment-proof admin WhatsApp push failed (non-fatal)", {
|
|
120
|
+
orderId: order.id,
|
|
121
|
+
error: err instanceof Error ? err.message : String(err),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
})();
|
|
125
|
+
}
|
|
62
126
|
export async function attachPaymentProofAction(orderId, proof) {
|
|
63
127
|
return wrapAction(async () => {
|
|
64
128
|
const user = await requireRoleUser(["buyer", "seller", "admin"]);
|
|
@@ -68,17 +132,41 @@ export async function attachPaymentProofAction(orderId, proof) {
|
|
|
68
132
|
if (!isAdminUser(user) && order.userId !== user.uid)
|
|
69
133
|
throw new OrderOwnershipError(orderId);
|
|
70
134
|
const pm = order.paymentMethod ?? "";
|
|
71
|
-
if (pm !== "cash" && pm !== "upi_manual") {
|
|
72
|
-
throw new ValidationError("Payment proof can only be attached to cash or
|
|
135
|
+
if (pm !== "cash" && pm !== "upi_manual" && pm !== "emi") {
|
|
136
|
+
throw new ValidationError("Payment proof can only be attached to cash, UPI, or EMI orders");
|
|
73
137
|
}
|
|
74
138
|
if (order.paymentProofUrl) {
|
|
75
139
|
throw new ValidationError("PROOF_ALREADY_ATTACHED");
|
|
76
140
|
}
|
|
141
|
+
// The 15-min sweep cancels+restocks the order once its window passes with
|
|
142
|
+
// no proof attached — a late submission must surface a clear "window
|
|
143
|
+
// expired" error rather than silently attaching proof to a dead order.
|
|
144
|
+
if (order.paymentDeadline && new Date(order.paymentDeadline) < new Date() && order.status !== "pending") {
|
|
145
|
+
throw new ValidationError("PAYMENT_WINDOW_EXPIRED");
|
|
146
|
+
}
|
|
147
|
+
if (!proof.buyerFraudAgreementAccepted) {
|
|
148
|
+
throw new ValidationError("You must confirm this payment is genuine before submitting proof.");
|
|
149
|
+
}
|
|
150
|
+
const paymentUpiMismatch = order.displayedUpiId
|
|
151
|
+
? normalizeUpi(proof.buyerReportedUpiId) !== normalizeUpi(order.displayedUpiId)
|
|
152
|
+
: false;
|
|
77
153
|
await orderRepository.update(orderId, {
|
|
78
154
|
paymentProofUrl: proof.proofUrl,
|
|
79
155
|
paymentTransactionId: proof.transactionId,
|
|
80
156
|
paymentProofMimeType: proof.mimeType,
|
|
81
157
|
paymentProofUploadedAt: new Date(),
|
|
158
|
+
buyerMarkedPaid: proof.buyerMarkedPaid,
|
|
159
|
+
buyerMarkedPaidAt: proof.buyerMarkedPaid ? new Date() : undefined,
|
|
160
|
+
buyerFraudAgreementAccepted: proof.buyerFraudAgreementAccepted,
|
|
161
|
+
buyerFraudAgreementAcceptedAt: new Date(),
|
|
162
|
+
buyerReportedUpiId: proof.buyerReportedUpiId,
|
|
163
|
+
paymentUpiMismatch,
|
|
164
|
+
});
|
|
165
|
+
notifyAdminsOfPaymentProof({
|
|
166
|
+
id: orderId,
|
|
167
|
+
userName: order.userName,
|
|
168
|
+
productTitle: order.productTitle,
|
|
169
|
+
totalPrice: order.totalPrice,
|
|
82
170
|
});
|
|
83
171
|
});
|
|
84
172
|
}
|
|
@@ -101,11 +189,158 @@ export async function adminVerifyPaymentAction(orderId) {
|
|
|
101
189
|
method: "manual",
|
|
102
190
|
transactionId: order.paymentTransactionId,
|
|
103
191
|
proofUrl: order.paymentProofUrl,
|
|
104
|
-
|
|
192
|
+
amount: order.totalPrice,
|
|
105
193
|
paidAt: new Date(),
|
|
106
194
|
verifiedBy: user.uid,
|
|
107
195
|
verificationMethod: "manual_review",
|
|
108
196
|
},
|
|
197
|
+
paymentReviewOutcome: "approved",
|
|
198
|
+
paymentReviewedBy: user.uid,
|
|
199
|
+
paymentReviewedAt: new Date(),
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Tier PP — "honest mistake" tier of the two-tier admin review (blurry
|
|
205
|
+
* screenshot, wrong amount typed). Clears the proof so the buyer can cleanly
|
|
206
|
+
* resubmit, and extends `paymentDeadline` by another 15 minutes from now so
|
|
207
|
+
* review latency doesn't eat into the buyer's time to fix it. Order stays
|
|
208
|
+
* `pending`/`pending` — no penalty.
|
|
209
|
+
*/
|
|
210
|
+
export async function adminRequestProofReuploadAction(orderId, note) {
|
|
211
|
+
return wrapAction(async () => {
|
|
212
|
+
const user = await requireRoleUser(["admin", "moderator"]);
|
|
213
|
+
if (!isAdminUser(user) && !isModeratorUser(user)) {
|
|
214
|
+
throw new ValidationError("Only admin or moderator can request a proof re-upload");
|
|
215
|
+
}
|
|
216
|
+
if (!note.trim())
|
|
217
|
+
throw new ValidationError(REASON_REQUIRED_MSG);
|
|
218
|
+
const order = await orderRepository.findById(orderId).catch(() => null);
|
|
219
|
+
if (!order)
|
|
220
|
+
throw new OrderNotFoundError(orderId);
|
|
221
|
+
if (order.paymentStatus === "paid") {
|
|
222
|
+
throw new ValidationError("This order's payment is already verified");
|
|
223
|
+
}
|
|
224
|
+
await orderRepository.update(orderId, {
|
|
225
|
+
paymentProofUrl: null,
|
|
226
|
+
paymentTransactionId: null,
|
|
227
|
+
paymentProofMimeType: null,
|
|
228
|
+
paymentProofUploadedAt: null,
|
|
229
|
+
buyerMarkedPaid: null,
|
|
230
|
+
buyerMarkedPaidAt: null,
|
|
231
|
+
buyerFraudAgreementAccepted: null,
|
|
232
|
+
buyerFraudAgreementAcceptedAt: null,
|
|
233
|
+
buyerReportedUpiId: null,
|
|
234
|
+
paymentUpiMismatch: null,
|
|
235
|
+
paymentDeadline: new Date(Date.now() + PAYMENT_WINDOW_MS),
|
|
236
|
+
paymentReviewOutcome: "reupload_requested",
|
|
237
|
+
paymentReviewNote: note,
|
|
238
|
+
paymentReviewedBy: user.uid,
|
|
239
|
+
paymentReviewedAt: new Date(),
|
|
240
|
+
});
|
|
241
|
+
await sendNotification({
|
|
242
|
+
userId: order.userId,
|
|
243
|
+
type: "payment_review",
|
|
244
|
+
priority: "high",
|
|
245
|
+
title: "Payment proof needs correction",
|
|
246
|
+
message: `Your payment proof for "${order.productTitle}" needs correction: ${note}. Please re-upload within 15 minutes.`,
|
|
247
|
+
relatedId: orderId,
|
|
248
|
+
relatedType: "order",
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Tier PP — "fraud" tier of the two-tier admin review. Cancels the order,
|
|
254
|
+
* restores stock, and triggers a new temporary 7-day full-account hard ban
|
|
255
|
+
* (extends the existing permanent-only `hardBanCascade` job with an
|
|
256
|
+
* `expiresAt`, rather than forking a parallel cascade — see
|
|
257
|
+
* `HardBanCascadeInput.expiresAt`).
|
|
258
|
+
*/
|
|
259
|
+
export async function adminRejectPaymentAsFraudAction(orderId, note) {
|
|
260
|
+
return wrapAction(async () => {
|
|
261
|
+
const user = await requireRoleUser(["admin", "moderator"]);
|
|
262
|
+
if (!isAdminUser(user) && !isModeratorUser(user)) {
|
|
263
|
+
throw new ValidationError("Only admin or moderator can reject a payment as fraudulent");
|
|
264
|
+
}
|
|
265
|
+
if (!note.trim())
|
|
266
|
+
throw new ValidationError(REASON_REQUIRED_MSG);
|
|
267
|
+
const order = await orderRepository.findById(orderId).catch(() => null);
|
|
268
|
+
if (!order)
|
|
269
|
+
throw new OrderNotFoundError(orderId);
|
|
270
|
+
if (order.paymentStatus === "paid") {
|
|
271
|
+
throw new ValidationError("This order's payment is already verified");
|
|
272
|
+
}
|
|
273
|
+
await restoreStockForOrder(getAdminDb(), { ...order, id: orderId }, {
|
|
274
|
+
status: "cancelled",
|
|
275
|
+
cancellationDate: new Date(),
|
|
276
|
+
cancellationReason: PAYMENT_FRAUD_REJECTED_REASON,
|
|
277
|
+
paymentReviewOutcome: "rejected_fraud",
|
|
278
|
+
paymentReviewNote: note,
|
|
279
|
+
paymentReviewedBy: user.uid,
|
|
280
|
+
paymentReviewedAt: new Date(),
|
|
281
|
+
});
|
|
282
|
+
const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000);
|
|
283
|
+
await enqueueJob({
|
|
284
|
+
jobType: "hardBanCascade",
|
|
285
|
+
payload: {
|
|
286
|
+
uid: order.userId,
|
|
287
|
+
reason: `Fraudulent payment proof on order ${orderId}: ${note}`,
|
|
288
|
+
bannedBy: user.uid,
|
|
289
|
+
expiresAt: expiresAt.toISOString(),
|
|
290
|
+
fraudOrderId: orderId,
|
|
291
|
+
},
|
|
292
|
+
requestedBy: user.uid,
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Tier PP — raises a dispute on an auto-approved order ("the automation
|
|
298
|
+
* might be wrong"). Only valid when `autoApproved === true` — a manually
|
|
299
|
+
* reviewed order already went through human judgment and disputes on it go
|
|
300
|
+
* through the existing return/refund flow instead. Callable by the buyer,
|
|
301
|
+
* the seller (store owner), or admin/moderator. Does not itself reverse
|
|
302
|
+
* payment/order status — surfaces to the admin queue for investigation.
|
|
303
|
+
*/
|
|
304
|
+
export async function raiseOrderDisputeAction(orderId, reason) {
|
|
305
|
+
return wrapAction(async () => {
|
|
306
|
+
const user = await requireRoleUser(["buyer", "seller", "admin"]);
|
|
307
|
+
if (!reason.trim())
|
|
308
|
+
throw new ValidationError(REASON_REQUIRED_MSG);
|
|
309
|
+
const order = await orderRepository.findById(orderId).catch(() => null);
|
|
310
|
+
if (!order)
|
|
311
|
+
throw new OrderNotFoundError(orderId);
|
|
312
|
+
const isBuyer = order.userId === user.uid;
|
|
313
|
+
let isSeller = false;
|
|
314
|
+
if (!isBuyer && !isAdminUser(user) && !isModeratorUser(user) && order.storeId) {
|
|
315
|
+
const store = await storeRepository.findById(order.storeId).catch(() => null);
|
|
316
|
+
isSeller = store?.ownerId === user.uid;
|
|
317
|
+
}
|
|
318
|
+
if (!isBuyer && !isSeller && !isAdminUser(user) && !isModeratorUser(user)) {
|
|
319
|
+
throw new OrderOwnershipError(orderId);
|
|
320
|
+
}
|
|
321
|
+
if (!order.autoApproved) {
|
|
322
|
+
throw new ValidationError("Disputes can only be raised on auto-approved orders. Use the return/refund flow for manually-reviewed orders.");
|
|
323
|
+
}
|
|
324
|
+
if (order.disputeStatus === "open")
|
|
325
|
+
return; // idempotent
|
|
326
|
+
await orderRepository.update(orderId, {
|
|
327
|
+
disputeRaised: true,
|
|
328
|
+
disputeRaisedBy: user.uid,
|
|
329
|
+
disputeRaisedAt: new Date(),
|
|
330
|
+
disputeReason: reason,
|
|
331
|
+
disputeStatus: "open",
|
|
109
332
|
});
|
|
333
|
+
// Notify every admin for manual investigation — a dispute on an
|
|
334
|
+
// auto-approved order means nobody has looked at it yet.
|
|
335
|
+
const admins = await userRepository.findByRole("admin");
|
|
336
|
+
await Promise.allSettled(admins.map((admin) => sendNotification({
|
|
337
|
+
userId: admin.uid,
|
|
338
|
+
type: "payment_review",
|
|
339
|
+
priority: "high",
|
|
340
|
+
title: "Dispute raised on auto-approved order",
|
|
341
|
+
message: `A dispute was raised on order "${order.productTitle}" (auto-approved payment). Reason: ${reason}.`,
|
|
342
|
+
relatedId: orderId,
|
|
343
|
+
relatedType: "order",
|
|
344
|
+
})));
|
|
110
345
|
});
|
|
111
346
|
}
|
|
@@ -61,6 +61,9 @@ export function orderDocumentToOrder(doc) {
|
|
|
61
61
|
trackingNumber: doc.trackingNumber,
|
|
62
62
|
shippingCarrier: doc.shippingCarrier,
|
|
63
63
|
notes: doc.notes,
|
|
64
|
+
autoApproved: doc.autoApproved,
|
|
65
|
+
disputeRaised: doc.disputeRaised,
|
|
66
|
+
disputeStatus: doc.disputeStatus,
|
|
64
67
|
createdAt: doc.createdAt instanceof Date
|
|
65
68
|
? doc.createdAt.toISOString()
|
|
66
69
|
: String(doc.createdAt),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { siteSettingsRepository } from "../../../../repositories";
|
|
2
|
+
import { roundRupees } from "../../../../utils/number.formatter";
|
|
2
3
|
import { PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, } from "../../../shared/features/payments/config";
|
|
3
4
|
/**
|
|
4
5
|
* Inflates the cart total by our platform fee + GST on that fee.
|
|
@@ -11,8 +12,8 @@ export async function resolvePaymentFee(baseAmount) {
|
|
|
11
12
|
const platformFeePercent = siteSettings?.commissions?.platformFeePercent ?? PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT;
|
|
12
13
|
const gstPercent = siteSettings?.commissions?.gstPercent ?? PAYMENTS_DEFAULT_GST_PERCENT;
|
|
13
14
|
const minimumTransactionFee = Math.max(0, siteSettings?.commissions?.minimumTransactionFee ?? 0);
|
|
14
|
-
const platformFee =
|
|
15
|
-
const gstOnFee =
|
|
15
|
+
const platformFee = roundRupees(baseAmount * (platformFeePercent / 100));
|
|
16
|
+
const gstOnFee = roundRupees(platformFee * (gstPercent / 100));
|
|
16
17
|
const rawTotal = baseAmount + platformFee + gstOnFee;
|
|
17
18
|
const totalAmount = Math.max(rawTotal, baseAmount + minimumTransactionFee);
|
|
18
19
|
return { baseAmount, platformFee, gstOnFee, totalAmount };
|
|
@@ -3,8 +3,8 @@ export type ApplyRefundDeductionInput = {
|
|
|
3
3
|
storeId: string;
|
|
4
4
|
orderId: string;
|
|
5
5
|
refundId: string;
|
|
6
|
-
/** Gross refund amount
|
|
7
|
-
|
|
6
|
+
/** Gross refund amount, decimal rupees. */
|
|
7
|
+
refundedAmount: number;
|
|
8
8
|
/** Platform fee rate (0–1). Defaults to DEFAULT_PLATFORM_FEE_RATE (0.05). */
|
|
9
9
|
platformFeeRate?: number;
|
|
10
10
|
reason: string;
|
|
@@ -15,13 +15,14 @@ import { wrapAction } from "@mohasinac/appkit/server";
|
|
|
15
15
|
*/
|
|
16
16
|
import { payoutRepository } from "../../../../repositories";
|
|
17
17
|
import { ValidationError } from "../../../../errors";
|
|
18
|
+
import { roundRupees } from "../../../../utils/number.formatter";
|
|
18
19
|
export async function applyRefundDeductionAction(input) {
|
|
19
20
|
return wrapAction(async () => {
|
|
20
|
-
if (input.
|
|
21
|
+
if (input.refundedAmount <= 0) {
|
|
21
22
|
throw new ValidationError("Refund amount must be positive");
|
|
22
23
|
}
|
|
23
24
|
const feeRate = input.platformFeeRate ?? 0.05;
|
|
24
|
-
const deductedAmount =
|
|
25
|
+
const deductedAmount = roundRupees(input.refundedAmount * (1 - feeRate));
|
|
25
26
|
const pending = await payoutRepository.findPendingByStore(input.storeId);
|
|
26
27
|
if (!pending) {
|
|
27
28
|
return { applied: false, reason: "no_pending_payout" };
|
|
@@ -32,7 +33,7 @@ export async function applyRefundDeductionAction(input) {
|
|
|
32
33
|
const updated = await payoutRepository.applyRefundDeduction(pending.id, {
|
|
33
34
|
orderId: input.orderId,
|
|
34
35
|
refundId: input.refundId,
|
|
35
|
-
refundedAmount: input.
|
|
36
|
+
refundedAmount: input.refundedAmount,
|
|
36
37
|
deductedAmount,
|
|
37
38
|
reason: input.reason,
|
|
38
39
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ProductDocument } from "../../../shared/features/products/types";
|
|
2
2
|
/** Assert a pre-order exists, is published, and has remaining capacity. */
|
|
3
3
|
export declare function assertPreOrderAvailable(preOrderId: string, requestedQty?: number): Promise<ProductDocument>;
|
|
4
|
-
/** Compute deposit amount
|
|
4
|
+
/** Compute deposit amount, decimal rupees. */
|
|
5
5
|
export declare function computeDeposit(product: ProductDocument): number;
|
|
6
6
|
/** Determine if the pre-order is still open for new reservations. */
|
|
7
7
|
export declare function isPreOrderOpen(product: ProductDocument): boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { productRepository } from "../../../../repositories";
|
|
2
2
|
import { isPreOrderListing } from "../../../../features/products/utils/listing-type";
|
|
3
|
+
import { roundRupees } from "../../../../utils/number.formatter";
|
|
3
4
|
import { PreOrderNotFoundError, PreOrderSoldOutError, PreOrderNotOpenError, } from "../../../shared/features/pre-orders/errors";
|
|
4
5
|
/** Assert a pre-order exists, is published, and has remaining capacity. */
|
|
5
6
|
export async function assertPreOrderAvailable(preOrderId, requestedQty = 1) {
|
|
@@ -14,12 +15,12 @@ export async function assertPreOrderAvailable(preOrderId, requestedQty = 1) {
|
|
|
14
15
|
throw new PreOrderSoldOutError(preOrderId);
|
|
15
16
|
return product;
|
|
16
17
|
}
|
|
17
|
-
/** Compute deposit amount
|
|
18
|
+
/** Compute deposit amount, decimal rupees. */
|
|
18
19
|
export function computeDeposit(product) {
|
|
19
20
|
if (product.preOrderDepositAmount)
|
|
20
21
|
return product.preOrderDepositAmount;
|
|
21
22
|
const percent = product.preOrderDepositPercent ?? 20;
|
|
22
|
-
return
|
|
23
|
+
return roundRupees((product.price * percent) / 100);
|
|
23
24
|
}
|
|
24
25
|
/** Determine if the pre-order is still open for new reservations. */
|
|
25
26
|
export function isPreOrderOpen(product) {
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { renderOgLayout } from "../seo/og-layout";
|
|
6
6
|
import { resolveOgImageUrl } from "../seo/og";
|
|
7
|
-
function formatPriceInr(
|
|
7
|
+
function formatPriceInr(amount, currency) {
|
|
8
8
|
return new Intl.NumberFormat("en-IN", {
|
|
9
9
|
style: "currency",
|
|
10
10
|
currency,
|
|
11
11
|
maximumFractionDigits: 0,
|
|
12
|
-
}).format(
|
|
12
|
+
}).format(amount);
|
|
13
13
|
}
|
|
14
14
|
export function renderPrizeDrawOg(doc, opts) {
|
|
15
|
-
const
|
|
16
|
-
const pricePerEntryLabel = typeof
|
|
17
|
-
? `${formatPriceInr(
|
|
15
|
+
const entryPrice = doc?.pricePerEntry ?? doc?.price ?? null;
|
|
16
|
+
const pricePerEntryLabel = typeof entryPrice === "number" && entryPrice > 0
|
|
17
|
+
? `${formatPriceInr(entryPrice, doc?.currency ?? "INR")} / entry`
|
|
18
18
|
: "Free entry";
|
|
19
19
|
const max = doc?.prizeMaxEntries ?? null;
|
|
20
20
|
const current = doc?.prizeCurrentEntries ?? 0;
|
|
@@ -9,7 +9,7 @@ export function renderProductOg(doc, opts) {
|
|
|
9
9
|
}, opts.siteName);
|
|
10
10
|
}
|
|
11
11
|
export function renderProductOgImage(data, siteName) {
|
|
12
|
-
const priceLabel = data.price ? `₹${
|
|
12
|
+
const priceLabel = data.price ? `₹${data.price.toLocaleString("en-IN")}` : null;
|
|
13
13
|
return renderOgLayout({
|
|
14
14
|
title: data.title,
|
|
15
15
|
imageUrl: data.imageUrl,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { couponsRepository } from "../../../../repositories";
|
|
2
|
+
import { roundRupees } from "../../../../utils/number.formatter";
|
|
2
3
|
import { CouponNotFoundError, CouponExpiredError, CouponUsageLimitError, CouponPerUserLimitError, CouponMinPurchaseError, CouponScopeError, } from "../../../shared/features/promotions/errors";
|
|
3
4
|
export async function validateCoupon(input, userId) {
|
|
4
5
|
const coupon = await couponsRepository.getCouponByCode(input.code).catch(() => null);
|
|
@@ -33,7 +34,8 @@ export function computeDiscount(coupon, cartTotal) {
|
|
|
33
34
|
const maxDiscount = coupon.discount?.maxDiscount;
|
|
34
35
|
let discount = 0;
|
|
35
36
|
if (type === "percentage") {
|
|
36
|
-
|
|
37
|
+
// audit-money-units-ok: percentage divisor (value is 0-100), not paise
|
|
38
|
+
discount = roundRupees((cartTotal * value) / 100);
|
|
37
39
|
if (maxDiscount)
|
|
38
40
|
discount = Math.min(discount, maxDiscount);
|
|
39
41
|
}
|
|
@@ -3,8 +3,8 @@ import type { RefundType } from "../../../../features/orders/schemas";
|
|
|
3
3
|
export type ProcessRefundInput = {
|
|
4
4
|
orderId: string;
|
|
5
5
|
type: RefundType;
|
|
6
|
-
/**
|
|
7
|
-
|
|
6
|
+
/** Decimal rupees. Must be > 0 and ≤ remaining refundable amount on the order. */
|
|
7
|
+
amount: number;
|
|
8
8
|
reason: string;
|
|
9
9
|
/** Product/item ids affected (for partial refunds). */
|
|
10
10
|
itemIds?: string[];
|
|
@@ -16,6 +16,7 @@ import { wrapAction } from "@mohasinac/appkit/server";
|
|
|
16
16
|
*/
|
|
17
17
|
import { randomUUID } from "crypto";
|
|
18
18
|
import { getProviders } from "../../../../contracts/registry";
|
|
19
|
+
import { rupeesToPaise } from "../../../../providers/payment-razorpay/index";
|
|
19
20
|
import { orderRepository } from "../../../..";
|
|
20
21
|
import { ORDER_FIELDS } from "../../../../constants/field-names";
|
|
21
22
|
import { NotFoundError, ValidationError } from "../../../../errors";
|
|
@@ -79,9 +80,9 @@ export async function processRefundAction(input) {
|
|
|
79
80
|
const order = await orderRepository.findById(input.orderId);
|
|
80
81
|
if (!order)
|
|
81
82
|
throw new NotFoundError(`Order ${input.orderId} not found`);
|
|
82
|
-
if (input.
|
|
83
|
+
if (input.amount <= 0)
|
|
83
84
|
throw new ValidationError("Refund amount must be positive");
|
|
84
|
-
if (input.
|
|
85
|
+
if (input.amount > order.totalPrice) {
|
|
85
86
|
throw new ValidationError("Refund amount exceeds order total");
|
|
86
87
|
}
|
|
87
88
|
// Guard: non-refundable orders (prize draws, bundles).
|
|
@@ -98,14 +99,14 @@ export async function processRefundAction(input) {
|
|
|
98
99
|
const payment = getProviders().payment;
|
|
99
100
|
if (!payment)
|
|
100
101
|
throw new ValidationError("Payment provider not configured");
|
|
101
|
-
const result = await payment.refund(input.razorpayPaymentId, input.
|
|
102
|
+
const result = await payment.refund(input.razorpayPaymentId, rupeesToPaise(input.amount));
|
|
102
103
|
razorpayRefundId = result.id;
|
|
103
104
|
}
|
|
104
|
-
const isFull = input.
|
|
105
|
+
const isFull = input.amount >= order.totalPrice;
|
|
105
106
|
const event = {
|
|
106
107
|
refundId,
|
|
107
108
|
type: input.type,
|
|
108
|
-
amount: input.
|
|
109
|
+
amount: input.amount,
|
|
109
110
|
...(input.itemIds?.length ? { itemIds: input.itemIds } : {}),
|
|
110
111
|
reason: input.reason,
|
|
111
112
|
refundedAt: now,
|
|
@@ -131,7 +132,7 @@ export async function processRefundAction(input) {
|
|
|
131
132
|
storeId: order.storeId,
|
|
132
133
|
orderId: input.orderId,
|
|
133
134
|
refundId,
|
|
134
|
-
|
|
135
|
+
refundedAmount: input.amount,
|
|
135
136
|
reason: input.reason,
|
|
136
137
|
}).catch(() => { });
|
|
137
138
|
}
|
|
@@ -105,7 +105,7 @@ export const onScamReportUpdate = defineFunction({
|
|
|
105
105
|
// files for the full data-flow explanation.
|
|
106
106
|
export const onShipmentItemWrite = defineFunction({
|
|
107
107
|
name: "onShipmentItemWrite",
|
|
108
|
-
description: "Recompute a shipment lot's itemCount +
|
|
108
|
+
description: "Recompute a shipment lot's itemCount + mainItemsProjectedRevenue on any item write.",
|
|
109
109
|
trigger: { kind: "documentWritten", pathPattern: "shipmentItems/{itemId}" },
|
|
110
110
|
handler: onShipmentItemWriteHandler,
|
|
111
111
|
options: { region: REGION },
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export declare const auctionSettlement: import("./types").ScheduledFunctionDefinition;
|
|
2
2
|
export declare const pendingOrderTimeout: import("./types").ScheduledFunctionDefinition;
|
|
3
|
+
export declare const paymentWindowTimeout: import("./types").ScheduledFunctionDefinition;
|
|
4
|
+
export declare const hardBanReinstatement: import("./types").ScheduledFunctionDefinition;
|
|
5
|
+
export declare const paymentReviewAutoApprove: import("./types").ScheduledFunctionDefinition;
|
|
3
6
|
export declare const couponExpiry: import("./types").ScheduledFunctionDefinition;
|
|
4
7
|
export declare const offerExpiry: import("./types").ScheduledFunctionDefinition;
|
|
5
8
|
export declare const productStatsSync: import("./types").ScheduledFunctionDefinition;
|
|
@@ -22,4 +25,4 @@ export declare const prizeRevealReminder: import("./types").ScheduledFunctionDef
|
|
|
22
25
|
export declare const bundleStockSync: import("./types").ScheduledFunctionDefinition;
|
|
23
26
|
export declare const emiInstallmentReminder: import("./types").ScheduledFunctionDefinition;
|
|
24
27
|
export declare const catalogueImageStalenessReminder: import("./types").ScheduledFunctionDefinition;
|
|
25
|
-
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, import("./types").ScheduledFunctionDefinition];
|
|
28
|
+
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, 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, catalogueImageStalenessReminderHandler, mediaTmpCleanupHandler, notificationPruneHandler, offerExpiryHandler, payoutBatchHandler, pendingOrderTimeoutHandler, positionsReconcileHandler, prizeRevealCloseHandler, prizeRevealExpiryHandler, prizeRevealOpenHandler, prizeRevealReminderHandler, productStatsSyncHandler, weeklyPayoutEligibilityHandler, testerSandboxCleanupHandler, } from "../jobs/handlers";
|
|
3
|
+
import { auctionSettlementHandler, autoPayoutEligibilityHandler, bundleStockSyncHandler, cartPruneHandler, cleanupRtdbEventsHandler, countersReconcileHandler, couponExpiryHandler, dailyDataCleanupHandler, draftPruneHandler, emiInstallmentReminderHandler, catalogueImageStalenessReminderHandler, mediaTmpCleanupHandler, notificationPruneHandler, offerExpiryHandler, payoutBatchHandler, paymentWindowTimeoutHandler, hardBanReinstatementHandler, paymentReviewAutoApproveHandler, pendingOrderTimeoutHandler, positionsReconcileHandler, prizeRevealCloseHandler, prizeRevealExpiryHandler, prizeRevealOpenHandler, prizeRevealReminderHandler, productStatsSyncHandler, weeklyPayoutEligibilityHandler, testerSandboxCleanupHandler, } from "../jobs/handlers";
|
|
4
4
|
import { defineFunction } from "./define";
|
|
5
5
|
const REGION = "asia-south1";
|
|
6
6
|
const EVERY_5_MIN = "every 5 minutes";
|
|
@@ -13,11 +13,32 @@ export const auctionSettlement = defineFunction({
|
|
|
13
13
|
});
|
|
14
14
|
export const pendingOrderTimeout = defineFunction({
|
|
15
15
|
name: "pendingOrderTimeout",
|
|
16
|
-
description: "Cancel pending orders that exceeded
|
|
16
|
+
description: "Cancel pending COD orders that exceeded the 24h timeout window (orders with a paymentDeadline are paymentWindowTimeout's domain instead).",
|
|
17
17
|
trigger: { kind: "schedule", cron: "0 */2 * * *" },
|
|
18
18
|
handler: pendingOrderTimeoutHandler,
|
|
19
19
|
options: { region: REGION, timeoutSeconds: 120, memory: "256MiB", maxInstances: 1 },
|
|
20
20
|
});
|
|
21
|
+
export const paymentWindowTimeout = defineFunction({
|
|
22
|
+
name: "paymentWindowTimeout",
|
|
23
|
+
description: "Cancel + restock orders whose 15-minute manual-payment window expired without proof.",
|
|
24
|
+
trigger: { kind: "schedule", cron: EVERY_5_MIN },
|
|
25
|
+
handler: paymentWindowTimeoutHandler,
|
|
26
|
+
options: { region: REGION, timeoutSeconds: 120, memory: "256MiB", maxInstances: 1 },
|
|
27
|
+
});
|
|
28
|
+
export const hardBanReinstatement = defineFunction({
|
|
29
|
+
name: "hardBanReinstatement",
|
|
30
|
+
description: "Re-enable Auth login for temporary hard-bans past their expiry.",
|
|
31
|
+
trigger: { kind: "schedule", cron: "*/15 * * * *" },
|
|
32
|
+
handler: hardBanReinstatementHandler,
|
|
33
|
+
options: { region: REGION, timeoutSeconds: 120, memory: "256MiB", maxInstances: 1 },
|
|
34
|
+
});
|
|
35
|
+
export const paymentReviewAutoApprove = defineFunction({
|
|
36
|
+
name: "paymentReviewAutoApprove",
|
|
37
|
+
description: "Auto-approve manual payment proofs unreviewed after 2 hours.",
|
|
38
|
+
trigger: { kind: "schedule", cron: "*/15 * * * *" },
|
|
39
|
+
handler: paymentReviewAutoApproveHandler,
|
|
40
|
+
options: { region: REGION, timeoutSeconds: 120, memory: "256MiB", maxInstances: 1 },
|
|
41
|
+
});
|
|
21
42
|
export const couponExpiry = defineFunction({
|
|
22
43
|
name: "couponExpiry",
|
|
23
44
|
description: "Mark coupons inactive past their endDate (daily 00:05 UTC).",
|
|
@@ -175,6 +196,9 @@ export const catalogueImageStalenessReminder = defineFunction({
|
|
|
175
196
|
export const SCHEDULED_FUNCTIONS = [
|
|
176
197
|
auctionSettlement,
|
|
177
198
|
pendingOrderTimeout,
|
|
199
|
+
paymentWindowTimeout,
|
|
200
|
+
hardBanReinstatement,
|
|
201
|
+
paymentReviewAutoApprove,
|
|
178
202
|
couponExpiry,
|
|
179
203
|
offerExpiry,
|
|
180
204
|
productStatsSync,
|
|
@@ -46,7 +46,7 @@ export async function runEmiInstallmentReminder(ctx) {
|
|
|
46
46
|
title: isOverdue ? "EMI installment overdue" : "EMI installment due soon",
|
|
47
47
|
message: isOverdue
|
|
48
48
|
? `Installment ${inst.index} for order ${id} is overdue. Pay now to avoid delaying your shipment.`
|
|
49
|
-
: `Installment ${inst.index} for order ${id} (₹${
|
|
49
|
+
: `Installment ${inst.index} for order ${id} (₹${inst.amount.toFixed(2)}) is due on ${dueDate.toDateString()}.`,
|
|
50
50
|
relatedId: id,
|
|
51
51
|
relatedType: "order",
|
|
52
52
|
actionUrl: `/user/orders/view/${id}`,
|
|
@@ -22,5 +22,9 @@ export interface HardBanCascadeInput {
|
|
|
22
22
|
uid: string;
|
|
23
23
|
reason: string;
|
|
24
24
|
bannedBy: string;
|
|
25
|
+
/** Tier PP — omitted/undefined = permanent (today's only caller, the manual admin hard-ban route). A Date makes this a temporary ban, auto-reinstated by `hardBanReinstatement` — set by `adminRejectPaymentAsFraudAction`. */
|
|
26
|
+
expiresAt?: Date;
|
|
27
|
+
/** Tier PP — the order whose payment proof was rejected as fraudulent, for traceability. Only set alongside `expiresAt`. */
|
|
28
|
+
fraudOrderId?: string;
|
|
25
29
|
}
|
|
26
30
|
export declare function runHardBanCascade(input: HardBanCascadeInput, ctx: JobContext): Promise<JobRunResult>;
|