@mohasinac/appkit 4.62.0 → 4.63.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/.build-stamp.json +3 -3
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +8 -29
- package/dist/_internal/client/features/layout/filterNavItems.d.ts +28 -0
- package/dist/_internal/client/features/layout/filterNavItems.js +35 -0
- package/dist/_internal/server/features/ads/booking.d.ts +118 -0
- package/dist/_internal/server/features/ads/booking.js +326 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +129 -9
- package/dist/_internal/server/features/checkout/actions.js +850 -79
- package/dist/_internal/server/features/checkout/expand-order-items.d.ts +1 -2
- package/dist/_internal/server/features/checkout/expand-order-items.js +32 -0
- package/dist/_internal/server/features/checkout/freeze-parts.d.ts +50 -0
- package/dist/_internal/server/features/checkout/freeze-parts.js +94 -0
- package/dist/_internal/server/features/checkout/value-otp-gate.d.ts +55 -0
- package/dist/_internal/server/features/checkout/value-otp-gate.js +60 -0
- package/dist/_internal/server/features/dashboard/attention.d.ts +128 -0
- package/dist/_internal/server/features/dashboard/attention.js +183 -0
- package/dist/_internal/server/features/dashboard/data.d.ts +47 -0
- package/dist/_internal/server/features/dashboard/data.js +82 -0
- package/dist/_internal/server/features/inventory/reservations.d.ts +99 -0
- package/dist/_internal/server/features/inventory/reservations.js +273 -0
- package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
- package/dist/_internal/server/features/invoicing/allocate.js +162 -0
- package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
- package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
- package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
- package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
- package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
- package/dist/_internal/server/features/invoicing/issue.js +202 -0
- package/dist/_internal/server/features/offers/destinations.d.ts +40 -0
- package/dist/_internal/server/features/offers/destinations.js +65 -0
- package/dist/_internal/server/features/orders/actions.d.ts +8 -1
- package/dist/_internal/server/features/orders/actions.js +81 -8
- package/dist/_internal/server/features/orders/adapters.js +54 -0
- package/dist/_internal/server/features/orders/amend-delivery.d.ts +56 -0
- package/dist/_internal/server/features/orders/amend-delivery.js +124 -0
- package/dist/_internal/server/features/orders/balance.d.ts +89 -0
- package/dist/_internal/server/features/orders/balance.js +256 -0
- package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
- package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
- package/dist/_internal/server/features/points/award.js +46 -4
- package/dist/_internal/server/features/pricing/actions.d.ts +58 -0
- package/dist/_internal/server/features/pricing/actions.js +144 -0
- package/dist/_internal/server/features/refunds/actions.js +26 -0
- package/dist/_internal/server/features/shipping/book-split.d.ts +86 -0
- package/dist/_internal/server/features/shipping/book-split.js +130 -0
- package/dist/_internal/server/features/shipping/book.d.ts +61 -0
- package/dist/_internal/server/features/shipping/book.js +176 -0
- package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
- package/dist/_internal/server/features/shipping/courier-block.js +264 -0
- package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
- package/dist/_internal/server/features/site-settings/adapters.js +29 -0
- package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
- package/dist/_internal/server/features/stores/adapters.js +65 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +95 -2
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +11 -2
- package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
- package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
- package/dist/_internal/server/jobs/core/index.d.ts +2 -1
- package/dist/_internal/server/jobs/core/index.js +2 -1
- package/dist/_internal/server/jobs/core/jobRunners.js +45 -0
- package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
- package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
- package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +65 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
- package/dist/_internal/server/jobs/core/reservationExpiry.d.ts +17 -0
- package/dist/_internal/server/jobs/core/reservationExpiry.js +40 -0
- package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
- package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +25 -2
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +1 -0
- package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
- package/dist/_internal/server/jobs/handlers/reservationExpiry.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/reservationExpiry.js +2 -0
- package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +296 -0
- package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
- package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
- package/dist/_internal/shared/checkout/order-math.d.ts +174 -0
- package/dist/_internal/shared/checkout/order-math.js +159 -0
- package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
- package/dist/_internal/shared/checkout/refundable-base.js +13 -1
- package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
- package/dist/_internal/shared/checkout/rules/index.js +1 -1
- package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +18 -0
- package/dist/_internal/shared/checkout/rules/payment-gate.js +25 -0
- package/dist/_internal/shared/checkout/split.d.ts +75 -0
- package/dist/_internal/shared/checkout/split.js +120 -0
- package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
- package/dist/_internal/shared/content/disclaimers.js +217 -0
- package/dist/_internal/shared/content/published-values.d.ts +93 -0
- package/dist/_internal/shared/content/published-values.js +206 -0
- package/dist/_internal/shared/features/admin/integrations.d.ts +139 -0
- package/dist/_internal/shared/features/admin/integrations.js +263 -0
- package/dist/_internal/shared/features/dashboard/hub-sections.d.ts +72 -0
- package/dist/_internal/shared/features/dashboard/hub-sections.js +75 -0
- package/dist/_internal/shared/features/emi/choice.d.ts +98 -0
- package/dist/_internal/shared/features/emi/choice.js +69 -0
- package/dist/_internal/shared/features/emi/group.d.ts +84 -0
- package/dist/_internal/shared/features/emi/group.js +126 -0
- package/dist/_internal/shared/features/ledger/posting.d.ts +107 -0
- package/dist/_internal/shared/features/ledger/posting.js +165 -0
- package/dist/_internal/shared/features/ledger/reports.d.ts +76 -0
- package/dist/_internal/shared/features/ledger/reports.js +127 -0
- package/dist/_internal/shared/features/ledger/rules.d.ts +170 -0
- package/dist/_internal/shared/features/ledger/rules.js +221 -0
- package/dist/_internal/shared/features/offers/coordination.d.ts +122 -0
- package/dist/_internal/shared/features/offers/coordination.js +80 -0
- package/dist/_internal/shared/features/orders/delivery-snapshot.d.ts +114 -0
- package/dist/_internal/shared/features/orders/delivery-snapshot.js +116 -0
- package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
- package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
- package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
- package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
- package/dist/_internal/shared/features/payouts/pay-period.d.ts +91 -0
- package/dist/_internal/shared/features/payouts/pay-period.js +104 -0
- package/dist/_internal/shared/features/points/accepts.d.ts +29 -0
- package/dist/_internal/shared/features/points/accepts.js +49 -0
- package/dist/_internal/shared/features/pricing/rate-registry.d.ts +150 -0
- package/dist/_internal/shared/features/pricing/rate-registry.js +246 -0
- package/dist/_internal/shared/features/shipping/parcel.d.ts +123 -0
- package/dist/_internal/shared/features/shipping/parcel.js +139 -0
- package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
- package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
- package/dist/_internal/shared/features/site-settings/fees.d.ts +16 -8
- package/dist/_internal/shared/features/site-settings/fees.js +12 -8
- package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
- package/dist/_internal/shared/fees/calculator.d.ts +33 -1
- package/dist/_internal/shared/fees/calculator.js +32 -2
- package/dist/_internal/shared/fees/explain.d.ts +81 -0
- package/dist/_internal/shared/fees/explain.js +101 -0
- package/dist/_internal/shared/history/index.d.ts +1 -1
- package/dist/_internal/shared/history/index.js +1 -1
- package/dist/_internal/shared/history/types.d.ts +7 -1
- package/dist/_internal/shared/history/types.js +25 -0
- package/dist/client.d.ts +21 -0
- package/dist/client.js +43 -0
- package/dist/constants/api-endpoints.d.ts +114 -0
- package/dist/constants/api-endpoints.js +55 -0
- package/dist/constants/field-names.d.ts +42 -0
- package/dist/constants/field-names.js +52 -0
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/shipping.d.ts +45 -0
- package/dist/contracts/shipping.js +15 -0
- package/dist/features/about/components/AboutView.js +1 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
- package/dist/features/account/components/UserOrdersView.js +47 -35
- package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
- package/dist/features/admin/components/AdminIntegrationsView.d.ts +55 -0
- package/dist/features/admin/components/AdminIntegrationsView.js +74 -0
- package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
- package/dist/features/admin/components/AdminInvoicingView.js +65 -0
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +33 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +81 -3
- package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
- package/dist/features/admin/components/AdminOrdersView.js +86 -5
- package/dist/features/admin/components/OwnerQuickActions.js +24 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
- package/dist/features/admin/constants/filter-tabs.js +6 -0
- package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminListingData.js +16 -0
- package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
- package/dist/features/admin/schemas/firestore.d.ts +62 -0
- package/dist/features/admin/schemas/firestore.js +5 -0
- package/dist/features/ads/schemas/booking-write.d.ts +120 -0
- package/dist/features/ads/schemas/booking-write.js +75 -0
- package/dist/features/ads/schemas/creative-form.d.ts +18 -0
- package/dist/features/ads/schemas/creative-form.js +51 -0
- package/dist/features/ads/schemas/firestore.d.ts +140 -0
- package/dist/features/ads/schemas/firestore.js +109 -0
- package/dist/features/auctions/repository/bid.repository.js +3 -1
- package/dist/features/audit-log/schemas/firestore.d.ts +140 -0
- package/dist/features/audit-log/schemas/firestore.js +89 -0
- package/dist/features/auth/actions/profile-actions.d.ts +69 -1
- package/dist/features/auth/actions/profile-actions.js +62 -1
- package/dist/features/auth/permissions/constants.js +13 -0
- package/dist/features/auth/schemas/firestore.d.ts +16 -2
- package/dist/features/auth/schemas/firestore.js +2 -1
- package/dist/features/blog/actions/blog-actions.d.ts +6 -0
- package/dist/features/blog/actions/blog-actions.js +17 -2
- package/dist/features/blog/api/route.js +4 -1
- package/dist/features/blog/columns/index.js +5 -0
- package/dist/features/blog/components/BlogIndexPageView.js +2 -1
- package/dist/features/blog/repository/blog.repository.d.ts +4 -0
- package/dist/features/blog/repository/blog.repository.js +5 -0
- package/dist/features/blog/schemas/blog-form.d.ts +3 -0
- package/dist/features/blog/schemas/blog-form.js +1 -0
- package/dist/features/blog/schemas/firestore.d.ts +38 -1
- package/dist/features/blog/schemas/firestore.js +23 -0
- package/dist/features/blog/schemas/index.d.ts +6 -0
- package/dist/features/blog/schemas/index.js +2 -0
- package/dist/features/blog/types/index.d.ts +2 -0
- package/dist/features/cart/components/CartPriceBreakdown.d.ts +25 -1
- package/dist/features/cart/components/CartPriceBreakdown.js +29 -6
- package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
- package/dist/features/cart/components/PointsTenderPicker.js +15 -0
- package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
- package/dist/features/cart/components/index.d.ts +2 -0
- package/dist/features/cart/components/index.js +1 -0
- package/dist/features/cart/repository/cart.repository.d.ts +33 -0
- package/dist/features/cart/repository/cart.repository.js +47 -0
- package/dist/features/cart/schemas/firestore.d.ts +116 -0
- package/dist/features/contact/email.d.ts +27 -10
- package/dist/features/contact/email.js +20 -3
- package/dist/features/dashboard/components/DashboardHubView.d.ts +83 -0
- package/dist/features/dashboard/components/DashboardHubView.js +56 -0
- package/dist/features/dashboard/components/DashboardSectionsClient.d.ts +23 -0
- package/dist/features/dashboard/components/DashboardSectionsClient.js +66 -0
- package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.d.ts +55 -0
- package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +175 -0
- package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +62 -0
- package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +108 -0
- package/dist/features/dispute-reasons/schemas/firestore.d.ts +62 -0
- package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
- package/dist/features/faq/components/FAQAccordion.js +29 -4
- package/dist/features/faq/components/FAQPageContent.js +2 -2
- package/dist/features/gateway-events/schemas/index.d.ts +2 -2
- package/dist/features/homepage/schemas/index.d.ts +8 -8
- package/dist/features/inventory/schemas/stock-reservation.d.ts +114 -0
- package/dist/features/inventory/schemas/stock-reservation.js +103 -0
- package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
- package/dist/features/invoicing/schemas/firestore.js +45 -0
- package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
- package/dist/features/invoicing/utils/financial-year.js +53 -0
- package/dist/features/jobs/actions/enqueue-job.js +18 -1
- package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
- package/dist/features/jobs/repository/jobs.repository.js +84 -1
- package/dist/features/jobs/schemas/firestore.d.ts +80 -0
- package/dist/features/jobs/schemas/firestore.js +37 -0
- package/dist/features/layout/AppLayoutShell.d.ts +9 -1
- package/dist/features/layout/AppLayoutShell.js +12 -4
- package/dist/features/layout/BottomActions.js +2 -1
- package/dist/features/layout/BottomNavbar.d.ts +10 -2
- package/dist/features/layout/SideActionDock.js +52 -2
- package/dist/features/layout/TitleBarLayout.js +13 -4
- package/dist/features/layout/TitleBarLayout.style.css +59 -0
- package/dist/features/layout/useCtaReveal.d.ts +16 -1
- package/dist/features/layout/useCtaReveal.js +17 -26
- package/dist/features/ledger/repository/journal.repository.d.ts +110 -0
- package/dist/features/ledger/repository/journal.repository.js +312 -0
- package/dist/features/ledger/schemas/expenses.d.ts +87 -0
- package/dist/features/ledger/schemas/expenses.js +27 -0
- package/dist/features/ledger/schemas/firestore.d.ts +183 -0
- package/dist/features/ledger/schemas/firestore.js +69 -0
- package/dist/features/lottery/schemas/zod.d.ts +6 -6
- package/dist/features/media/MediaImage.js +22 -1
- package/dist/features/media/upload/ImageUpload.js +1 -1
- package/dist/features/obligations/constants/policies.js +24 -1
- package/dist/features/orders/components/BalancePaymentPanel.d.ts +12 -0
- package/dist/features/orders/components/BalancePaymentPanel.js +94 -0
- package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
- package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
- package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
- package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
- package/dist/features/orders/components/RaiseDisputeForm.js +119 -0
- package/dist/features/orders/components/RefundRequestView.js +19 -1
- package/dist/features/orders/components/index.d.ts +4 -0
- package/dist/features/orders/components/index.js +2 -0
- package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
- package/dist/features/orders/constants/order-lane-tabs.js +88 -0
- package/dist/features/orders/repository/orders.repository.d.ts +85 -1
- package/dist/features/orders/repository/orders.repository.js +205 -6
- package/dist/features/orders/schemas/balance.d.ts +40 -0
- package/dist/features/orders/schemas/balance.js +47 -0
- package/dist/features/orders/schemas/firestore.d.ts +398 -1
- package/dist/features/orders/schemas/firestore.js +43 -0
- package/dist/features/orders/schemas/index.d.ts +56 -8
- package/dist/features/orders/schemas/index.js +12 -0
- package/dist/features/orders/types/index.d.ts +47 -0
- package/dist/features/orders/utils/courier-block.d.ts +25 -0
- package/dist/features/orders/utils/courier-block.js +23 -0
- package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
- package/dist/features/payment-cases/schemas/firestore.js +1 -0
- package/dist/features/payments/repository/payout.repository.js +3 -2
- package/dist/features/payments/schemas/firestore.d.ts +92 -1
- package/dist/features/payments/schemas/firestore.js +23 -0
- package/dist/features/pricing/components/AdminPricingView.d.ts +13 -0
- package/dist/features/pricing/components/AdminPricingView.js +157 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
- package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
- package/dist/features/products/components/ProductDetailPageView.js +2 -2
- package/dist/features/products/schemas/firestore.d.ts +26 -1
- package/dist/features/products/schemas/firestore.js +2 -0
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
- package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
- package/dist/features/promotions/actions/coupon-stacking.js +21 -2
- package/dist/features/promotions/components/CouponCard.js +13 -0
- package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
- package/dist/features/promotions/constants/coupon-help.js +9 -1
- package/dist/features/promotions/schemas/firestore.d.ts +24 -0
- package/dist/features/promotions/schemas/firestore.js +4 -0
- package/dist/features/promotions/types/index.d.ts +19 -1
- package/dist/features/reviews/repository/reviews.repository.d.ts +14 -0
- package/dist/features/reviews/repository/reviews.repository.js +16 -0
- package/dist/features/scams/components/ScamProfileView.js +2 -2
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/repository/scammer.repository.js +2 -1
- package/dist/features/scams/schemas/firestore.d.ts +2 -1
- package/dist/features/scams/schemas/firestore.js +2 -1
- package/dist/features/search/action-index/tab-entries.js +1 -1
- package/dist/features/seller/actions/offer-actions.js +56 -0
- package/dist/features/seller/actions/seller-actions.d.ts +1 -1
- package/dist/features/seller/actions/seller-actions.js +37 -3
- package/dist/features/seller/components/DispatchForm.d.ts +11 -0
- package/dist/features/seller/components/DispatchForm.js +190 -0
- package/dist/features/seller/components/SellerOrdersView.js +221 -27
- package/dist/features/seller/components/index.d.ts +1 -0
- package/dist/features/seller/components/index.js +1 -0
- package/dist/features/seller/hooks/useSellerListingData.js +25 -0
- package/dist/features/seller/repository/offer.repository.js +4 -3
- package/dist/features/seller/schemas/firestore.d.ts +23 -2
- package/dist/features/seller/schemas/firestore.js +3 -2
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/seller/schemas/order-forms.d.ts +61 -4
- package/dist/features/seller/schemas/order-forms.js +41 -8
- package/dist/features/shipments/schemas/firestore.d.ts +25 -0
- package/dist/features/shipments/schemas/validation.d.ts +4 -4
- package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +82 -0
- package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +145 -0
- package/dist/features/shipping-boxes/schemas/firestore.d.ts +80 -0
- package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
- package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
- package/dist/features/stores/repository/store.repository.d.ts +18 -0
- package/dist/features/stores/repository/store.repository.js +27 -1
- package/dist/features/stores/schemas/firestore.d.ts +112 -0
- package/dist/features/stores/schemas/firestore.js +20 -0
- package/dist/features/stores/schemas/index.d.ts +6 -6
- package/dist/features/stores/types/index.d.ts +19 -0
- package/dist/features/support/repository/support.repository.js +72 -6
- package/dist/features/support/schemas/firestore.d.ts +17 -0
- package/dist/features/support/schemas/index.d.ts +8 -8
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +33 -1
- package/dist/next/routing/route-map.d.ts +112 -0
- package/dist/next/routing/route-map.js +63 -0
- package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
- package/dist/providers/shipping-shiprocket/index.js +84 -1
- package/dist/react/contexts/SessionContext.d.ts +17 -1
- package/dist/schemas/registry.d.ts +69 -34
- package/dist/schemas/sieve.d.ts +2 -2
- package/dist/security/pii-schemas.d.ts +1 -1
- package/dist/security/pii-schemas.js +45 -0
- package/dist/server-entry.d.ts +2 -2
- package/dist/server-entry.js +8 -1
- package/dist/server.d.ts +36 -1
- package/dist/server.js +183 -1
- package/dist/styles.css +412 -80
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +1 -0
- package/dist/tokens/themes/default-light.js +1 -0
- package/dist/tokens/themes/required.d.ts +1 -1
- package/dist/tokens/themes/required.js +1 -0
- package/dist/tokens/tokens.css +15 -0
- package/dist/ui/components/Button.d.ts +10 -1
- package/dist/ui/components/Button.js +25 -3
- package/dist/ui/components/Chart.d.ts +63 -0
- package/dist/ui/components/Chart.js +169 -0
- package/dist/ui/components/Chart.style.css +214 -0
- package/dist/ui/components/Disclaimer.d.ts +19 -0
- package/dist/ui/components/Disclaimer.js +83 -0
- package/dist/ui/components/OverflowRow.js +54 -2
- package/dist/ui/components/OverflowRow.style.css +38 -0
- package/dist/ui/components/RichTextEditor.js +99 -8
- package/dist/ui/components/chart-spec.d.ts +68 -0
- package/dist/ui/components/chart-spec.js +140 -0
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/components/surface-tokens.d.ts +1 -1
- package/dist/ui/components/surface-tokens.js +9 -0
- package/dist/ui/components/tabs-overflow.js +64 -11
- package/dist/ui/components/toolbar-collapse.d.ts +13 -0
- package/dist/ui/components/toolbar-collapse.js +10 -1
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/rich-text/RichText.d.ts +10 -1
- package/dist/ui/rich-text/RichText.js +33 -2
- package/dist/ui/rich-text/RichText.style.css +83 -79
- package/dist/ui/rich-text/RichTextRenderer.d.ts +30 -1
- package/dist/ui/rich-text/RichTextRenderer.js +34 -2
- package/dist/ui/rich-text/chart-blocks.d.ts +62 -0
- package/dist/ui/rich-text/chart-blocks.js +87 -0
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +1834 -1822
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disclaimers — one registry, rendered by `<Disclaimer id>` (Phase 12).
|
|
3
|
+
*
|
|
4
|
+
* ## 🛑 Why a registry and not a sentence per surface
|
|
5
|
+
*
|
|
6
|
+
* Same failure mode as the published numbers in Phase 9: if each surface
|
|
7
|
+
* writes its own, they drift, and **the legally material ones end up
|
|
8
|
+
* weakest** — because the surface that most needs a careful disclaimer is
|
|
9
|
+
* usually the one whose author was busiest. The scam registry is the example:
|
|
10
|
+
* naming a person a scammer is defamation exposure, and it had no disclaimer
|
|
11
|
+
* at all.
|
|
12
|
+
*
|
|
13
|
+
* ## The three rules every entry obeys
|
|
14
|
+
*
|
|
15
|
+
* 1. **Visible BEFORE the decision it qualifies**, not only on a policy page
|
|
16
|
+
* reachable from the footer. The protection disclaimer belongs beside the
|
|
17
|
+
* checkbox, not in `/refund-policy`.
|
|
18
|
+
* 2. **It names a LIMIT or an EXCLUSION.** A disclaimer that only says "we
|
|
19
|
+
* try our best" qualifies nothing and is worse than none — it reads as
|
|
20
|
+
* cover while providing none.
|
|
21
|
+
* 3. **It AGREES with the code.** Limits render from the constants that
|
|
22
|
+
* enforce them (`SALE_PROTECTION_MAX_VALUE`, the claim windows), through
|
|
23
|
+
* the same `{{token}}` mechanism as Phase 9, so a constant change updates
|
|
24
|
+
* the published terms rather than contradicting them.
|
|
25
|
+
*
|
|
26
|
+
* ## 🛑 NOT a cookie-banner blanket
|
|
27
|
+
*
|
|
28
|
+
* A disclaimer that appears everywhere is read nowhere. Each entry names the
|
|
29
|
+
* specific surfaces that need it, and `audit-disclaimer-coverage` checks those
|
|
30
|
+
* surfaces render one — not that every page does.
|
|
31
|
+
*/
|
|
32
|
+
export const DISCLAIMERS = {
|
|
33
|
+
/*
|
|
34
|
+
* ── 🛑 THE DEFAMATION ONE. Read this before editing it ────────────────────
|
|
35
|
+
*
|
|
36
|
+
* A scam profile names a real person, with their payment handle and their
|
|
37
|
+
* phone number, on a public page. That is defamation exposure, and the
|
|
38
|
+
* registry had NO disclaimer of any kind.
|
|
39
|
+
*
|
|
40
|
+
* Four things this text must do, each for a specific reason:
|
|
41
|
+
*
|
|
42
|
+
* 1. **Distinguish an ALLEGATION from a verified finding.** The status badge
|
|
43
|
+
* already says `pending_review` vs `verified`, but a visitor reads the
|
|
44
|
+
* name and the amount, not the badge — so the distinction has to be in
|
|
45
|
+
* words.
|
|
46
|
+
* 2. **State the evidence standard**, because "we checked" is not a standard
|
|
47
|
+
* and invites the reader to assume a higher one than we applied.
|
|
48
|
+
* 3. **Name the removal route.** A person named here needs a way to contest
|
|
49
|
+
* it that does not begin with a lawyer, and publishing one is itself part
|
|
50
|
+
* of the defence.
|
|
51
|
+
* 4. 🛑 **Refuse the shared-guilt inference.** `relatedScammerIds` means
|
|
52
|
+
* SAME IDENTITY — the same person under another handle — and never
|
|
53
|
+
* "similar pattern". A reader who takes it as the latter concludes that
|
|
54
|
+
* everyone in a cluster is guilty of everyone else's conduct, which is
|
|
55
|
+
* the single most damaging misreading this page permits.
|
|
56
|
+
*/
|
|
57
|
+
"scam-registry": {
|
|
58
|
+
heading: "About these reports",
|
|
59
|
+
body: "These are reports submitted by buyers and sellers, not findings of fact or a legal judgment. " +
|
|
60
|
+
"A profile marked **under review** is an unverified allegation. A profile marked **verified** means " +
|
|
61
|
+
"our team has seen supporting evidence — payment records, messages or delivery proof — supplied by the " +
|
|
62
|
+
"person reporting; it is not a court finding and we are not able to investigate beyond the documents " +
|
|
63
|
+
"we are shown. " +
|
|
64
|
+
"Linked profiles indicate the SAME person under another name or handle, and never that separate people " +
|
|
65
|
+
"are connected to each other's conduct. " +
|
|
66
|
+
"If you are named here and believe it is wrong, contact us and we will review the report and remove it " +
|
|
67
|
+
"if it is not supported.",
|
|
68
|
+
tone: "warning",
|
|
69
|
+
surfaces: ["ScamProfileView", "ScamRegistryView", "/report"],
|
|
70
|
+
},
|
|
71
|
+
/*
|
|
72
|
+
* Gaming law in India is STATE-SPECIFIC, and the distinction that matters
|
|
73
|
+
* legally is skill versus chance. The entry names the exclusions rather than
|
|
74
|
+
* claiming a position we cannot defend in every state.
|
|
75
|
+
*/
|
|
76
|
+
"prize-draw": {
|
|
77
|
+
heading: "Prize draw terms",
|
|
78
|
+
body: "Entry requires a purchase and is void where prohibited by local law. Residents of states that " +
|
|
79
|
+
"restrict prize draws or games of chance are not eligible, and an entry from such a state will be " +
|
|
80
|
+
"refunded rather than drawn. Prizes are as described on the listing, are not transferable and cannot " +
|
|
81
|
+
"be exchanged for cash. The draw is run by {{siteName}} and is not affiliated with any government lottery.",
|
|
82
|
+
tone: "warning",
|
|
83
|
+
surfaces: ["PrizeDrawDetailPageView", "/prize-draws", "/lottery", "PrizeRevealModal"],
|
|
84
|
+
},
|
|
85
|
+
/*
|
|
86
|
+
* 🛑 Shown wherever a historical price appears. Collectibles displayed with
|
|
87
|
+
* past realised prices invite an appreciation inference, and the moment a
|
|
88
|
+
* buyer treats that as a projection we are giving investment advice we are
|
|
89
|
+
* not licensed to give.
|
|
90
|
+
*/
|
|
91
|
+
"not-investment-advice": {
|
|
92
|
+
body: "Prices shown are past transactions, not a valuation, a projection or a guarantee. Collectibles can " +
|
|
93
|
+
"fall in value as easily as rise, may be difficult to sell at any price, and {{siteName}} does not provide " +
|
|
94
|
+
"investment advice. Nothing here should be relied on as a reason to buy.",
|
|
95
|
+
tone: "legal",
|
|
96
|
+
surfaces: ["PriceIndexView", "RealisedPriceStrip", "/franchise", "ProductDetailPageView"],
|
|
97
|
+
},
|
|
98
|
+
/*
|
|
99
|
+
* 🛑 Names the SAMPLE, because an index built from four sales reads exactly
|
|
100
|
+
* like one built from four hundred — and "asked ≠ sold" is the distinction a
|
|
101
|
+
* seller pricing against it most needs.
|
|
102
|
+
*/
|
|
103
|
+
"price-index": {
|
|
104
|
+
body: "Each figure is drawn from a limited number of observed sales over the period shown, and a small " +
|
|
105
|
+
"sample can move sharply on one unusual transaction. Asking prices are not sale prices: an item " +
|
|
106
|
+
"listed at a figure may never have sold at it.",
|
|
107
|
+
tone: "legal",
|
|
108
|
+
surfaces: ["PriceIndexView", "PriceBandChart"],
|
|
109
|
+
},
|
|
110
|
+
"authenticity": {
|
|
111
|
+
body: "{{siteName}} is not an authentication or grading service. We do not inspect, test or re-grade items, " +
|
|
112
|
+
"and a grade shown on a listing is the one the seller states a third-party grader assigned. " +
|
|
113
|
+
"Guidance on spotting a counterfeit is general information, not a verification of any particular item.",
|
|
114
|
+
tone: "legal",
|
|
115
|
+
surfaces: ["/spot-a-fake", "ProductDetailPageView", "authenticityKnowledge"],
|
|
116
|
+
},
|
|
117
|
+
/*
|
|
118
|
+
* 🛑 **"Not insurance" is the load-bearing phrase.** There is no insurer —
|
|
119
|
+
* this is our own cover, funded by us, and calling it insurance would be a
|
|
120
|
+
* regulatory misstatement as well as a false one.
|
|
121
|
+
*
|
|
122
|
+
* Every limit renders from the constant that enforces it, so a change to
|
|
123
|
+
* `SALE_PROTECTION_MAX_VALUE` or a claim window updates this text rather
|
|
124
|
+
* than contradicting it.
|
|
125
|
+
*/
|
|
126
|
+
"protection-cover": {
|
|
127
|
+
heading: "What protection covers",
|
|
128
|
+
body: "Buyer protection is cover provided by {{siteName}}. It is **not insurance** and there is no insurer. " +
|
|
129
|
+
"Shipment protection covers loss or damage in transit and must be claimed within " +
|
|
130
|
+
"{{shipmentClaimHours}} hours of delivery. Sale protection covers an item up to " +
|
|
131
|
+
"{{saleProtectionMaxValue}} and must be claimed within {{saleClaimHours}} hours of delivery. " +
|
|
132
|
+
"Neither covers a change of mind, an item sold as final sale, or a claim made after its window has " +
|
|
133
|
+
"closed.",
|
|
134
|
+
tone: "legal",
|
|
135
|
+
surfaces: ["StoreAddonsPicker", "/fees", "/refund-policy", "ProtectionClaimForm"],
|
|
136
|
+
},
|
|
137
|
+
/*
|
|
138
|
+
* 🛑 "Management figures, not audited accounts" — and the GSTR-1 export is
|
|
139
|
+
* the INPUT to a filing, never a filing. Implying a return had been filed
|
|
140
|
+
* when it had not is the most consequential thing this product could say.
|
|
141
|
+
*/
|
|
142
|
+
"accounting-output": {
|
|
143
|
+
body: "These are management figures produced from this platform's own records. They are not audited " +
|
|
144
|
+
"accounts and have not been reviewed by an accountant. The GSTR-1 export is a draft for your " +
|
|
145
|
+
"accountant to check and use — nothing here is filed with any tax authority, and {{siteName}} has no " +
|
|
146
|
+
"connection to the GST portal.",
|
|
147
|
+
tone: "warning",
|
|
148
|
+
surfaces: ["AdminInvoicingView", "AdminAnalyticsView", "ProfitLossView", "TrialBalanceView"],
|
|
149
|
+
},
|
|
150
|
+
"live-items": {
|
|
151
|
+
heading: "Live item terms",
|
|
152
|
+
body: "Live animals and plants ship only where law permits, and some species cannot be sent across state " +
|
|
153
|
+
"or international borders at all — CITES-listed species in particular. The buyer is responsible for " +
|
|
154
|
+
"holding any licence their own jurisdiction requires. No guarantee of health, size, sex or lifespan " +
|
|
155
|
+
"is given beyond what the listing states, and a live item cannot be returned for a change of mind.",
|
|
156
|
+
tone: "warning",
|
|
157
|
+
surfaces: ["LiveItemDetailPageView", "/live"],
|
|
158
|
+
},
|
|
159
|
+
"pre-order": {
|
|
160
|
+
body: "A release date on a pre-order is the manufacturer's estimate and can move or be cancelled by them. " +
|
|
161
|
+
"Your deposit is refundable until the item ships; the remaining balance is charged when it is ready " +
|
|
162
|
+
"to dispatch, against the terms shown when you placed the pre-order.",
|
|
163
|
+
tone: "legal",
|
|
164
|
+
surfaces: ["PreOrderDetailPageView", "/pre-orders"],
|
|
165
|
+
},
|
|
166
|
+
"auction-binding": {
|
|
167
|
+
body: "A bid is a binding offer to buy at that price and cannot be withdrawn. If the reserve price is not " +
|
|
168
|
+
"met the item does not sell, even if yours was the highest bid. Winning starts a payment window — " +
|
|
169
|
+
"miss it and the win is forfeited.",
|
|
170
|
+
tone: "warning",
|
|
171
|
+
surfaces: ["PlaceBidForm", "AuctionDetailPageView", "/auctions"],
|
|
172
|
+
},
|
|
173
|
+
"emi": {
|
|
174
|
+
body: "EMI adds a surcharge to the order total, shown before you pay. The instalment plan is between you " +
|
|
175
|
+
"and {{siteName}} rather than a bank, and a missed instalment may suspend access to the order and is " +
|
|
176
|
+
"recoverable as a debt.",
|
|
177
|
+
tone: "legal",
|
|
178
|
+
surfaces: ["CheckoutRouteClient", "/fees", "EmiScheduleTable"],
|
|
179
|
+
},
|
|
180
|
+
"delivery-estimate": {
|
|
181
|
+
body: "Delivery dates are estimates from the courier, not guarantees, and can be affected by weather, " +
|
|
182
|
+
"strikes and customs. A late delivery is not by itself grounds for a refund.",
|
|
183
|
+
tone: "legal",
|
|
184
|
+
surfaces: ["CheckoutRouteClient", "ProductDetailPageView", "OrderTrackView"],
|
|
185
|
+
},
|
|
186
|
+
"user-content": {
|
|
187
|
+
body: "Reviews, catalogue entries and comments are the opinions of the people who wrote them, not " +
|
|
188
|
+
"{{siteName}}'s. We remove content that breaks our rules when it is reported, but we do not verify every " +
|
|
189
|
+
"claim made in it.",
|
|
190
|
+
tone: "legal",
|
|
191
|
+
surfaces: ["ReviewsList", "ReviewDetailShell", "PublicProfileView", "BlogPostView"],
|
|
192
|
+
},
|
|
193
|
+
"tax-computation": {
|
|
194
|
+
body: "GST shown is computed from the information available to us at the time of supply — the item's tax " +
|
|
195
|
+
"code and the delivery address you gave. Your own tax position, including any input credit, is yours " +
|
|
196
|
+
"to determine with your accountant.",
|
|
197
|
+
tone: "legal",
|
|
198
|
+
surfaces: ["InvoicePageView", "/gst", "OrderSummary"],
|
|
199
|
+
},
|
|
200
|
+
/*
|
|
201
|
+
* 🛑 The Phase 5b obligations act on timers — cancelling orders, approving
|
|
202
|
+
* returns, completing orders. A buyer whose order was cancelled by a sweep
|
|
203
|
+
* must be TOLD it was automatic and how to contest it; otherwise the first
|
|
204
|
+
* they know is a refund they did not request, which reads as us losing their
|
|
205
|
+
* order.
|
|
206
|
+
*/
|
|
207
|
+
"automated-decision": {
|
|
208
|
+
body: "This was done automatically, by a time limit rather than by a person. If you think it was wrong, " +
|
|
209
|
+
"reply to this notification or open a support ticket and a person will look at it.",
|
|
210
|
+
tone: "legal",
|
|
211
|
+
surfaces: [
|
|
212
|
+
"obligation notifications",
|
|
213
|
+
"OrderStatusTimeline",
|
|
214
|
+
"AdminObligationsView",
|
|
215
|
+
],
|
|
216
|
+
},
|
|
217
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Published numbers — ONE definition, rendered everywhere (Phase 9).
|
|
3
|
+
*
|
|
4
|
+
* ## 🛑 The problem this solves, stated as a measurement
|
|
5
|
+
*
|
|
6
|
+
* The same fact was published in four places with different answers. The
|
|
7
|
+
* refund timeline appeared as "5–7 business days via Razorpay" (policy page,
|
|
8
|
+
* naming the wrong gateway), "5–7 business days" (`REFUND_COPY`) and "3–5
|
|
9
|
+
* business days" (the FAQ). The return window appeared as 7 days, 2 days and
|
|
10
|
+
* 48 hours. The seller's return-response window is 48 hours in the FAQ and 3
|
|
11
|
+
* days in `AdminOrdersGuideView`. The offer checkout deadline is 48h in code
|
|
12
|
+
* and 24h in both the FAQ and the seed.
|
|
13
|
+
*
|
|
14
|
+
* Four owners, nothing reconciling them, and one of the four — the FAQ — is
|
|
15
|
+
* **seeded into Firestore and then admin-editable**, so a number quoted there
|
|
16
|
+
* drifts *after* deployment with no audit able to see it.
|
|
17
|
+
*
|
|
18
|
+
* ## 🛑 So copy carries TOKENS, and the token resolves at render time
|
|
19
|
+
*
|
|
20
|
+
* `{{returnWindowDays}}` in an FAQ answer is a promise that cannot drift: the
|
|
21
|
+
* FAQ is still admin-editable, but the NUMBER inside it comes from here. An
|
|
22
|
+
* admin can rewrite the sentence and cannot contradict the code.
|
|
23
|
+
*
|
|
24
|
+
* ## 🛑 This is NOT a settings group, and must not become one
|
|
25
|
+
*
|
|
26
|
+
* Nothing here is admin-editable. These are the values the CODE enforces —
|
|
27
|
+
* `ORDER_RETURN_WINDOW_MS`, the obligation policies, `LANE_CHECKOUT_WINDOW_MS`
|
|
28
|
+
* — surfaced for rendering. An editable copy of an enforced constant is two
|
|
29
|
+
* sources of truth with a settings UI making the wrong one look
|
|
30
|
+
* authoritative, which is the 18-dead-settings pattern (D28/D44/D57/D60)
|
|
31
|
+
* arriving from the opposite direction: not a control that does nothing, but a
|
|
32
|
+
* control that appears to do something the code ignores.
|
|
33
|
+
*
|
|
34
|
+
* Where a value genuinely IS configurable, the entry derives it from the
|
|
35
|
+
* setting rather than restating it — see `resolvePublishedValues`.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Every token that may appear in published copy.
|
|
39
|
+
*
|
|
40
|
+
* 🛑 A `Record` over this union, so a token added to the type without a value
|
|
41
|
+
* is a COMPILE error — and a token used in copy that is not in the union is
|
|
42
|
+
* caught by `resolvePublishedCopy` leaving it visibly unresolved rather than
|
|
43
|
+
* silently blanking it. Both directions matter: a blanked token reads as a
|
|
44
|
+
* sentence with a word missing, which nobody reports, while `{{wrongKey}}` on
|
|
45
|
+
* a live page gets reported in minutes.
|
|
46
|
+
*/
|
|
47
|
+
export type PublishedValueKey = "returnWindowDays" | "sellerAcceptDays" | "sellerDispatchBusinessDays" | "returnRespondHours" | "returnPostDays" | "offerCheckoutHours" | "paymentWindowMinutes" | "deliveryConfirmDays" | "orderCompleteDays" | "shipmentClaimHours" | "saleClaimHours" | "disputeTransitWindowDays" | "disputeNotReachedGraceDays" | "platformFeeMax" | "platformFeePercent" | "shipmentProtectionPercent" | "shipmentProtectionMin" | "saleProtectionPercent" | "saleProtectionMin" | "saleProtectionMaxValue" | "codHandlingPercent" | "codDepositPercent" | "giftWrapFee" | "pointsEarnPercent" | "pointsMaxRedemptionPercent" | "pointsExpiryMonths" | "refundBusinessDaysMin" | "refundBusinessDaysMax" | "siteName";
|
|
48
|
+
export type PublishedValues = Record<PublishedValueKey, string>;
|
|
49
|
+
/**
|
|
50
|
+
* The settings this registry reads, where a value genuinely is configurable.
|
|
51
|
+
*
|
|
52
|
+
* Deliberately a narrow shape rather than `SiteSettingsDocument`: this module
|
|
53
|
+
* is imported by client components to render copy, and widening it to the
|
|
54
|
+
* whole settings document would invite a caller to pass one in — which is Root
|
|
55
|
+
* Cause #70's leak (a raw document reaching a Client Component prop, where
|
|
56
|
+
* TypeScript's structural typing strips nothing at runtime).
|
|
57
|
+
*/
|
|
58
|
+
export interface PublishedValueSettings {
|
|
59
|
+
/**
|
|
60
|
+
* The operator's display name, for the disclaimers that name who is making
|
|
61
|
+
* the statement. Falls back to `SITE_CONFIG.brand.name`.
|
|
62
|
+
*/
|
|
63
|
+
siteName?: string;
|
|
64
|
+
platformFeeMax?: number;
|
|
65
|
+
platformFeePercent?: number;
|
|
66
|
+
shipmentProtectionFeePercent?: number;
|
|
67
|
+
shipmentProtectionFeeMin?: number;
|
|
68
|
+
saleProtectionFeePercent?: number;
|
|
69
|
+
saleProtectionFeeMin?: number;
|
|
70
|
+
codHandlingFeePercent?: number;
|
|
71
|
+
codDepositPercent?: number;
|
|
72
|
+
giftWrapFee?: number;
|
|
73
|
+
returnWindowDays?: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Resolve every published value.
|
|
77
|
+
*
|
|
78
|
+
* 🛑 Settings are read where they exist and the CODE is read where it does
|
|
79
|
+
* not. A value with no setting is not a gap to fill with a literal — it is a
|
|
80
|
+
* constant the code enforces, and restating it here is how the four
|
|
81
|
+
* contradictions above happened in the first place.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolvePublishedValues(settings?: PublishedValueSettings): PublishedValues;
|
|
84
|
+
/**
|
|
85
|
+
* Replace every `{{token}}` in a string.
|
|
86
|
+
*
|
|
87
|
+
* 🛑 An UNKNOWN token is left verbatim, never blanked. A blanked token reads
|
|
88
|
+
* as a sentence with a word missing — which looks like clumsy copy and nobody
|
|
89
|
+
* reports — while a visible `{{returnWindowDayz}}` on a live page is reported
|
|
90
|
+
* within minutes. Failing loudly is the whole point of a token system whose
|
|
91
|
+
* copy is admin-editable.
|
|
92
|
+
*/
|
|
93
|
+
export declare function resolvePublishedCopy(text: string, values: PublishedValues): string;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Published numbers — ONE definition, rendered everywhere (Phase 9).
|
|
3
|
+
*
|
|
4
|
+
* ## 🛑 The problem this solves, stated as a measurement
|
|
5
|
+
*
|
|
6
|
+
* The same fact was published in four places with different answers. The
|
|
7
|
+
* refund timeline appeared as "5–7 business days via Razorpay" (policy page,
|
|
8
|
+
* naming the wrong gateway), "5–7 business days" (`REFUND_COPY`) and "3–5
|
|
9
|
+
* business days" (the FAQ). The return window appeared as 7 days, 2 days and
|
|
10
|
+
* 48 hours. The seller's return-response window is 48 hours in the FAQ and 3
|
|
11
|
+
* days in `AdminOrdersGuideView`. The offer checkout deadline is 48h in code
|
|
12
|
+
* and 24h in both the FAQ and the seed.
|
|
13
|
+
*
|
|
14
|
+
* Four owners, nothing reconciling them, and one of the four — the FAQ — is
|
|
15
|
+
* **seeded into Firestore and then admin-editable**, so a number quoted there
|
|
16
|
+
* drifts *after* deployment with no audit able to see it.
|
|
17
|
+
*
|
|
18
|
+
* ## 🛑 So copy carries TOKENS, and the token resolves at render time
|
|
19
|
+
*
|
|
20
|
+
* `{{returnWindowDays}}` in an FAQ answer is a promise that cannot drift: the
|
|
21
|
+
* FAQ is still admin-editable, but the NUMBER inside it comes from here. An
|
|
22
|
+
* admin can rewrite the sentence and cannot contradict the code.
|
|
23
|
+
*
|
|
24
|
+
* ## 🛑 This is NOT a settings group, and must not become one
|
|
25
|
+
*
|
|
26
|
+
* Nothing here is admin-editable. These are the values the CODE enforces —
|
|
27
|
+
* `ORDER_RETURN_WINDOW_MS`, the obligation policies, `LANE_CHECKOUT_WINDOW_MS`
|
|
28
|
+
* — surfaced for rendering. An editable copy of an enforced constant is two
|
|
29
|
+
* sources of truth with a settings UI making the wrong one look
|
|
30
|
+
* authoritative, which is the 18-dead-settings pattern (D28/D44/D57/D60)
|
|
31
|
+
* arriving from the opposite direction: not a control that does nothing, but a
|
|
32
|
+
* control that appears to do something the code ignores.
|
|
33
|
+
*
|
|
34
|
+
* Where a value genuinely IS configurable, the entry derives it from the
|
|
35
|
+
* setting rather than restating it — see `resolvePublishedValues`.
|
|
36
|
+
*/
|
|
37
|
+
/*
|
|
38
|
+
* 🛑 Every import here is the thing that ENFORCES the value, not a mirror of
|
|
39
|
+
* it. That is what makes "the code wins" structural rather than a convention
|
|
40
|
+
* somebody has to remember — and it is why there is no literal for the offer
|
|
41
|
+
* deadline or the claim windows even though both appear in published copy.
|
|
42
|
+
*/
|
|
43
|
+
import { SITE_CONFIG } from "../../../core/site-config.js";
|
|
44
|
+
import { OBLIGATION_POLICIES } from "../../../features/obligations/constants/policies.js";
|
|
45
|
+
import { POINTS_EARN_PERCENT, POINTS_EXPIRY_MONTHS, POINTS_MAX_REDEMPTION_PERCENT, } from "../../../features/points/schemas/firestore.js";
|
|
46
|
+
import { PAYMENT_WINDOW_MINUTES } from "../../../features/orders/constants/payment-window.js";
|
|
47
|
+
import { SALE_PROTECTION_MAX_VALUE } from "../features/shipping/protections.js";
|
|
48
|
+
import { LANE_CHECKOUT_WINDOW_MS } from "../checkout/lanes.js";
|
|
49
|
+
import { DISPUTE_TRANSIT_WINDOW_DAYS, DISPUTE_NOT_REACHED_GRACE_DAYS, } from "../features/orders/dispute-reasons.js";
|
|
50
|
+
/**
|
|
51
|
+
* The offer checkout deadline, in hours, derived from the constant the lapse
|
|
52
|
+
* sweep actually enforces.
|
|
53
|
+
*
|
|
54
|
+
* 🛑 Decision 23: the CODE wins this contradiction, not the FAQ's 24h and not
|
|
55
|
+
* the seed's. An offer accepted yesterday carries a 48h `checkoutDeadline`
|
|
56
|
+
* stored on it, so publishing 24 would be telling a buyer their live offer
|
|
57
|
+
* expires sooner than it does — and changing the code to match the FAQ would
|
|
58
|
+
* shorten deadlines already granted.
|
|
59
|
+
*/
|
|
60
|
+
const OFFER_CHECKOUT_HOURS = Math.round(LANE_CHECKOUT_WINDOW_MS.offer / 3600000);
|
|
61
|
+
/*
|
|
62
|
+
* ── The decided values (decision 23) ─────────────────────────────────────────
|
|
63
|
+
*
|
|
64
|
+
* Two live contradictions are resolved by NAMING A WINNER rather than
|
|
65
|
+
* averaging:
|
|
66
|
+
*
|
|
67
|
+
* - **return-response: 48 hours.** The FAQ wins over
|
|
68
|
+
* `AdminOrdersGuideView`'s 3 days, because 48h is the buyer-facing promise
|
|
69
|
+
* and the one a buyer has already read.
|
|
70
|
+
* - **offer checkout: 48 hours.** The CODE wins over the FAQ's and the seed's
|
|
71
|
+
* 24h, because changing it would break live offers — an offer accepted
|
|
72
|
+
* yesterday has a 48h deadline stored on it.
|
|
73
|
+
*
|
|
74
|
+
* Both are derived from the obligation policies and `LANE_CHECKOUT_WINDOW_MS`
|
|
75
|
+
* below rather than restated here, so "the code wins" is structural.
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* A policy's duration in minutes, whatever unit it declares.
|
|
79
|
+
*
|
|
80
|
+
* 🛑 EXHAUSTIVE over `DurationUnit`, which is `minutes | hours | days` — not
|
|
81
|
+
* the two-case ternary this started as. A `minutes` duration read by a
|
|
82
|
+
* hours-or-days ternary would be published as that many HOURS: a 15-minute
|
|
83
|
+
* window rendered to a buyer as 15 hours, with nothing erroring. The
|
|
84
|
+
* `switch` with no default is what makes a fourth unit a compile error rather
|
|
85
|
+
* than a silent 60× on a published promise.
|
|
86
|
+
*/
|
|
87
|
+
function policyMinutes(kind) {
|
|
88
|
+
const d = OBLIGATION_POLICIES[kind].duration;
|
|
89
|
+
switch (d.unit) {
|
|
90
|
+
case "minutes":
|
|
91
|
+
return d.value;
|
|
92
|
+
case "hours":
|
|
93
|
+
return d.value * 60;
|
|
94
|
+
case "days":
|
|
95
|
+
return d.value * 24 * 60;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Days, rounded.
|
|
100
|
+
*
|
|
101
|
+
* 🛑 `Math.round`, not `Math.floor`. A 36-hour window floors to 1 day, which
|
|
102
|
+
* UNDERSTATES a promise to a buyer — and a published window shorter than the
|
|
103
|
+
* one the code enforces is the direction that generates complaints. Rounding
|
|
104
|
+
* up-or-nearest can only overstate, which is the safe error. A policy whose
|
|
105
|
+
* duration does not divide cleanly into days should be published in hours
|
|
106
|
+
* instead; this is for the ones that do.
|
|
107
|
+
*/
|
|
108
|
+
function policyDays(kind) {
|
|
109
|
+
return Math.round(policyMinutes(kind) / (24 * 60));
|
|
110
|
+
}
|
|
111
|
+
/** Hours, from the obligation policy that enforces it. */
|
|
112
|
+
function policyHours(kind) {
|
|
113
|
+
return Math.round(policyMinutes(kind) / 60);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Resolve every published value.
|
|
117
|
+
*
|
|
118
|
+
* 🛑 Settings are read where they exist and the CODE is read where it does
|
|
119
|
+
* not. A value with no setting is not a gap to fill with a literal — it is a
|
|
120
|
+
* constant the code enforces, and restating it here is how the four
|
|
121
|
+
* contradictions above happened in the first place.
|
|
122
|
+
*/
|
|
123
|
+
export function resolvePublishedValues(settings) {
|
|
124
|
+
return {
|
|
125
|
+
// ── Windows: every one of these comes from the thing that enforces it ──
|
|
126
|
+
returnWindowDays: String(settings?.returnWindowDays ?? 7),
|
|
127
|
+
sellerAcceptDays: String(policyDays("seller-accept")),
|
|
128
|
+
sellerDispatchBusinessDays: String(policyDays("seller-dispatch")),
|
|
129
|
+
returnRespondHours: String(policyHours("return-respond")),
|
|
130
|
+
returnPostDays: String(policyDays("return-post")),
|
|
131
|
+
offerCheckoutHours: String(OFFER_CHECKOUT_HOURS),
|
|
132
|
+
paymentWindowMinutes: String(PAYMENT_WINDOW_MINUTES),
|
|
133
|
+
deliveryConfirmDays: String(policyDays("delivery-confirm")),
|
|
134
|
+
orderCompleteDays: String(policyDays("order-complete")),
|
|
135
|
+
shipmentClaimHours: String(policyHours("claim-shipping")),
|
|
136
|
+
saleClaimHours: String(policyHours("claim-sale")),
|
|
137
|
+
/*
|
|
138
|
+
* Straight from the dispute module's own constants, not re-typed here.
|
|
139
|
+
* Two copies of a published number is the exact drift Phase 9 exists to
|
|
140
|
+
* remove — the table in this file's own header records a return window
|
|
141
|
+
* that code said 7, one FAQ said 2 and another said 48 hours.
|
|
142
|
+
*/
|
|
143
|
+
disputeTransitWindowDays: String(DISPUTE_TRANSIT_WINDOW_DAYS),
|
|
144
|
+
disputeNotReachedGraceDays: String(DISPUTE_NOT_REACHED_GRACE_DAYS),
|
|
145
|
+
// ── Money: settings-driven, with the schema defaults as the fallback ───
|
|
146
|
+
platformFeeMax: formatRupees(settings?.platformFeeMax ?? 10),
|
|
147
|
+
platformFeePercent: String(settings?.platformFeePercent ?? 2),
|
|
148
|
+
shipmentProtectionPercent: String(settings?.shipmentProtectionFeePercent ?? 2),
|
|
149
|
+
shipmentProtectionMin: formatRupees(settings?.shipmentProtectionFeeMin ?? 30),
|
|
150
|
+
saleProtectionPercent: String(settings?.saleProtectionFeePercent ?? 3),
|
|
151
|
+
saleProtectionMin: formatRupees(settings?.saleProtectionFeeMin ?? 49),
|
|
152
|
+
saleProtectionMaxValue: formatRupees(SALE_PROTECTION_MAX_VALUE),
|
|
153
|
+
codHandlingPercent: String(settings?.codHandlingFeePercent ?? 2),
|
|
154
|
+
codDepositPercent: String(settings?.codDepositPercent ?? 10),
|
|
155
|
+
giftWrapFee: formatRupees(settings?.giftWrapFee ?? 0),
|
|
156
|
+
// ── Points ─────────────────────────────────────────────────────────────
|
|
157
|
+
pointsEarnPercent: String(POINTS_EARN_PERCENT),
|
|
158
|
+
pointsMaxRedemptionPercent: String(POINTS_MAX_REDEMPTION_PERCENT),
|
|
159
|
+
pointsExpiryMonths: String(POINTS_EXPIRY_MONTHS),
|
|
160
|
+
// ── Refunds ────────────────────────────────────────────────────────────
|
|
161
|
+
/*
|
|
162
|
+
* 🛑 The gateway's own processing time, and the ONE value here that no
|
|
163
|
+
* code enforces — so it is a literal, and that is stated rather than
|
|
164
|
+
* hidden. It is also where the three-way contradiction lived (5–7 / 5–7 /
|
|
165
|
+
* 3–5), which is the argument for putting it here at all: a number nothing
|
|
166
|
+
* enforces is exactly the one that drifts.
|
|
167
|
+
*
|
|
168
|
+
* 🛑 And the published copy must NOT name the gateway. The policy page
|
|
169
|
+
* said "via Razorpay" while payment ran through PhonePe, and it will be
|
|
170
|
+
* wrong again the next time a provider changes — a fact about our vendor
|
|
171
|
+
* is not a fact the buyer needs.
|
|
172
|
+
*/
|
|
173
|
+
refundBusinessDaysMin: "5",
|
|
174
|
+
refundBusinessDaysMax: "7",
|
|
175
|
+
/*
|
|
176
|
+
* `SITE_CONFIG.brand.name` is appkit's own neutral default ("App") until a
|
|
177
|
+
* consumer overrides it, which is exactly the right failure mode here: a
|
|
178
|
+
* fork that forgets to configure its brand publishes a visibly generic
|
|
179
|
+
* disclaimer rather than silently attributing its legal statements to us.
|
|
180
|
+
*/
|
|
181
|
+
siteName: settings?.siteName ?? SITE_CONFIG.brand.name,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Replace every `{{token}}` in a string.
|
|
186
|
+
*
|
|
187
|
+
* 🛑 An UNKNOWN token is left verbatim, never blanked. A blanked token reads
|
|
188
|
+
* as a sentence with a word missing — which looks like clumsy copy and nobody
|
|
189
|
+
* reports — while a visible `{{returnWindowDayz}}` on a live page is reported
|
|
190
|
+
* within minutes. Failing loudly is the whole point of a token system whose
|
|
191
|
+
* copy is admin-editable.
|
|
192
|
+
*/
|
|
193
|
+
export function resolvePublishedCopy(text, values) {
|
|
194
|
+
return text.replace(/\{\{(\w+)\}\}/g, (whole, key) => {
|
|
195
|
+
const resolved = values[key];
|
|
196
|
+
return resolved ?? whole;
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/** `₹10`, `₹1,499.50` — no trailing `.00` on a whole rupee figure. */
|
|
200
|
+
function formatRupees(amount) {
|
|
201
|
+
const whole = Number.isInteger(amount);
|
|
202
|
+
return `₹${amount.toLocaleString("en-IN", {
|
|
203
|
+
minimumFractionDigits: whole ? 0 : 2,
|
|
204
|
+
maximumFractionDigits: 2,
|
|
205
|
+
})}`;
|
|
206
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The integration switches, and what turning each one OFF actually does.
|
|
3
|
+
*
|
|
4
|
+
* ## 🛑 This is a VIEW over existing fields, never a second store
|
|
5
|
+
*
|
|
6
|
+
* Three of the four already have an authoritative field:
|
|
7
|
+
*
|
|
8
|
+
* payments -> `payment.razorpayEnabled`
|
|
9
|
+
* email -> `messaging.emailEnabled` (read by `guardSend`)
|
|
10
|
+
* shipping -> `shipping.provider` ("manual" | "shiprocket")
|
|
11
|
+
*
|
|
12
|
+
* Adding an `integrationSwitches.payments` beside those would be a
|
|
13
|
+
* denormalised mirror, and it would drift the first time a path wrote one of
|
|
14
|
+
* the pair and not the other (Root Cause #42) — at which point the admin page
|
|
15
|
+
* says "on" while the code that enforces it reads "off". Only `support.enabled`
|
|
16
|
+
* is new, because only support had nothing.
|
|
17
|
+
*
|
|
18
|
+
* ## 🛑 Off does not mean the same thing twice
|
|
19
|
+
*
|
|
20
|
+
* "Payments off" stops money. "Support off" hides a contact route. "Shipping
|
|
21
|
+
* off" is not even expressible — a parcel still has to move, so the shipping
|
|
22
|
+
* switch selects manual (self-ship) rather than stopping anything.
|
|
23
|
+
*
|
|
24
|
+
* Presenting four interchangeable toggles would invite an admin to flip the
|
|
25
|
+
* expensive one by muscle memory, so every row carries its own
|
|
26
|
+
* `offConsequence` and the dangerous ones are marked.
|
|
27
|
+
*/
|
|
28
|
+
import type { SiteSettingsDocument } from "../../../../features/admin/schemas/firestore";
|
|
29
|
+
export type IntegrationId = "payments" | "email" | "shipping" | "support";
|
|
30
|
+
export interface IntegrationDescriptor {
|
|
31
|
+
id: IntegrationId;
|
|
32
|
+
label: string;
|
|
33
|
+
/** One line: what this integration IS. */
|
|
34
|
+
summary: string;
|
|
35
|
+
/** 🛑 Shown on the row. What switching it off does, in the admin's terms. */
|
|
36
|
+
offConsequence: string;
|
|
37
|
+
/**
|
|
38
|
+
* `true` when turning it off stops money or breaks a flow a user is
|
|
39
|
+
* mid-way through. Drives a confirmation and a visual warning — an
|
|
40
|
+
* accidental click here is expensive.
|
|
41
|
+
*/
|
|
42
|
+
severe: boolean;
|
|
43
|
+
/** The settings path the switch actually writes. Named, so it is auditable. */
|
|
44
|
+
field: string;
|
|
45
|
+
/**
|
|
46
|
+
* Whether this integration's API routes are closed when it is off, and WHY
|
|
47
|
+
* that answer is what it is. Three different answers for four integrations,
|
|
48
|
+
* so a uniform wrapper applied to everything would be wrong three ways.
|
|
49
|
+
*
|
|
50
|
+
* - `"gated"` — the routes 404 when off (payments, support).
|
|
51
|
+
* - `"none"` — there is nothing to gate, stated with the reason, so nobody
|
|
52
|
+
* later "completes" the set by guarding a route that must
|
|
53
|
+
* stay open.
|
|
54
|
+
*/
|
|
55
|
+
routeGuard: "gated" | "none";
|
|
56
|
+
/** Human reason for `routeGuard`, shown nowhere — it is for the next reader. */
|
|
57
|
+
routeGuardNote: string;
|
|
58
|
+
/**
|
|
59
|
+
* 🛑 Which way the guard fails when the settings read itself throws, and this
|
|
60
|
+
* genuinely DIFFERS per integration — a single uniform direction would be
|
|
61
|
+
* the wrong call for one of them whichever one was picked.
|
|
62
|
+
*
|
|
63
|
+
* `true` (payments): a Firestore blip must not open a money route. Closed is
|
|
64
|
+
* the safe direction for money.
|
|
65
|
+
*
|
|
66
|
+
* `false` (support): refusing support because Firestore hiccupped is worse
|
|
67
|
+
* than briefly allowing a ticket nobody wanted — and it is the same choice
|
|
68
|
+
* `guardSend` makes on the same read.
|
|
69
|
+
*/
|
|
70
|
+
failClosed: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 🛑 A `Record<IntegrationId, …>`, so a fifth integration cannot be added
|
|
74
|
+
* without writing its off-consequence. A row with no stated consequence is
|
|
75
|
+
* exactly the interchangeable-toggle failure this file exists to prevent.
|
|
76
|
+
*/
|
|
77
|
+
export declare const INTEGRATIONS: Record<IntegrationId, IntegrationDescriptor>;
|
|
78
|
+
/** Display order. Money first, because it is what an admin came to check. */
|
|
79
|
+
export declare const INTEGRATION_ORDER: readonly IntegrationId[];
|
|
80
|
+
/** What a switch reads/writes. `shipping` is a provider, not a boolean. */
|
|
81
|
+
export type IntegrationState = {
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Read each switch out of a settings document.
|
|
86
|
+
*
|
|
87
|
+
* 🛑 Defaults differ per integration and are NOT a uniform `?? false`:
|
|
88
|
+
* `razorpayEnabled` genuinely defaults off (it is opt-in and the account runs
|
|
89
|
+
* test keys), while email and support default ON because an older settings
|
|
90
|
+
* document with no such field must not read as "we stopped talking to
|
|
91
|
+
* customers".
|
|
92
|
+
*
|
|
93
|
+
* 🛑 THIS FUNCTION IS THE EXPRESSION THE ROUTE GUARDS USE. `withOnlinePaymentEnabled`
|
|
94
|
+
* had hand-written the payments half, and the first version of this file
|
|
95
|
+
* reproduced it WRONG — see the payments line. Both now resolve here, so the
|
|
96
|
+
* admin page and the guard cannot disagree about whether an integration is on.
|
|
97
|
+
* That disagreement is the entire failure mode this file's header warns about
|
|
98
|
+
* (Root Cause #42), and it had already happened once, inside the file.
|
|
99
|
+
*/
|
|
100
|
+
export declare function readIntegrationStates(settings: Partial<SiteSettingsDocument> | null | undefined): Record<IntegrationId, IntegrationState>;
|
|
101
|
+
/**
|
|
102
|
+
* Turn a desired state into the settings patch that expresses it.
|
|
103
|
+
*
|
|
104
|
+
* Returned as a nested partial rather than applied here, so the caller does
|
|
105
|
+
* one write and the audit log records one action.
|
|
106
|
+
*/
|
|
107
|
+
/**
|
|
108
|
+
* The settings groups an integration switch may write, and nothing else.
|
|
109
|
+
*
|
|
110
|
+
* 🛑 Deliberately a LOCAL shape rather than `Partial<SiteSettingsDocument>`.
|
|
111
|
+
* This module sits in `_internal/shared` and the settings schema pulls in the
|
|
112
|
+
* whole admin feature; importing it here to describe four booleans would add
|
|
113
|
+
* an edge `audit-import-cycles` exists to keep out. The four groups below are
|
|
114
|
+
* the entire surface these two functions write, so a local type is both
|
|
115
|
+
* narrower and honest.
|
|
116
|
+
*
|
|
117
|
+
* It replaces `Record<string, unknown>`, which said "some object" and
|
|
118
|
+
* therefore type-checked a patch that wrote a misspelled group or the wrong
|
|
119
|
+
* value shape — on a function whose whole job is flipping production kill
|
|
120
|
+
* switches.
|
|
121
|
+
*/
|
|
122
|
+
export interface IntegrationPatch {
|
|
123
|
+
payment?: {
|
|
124
|
+
razorpayEnabled?: boolean;
|
|
125
|
+
phonepeEnabled?: boolean;
|
|
126
|
+
};
|
|
127
|
+
messaging?: {
|
|
128
|
+
emailEnabled: boolean;
|
|
129
|
+
};
|
|
130
|
+
shipping?: {
|
|
131
|
+
provider: "manual" | "shiprocket";
|
|
132
|
+
};
|
|
133
|
+
support?: {
|
|
134
|
+
enabled: boolean;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export declare function integrationPatch(id: IntegrationId, enabled: boolean): IntegrationPatch;
|
|
138
|
+
/** Every patch for a bulk enable/disable, merged into one object. */
|
|
139
|
+
export declare function allIntegrationsPatch(enabled: boolean): IntegrationPatch;
|