@mohasinac/appkit 3.8.2 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +3 -7
- package/dist/index.js +7 -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/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 +8 -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
|
@@ -136,7 +136,7 @@ export interface CategoryDocument extends BaseDocument {
|
|
|
136
136
|
*/
|
|
137
137
|
bundleKind?: "special" | "brand";
|
|
138
138
|
/** Discounted bundle price in paise. */
|
|
139
|
-
|
|
139
|
+
bundlePrice?: number;
|
|
140
140
|
/** Rule resolving the bundle's member products — static list or live query. */
|
|
141
141
|
bundleQueryRule?: BundleQueryRule;
|
|
142
142
|
/** Snapshot stock state — recomputed by onProductStockChange. */
|
|
@@ -231,7 +231,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
|
|
|
231
231
|
brandFounded: z.ZodOptional<z.ZodNumber>;
|
|
232
232
|
brandBannerImage: z.ZodOptional<z.ZodString>;
|
|
233
233
|
bundleKind: z.ZodOptional<z.ZodEnum<["special", "brand"]>>;
|
|
234
|
-
|
|
234
|
+
bundlePrice: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, number>>;
|
|
235
235
|
bundleQueryRule: z.ZodOptional<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
236
236
|
type: z.ZodLiteral<"static">;
|
|
237
237
|
productIds: z.ZodArray<z.ZodString, "many">;
|
|
@@ -443,7 +443,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
|
|
|
443
443
|
brandCountry?: string | undefined;
|
|
444
444
|
brandFounded?: number | undefined;
|
|
445
445
|
brandBannerImage?: string | undefined;
|
|
446
|
-
|
|
446
|
+
bundlePrice?: number | undefined;
|
|
447
447
|
bundleQueryRule?: {
|
|
448
448
|
type: "static";
|
|
449
449
|
productIds: string[];
|
|
@@ -537,7 +537,7 @@ export declare const categoryFirestoreSchema: z.ZodObject<{
|
|
|
537
537
|
brandCountry?: string | undefined;
|
|
538
538
|
brandFounded?: number | undefined;
|
|
539
539
|
brandBannerImage?: string | undefined;
|
|
540
|
-
|
|
540
|
+
bundlePrice?: number | undefined;
|
|
541
541
|
bundleQueryRule?: {
|
|
542
542
|
type: "static";
|
|
543
543
|
productIds: string[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./firestore";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
import { auditTimestampsShape, firestoreDateSchema,
|
|
3
|
+
import { auditTimestampsShape, firestoreDateSchema, rupeesSchema } from "../../../schemas/firestore-helpers";
|
|
4
4
|
// ─── Firestore document schema (W2) ───────────────────────────────────────────
|
|
5
5
|
// Mirrors CategoryDocument + nested types in ./firestore.ts.
|
|
6
6
|
// Registered into SCHEMAS.firestore.categories.
|
|
@@ -78,7 +78,7 @@ export const categoryFirestoreSchema = z.object({
|
|
|
78
78
|
brandFounded: z.number().int().optional(),
|
|
79
79
|
brandBannerImage: z.string().optional(),
|
|
80
80
|
bundleKind: z.enum(["special", "brand"]).optional(),
|
|
81
|
-
|
|
81
|
+
bundlePrice: rupeesSchema.optional(),
|
|
82
82
|
bundleQueryRule: bundleQueryRuleSchema.optional(),
|
|
83
83
|
bundleStockStatus: z.enum(["in_stock", "out_of_stock"]).optional(),
|
|
84
84
|
bundleQueryResolvedAt: firestoreDateSchema.optional(),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkout Value OTP Actions (appkit) — Tier PP.
|
|
3
|
+
*
|
|
4
|
+
* OTP gate for placing a checkout whose total is at/above
|
|
5
|
+
* `siteSettings.payment.otpCheckoutThreshold` (skipped for COD). A distinct
|
|
6
|
+
* purpose from `checkout-actions.ts`'s third-party shipping consent OTP —
|
|
7
|
+
* same crypto primitives, separate Firestore namespace and copy.
|
|
8
|
+
*/
|
|
9
|
+
/** Sends a checkout-value OTP to the buyer's registered email. Returns masked email so the UI can confirm which inbox to check. */
|
|
10
|
+
export declare function sendCheckoutValueOtp(userId: string, userEmail: string): Promise<{
|
|
11
|
+
maskedEmail: string;
|
|
12
|
+
}>;
|
|
13
|
+
/** Verifies the 6-digit checkout-value OTP and marks the Firestore record verified. */
|
|
14
|
+
export declare function verifyCheckoutValueOtp(userId: string, code: string): Promise<void>;
|
|
15
|
+
/** Whether the buyer has a currently-verified checkout-value OTP on file. */
|
|
16
|
+
export declare function isCheckoutValueOtpVerified(userId: string): Promise<boolean>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkout Value OTP Actions (appkit) — Tier PP.
|
|
3
|
+
*
|
|
4
|
+
* OTP gate for placing a checkout whose total is at/above
|
|
5
|
+
* `siteSettings.payment.otpCheckoutThreshold` (skipped for COD). A distinct
|
|
6
|
+
* purpose from `checkout-actions.ts`'s third-party shipping consent OTP —
|
|
7
|
+
* same crypto primitives, separate Firestore namespace and copy.
|
|
8
|
+
*/
|
|
9
|
+
import { timingSafeEqual } from "crypto";
|
|
10
|
+
import { ValidationError } from "../../../errors";
|
|
11
|
+
import { serverLogger } from "../../../monitoring";
|
|
12
|
+
import { sendEmail } from "../../contact/email";
|
|
13
|
+
import { getAdminDb } from "../../../providers/db-firebase";
|
|
14
|
+
import { resolveDate } from "../../../utils";
|
|
15
|
+
import { CHECKOUT_VALUE_OTP_EXPIRY_MS, CHECKOUT_VALUE_OTP_MAX_ATTEMPTS, hashOtp, generateOtpCode, checkoutValueOtpRef, enforceCheckoutValueOtpRateLimit, } from "../../auth/checkout-value-otp";
|
|
16
|
+
/** Sends a checkout-value OTP to the buyer's registered email. Returns masked email so the UI can confirm which inbox to check. */
|
|
17
|
+
export async function sendCheckoutValueOtp(userId, userEmail) {
|
|
18
|
+
const db = getAdminDb();
|
|
19
|
+
await enforceCheckoutValueOtpRateLimit(db, userId);
|
|
20
|
+
const code = generateOtpCode();
|
|
21
|
+
const codeHash = hashOtp(code);
|
|
22
|
+
const expiresAt = new Date(Date.now() + CHECKOUT_VALUE_OTP_EXPIRY_MS);
|
|
23
|
+
await checkoutValueOtpRef(db, userId).set({
|
|
24
|
+
codeHash,
|
|
25
|
+
expiresAt,
|
|
26
|
+
attempts: 0,
|
|
27
|
+
verified: false,
|
|
28
|
+
createdAt: new Date(),
|
|
29
|
+
});
|
|
30
|
+
const siteName = process.env.NEXT_PUBLIC_SITE_NAME || "LetItRip";
|
|
31
|
+
const [local, domain] = userEmail.split("@");
|
|
32
|
+
const maskedEmail = domain
|
|
33
|
+
? `${local.length <= 2 ? "*".repeat(local.length) : local[0] + "*".repeat(local.length - 2) + local[local.length - 1]}@${domain}`
|
|
34
|
+
: "***";
|
|
35
|
+
await sendEmail({
|
|
36
|
+
to: userEmail,
|
|
37
|
+
subject: `${siteName}: Verify your order`,
|
|
38
|
+
html: `
|
|
39
|
+
<div style="font-family:sans-serif;max-width:480px;margin:0 auto;padding:24px">
|
|
40
|
+
<h2 style="margin-bottom:8px">Verify Your Order</h2>
|
|
41
|
+
<p style="color:#555">Your cart total requires verification before checkout. Enter this code to continue:</p>
|
|
42
|
+
<div style="font-size:36px;font-weight:bold;letter-spacing:8px;text-align:center;margin:24px 0;padding:16px;background:#f3f4f6;border-radius:8px">${code}</div>
|
|
43
|
+
<p style="color:#888;font-size:12px">This code expires in 10 minutes. If you did not request this, please ignore this email.</p>
|
|
44
|
+
</div>
|
|
45
|
+
`,
|
|
46
|
+
});
|
|
47
|
+
serverLogger.info(`Checkout value OTP sent: uid=${userId}`);
|
|
48
|
+
return { maskedEmail };
|
|
49
|
+
}
|
|
50
|
+
/** Verifies the 6-digit checkout-value OTP and marks the Firestore record verified. */
|
|
51
|
+
export async function verifyCheckoutValueOtp(userId, code) {
|
|
52
|
+
const db = getAdminDb();
|
|
53
|
+
const ref = checkoutValueOtpRef(db, userId);
|
|
54
|
+
const snap = await ref.get();
|
|
55
|
+
if (!snap.exists) {
|
|
56
|
+
throw new ValidationError("No verification code found. Please request a new code.");
|
|
57
|
+
}
|
|
58
|
+
const otpDoc = snap.data();
|
|
59
|
+
if (otpDoc.verified)
|
|
60
|
+
return;
|
|
61
|
+
if (otpDoc.attempts >= CHECKOUT_VALUE_OTP_MAX_ATTEMPTS) {
|
|
62
|
+
throw new ValidationError("Too many failed attempts. Please request a new code.");
|
|
63
|
+
}
|
|
64
|
+
if (Date.now() > (resolveDate(otpDoc.expiresAt)?.getTime() ?? 0)) {
|
|
65
|
+
throw new ValidationError("Code expired. Please request a new one.");
|
|
66
|
+
}
|
|
67
|
+
const inputHash = hashOtp(code);
|
|
68
|
+
if (!timingSafeEqual(Buffer.from(inputHash, "hex"), Buffer.from(otpDoc.codeHash, "hex"))) {
|
|
69
|
+
await ref.update({ attempts: otpDoc.attempts + 1 });
|
|
70
|
+
throw new ValidationError("Invalid code. Please check and try again.");
|
|
71
|
+
}
|
|
72
|
+
await ref.update({ verified: true, verifiedAt: new Date() });
|
|
73
|
+
serverLogger.info(`Checkout value OTP verified: uid=${userId}`);
|
|
74
|
+
}
|
|
75
|
+
/** Whether the buyer has a currently-verified checkout-value OTP on file. */
|
|
76
|
+
export async function isCheckoutValueOtpVerified(userId) {
|
|
77
|
+
const db = getAdminDb();
|
|
78
|
+
const snap = await checkoutValueOtpRef(db, userId).get();
|
|
79
|
+
if (!snap.exists)
|
|
80
|
+
return false;
|
|
81
|
+
const otpDoc = snap.data();
|
|
82
|
+
return otpDoc.verified === true;
|
|
83
|
+
}
|
|
@@ -21,7 +21,7 @@ export type FailedPaymentDocument = {
|
|
|
21
21
|
uid: string;
|
|
22
22
|
gatewayOrderId?: string;
|
|
23
23
|
gatewayPaymentId?: string;
|
|
24
|
-
/** Amount in
|
|
24
|
+
/** Amount in decimal rupees. */
|
|
25
25
|
amountRs?: number;
|
|
26
26
|
addressId?: string;
|
|
27
27
|
reason: FailedPaymentReason;
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
export { ClassifiedListView } from "./ClassifiedListView";
|
|
2
|
-
export type { ClassifiedListViewProps } from "./ClassifiedListView";
|
|
3
|
-
export { ClassifiedIndexListing } from "./ClassifiedIndexListing";
|
|
4
|
-
export type { ClassifiedIndexListingProps } from "./ClassifiedIndexListing";
|
|
5
1
|
export { ClassifiedFilters } from "./ClassifiedFilters";
|
|
6
2
|
export type { ClassifiedFiltersProps } from "./ClassifiedFilters";
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
export { DigitalCodesListView } from "./DigitalCodesListView";
|
|
2
|
-
export type { DigitalCodesListViewProps } from "./DigitalCodesListView";
|
|
3
|
-
export { DigitalCodesIndexListing } from "./DigitalCodesIndexListing";
|
|
4
|
-
export type { DigitalCodesIndexListingProps } from "./DigitalCodesIndexListing";
|
|
5
1
|
export { DigitalCodeFilters } from "./DigitalCodeFilters";
|
|
6
2
|
export type { DigitalCodeFiltersProps } from "./DigitalCodeFilters";
|
|
@@ -348,7 +348,7 @@ export declare const spinPrizeSchema: z.ZodObject<{
|
|
|
348
348
|
isActive: boolean;
|
|
349
349
|
couponId?: string | undefined;
|
|
350
350
|
}>;
|
|
351
|
-
/** Lottery slot schema — client-safe shape (no
|
|
351
|
+
/** Lottery slot schema — client-safe shape (no price/weight sent to clients). */
|
|
352
352
|
export declare const lotterySlotClientSchema: z.ZodObject<{
|
|
353
353
|
slotNumber: z.ZodNumber;
|
|
354
354
|
name: z.ZodString;
|
|
@@ -77,7 +77,7 @@ export const spinPrizeSchema = z.object({
|
|
|
77
77
|
weight: z.number(),
|
|
78
78
|
isActive: z.boolean(),
|
|
79
79
|
});
|
|
80
|
-
/** Lottery slot schema — client-safe shape (no
|
|
80
|
+
/** Lottery slot schema — client-safe shape (no price/weight sent to clients). */
|
|
81
81
|
export const lotterySlotClientSchema = z.object({
|
|
82
82
|
slotNumber: z.number().int().min(1),
|
|
83
83
|
name: z.string(),
|
|
@@ -24,7 +24,7 @@ function FeaturedBundleCard({ bundle, onBuyNow }) {
|
|
|
24
24
|
const memberCount = bundle.bundleProductIds?.length ?? 0;
|
|
25
25
|
const cover = bundle.display?.coverImage;
|
|
26
26
|
const href = String(ROUTES.PUBLIC.BUNDLE_DETAIL?.(bundle.slug) ?? "#");
|
|
27
|
-
return (_jsxs(Stack, { gap: "none", surface: "default", rounded: "xl", border: "default", children: [_jsxs(Link, { href: href, className: "group block p-[var(--appkit-space-3)] hover:no-underline", children: [_jsx(Div, { className: `relative mb-2 aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: cover ? (_jsx(MediaImage, { src: cover, alt: bundle.name, size: "card", className: "transition-transform group-hover:scale-105" })) : (_jsx(Row, { textSize: "3xl", className: "h-full w-full", align: "center", justify: "center", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2", size: "sm", weight: "semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1", wrap: true, children: [_jsx(Text, { size: "sm", weight: "bold", children: bundle.
|
|
28
|
-
? formatCurrency(bundle.
|
|
27
|
+
return (_jsxs(Stack, { gap: "none", surface: "default", rounded: "xl", border: "default", children: [_jsxs(Link, { href: href, className: "group block p-[var(--appkit-space-3)] hover:no-underline", children: [_jsx(Div, { className: `relative mb-2 aspect-square ${__O.hidden}`, rounded: "lg", surface: "subtle", children: cover ? (_jsx(MediaImage, { src: cover, alt: bundle.name, size: "card", className: "transition-transform group-hover:scale-105" })) : (_jsx(Row, { textSize: "3xl", className: "h-full w-full", align: "center", justify: "center", children: PLACEHOLDER_EMOJI })) }), _jsx(Text, { className: "line-clamp-2", size: "sm", weight: "semibold", children: bundle.name }), _jsxs(Row, { gap: "sm", align: "center", className: "mt-1", wrap: true, children: [_jsx(Text, { size: "sm", weight: "bold", children: bundle.bundlePrice
|
|
28
|
+
? formatCurrency(bundle.bundlePrice, "INR")
|
|
29
29
|
: BUNDLE_COPY.featured.priceFallback }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u00B7 ", BUNDLE_COPY.featured.itemCount(memberCount)] }), stock !== "in_stock" && (_jsx(Badge, { variant: BUNDLE_STOCK_VARIANT[stock], children: BUNDLE_COPY.stockBadge.listVariantOutOfStock }))] })] }), onBuyNow && (_jsx(Div, { border: "subtle", className: `border-t ${__P.p3}`, padding: "t-xs", children: _jsx(BundleBuyNowCta, { bundleSlug: bundle.slug, outOfStock: stock === "out_of_stock", onBuyNow: onBuyNow, compact: true }) }))] }));
|
|
30
30
|
}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
export { LiveItemsListView } from "./LiveItemsListView";
|
|
2
|
-
export type { LiveItemsListViewProps } from "./LiveItemsListView";
|
|
3
|
-
export { LiveItemsIndexListing } from "./LiveItemsIndexListing";
|
|
4
|
-
export type { LiveItemsIndexListingProps } from "./LiveItemsIndexListing";
|
|
5
1
|
export { LiveItemFilters } from "./LiveItemFilters";
|
|
6
2
|
export type { LiveItemFiltersProps } from "./LiveItemFilters";
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export interface LotterySlot {
|
|
8
8
|
slotNumber: number;
|
|
9
9
|
name: string;
|
|
10
|
-
|
|
10
|
+
price: number;
|
|
11
11
|
weight: number;
|
|
12
12
|
isBooked: boolean;
|
|
13
13
|
bookedByUserLotteryNumber?: number;
|
|
@@ -27,7 +27,7 @@ export interface LotteryConfig {
|
|
|
27
27
|
slots: LotterySlot[];
|
|
28
28
|
totalSlots: number;
|
|
29
29
|
pricingMode: LotteryPricingMode;
|
|
30
|
-
|
|
30
|
+
uniformPrice?: number;
|
|
31
31
|
drawWindowDurationMinutes: number;
|
|
32
32
|
maxPullsPerTransaction: number;
|
|
33
33
|
maxPullsPerUser: number;
|
|
@@ -54,7 +54,7 @@ export declare class LotteryError extends Error {
|
|
|
54
54
|
* Weight is always at least 1 (never 0).
|
|
55
55
|
* For uniform pricing: all slots get weight 50.
|
|
56
56
|
*/
|
|
57
|
-
export declare function computeWeight(
|
|
57
|
+
export declare function computeWeight(price: number, maxPrice: number): number;
|
|
58
58
|
/**
|
|
59
59
|
* Pick a slot using weighted random selection. Uses the Web Crypto API, not
|
|
60
60
|
* `Math.random()`, so the fairness claim shown to users (PrizeRevealModal's
|
|
@@ -17,10 +17,10 @@ export class LotteryError extends Error {
|
|
|
17
17
|
* Weight is always at least 1 (never 0).
|
|
18
18
|
* For uniform pricing: all slots get weight 50.
|
|
19
19
|
*/
|
|
20
|
-
export function computeWeight(
|
|
21
|
-
if (
|
|
20
|
+
export function computeWeight(price, maxPrice) {
|
|
21
|
+
if (maxPrice === 0)
|
|
22
22
|
return 50;
|
|
23
|
-
return Math.max(1, Math.round((1 -
|
|
23
|
+
return Math.max(1, Math.round((1 - price / maxPrice) * 99) + 1);
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Cryptographically-random integer in [0, maxExclusive) via the Web Crypto
|
|
@@ -60,9 +60,9 @@ export function assignSlotWeights(config) {
|
|
|
60
60
|
if (config.pricingMode === "uniform") {
|
|
61
61
|
return config.slots.map((sl) => ({ ...sl, weight: 50 }));
|
|
62
62
|
}
|
|
63
|
-
const maxPrice = Math.max(...config.slots.map((sl) => sl.
|
|
63
|
+
const maxPrice = Math.max(...config.slots.map((sl) => sl.price), 0);
|
|
64
64
|
return config.slots.map((sl) => ({
|
|
65
65
|
...sl,
|
|
66
|
-
weight: computeWeight(sl.
|
|
66
|
+
weight: computeWeight(sl.price, maxPrice),
|
|
67
67
|
}));
|
|
68
68
|
}
|
|
@@ -19,7 +19,7 @@ function legacyFallback(order) {
|
|
|
19
19
|
method,
|
|
20
20
|
transactionId: order.paymentTransactionId ?? order.paymentId,
|
|
21
21
|
proofUrl: order.paymentProofUrl,
|
|
22
|
-
|
|
22
|
+
amount: order.totalPrice,
|
|
23
23
|
verificationMethod: method === "razorpay" ? "webhook" : method === "cod" ? "cod_collection" : "manual_review",
|
|
24
24
|
};
|
|
25
25
|
}
|
|
@@ -28,5 +28,5 @@ export function OrderPaymentSummary({ order, className = "" }) {
|
|
|
28
28
|
if (!record) {
|
|
29
29
|
return (_jsx(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: _jsx(Text, { size: "sm", color: "muted", children: "No payment information recorded yet." }) }));
|
|
30
30
|
}
|
|
31
|
-
return (_jsxs(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsxs(Row, { justify: "between", align: "center", className: "mb-2", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Payment" }), _jsx(Badge, { variant: order.paymentStatus === "paid" ? "success" : "default", children: order.paymentStatus ?? "pending" })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Method" }), _jsx(Text, { size: "sm", weight: "medium", children: METHOD_LABEL[record.method] })] }), _jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Amount" }), _jsx(Text, { size: "sm", weight: "medium", children: formatCurrency(record.
|
|
31
|
+
return (_jsxs(Div, { className: className, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsxs(Row, { justify: "between", align: "center", className: "mb-2", children: [_jsx(Heading, { level: 3, size: "sm", weight: "semibold", color: "muted", children: "Payment" }), _jsx(Badge, { variant: order.paymentStatus === "paid" ? "success" : "default", children: order.paymentStatus ?? "pending" })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Method" }), _jsx(Text, { size: "sm", weight: "medium", children: METHOD_LABEL[record.method] })] }), _jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Amount" }), _jsx(Text, { size: "sm", weight: "medium", children: formatCurrency(record.amount, order.currency ?? "INR") })] }), record.transactionId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Reference" }), _jsx(Text, { size: "sm", weight: "medium", children: record.transactionId })] })), record.paidAt && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Paid at" }), _jsx(Text, { size: "sm", children: new Date(record.paidAt).toLocaleString() })] })), record.verifiedBy && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Verified by" }), _jsx(Text, { size: "sm", children: record.verifiedBy })] })), record.gatewayRef?.paymentId && (_jsxs(Row, { justify: "between", children: [_jsx(Text, { size: "sm", color: "muted", children: "Gateway payment ID" }), _jsx(Text, { size: "sm", children: record.gatewayRef.paymentId })] }))] })] }));
|
|
32
32
|
}
|
|
@@ -11,6 +11,6 @@ export function OrderSiblingPayments({ siblings, currentOrderId, className = "",
|
|
|
11
11
|
return null;
|
|
12
12
|
return (_jsxs(Div, { className: `${className}`, rounded: "xl", padding: "md", surface: "muted", border: "default", children: [_jsx(Heading, { level: 3, className: "mb-3", color: "muted", size: "sm", weight: "semibold", children: REFUND_COPY.siblingPayments.heading(others.length) }), _jsx(Stack, { gap: "xs", children: others.map((o) => {
|
|
13
13
|
const href = String(ROUTES.USER.ORDER_DETAIL(o.id));
|
|
14
|
-
return (_jsxs(Row, { justify: "between", align: "center", gap: "sm", children: [_jsx(Link, { href: href, className: "text-[length:var(--appkit-text-sm)] font-medium text-[color:var(--appkit-color-primary)] hover:underline", children: o.id }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "xs", color: "muted", transform: "capitalize", children: o.status }), _jsx(Text, { size: "xs", weight: "semibold", children: formatCurrency(o.totalPrice
|
|
14
|
+
return (_jsxs(Row, { justify: "between", align: "center", gap: "sm", children: [_jsx(Link, { href: href, className: "text-[length:var(--appkit-text-sm)] font-medium text-[color:var(--appkit-color-primary)] hover:underline", children: o.id }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Text, { size: "xs", color: "muted", transform: "capitalize", children: o.status }), _jsx(Text, { size: "xs", weight: "semibold", children: formatCurrency(o.totalPrice, o.currency ?? "INR") })] })] }, o.id));
|
|
15
15
|
}) })] }));
|
|
16
16
|
}
|
|
@@ -10,7 +10,7 @@ function formatDate(d) {
|
|
|
10
10
|
return dt.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
|
|
11
11
|
}
|
|
12
12
|
function RefundRow({ event, currency }) {
|
|
13
|
-
return (_jsxs(Row, { border: "subtle", justify: "between", align: "start", gap: "sm", className: "border-b last:border-0", padding: "y-sm", children: [_jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Badge, { variant: event.type === "full" ? "danger" : "warning", children: event.type === "full" ? REFUND_COPY.history.badgeFull : REFUND_COPY.history.badgePartial }), _jsx(Text, { size: "xs", color: "muted", children: formatDate(event.refundedAt) })] }), _jsx(Text, { size: "sm", children: event.reason }), event.manualTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelTxn, " ", event.manualTransactionId] })), event.razorpayRefundId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelRazorpay, " ", event.razorpayRefundId] }))] }), _jsx(Text, { size: "sm", weight: "semibold", className: "shrink-0", children: formatCurrency(event.amount
|
|
13
|
+
return (_jsxs(Row, { border: "subtle", justify: "between", align: "start", gap: "sm", className: "border-b last:border-0", padding: "y-sm", children: [_jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Badge, { variant: event.type === "full" ? "danger" : "warning", children: event.type === "full" ? REFUND_COPY.history.badgeFull : REFUND_COPY.history.badgePartial }), _jsx(Text, { size: "xs", color: "muted", children: formatDate(event.refundedAt) })] }), _jsx(Text, { size: "sm", children: event.reason }), event.manualTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelTxn, " ", event.manualTransactionId] })), event.razorpayRefundId && (_jsxs(Text, { size: "xs", color: "muted", children: [REFUND_COPY.history.labelRazorpay, " ", event.razorpayRefundId] }))] }), _jsx(Text, { size: "sm", weight: "semibold", className: "shrink-0", children: formatCurrency(event.amount, currency) })] }));
|
|
14
14
|
}
|
|
15
15
|
/** Warning triangle icon — inline SVG kept here since it's a single-use decorative element. */
|
|
16
16
|
function WarningIcon() {
|
|
@@ -41,5 +41,5 @@ export function RefundRequestView({ order, onSubmitRequest, isLoading = false, c
|
|
|
41
41
|
setError(err instanceof Error ? err.message : REFUND_COPY.request.errorFallback);
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
|
-
return (_jsxs(Stack, { gap: "md", className: className, children: [_jsxs(Text, { size: "sm", color: "muted", children: [REFUND_COPY.request.orderTotalLabel, " ", _jsx(Span, { weight: "bold", children: formatCurrency(order.totalPrice
|
|
44
|
+
return (_jsxs(Stack, { gap: "md", className: className, children: [_jsxs(Text, { size: "sm", color: "muted", children: [REFUND_COPY.request.orderTotalLabel, " ", _jsx(Span, { weight: "bold", children: formatCurrency(order.totalPrice, order.currency ?? "INR") })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", weight: "semibold", children: [REFUND_COPY.request.reasonLabel, " ", _jsx(Span, { "aria-hidden": true, children: "*" })] }), _jsx(Textarea, { value: reason, onChange: (e) => setReason(e.target.value), placeholder: REFUND_COPY.request.reasonPlaceholder, rows: 3, "aria-required": "true", "aria-label": REFUND_COPY.request.reasonLabel })] }), _jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", weight: "semibold", children: REFUND_COPY.request.acknowledgeHeading }), REFUND_COPY.request.acknowledgments.map((text, i) => (_jsx(Checkbox, { checked: acknowledged[i], onChange: () => handleToggle(i), label: _jsx(Text, { size: "sm", className: "leading-snug", children: text }), "aria-label": `Acknowledgment ${i + 1}` }, i)))] }), error && (_jsx(Text, { size: "sm", color: "danger", role: "alert", children: error })), _jsx(Button, { variant: "danger", onClick: handleSubmit, disabled: !canSubmit, "aria-busy": isLoading, children: isLoading ? REFUND_COPY.request.submittingLabel : REFUND_COPY.request.submitLabel })] }));
|
|
45
45
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 15-minute payment window shared constant — imported by the checkout action
|
|
3
|
+
* (stamps `order.paymentDeadline`), the buyer countdown UI, and the
|
|
4
|
+
* `paymentWindowTimeout` sweep job, so they can never drift out of sync.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PAYMENT_WINDOW_MINUTES = 15;
|
|
7
|
+
export declare const PAYMENT_WINDOW_MS: number;
|
|
8
|
+
/** Cancellation reasons this feature writes to `OrderDocument.cancellationReason` (a free-form string field). */
|
|
9
|
+
export declare const PAYMENT_WINDOW_EXPIRED_REASON = "payment_window_expired";
|
|
10
|
+
export declare const PAYMENT_FRAUD_REJECTED_REASON = "payment_fraud_rejected";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 15-minute payment window shared constant — imported by the checkout action
|
|
3
|
+
* (stamps `order.paymentDeadline`), the buyer countdown UI, and the
|
|
4
|
+
* `paymentWindowTimeout` sweep job, so they can never drift out of sync.
|
|
5
|
+
*/
|
|
6
|
+
export const PAYMENT_WINDOW_MINUTES = 15;
|
|
7
|
+
export const PAYMENT_WINDOW_MS = PAYMENT_WINDOW_MINUTES * 60 * 1000;
|
|
8
|
+
/** Cancellation reasons this feature writes to `OrderDocument.cancellationReason` (a free-form string field). */
|
|
9
|
+
export const PAYMENT_WINDOW_EXPIRED_REASON = "payment_window_expired";
|
|
10
|
+
export const PAYMENT_FRAUD_REJECTED_REASON = "payment_fraud_rejected";
|
|
@@ -188,6 +188,31 @@ declare class OrderRepository extends BaseRepository<OrderDocument> {
|
|
|
188
188
|
ref: DocumentReference;
|
|
189
189
|
data: OrderDocument;
|
|
190
190
|
}>>;
|
|
191
|
+
/**
|
|
192
|
+
* Cloud Functions: 15-minute payment-window sweep — orders past their
|
|
193
|
+
* `paymentDeadline` with no proof uploaded yet. Filters out orders that
|
|
194
|
+
* already have `paymentProofUrl` set in-memory (the 2-hour auto-approve
|
|
195
|
+
* sweep owns those instead) rather than as a Firestore inequality, since a
|
|
196
|
+
* `paymentProofUrl != null` filter would silently exclude every doc where
|
|
197
|
+
* the field isn't set at all — the opposite of what's needed here.
|
|
198
|
+
*/
|
|
199
|
+
getExpiredPaymentDeadlines(): Promise<Array<{
|
|
200
|
+
id: string;
|
|
201
|
+
ref: DocumentReference;
|
|
202
|
+
data: OrderDocument;
|
|
203
|
+
}>>;
|
|
204
|
+
/**
|
|
205
|
+
* Cloud Functions: 2-hour auto-approve sweep — orders with a submitted
|
|
206
|
+
* proof that no admin has acted on yet (`paymentReviewOutcome` unset).
|
|
207
|
+
* Filters that in-memory rather than as a Firestore inequality for the
|
|
208
|
+
* same reason as `getExpiredPaymentDeadlines` — a `!= null` filter would
|
|
209
|
+
* silently exclude every doc where the field was never set at all.
|
|
210
|
+
*/
|
|
211
|
+
getUnreviewedProofPastDeadline(hours?: number): Promise<Array<{
|
|
212
|
+
id: string;
|
|
213
|
+
ref: DocumentReference;
|
|
214
|
+
data: OrderDocument;
|
|
215
|
+
}>>;
|
|
191
216
|
/**
|
|
192
217
|
* Cloud Functions: find delivered orders eligible for the weekly payout sweep.
|
|
193
218
|
*
|
|
@@ -103,7 +103,7 @@ class OrderRepository extends BaseRepository {
|
|
|
103
103
|
paymentRecord: {
|
|
104
104
|
method: "cod",
|
|
105
105
|
transactionId: note,
|
|
106
|
-
|
|
106
|
+
amount: order.totalPrice,
|
|
107
107
|
paidAt: new Date(),
|
|
108
108
|
verifiedBy,
|
|
109
109
|
verificationMethod: "cod_collection",
|
|
@@ -291,6 +291,55 @@ class OrderRepository extends BaseRepository {
|
|
|
291
291
|
data: this.decryptOrder({ id: d.id, ...d.data() }),
|
|
292
292
|
}));
|
|
293
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Cloud Functions: 15-minute payment-window sweep — orders past their
|
|
296
|
+
* `paymentDeadline` with no proof uploaded yet. Filters out orders that
|
|
297
|
+
* already have `paymentProofUrl` set in-memory (the 2-hour auto-approve
|
|
298
|
+
* sweep owns those instead) rather than as a Firestore inequality, since a
|
|
299
|
+
* `paymentProofUrl != null` filter would silently exclude every doc where
|
|
300
|
+
* the field isn't set at all — the opposite of what's needed here.
|
|
301
|
+
*/
|
|
302
|
+
async getExpiredPaymentDeadlines() {
|
|
303
|
+
const snap = await this.db
|
|
304
|
+
.collection(this.collection)
|
|
305
|
+
.where(ORDER_FIELDS.STATUS, "==", OrderStatusValues.PENDING)
|
|
306
|
+
.where(ORDER_FIELDS.PAYMENT_STATUS, "==", "pending")
|
|
307
|
+
.where(ORDER_FIELDS.PAYMENT_DEADLINE, "<=", new Date())
|
|
308
|
+
.limit(500)
|
|
309
|
+
.get();
|
|
310
|
+
return snap.docs
|
|
311
|
+
.map((d) => ({
|
|
312
|
+
id: d.id,
|
|
313
|
+
ref: d.ref,
|
|
314
|
+
data: this.decryptOrder({ id: d.id, ...d.data() }),
|
|
315
|
+
}))
|
|
316
|
+
.filter((entry) => !entry.data.paymentProofUrl);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Cloud Functions: 2-hour auto-approve sweep — orders with a submitted
|
|
320
|
+
* proof that no admin has acted on yet (`paymentReviewOutcome` unset).
|
|
321
|
+
* Filters that in-memory rather than as a Firestore inequality for the
|
|
322
|
+
* same reason as `getExpiredPaymentDeadlines` — a `!= null` filter would
|
|
323
|
+
* silently exclude every doc where the field was never set at all.
|
|
324
|
+
*/
|
|
325
|
+
async getUnreviewedProofPastDeadline(hours = 2) {
|
|
326
|
+
const cutoff = new Date();
|
|
327
|
+
cutoff.setHours(cutoff.getHours() - hours);
|
|
328
|
+
const snap = await this.db
|
|
329
|
+
.collection(this.collection)
|
|
330
|
+
.where(ORDER_FIELDS.STATUS, "==", OrderStatusValues.PENDING)
|
|
331
|
+
.where(ORDER_FIELDS.PAYMENT_STATUS, "==", "pending")
|
|
332
|
+
.where(ORDER_FIELDS.PAYMENT_PROOF_UPLOADED_AT, "<=", cutoff)
|
|
333
|
+
.limit(500)
|
|
334
|
+
.get();
|
|
335
|
+
return snap.docs
|
|
336
|
+
.map((d) => ({
|
|
337
|
+
id: d.id,
|
|
338
|
+
ref: d.ref,
|
|
339
|
+
data: this.decryptOrder({ id: d.id, ...d.data() }),
|
|
340
|
+
}))
|
|
341
|
+
.filter((entry) => !!entry.data.paymentProofUrl && !entry.data.paymentReviewOutcome);
|
|
342
|
+
}
|
|
294
343
|
/**
|
|
295
344
|
* Cloud Functions: find delivered orders eligible for the weekly payout sweep.
|
|
296
345
|
*
|
|
@@ -100,6 +100,9 @@ export interface OrderDocumentItem {
|
|
|
100
100
|
cancelledQuantity?: number;
|
|
101
101
|
cancelledAt?: Date;
|
|
102
102
|
cancelledReason?: string;
|
|
103
|
+
/** SB-UNI-5 — forwarded from the cart line when this order item is an expanded bundle, so the order-detail UI can collapse it back under a "Bundle: <name>" header and stock-restore logic can fan back out to member products. */
|
|
104
|
+
bundleCategorySlug?: string;
|
|
105
|
+
bundleProductIds?: string[];
|
|
103
106
|
/** P-8 GST — snapshotted from the product at order time so the invoice stays accurate even if the product's HSN/rate later changes. */
|
|
104
107
|
hsnCode?: string;
|
|
105
108
|
gstRate?: 0 | 5 | 12 | 18 | 28;
|
|
@@ -178,7 +181,7 @@ export interface OrderDocument extends BaseDocument {
|
|
|
178
181
|
platformFee?: number;
|
|
179
182
|
depositAmount?: number;
|
|
180
183
|
codRemainingAmount?: number;
|
|
181
|
-
/** COD handling fee charged to the buyer: max(
|
|
184
|
+
/** COD handling fee charged to the buyer: max(codHandlingFeeMin, subtotal × codHandlingFeePercent / 100). Only set when paymentMethod === "cod". */
|
|
182
185
|
codHandlingFee?: number;
|
|
183
186
|
/** Order subtotal before GST — the amount GST is computed on. */
|
|
184
187
|
taxableAmount?: number;
|
|
@@ -274,6 +277,51 @@ export interface OrderDocument extends BaseDocument {
|
|
|
274
277
|
paymentProofMimeType?: string;
|
|
275
278
|
/** When the buyer submitted the proof. */
|
|
276
279
|
paymentProofUploadedAt?: Date;
|
|
280
|
+
/**
|
|
281
|
+
* Deadline for the buyer to pay/upload proof. Set only at creation for
|
|
282
|
+
* `upi_manual`/`cash`/`emi` orders — never for `cod`, `razorpay`, or
|
|
283
|
+
* `admin_bypass` (those either pay before order creation or have no proof
|
|
284
|
+
* step). `paymentWindowTimeout` cancels + restocks any order still
|
|
285
|
+
* `pending`/`pending` with no `paymentProofUrl` past this timestamp.
|
|
286
|
+
* Extended by 15 more minutes when admin requests a proof re-upload.
|
|
287
|
+
*/
|
|
288
|
+
paymentDeadline?: Date;
|
|
289
|
+
/** True once a cancellation path has restored `availableQuantity` for this order's items. Guards against double-restock. */
|
|
290
|
+
stockRestored?: boolean;
|
|
291
|
+
stockRestoredAt?: Date;
|
|
292
|
+
/**
|
|
293
|
+
* UPI VPA resolved and shown to the buyer at order-creation time — the
|
|
294
|
+
* seller's own `payoutDetails.upiId` for seller-owned stores (falling back
|
|
295
|
+
* to `siteSettings.contact.upiVpa` if unconfigured), or the site UPI
|
|
296
|
+
* directly for admin-owned stores. Immutable "ground truth" for the
|
|
297
|
+
* cross-check below; never client-supplied.
|
|
298
|
+
*/
|
|
299
|
+
displayedUpiId?: string;
|
|
300
|
+
/** UPI VPA the buyer says they actually paid from/to, per their own UPI app — the real cross-check signal against `displayedUpiId`. */
|
|
301
|
+
buyerReportedUpiId?: string;
|
|
302
|
+
/** True when `buyerReportedUpiId` doesn't match `displayedUpiId` — surfaced prominently in the admin review UI. */
|
|
303
|
+
paymentUpiMismatch?: boolean;
|
|
304
|
+
/** Buyer's explicit "I have paid" declaration, distinct from admin's own verification. */
|
|
305
|
+
buyerMarkedPaid?: boolean;
|
|
306
|
+
buyerMarkedPaidAt?: Date;
|
|
307
|
+
/** Buyer's required "this payment is genuine, no fraudulent tricks/chargebacks" agreement — server-validated, not just a client-side disable. */
|
|
308
|
+
buyerFraudAgreementAccepted?: boolean;
|
|
309
|
+
buyerFraudAgreementAcceptedAt?: Date;
|
|
310
|
+
/** Which of the three admin review actions was taken on this order's payment proof. */
|
|
311
|
+
paymentReviewOutcome?: "approved" | "reupload_requested" | "rejected_fraud";
|
|
312
|
+
/** Admin's reason text — required for both `reupload_requested` and `rejected_fraud`. */
|
|
313
|
+
paymentReviewNote?: string;
|
|
314
|
+
paymentReviewedBy?: string;
|
|
315
|
+
paymentReviewedAt?: Date;
|
|
316
|
+
/** True when `paymentReviewAutoApprove` approved this order after 2 hours of no manual admin review. */
|
|
317
|
+
autoApproved?: boolean;
|
|
318
|
+
autoApprovedAt?: Date;
|
|
319
|
+
/** Buyer/seller/admin dispute raised against an auto-approved order — surfaces to the admin queue, does not itself reverse payment/order status. */
|
|
320
|
+
disputeRaised?: boolean;
|
|
321
|
+
disputeRaisedBy?: string;
|
|
322
|
+
disputeRaisedAt?: Date;
|
|
323
|
+
disputeReason?: string;
|
|
324
|
+
disputeStatus?: "open" | "resolved";
|
|
277
325
|
/**
|
|
278
326
|
* Same-shape payment record regardless of how the buyer paid — manual
|
|
279
327
|
* (cash/UPI proof), Razorpay (webhook-verified), or COD (collected on
|
|
@@ -309,7 +357,7 @@ export interface OrderPaymentRecord {
|
|
|
309
357
|
transactionId?: string;
|
|
310
358
|
/** Manual proof upload | COD collection receipt photo (optional) | n/a for razorpay. */
|
|
311
359
|
proofUrl?: string;
|
|
312
|
-
|
|
360
|
+
amount: number;
|
|
313
361
|
paidAt?: Date;
|
|
314
362
|
/** Admin/seller uid (manual/COD) | "razorpay-webhook" (razorpay, automatic). */
|
|
315
363
|
verifiedBy?: string;
|