@mohasinac/appkit 4.13.1 → 4.15.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/layout/DashboardLayoutClient.js +14 -5
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +3 -0
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +6 -0
- package/dist/_internal/client/features/lottery/LotteryDetailView.d.ts +8 -0
- package/dist/_internal/client/features/lottery/LotteryDetailView.js +4 -1
- package/dist/_internal/client/features/lottery/LotteryListView.d.ts +7 -0
- package/dist/_internal/client/features/lottery/LotteryListView.js +1 -1
- package/dist/_internal/client/features/lottery/PrizeDrawLotteryDetailView.js +4 -1
- package/dist/_internal/client/features/lottery/slot-collage-items.d.ts +15 -0
- package/dist/_internal/client/features/lottery/slot-collage-items.js +13 -0
- package/dist/_internal/server/features/auctions/actions.js +8 -2
- package/dist/_internal/server/features/bundles/data.d.ts +16 -0
- package/dist/_internal/server/features/bundles/data.js +26 -0
- package/dist/_internal/server/features/bundles/index.d.ts +1 -1
- package/dist/_internal/server/features/bundles/index.js +1 -1
- package/dist/_internal/server/features/cart/service.d.ts +3 -3
- package/dist/_internal/server/features/checkout/actions.js +25 -0
- package/dist/_internal/server/features/checkout/locked-lines.d.ts +38 -0
- package/dist/_internal/server/features/checkout/locked-lines.js +171 -0
- package/dist/_internal/server/features/checkout/source-context.d.ts +5 -0
- package/dist/_internal/server/features/checkout/source-context.js +157 -0
- package/dist/_internal/server/features/homepage/index.d.ts +0 -1
- package/dist/_internal/server/features/homepage/index.js +7 -1
- package/dist/_internal/server/features/lottery/adapters.js +4 -0
- package/dist/_internal/server/features/offers/adapters.d.ts +103 -0
- package/dist/_internal/server/features/offers/adapters.js +88 -0
- package/dist/_internal/server/features/offers/index.d.ts +2 -0
- package/dist/_internal/server/features/offers/index.js +1 -0
- package/dist/_internal/server/features/orders/adapters.js +24 -0
- package/dist/_internal/server/features/products/data.js +15 -37
- package/dist/_internal/server/features/products/index.d.ts +1 -1
- package/dist/_internal/server/features/products/index.js +1 -1
- package/dist/_internal/server/features/products/list-public.d.ts +46 -20
- package/dist/_internal/server/features/products/list-public.js +266 -90
- package/dist/_internal/server/features/products/listing-tab-counts.d.ts +44 -0
- package/dist/_internal/server/features/products/listing-tab-counts.js +97 -0
- package/dist/_internal/server/features/site-settings/adapters.d.ts +51 -0
- package/dist/_internal/server/features/site-settings/adapters.js +75 -0
- package/dist/_internal/server/features/site-settings/index.d.ts +1 -0
- package/dist/_internal/server/features/site-settings/index.js +1 -0
- package/dist/_internal/server/features/stores/adapters.d.ts +56 -0
- package/dist/_internal/server/features/stores/adapters.js +91 -0
- package/dist/_internal/server/features/stores/index.d.ts +1 -0
- package/dist/_internal/server/features/stores/index.js +1 -0
- package/dist/_internal/server/jobs/core/auctionSettlement.js +56 -2
- package/dist/_internal/server/jobs/core/offerExpiry.js +55 -19
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +5 -0
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +33 -1
- package/dist/_internal/server/jobs/handlers/messages.d.ts +7 -0
- package/dist/_internal/server/jobs/handlers/messages.js +10 -0
- package/dist/_internal/shared/actions/action-registry.js +17 -1
- package/dist/_internal/shared/checkout/lanes.d.ts +25 -0
- package/dist/_internal/shared/checkout/lanes.js +26 -0
- package/dist/_internal/shared/features/auctions/config.d.ts +27 -0
- package/dist/_internal/shared/features/auctions/config.js +27 -0
- package/dist/_internal/shared/features/auctions/schema.d.ts +14 -2
- package/dist/_internal/shared/features/auctions/schema.js +13 -1
- package/dist/_internal/shared/features/blog/schema.d.ts +2 -2
- package/dist/_internal/shared/features/cart/schema.d.ts +20 -15
- package/dist/_internal/shared/features/cart/schema.js +15 -0
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +32 -32
- package/dist/_internal/shared/features/emi/schedule.d.ts +24 -3
- package/dist/_internal/shared/features/emi/schedule.js +20 -5
- package/dist/_internal/shared/features/events/schema.d.ts +2 -2
- package/dist/_internal/shared/features/homepage/section-gate.d.ts +14 -0
- package/dist/_internal/shared/features/homepage/section-gate.js +51 -0
- package/dist/_internal/shared/features/offers/config.d.ts +30 -0
- package/dist/_internal/shared/features/offers/config.js +59 -0
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +30 -30
- package/dist/_internal/shared/features/products/to-product-item.js +6 -0
- package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
- package/dist/_internal/shared/features/site-settings/fees.d.ts +60 -0
- package/dist/_internal/shared/features/site-settings/fees.js +39 -0
- package/dist/_internal/shared/features/site-settings/types.d.ts +40 -0
- package/dist/_internal/shared/features/site-settings/types.js +1 -0
- package/dist/_internal/shared/history/history.d.ts +88 -0
- package/dist/_internal/shared/history/history.js +198 -0
- package/dist/_internal/shared/history/index.d.ts +4 -0
- package/dist/_internal/shared/history/index.js +2 -0
- package/dist/_internal/shared/history/types.d.ts +61 -0
- package/dist/_internal/shared/history/types.js +6 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +54 -1
- package/dist/_internal/shared/listing-types/_registry.js +67 -0
- package/dist/_internal/shared/listing-types/art/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/art/config.js +5 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +13 -0
- package/dist/_internal/shared/listing-types/auction/config.js +21 -0
- package/dist/_internal/shared/listing-types/availability.d.ts +79 -0
- package/dist/_internal/shared/listing-types/availability.js +104 -0
- package/dist/_internal/shared/listing-types/capabilities.d.ts +15 -0
- package/dist/_internal/shared/listing-types/capabilities.js +12 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/classified/config.js +5 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +11 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +22 -2
- package/dist/_internal/shared/listing-types/live/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/live/config.js +5 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +19 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +11 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +15 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/standard/config.js +5 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +5 -0
- package/dist/client.d.ts +20 -7
- package/dist/client.js +22 -4
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +57 -8
- package/dist/constants/field-names.js +101 -8
- package/dist/constants/table-keys.d.ts +17 -0
- package/dist/constants/table-keys.js +17 -0
- package/dist/errors/error-codes.d.ts +13 -1
- package/dist/errors/error-codes.js +13 -1
- package/dist/errors/error-display-map.js +12 -3
- package/dist/errors/messages.d.ts +10 -2
- package/dist/errors/messages.js +10 -2
- package/dist/features/about/components/AboutView.d.ts +3 -0
- package/dist/features/about/components/AboutView.js +3 -2
- package/dist/features/about/components/PolicyPageView.d.ts +2 -1
- package/dist/features/about/components/PolicyPageView.js +61 -23
- package/dist/features/about/components/PublicProfileView.js +5 -0
- package/dist/features/about/schemas/firestore.d.ts +3 -0
- package/dist/features/account/components/UserBidsView.js +12 -4
- package/dist/features/account/components/UserOrdersView.js +7 -0
- package/dist/features/account/components/UserReturnsView.d.ts +3 -0
- package/dist/features/account/components/UserReturnsView.js +17 -1
- package/dist/features/account/components/index.d.ts +0 -2
- package/dist/features/account/components/index.js +0 -1
- package/dist/features/account/schemas/index.d.ts +2 -2
- package/dist/features/account/types/index.d.ts +21 -2
- package/dist/features/addresses/schemas/index.d.ts +4 -4
- package/dist/features/admin/components/AdminArtView.js +8 -3
- package/dist/features/admin/components/AdminAuditLogView.js +1 -0
- package/dist/features/admin/components/AdminBidsView.js +15 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +65 -33
- package/dist/features/admin/components/AdminClassifiedView.js +8 -3
- package/dist/features/admin/components/AdminDigitalCodesView.js +8 -3
- package/dist/features/admin/components/AdminFeatureEditorView.js +35 -6
- package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -0
- package/dist/features/admin/components/AdminLiveView.js +8 -3
- package/dist/features/admin/components/AdminNavEditorView.js +15 -5
- package/dist/features/admin/components/AdminNewsletterView.js +18 -2
- package/dist/features/admin/components/AdminOffersView.d.ts +4 -0
- package/dist/features/admin/components/AdminOffersView.js +230 -0
- package/dist/features/admin/components/AdminOrdersView.js +10 -1
- package/dist/features/admin/components/AdminPaymentMethodsView.js +24 -4
- package/dist/features/admin/components/AdminPrizeDrawsView.js +5 -0
- package/dist/features/admin/components/AdminProductsView.js +16 -29
- package/dist/features/admin/components/AdminScammerEditorView.d.ts +2 -1
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -13
- package/dist/features/admin/components/AdminScammersView.js +3 -8
- package/dist/features/admin/components/AdminSectionsView.js +32 -23
- package/dist/features/admin/components/AdminSessionsView.js +17 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +31 -13
- package/dist/features/admin/components/AdminSiteView.js +6 -2
- package/dist/features/admin/components/AdminStickersView.js +8 -3
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +1 -0
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -2
- package/dist/features/admin/components/sections/adminSectionsTypes.js +45 -27
- package/dist/features/admin/constants/filter-tabs.d.ts +89 -0
- package/dist/features/admin/constants/filter-tabs.js +56 -0
- package/dist/features/admin/schemas/firestore.d.ts +122 -3
- package/dist/features/admin/schemas/firestore.js +1 -0
- package/dist/features/admin/schemas/homepage-section-form.d.ts +22 -0
- package/dist/features/admin/schemas/homepage-section-form.js +68 -0
- package/dist/features/admin/schemas/nav-item-form.d.ts +74 -0
- package/dist/features/admin/schemas/nav-item-form.js +72 -0
- package/dist/features/auctions/actions/bid-actions.d.ts +20 -5
- package/dist/features/auctions/actions/bid-actions.js +93 -20
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +10 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +22 -4
- package/dist/features/auctions/components/AuctionDetailPageView.js +11 -6
- package/dist/features/auctions/components/AuctionsListView.js +5 -6
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +7 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +19 -2
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +8 -4
- package/dist/features/auctions/components/bid-detail-fields.d.ts +29 -0
- package/dist/features/auctions/components/bid-detail-fields.js +103 -0
- package/dist/features/auctions/repository/bid.repository.d.ts +13 -0
- package/dist/features/auctions/repository/bid.repository.js +23 -0
- package/dist/features/auctions/schemas/firestore.d.ts +17 -0
- package/dist/features/auctions/schemas/index.d.ts +12 -12
- package/dist/features/audit-log/schemas/firestore.d.ts +14 -0
- package/dist/features/audit-log/schemas/firestore.js +7 -0
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +10 -1
- package/dist/features/blog/actions/blog-actions.d.ts +7 -7
- package/dist/features/blog/schemas/blog-form.d.ts +80 -0
- package/dist/features/blog/schemas/blog-form.js +100 -0
- package/dist/features/blog/schemas/index.d.ts +6 -6
- package/dist/features/cart/repository/cart.repository.js +1 -0
- package/dist/features/cart/schemas/firestore.d.ts +15 -0
- package/dist/features/catalogue/schemas/validation.d.ts +4 -4
- package/dist/features/categories/components/BrandDetailPageView.js +23 -40
- package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -7
- package/dist/features/categories/components/BrandDetailTabs.js +8 -12
- package/dist/features/categories/components/BundleCollage.js +1 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +53 -57
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +10 -8
- package/dist/features/categories/components/CategoryDetailTabs.js +11 -16
- package/dist/features/categories/components/CategoryProductsListing.js +11 -1
- package/dist/features/categories/components/ConcernCard.js +7 -1
- package/dist/features/categories/schemas/firestore.d.ts +13 -0
- package/dist/features/categories/schemas/index.d.ts +26 -26
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +16 -1
- package/dist/features/classified/components/ClassifiedDetailPageView.js +23 -3
- package/dist/features/events/components/AdminEventEditorView.js +32 -54
- package/dist/features/events/components/AdminEventEntriesView.js +22 -3
- package/dist/features/events/components/AdminEventsView.js +15 -11
- package/dist/features/events/components/EventFilters.d.ts +9 -1
- package/dist/features/events/components/EventFilters.js +45 -21
- package/dist/features/events/components/EventsIndexListing.d.ts +6 -1
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/components/EventsListPageView.js +13 -4
- package/dist/features/events/repository/events.repository.d.ts +17 -0
- package/dist/features/events/repository/events.repository.js +27 -0
- package/dist/features/events/schemas/event-form.d.ts +113 -0
- package/dist/features/events/schemas/event-form.js +82 -0
- package/dist/features/events/schemas/firestore.d.ts +12 -0
- package/dist/features/events/schemas/firestore.js +12 -0
- package/dist/features/events/schemas/index.d.ts +50 -50
- package/dist/features/events/types/index.d.ts +11 -0
- package/dist/features/events/types/index.js +57 -1
- package/dist/features/faq/actions/faq-actions.d.ts +12 -12
- package/dist/features/faq/schemas/index.d.ts +8 -8
- package/dist/features/filters/FilterFacetSection.d.ts +7 -1
- package/dist/features/filters/FilterFacetSection.js +11 -3
- package/dist/features/grouped/schemas/grouped-listing-form.d.ts +101 -0
- package/dist/features/grouped/schemas/grouped-listing-form.js +89 -0
- package/dist/features/grouped/schemas/index.d.ts +4 -4
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +11 -3
- package/dist/features/homepage/actions/homepage-section-actions.js +33 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +7 -1
- package/dist/features/homepage/components/AnnouncementBar.js +3 -3
- package/dist/features/homepage/components/MarketplaceHomepageView.js +20 -6
- package/dist/features/homepage/hooks/homepage-query.d.ts +16 -0
- package/dist/features/homepage/hooks/homepage-query.js +45 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +10 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.js +28 -8
- package/dist/features/homepage/hooks/useFeaturedPreOrders.js +17 -8
- package/dist/features/homepage/hooks/useFeaturedProducts.js +15 -8
- package/dist/features/homepage/schemas/index.d.ts +33 -2
- package/dist/features/homepage/schemas/index.js +24 -0
- package/dist/features/layout/AppLayoutShell.d.ts +11 -1
- package/dist/features/layout/AppLayoutShell.js +15 -14
- package/dist/features/layout/BackToTop.d.ts +9 -0
- package/dist/features/layout/BackToTop.js +10 -1
- package/dist/features/layout/BottomActions.js +28 -25
- package/dist/features/layout/BottomChrome.d.ts +34 -0
- package/dist/features/layout/BottomChrome.js +55 -0
- package/dist/features/layout/BottomNavLayout.d.ts +6 -0
- package/dist/features/layout/BottomNavLayout.js +7 -1
- package/dist/features/layout/BottomNavbar.js +15 -2
- package/dist/features/layout/FooterLayout.js +11 -1
- package/dist/features/layout/NavbarLayout.js +1 -1
- package/dist/features/layout/TitleBarLayout.d.ts +7 -0
- package/dist/features/layout/TitleBarLayout.js +28 -5
- package/dist/features/layout/index.d.ts +2 -0
- package/dist/features/layout/index.js +1 -0
- package/dist/features/lottery/types/index.d.ts +3 -0
- package/dist/features/media/MediaPickerModal.js +5 -1
- package/dist/features/messages/schemas/index.d.ts +2 -2
- package/dist/features/orders/components/OrderScopeTabs.d.ts +20 -0
- package/dist/features/orders/components/OrderScopeTabs.js +31 -0
- package/dist/features/orders/components/OrderStatusTimeline.d.ts +5 -1
- package/dist/features/orders/components/OrderStatusTimeline.js +39 -20
- package/dist/features/orders/constants/order-scope.d.ts +48 -0
- package/dist/features/orders/constants/order-scope.js +111 -0
- package/dist/features/orders/repository/orders.repository.d.ts +54 -7
- package/dist/features/orders/repository/orders.repository.js +121 -22
- package/dist/features/orders/schemas/firestore.d.ts +152 -0
- package/dist/features/orders/schemas/firestore.js +30 -0
- package/dist/features/orders/schemas/index.d.ts +18 -18
- package/dist/features/orders/types/index.d.ts +35 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +14 -9
- package/dist/features/pre-orders/components/PreOrdersListView.js +6 -5
- package/dist/features/pre-orders/schemas/index.d.ts +1 -1
- package/dist/features/products/actions/product-actions.d.ts +14 -0
- package/dist/features/products/actions/product-actions.js +49 -11
- package/dist/features/products/api/route.d.ts +12 -0
- package/dist/features/products/api/route.js +42 -100
- package/dist/features/products/components/ArtStickersListView.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +13 -11
- package/dist/features/products/components/AvailabilityTabs.d.ts +11 -0
- package/dist/features/products/components/AvailabilityTabs.js +47 -0
- package/dist/features/products/components/GroupSettingsPanel.js +5 -1
- package/dist/features/products/components/MakeOfferButton.js +48 -49
- package/dist/features/products/components/PrizeDrawCollage.d.ts +20 -4
- package/dist/features/products/components/PrizeDrawCollage.js +9 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +14 -12
- package/dist/features/products/components/PrizeDrawsListingView.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.d.ts +7 -1
- package/dist/features/products/components/PrizeDrawsSection.js +23 -18
- package/dist/features/products/components/ProductDetailPageView.d.ts +4 -1
- package/dist/features/products/components/ProductDetailPageView.js +18 -4
- package/dist/features/products/components/ProductForm.js +5 -2
- package/dist/features/products/components/ProductGrid.js +6 -1
- package/dist/features/products/components/ProductsIndexListing.js +22 -32
- package/dist/features/products/components/ProductsIndexPageView.js +6 -9
- package/dist/features/products/components/index.d.ts +2 -2
- package/dist/features/products/components/index.js +1 -1
- package/dist/features/products/config/listing-type-listing-config.d.ts +20 -0
- package/dist/features/products/config/listing-type-listing-config.js +22 -10
- package/dist/features/products/constants/action-defs.d.ts +2 -0
- package/dist/features/products/constants/action-defs.js +6 -0
- package/dist/features/products/hooks/useAvailabilityScope.d.ts +13 -0
- package/dist/features/products/hooks/useAvailabilityScope.js +19 -0
- package/dist/features/products/hooks/useProducts.d.ts +5 -0
- package/dist/features/products/hooks/useProducts.js +13 -2
- package/dist/features/products/repository/products.repository.d.ts +31 -2
- package/dist/features/products/repository/products.repository.js +53 -21
- package/dist/features/products/schemas/firestore.d.ts +17 -3
- package/dist/features/products/schemas/firestore.js +7 -2
- package/dist/features/products/schemas/index.d.ts +64 -64
- package/dist/features/products/schemas/product-features.validators.d.ts +79 -6
- package/dist/features/products/schemas/product-features.validators.js +63 -0
- package/dist/features/products/types/index.d.ts +16 -1
- package/dist/features/promotions/schemas/index.d.ts +2 -2
- package/dist/features/reviews/schemas/index.d.ts +16 -16
- package/dist/features/scams/constants/scammer-status-display.d.ts +28 -0
- package/dist/features/scams/constants/scammer-status-display.js +79 -0
- package/dist/features/search/schemas/index.d.ts +4 -4
- package/dist/features/seller/actions/offer-actions.js +57 -4
- package/dist/features/seller/components/OfferPhaseTimeline.d.ts +59 -0
- package/dist/features/seller/components/OfferPhaseTimeline.js +107 -0
- package/dist/features/seller/components/SellerArtView.js +5 -0
- package/dist/features/seller/components/SellerAuctionsView.js +13 -15
- package/dist/features/seller/components/SellerBidsView.js +11 -4
- package/dist/features/seller/components/SellerClassifiedView.js +5 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +17 -17
- package/dist/features/seller/components/SellerDigitalCodesView.js +5 -0
- package/dist/features/seller/components/SellerLiveView.js +5 -0
- package/dist/features/seller/components/SellerOffersView.js +2 -1
- package/dist/features/seller/components/SellerOrdersView.js +31 -9
- package/dist/features/seller/components/SellerPayoutSettingsView.js +56 -31
- package/dist/features/seller/components/SellerPreOrdersView.js +5 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.js +14 -16
- package/dist/features/seller/components/SellerProductShell.js +7 -1
- package/dist/features/seller/components/SellerProductsView.js +11 -8
- package/dist/features/seller/components/SellerStickersView.js +5 -0
- package/dist/features/seller/components/index.d.ts +0 -2
- package/dist/features/seller/components/index.js +0 -1
- package/dist/features/seller/repository/offer.repository.d.ts +142 -24
- package/dist/features/seller/repository/offer.repository.js +165 -26
- package/dist/features/seller/schemas/coupon-form.d.ts +72 -0
- package/dist/features/seller/schemas/coupon-form.js +116 -0
- package/dist/features/seller/schemas/firestore.d.ts +56 -2
- package/dist/features/seller/schemas/firestore.js +27 -0
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/seller/schemas/offer-forms.d.ts +46 -0
- package/dist/features/seller/schemas/offer-forms.js +42 -0
- package/dist/features/seller/server.d.ts +0 -1
- package/dist/features/seller/server.js +0 -1
- package/dist/features/shell/SectionForm.d.ts +99 -0
- package/dist/features/shell/SectionForm.js +128 -0
- package/dist/features/shell/build-sections.d.ts +63 -0
- package/dist/features/shell/build-sections.js +207 -0
- package/dist/features/shell/entity-form.d.ts +109 -0
- package/dist/features/shell/entity-form.js +96 -0
- package/dist/features/shell/field-ui-meta.d.ts +115 -0
- package/dist/features/shell/field-ui-meta.js +324 -0
- package/dist/features/shell/index.d.ts +8 -0
- package/dist/features/shell/index.js +4 -0
- package/dist/features/status-history/components/StatusTimeline.d.ts +74 -0
- package/dist/features/status-history/components/StatusTimeline.js +46 -0
- package/dist/features/status-history/index.d.ts +11 -0
- package/dist/features/status-history/index.js +10 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.d.ts +27 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.js +82 -0
- package/dist/features/store-extensions/index.d.ts +12 -0
- package/dist/features/store-extensions/index.js +12 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +36 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.js +114 -0
- package/dist/features/store-extensions/schemas/analytics-forms.d.ts +57 -0
- package/dist/features/store-extensions/schemas/analytics-forms.js +158 -0
- package/dist/features/store-extensions/schemas/custom-role-form.d.ts +85 -0
- package/dist/features/store-extensions/schemas/custom-role-form.js +118 -0
- package/dist/features/store-extensions/schemas/firestore.d.ts +21 -1
- package/dist/features/store-extensions/schemas/firestore.js +60 -0
- package/dist/features/store-extensions/schemas/google-config-form.d.ts +53 -0
- package/dist/features/store-extensions/schemas/google-config-form.js +105 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +28 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.js +80 -0
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +78 -0
- package/dist/features/store-extensions/schemas/listing-template-form.js +87 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.d.ts +49 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.js +101 -0
- package/dist/features/store-extensions/schemas/payout-method-form.d.ts +153 -0
- package/dist/features/store-extensions/schemas/payout-method-form.js +155 -0
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +25 -0
- package/dist/features/store-extensions/schemas/report-create-form.js +79 -0
- package/dist/features/store-extensions/schemas/report-review-form.d.ts +47 -0
- package/dist/features/store-extensions/schemas/report-review-form.js +111 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +148 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.js +104 -0
- package/dist/features/store-extensions/schemas/store-category-form.d.ts +54 -0
- package/dist/features/store-extensions/schemas/store-category-form.js +73 -0
- package/dist/features/stores/api/[storeSlug]/route.js +2 -25
- package/dist/features/stores/components/StoreAuctionsListing.js +15 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +12 -2
- package/dist/features/stores/components/StoreDetailLayoutView.js +24 -71
- package/dist/features/stores/components/StoreDigitalCodesListing.js +12 -2
- package/dist/features/stores/components/StoreLiveItemsListing.js +12 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +12 -1
- package/dist/features/stores/components/StoreProductsListing.js +11 -1
- package/dist/features/stores/repository/store.repository.js +6 -0
- package/dist/features/stores/schemas/index.d.ts +6 -6
- package/dist/features/support/schemas/index.d.ts +4 -4
- package/dist/features/tester/actions/checklist-item-actions.d.ts +4 -4
- package/dist/features/tester/seed-data/offers-tester-seed-data.js +119 -3
- package/dist/features/tester/seed-data/products-tester-seed-data.js +131 -1
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +431 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +25 -12
- package/dist/index.js +26 -11
- package/dist/next/routing/route-map.d.ts +23 -3
- package/dist/next/routing/route-map.js +14 -2
- package/dist/providers/db-firebase/base.repository.d.ts +30 -0
- package/dist/providers/db-firebase/base.repository.js +50 -1
- package/dist/providers/db-firebase/index.d.ts +1 -1
- package/dist/providers/db-firebase/index.js +1 -1
- package/dist/providers/db-firebase/sieve.d.ts +25 -0
- package/dist/providers/db-firebase/sieve.js +52 -18
- package/dist/react/hooks/useUrlTable.js +10 -1
- package/dist/schemas/firestore-value.d.ts +8 -0
- package/dist/schemas/firestore-value.js +44 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/registry.d.ts +702 -69
- package/dist/schemas/registry.js +64 -1
- package/dist/seed/_helpers/category-forest.d.ts +2 -0
- package/dist/seed/_helpers/category-forest.js +309 -0
- package/dist/seed/_helpers/category-tree.d.ts +27 -0
- package/dist/seed/_helpers/category-tree.js +103 -0
- package/dist/seed/bids-seed-data.js +30 -0
- package/dist/seed/catalogue-seed-data.js +12 -12
- package/dist/seed/categories-seed-data.js +177 -162
- package/dist/seed/events-seed-data.js +61 -10
- package/dist/seed/homepage-sections-seed-data.js +5 -1
- package/dist/seed/offers-seed-data.js +244 -34
- package/dist/seed/orders-seed-data.js +336 -1
- package/dist/seed/products-art-seed-data.js +50 -12
- package/dist/seed/products-auctions-seed-data.js +138 -18
- package/dist/seed/products-classifieds-seed-data.js +80 -16
- package/dist/seed/products-digital-codes-seed-data.js +66 -18
- package/dist/seed/products-live-items-seed-data.js +64 -13
- package/dist/seed/products-preorders-seed-data.d.ts +0 -1
- package/dist/seed/products-preorders-seed-data.js +52 -13
- package/dist/seed/products-prize-draws-seed-data.js +63 -14
- package/dist/seed/products-standard-seed-data.js +99 -26
- package/dist/seed/products-stickers-seed-data.js +47 -12
- package/dist/seed/reviews-seed-data.js +6 -1
- package/dist/seed/site-settings-seed-data.d.ts +1 -38
- package/dist/seed/site-settings-seed-data.js +38 -76
- package/dist/seed/stores-seed-data.js +71 -1
- package/dist/seed/users-seed-data.js +15 -5
- package/dist/server-entry.d.ts +1 -2
- package/dist/server-entry.js +4 -3
- package/dist/server.d.ts +6 -3
- package/dist/server.js +13 -4
- package/dist/styles.css +78 -12
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Button.style.css +19 -4
- package/dist/ui/components/CollapsibleSection.d.ts +17 -1
- package/dist/ui/components/CollapsibleSection.js +6 -2
- package/dist/ui/components/FilterChipGroup.d.ts +25 -1
- package/dist/ui/components/FilterChipGroup.js +21 -4
- package/dist/ui/components/HandMode.style.css +47 -0
- package/dist/ui/components/Layout.d.ts +9 -2
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/ListingLayout.js +8 -8
- package/dist/ui/components/ListingLayout.style.css +8 -7
- package/dist/ui/components/RecordDetailModal.d.ts +10 -1
- package/dist/ui/components/RecordDetailModal.js +2 -2
- package/dist/ui/components/StickyToolbar.d.ts +3 -1
- package/dist/ui/components/StickyToolbar.js +62 -20
- package/dist/ui/components/bottom-chrome-slot.d.ts +21 -0
- package/dist/ui/components/bottom-chrome-slot.js +29 -0
- package/dist/ui/components/index.style.css +3 -0
- package/dist/ui/forms/FormShell.d.ts +43 -13
- package/dist/ui/forms/FormShell.js +22 -11
- package/dist/ui/forms/index.d.ts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +2 -1
- package/scripts/node-esm-loader.mjs +65 -0
- package/scripts/seed-cli-loader.mjs +6 -49
- package/scripts/seed-cli.mjs +1 -1
|
@@ -400,6 +400,53 @@ const rawTesterChecklistItems = [
|
|
|
400
400
|
},
|
|
401
401
|
],
|
|
402
402
|
},
|
|
403
|
+
{
|
|
404
|
+
// Root Cause #68, part 2. Every case here is a LAYOUT assertion — an image
|
|
405
|
+
// that renders at 0x0, or a tile that lays out sideways, is invisible to
|
|
406
|
+
// tsc, to lint and to jsdom, so a human eye is the only gate that catches
|
|
407
|
+
// a regression. Bundle tiles rendered blank for weeks before this.
|
|
408
|
+
pageKey: "image-tile-layout",
|
|
409
|
+
pageLabel: "Image Tiles & Collages",
|
|
410
|
+
href: "/bundles/bundle-burst-battlers-pack",
|
|
411
|
+
cases: [
|
|
412
|
+
{
|
|
413
|
+
key: "bundle-member-thumbnails",
|
|
414
|
+
label: "A bundle's member tiles show the real product photo, filling the whole square tile — not a blank/grey box",
|
|
415
|
+
description: "The three members of \"Burst Battlers Pack\" each have a mainImage. If you see grey boxes, the image collapsed to 0x0 — check whether a `block`/`flex`/`hidden` Tailwind class has been added back onto the tile's <Button>, which silently overrides appkit's own display and voids the fix.",
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
key: "bundle-badge-position",
|
|
419
|
+
label: "The #1 / #2 / #3 badge sits at the TOP-LEFT corner of each bundle tile, not floating in the middle of it",
|
|
420
|
+
description: "The badge is absolutely positioned. If it drifts toward the centre, it is anchoring to the button's collapsed inner span instead of the tile box — the same root cause as a blank thumbnail, and often the first visible symptom.",
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
key: "bundle-tile-opens-lightbox",
|
|
424
|
+
label: "Clicking a bundle tile opens the lightbox at that item and cycles through the others; the product title below the tile still links to the product page",
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
key: "prizedraw-collage-stacked",
|
|
428
|
+
label: "Prize-draw collage tiles stack the image ABOVE the title/value caption at full card width — the image is never squashed beside the text at half width",
|
|
429
|
+
href: "/prize-draws/prizedraw-tester-sandbox-1",
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
key: "concern-card-icon-above-label",
|
|
433
|
+
label: "Category concern cards show their icon ABOVE the label, not beside it",
|
|
434
|
+
description: "This is a deliberate visual change: the card always asked for a vertical layout but had been rendering side-by-side. Confirm the stacked layout looks right rather than assuming the old side-by-side was intended.",
|
|
435
|
+
href: "/categories",
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
key: "media-picker-existing-grid",
|
|
439
|
+
label: "In any media field, \"Choose existing\" shows each file as a square thumbnail with the filename underneath — not thumbnail-beside-filename with a shrunken image",
|
|
440
|
+
href: "/admin/media",
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
key: "icon-button-spacing",
|
|
444
|
+
label: "Buttons that combine an icon and a label still have normal spacing between them, and a loading button's spinner stays centred against its text",
|
|
445
|
+
description: "Regression check for the shared Button change that fixed the tiles — it altered how the button's own alignment reaches its children, so spot-check a few ordinary buttons anywhere in the app.",
|
|
446
|
+
href: "/products",
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
},
|
|
403
450
|
{
|
|
404
451
|
pageKey: "buying-checkout",
|
|
405
452
|
pageLabel: "Buying & Checkout",
|
|
@@ -1069,6 +1116,236 @@ const rawTesterChecklistItems = [
|
|
|
1069
1116
|
label: "An accepted offer past its 48-hour checkout window can no longer be checked out, and is cleared from the cart with a notification to the buyer",
|
|
1070
1117
|
description: "Background/low-priority — requires waiting out the window or adjusting the fixture's checkoutDeadline.",
|
|
1071
1118
|
},
|
|
1119
|
+
{
|
|
1120
|
+
key: "nav-item-invalid-href-inline",
|
|
1121
|
+
label: "A nav item with a bad destination is refused on the FIELD, not by a banner",
|
|
1122
|
+
description: "The routes always validated nav items; the form did not, so an invalid href came back as a 400 after a round-trip. Enter \"products\" (no leading slash) and confirm the error appears under the Destination field.",
|
|
1123
|
+
href: "/admin/navigation",
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
key: "homepage-section-invalid-config-inline",
|
|
1127
|
+
label: "A homepage section with malformed config JSON, or a negative order, is refused inline",
|
|
1128
|
+
description: "Same shape: the route validated, the form did not. Paste broken JSON into Config, and separately set Order to -1 — each should report on its own field.",
|
|
1129
|
+
href: "/admin/sections",
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
key: "classified-keeps-meetup-city",
|
|
1133
|
+
label: "A classified listing still has its meetup city after saving",
|
|
1134
|
+
description: "Regression test for CONFIRMED silent data loss found 2026-08-24: the product create schema stripped every key it did not name, and it named NONE of the classified / digital-code / live-item / prize-draw fields. A seller filled them in, pressed Publish, saw a success — and the fields were dropped before the write. Create a classified with a meetup city and contact method, save, then reopen it: both must still be there.",
|
|
1135
|
+
href: "/store/classified/new",
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
key: "live-item-keeps-species-and-cites",
|
|
1139
|
+
label: "A live-item listing keeps its species, transport method, permitted jurisdictions and CITES reference",
|
|
1140
|
+
description: "Same bug. Jurisdiction is the one that matters most — shipping a live animal into a territory that forbids it is exactly what that field exists to prevent, and it was being discarded.",
|
|
1141
|
+
href: "/store/live/new",
|
|
1142
|
+
},
|
|
1143
|
+
{
|
|
1144
|
+
key: "digital-code-keeps-delivery-method",
|
|
1145
|
+
label: "A digital-code listing keeps its delivery method and pool size",
|
|
1146
|
+
href: "/store/digital-codes/new",
|
|
1147
|
+
},
|
|
1148
|
+
{
|
|
1149
|
+
key: "prize-draw-keeps-entry-price",
|
|
1150
|
+
label: "A prize draw keeps its price per entry and maximum entries",
|
|
1151
|
+
href: "/store/prize-draws/new",
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
key: "per-type-fields-survive-EDIT-too",
|
|
1155
|
+
label: "Editing a classified's TITLE does not wipe its meetup city",
|
|
1156
|
+
description: "The fix had to cover the update path as well as create — a create-only fix would mean the listing saved correctly and then lost its per-type block the first time anyone edited anything else (Root Cause #39).",
|
|
1157
|
+
href: "/store/classified",
|
|
1158
|
+
},
|
|
1159
|
+
{
|
|
1160
|
+
key: "address-routes-normalised",
|
|
1161
|
+
label: "Adding and editing an address works, and the OLD urls still resolve",
|
|
1162
|
+
description: "/user/addresses/add and /user/addresses/edit/[id] were the only two non-standard route shapes in the app; every other entity uses /new and /[id]/edit. Both old paths are kept as redirects, so a bookmark still works. Check the buttons on the addresses page, then visit /user/addresses/add directly and confirm it lands on /user/addresses/new.",
|
|
1163
|
+
href: "/user/addresses",
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
key: "custom-role-rejects-fake-permissions",
|
|
1167
|
+
label: "A custom role cannot be saved with a permission this system does not define",
|
|
1168
|
+
description: "Regression test for a real gap found 2026-08-24: both the create and update routes spread the raw request body into Firestore with NO validation, and neither page had a schema. Enter \"admin:widgets:frobnicate\" in the permissions box — it should be refused and NAMED. A permission outside the catalogue never matches anything, so the role would have read as configured and granted nothing.",
|
|
1169
|
+
href: "/admin/roles/new",
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
key: "custom-role-edit-does-not-rewrite-creator",
|
|
1173
|
+
label: "Editing a role does not change who created it",
|
|
1174
|
+
description: "The edit page used to PATCH the whole loaded document — id, createdAt, createdBy and slug included — so any save re-attributed the privilege grant and could change the role's stable identifier. Edit a role, save, and confirm its creator and slug are unchanged.",
|
|
1175
|
+
href: "/admin/roles",
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
key: "custom-role-rejects-empty",
|
|
1179
|
+
label: "A role with no name cannot be created",
|
|
1180
|
+
href: "/admin/roles/new",
|
|
1181
|
+
},
|
|
1182
|
+
{
|
|
1183
|
+
key: "bid-row-opens-in-all-three-portals",
|
|
1184
|
+
label: "A bid can be OPENED, not just seen — as a buyer, as a seller, and as an admin",
|
|
1185
|
+
description: "All three bid listings were dead ends: a row could be seen and never opened, so the amount, auction, timing and outcome existed only as a table row. Open one from /user/bids, /store/bids and /admin/bids and confirm each shows the auction, amount, when it was placed and its status.",
|
|
1186
|
+
href: "/user/bids",
|
|
1187
|
+
},
|
|
1188
|
+
{
|
|
1189
|
+
key: "bid-detail-hides-bidder-from-buyer",
|
|
1190
|
+
label: "A buyer's own bid detail does NOT show a bidder name; the seller and admin views DO",
|
|
1191
|
+
description: "One shared field builder serves all three portals, gated on the viewer's role — so a copy-paste cannot start showing one buyer another's identity.",
|
|
1192
|
+
href: "/user/bids",
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
key: "admin-bid-view-before-cancel",
|
|
1196
|
+
label: "The admin bid row menu offers View before Cancel",
|
|
1197
|
+
description: "It previously offered ONLY Cancel — a destructive action on a record the admin had never been able to read. A menu of pure mutations is not a detail affordance (Root Cause #56).",
|
|
1198
|
+
href: "/admin/bids",
|
|
1199
|
+
},
|
|
1200
|
+
{
|
|
1201
|
+
key: "bid-row-keyboard-reachable",
|
|
1202
|
+
label: "A bid row can be opened with the keyboard, and public bid history rows still cannot",
|
|
1203
|
+
description: "Rows are only focusable when they are actually interactive. On an auction's PUBLIC bid history the same table renders with no row handler, so those rows must not be tab stops.",
|
|
1204
|
+
href: "/user/bids",
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
key: "listing-template-edit-page-works",
|
|
1208
|
+
label: "Editing a listing template loads, saves and deletes — the page is not a 404",
|
|
1209
|
+
description: "Regression test for a real bug found 2026-08-24: /api/store/listing-templates/[id] did not exist, while the constant, the edit page's three calls (GET on load, PATCH on save, DELETE) and the list page's Edit button all did. Clicking Edit gave a page that 404'd on load, on save and on delete. Open a template from the list, change its name, save, reopen.",
|
|
1210
|
+
href: "/store/listing-templates",
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
key: "listing-template-not-editable-across-stores",
|
|
1214
|
+
label: "One seller cannot open another seller's listing template by URL",
|
|
1215
|
+
description: "The new route checks the template's storeId against the caller's own store and returns \"not found\" (deliberately not \"forbidden\", which would confirm the id exists).",
|
|
1216
|
+
href: "/store/listing-templates",
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
key: "payout-method-rejects-blank-bank-details",
|
|
1220
|
+
label: "A BANK payout method cannot be saved with a blank account number, IFSC or holder name",
|
|
1221
|
+
description: "This was validated at ZERO layers: the fields were bare inputs with no `required` and no pattern, the page's onSave checked nothing, and both the POST and PATCH routes wrote the raw request body straight into Firestore. An empty bank payout method saved cleanly and only failed at payout time. Select Bank account, leave the fields blank, save — each should be refused on the field itself.",
|
|
1222
|
+
href: "/store/payout-methods/new",
|
|
1223
|
+
},
|
|
1224
|
+
{
|
|
1225
|
+
key: "payout-method-rejects-bad-ifsc",
|
|
1226
|
+
label: "An IFSC code of the wrong shape is refused",
|
|
1227
|
+
description: "Enter \"ABC123\" as the IFSC. It should be refused inline with the expected format, matching the rule Payout Settings already enforces. Then check a UPI method rejects a VPA with no @.",
|
|
1228
|
+
href: "/store/payout-methods/new",
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
key: "shipping-config-rejects-rateless-rule",
|
|
1232
|
+
label: "A \"flat\" shipping rule with no flat rate is refused, and a negative rate is refused",
|
|
1233
|
+
description: "Both the page and the route used to accept anything — the route spread the raw body into Firestore, so a rate of \"abc\" or a negative free-above threshold was persisted verbatim.",
|
|
1234
|
+
href: "/store/shipping-configs/new",
|
|
1235
|
+
},
|
|
1236
|
+
{
|
|
1237
|
+
key: "grouped-listing-count-not-caller-settable",
|
|
1238
|
+
label: "A grouped listing's member count always matches its member list",
|
|
1239
|
+
description: "activeMemberCount is derived from productIds.length by the route and is no longer accepted from the request body — it is what the public visibility check reads, so a caller-supplied count could have hidden or shown a group incorrectly.",
|
|
1240
|
+
href: "/store/grouped-listings",
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
key: "store-feature-new-actually-creates",
|
|
1244
|
+
label: "Creating a store feature badge from /store/features/new actually creates it",
|
|
1245
|
+
description: "Regression test for a real bug found 2026-08-24: that page collected a single Label, validated it was non-empty, then navigated back to the list WITHOUT calling any API — the badge was silently discarded and the seller saw a normal success flow. It now renders the real editor, so all ten fields are present and the badge appears in the list afterwards.",
|
|
1246
|
+
href: "/store/features/new",
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
key: "store-feature-edit-page-exists",
|
|
1250
|
+
label: "A store feature badge can be edited on its own page, not only in a drawer",
|
|
1251
|
+
description: "ROUTES.STORE.FEATURES_EDIT pointed at /store/features/[id]/edit with no page behind it and no caller anywhere — a dead route key. Open a badge's edit page directly by URL and confirm it loads with the badge's current values.",
|
|
1252
|
+
href: "/store/features",
|
|
1253
|
+
},
|
|
1254
|
+
{
|
|
1255
|
+
key: "feature-editor-validates",
|
|
1256
|
+
label: "The feature badge editor reports what is wrong instead of just disabling Save",
|
|
1257
|
+
description: "It had NO validation: ten fields, `required` on the inputs (an HTML attribute a programmatic submit bypasses), and nothing else — max lengths, display-order bounds and the product-types minimum were never checked. Submit with an over-long label, or a store-scoped badge with no store selected, and confirm the error appears on the field itself.",
|
|
1258
|
+
href: "/admin/features/new",
|
|
1259
|
+
},
|
|
1260
|
+
{
|
|
1261
|
+
key: "store-category-rejects-empty",
|
|
1262
|
+
label: "A storefront category with no label cannot be created",
|
|
1263
|
+
description: "Both the form AND the route used to accept anything — the page had raw inputs with no validation and the API spread the request body straight into Firestore, so a completely empty category could be saved. They now share one schema. Confirm an empty Label is refused inline, not by a generic \"Save failed\" toast.",
|
|
1264
|
+
href: "/store/categories/new",
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
key: "blog-editor-sections-not-steps",
|
|
1268
|
+
label: "The blog editor shows every field at once in collapsible sections — not a 4-step wizard that blocks step 2",
|
|
1269
|
+
description: "Open any post. Content / Media / SEO & Tags / Publish should all be reachable immediately, with ONE Save button at the bottom. Previously a missing title blocked access to every later step, so a post could become uneditable because of a field on page 1.",
|
|
1270
|
+
href: "/admin/blog",
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
key: "blog-existing-post-slug-is-valid",
|
|
1274
|
+
label: "Opening an EXISTING blog post shows no error on the Slug field",
|
|
1275
|
+
description: "Regression test for a real bug found 2026-08-24: the form required slugs to start with `blog-`, but all 20 stored posts hold the bare slug (the `blog-` prefix is on the document ID, not the slug field, and the public URL uses the bare form). Every existing post therefore opened with an invalid Slug, and correcting it to satisfy the rule would have changed the stored slug and 404'd the live URL.",
|
|
1276
|
+
href: "/admin/blog",
|
|
1277
|
+
},
|
|
1278
|
+
{
|
|
1279
|
+
key: "blog-new-post-url-matches-existing",
|
|
1280
|
+
label: "A newly created post's public URL has the same shape as an existing post's — no doubled `blog-` segment",
|
|
1281
|
+
description: "Create a post titled \"Test Slug Shape\", save, then open it publicly. The URL should read /blog/test-slug-shape, matching every seeded post.",
|
|
1282
|
+
href: "/admin/blog/new",
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
key: "blog-readtime-updates-on-edit",
|
|
1286
|
+
label: "Editing a post's body updates its \"N min read\" estimate",
|
|
1287
|
+
description: "It used to be computed on create only, so the estimate froze at whatever the first draft was (Root Cause #39 — a CREATE transform with no UPDATE counterpart). Add several paragraphs to an existing post, save, and confirm the read time grows.",
|
|
1288
|
+
href: "/admin/blog",
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
key: "blog-error-summary-jumps-to-section",
|
|
1292
|
+
label: "Clearing the title shows an error summary whose link OPENS the right section and focuses the field",
|
|
1293
|
+
description: "The jump was dead before this work — the section list was hardcoded empty in both context paths, so the summary's link resolved to nothing for every form in the app.",
|
|
1294
|
+
href: "/admin/blog",
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
key: "blog-media-survives-collapse",
|
|
1298
|
+
label: "Collapsing the Media section mid-upload does NOT cancel the upload",
|
|
1299
|
+
description: "Collapsible panels unmount their children by default, which discards an in-flight transfer. The Media section is explicitly kept mounted.",
|
|
1300
|
+
href: "/admin/blog",
|
|
1301
|
+
},
|
|
1302
|
+
{
|
|
1303
|
+
key: "event-editor-sections-not-steps",
|
|
1304
|
+
label: "The event editor shows Details / Media / Settings / Raffle as sections, all reachable at once",
|
|
1305
|
+
description: "The old wizard gated Settings behind Details validating, so a missing end date made a poll's options unreachable. Also confirm the per-type rules still surface inline: an Offer event with no coupon, and a Poll with fewer than 2 options, should each show an error on the field itself rather than a step-blocking banner.",
|
|
1306
|
+
href: "/admin/events",
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
key: "offer-history-timeline-renders",
|
|
1310
|
+
label: "An offer shows a timeline of every phase it went through, each stamped with who did it and when",
|
|
1311
|
+
description: "Open any offer on My Offers and expand its history. Offer made / countered / accepted / paid should each appear with a real timestamp and a Buyer or Store tag. Before this existed, an offer showed only its current status — the negotiation that produced it was not merely un-displayed, it was destroyed: each counter created a brand-new unlinked document.",
|
|
1312
|
+
href: "/user/offers",
|
|
1313
|
+
},
|
|
1314
|
+
{
|
|
1315
|
+
key: "offer-history-legacy-no-fabricated-date",
|
|
1316
|
+
label: "An offer with NO recorded history still renders a timeline, and its Expired step shows an em-dash rather than a made-up date",
|
|
1317
|
+
description: "Open the X Wizard Arrow expired offer — it is seeded deliberately without statusHistory, which is the exact shape of every offer written before this feature. Its timeline must still render, and the Expired step must show a dash, not a date. A date there would be fabricated: expireMany never wrote one, updatedAt means \"last write of any kind\", and expiresAt is a deadline rather than an event.",
|
|
1318
|
+
href: "/admin/offers",
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
key: "offer-chain-walks-three-rounds",
|
|
1322
|
+
label: "A three-round negotiation reads as ONE story, oldest first, with rounds 1 and 2 labelled Superseded — never Withdrawn",
|
|
1323
|
+
description: "Open the Metal Storm Pegasus offer in the admin list. All three rounds should appear on one rail under Round 1 / Round 2 / Round 3 dividers, each with its own note. The first two rounds are stored as withdrawn but carry supersededByOfferId, and must read neutral: the buyer did not walk away, they countered. Contrast the Driger V offer, a genuine walk-away, which reads Withdrawn.",
|
|
1324
|
+
href: "/admin/offers",
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
key: "offer-detail-opens-on-fresh-data",
|
|
1328
|
+
label: "Opening an offer row fetches that offer, rather than showing whatever the list last cached",
|
|
1329
|
+
description: "Open an offer, close it, have the seller respond in another session, then reopen the same row — the panel should show the new state without a full page reload, and the chain should be present.",
|
|
1330
|
+
href: "/admin/offers",
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
key: "admin-offer-cancel-requires-reason",
|
|
1334
|
+
label: "Admin Cancel opens a form demanding a reason — a short one is rejected inline, and a valid one reaches the buyer, the audit log AND the offer's own timeline",
|
|
1335
|
+
description: "Cancel an offer as an admin. Type fewer than 10 characters: it must be refused before submitting. Then give a real reason and confirm four things: the offer is cancelled, the buyer's locked cart line is cleared (their whole cart is otherwise blocked by the offer lane), the buyer's notification quotes the reason, and the action appears in both /admin/audit-log and the offer's own timeline. Previously the route accepted a reason and never read it, so the buyer was told nothing.",
|
|
1336
|
+
href: "/admin/offers",
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
key: "admin-cannot-accept-or-counter",
|
|
1340
|
+
label: "The admin row menu offers only View and Cancel — never Accept, Counter or Decline",
|
|
1341
|
+
description: "The store keeps sole authority over its own pricing; admin is a coordinator, and cancel is an escalation that is itself recorded. There should also be no bulk Cancel: one shared reason across a mixed selection is worse audit data than none.",
|
|
1342
|
+
href: "/admin/offers",
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
key: "store-still-accepts",
|
|
1346
|
+
label: "The store can still Accept, Counter and Decline its own offers after the admin surface was added",
|
|
1347
|
+
href: "/store/offers",
|
|
1348
|
+
},
|
|
1072
1349
|
],
|
|
1073
1350
|
},
|
|
1074
1351
|
{
|
|
@@ -1196,6 +1473,42 @@ const rawTesterChecklistItems = [
|
|
|
1196
1473
|
{ key: "my-prize-draws", label: "\"My Prize Draw Entries\" shows accurate entries and outcomes", href: "/user/prize-draws" },
|
|
1197
1474
|
{ key: "my-digital-codes", label: "\"My Digital Codes\" shows purchased codes correctly", href: "/user/digital-codes" },
|
|
1198
1475
|
{ key: "my-offers", label: "\"My Offers\" list shows accurate offer history", href: "/user/offers" },
|
|
1476
|
+
{
|
|
1477
|
+
key: "order-timeline-shows-real-events",
|
|
1478
|
+
label: "An order's timeline shows the transitions that actually happened, each stamped with who made it",
|
|
1479
|
+
description: "Open a delivered order. Placed / confirmed / shipped with its tracking number / delivered should each carry a real timestamp and a Buyer, Store, Admin or System tag. This used to be synthesised from four scalar date fields, so any transition without a dedicated date column — a payment review, a re-upload request — was invisible.",
|
|
1480
|
+
href: "/user/orders",
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
key: "order-partial-refund-in-timeline",
|
|
1484
|
+
label: "A PARTIAL refund appears on the order timeline with its amount and reason",
|
|
1485
|
+
description: "Open the X Knife Shinobi order. A partial refund changes no status field at all, so it can only reach the timeline as an explicit entry — if partial refunds are missing while full ones show, that is the bug.",
|
|
1486
|
+
href: "/user/orders",
|
|
1487
|
+
},
|
|
1488
|
+
{
|
|
1489
|
+
key: "order-auction-won-vs-bought-out",
|
|
1490
|
+
label: "A won auction and a bought-out auction are visibly DIFFERENT on the order, not both just \"auction\"",
|
|
1491
|
+
description: "Compare the Diablo Nemesis order (won at ₹6,200 against a real ladder) with the Spriggan Requiem order (bought out at ₹4,999 while the standing bid was ₹3,100). Both are orderType \"auction\" — only the provenance record separates them. Crucially the buyout must NOT report zero bids: a buyout is itself a real bid, and Buy Now is no longer gated on the auction having no bids.",
|
|
1492
|
+
href: "/user/orders",
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
key: "order-offer-shows-what-was-saved",
|
|
1496
|
+
label: "An order placed from an accepted offer shows the offered amount against the asking price at the time",
|
|
1497
|
+
description: "The listing price can change afterwards, which is exactly why it is captured once at order time and never recomputed.",
|
|
1498
|
+
href: "/user/orders",
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
key: "order-history-no-money-churn",
|
|
1502
|
+
label: "The order timeline shows status, payment and refund events only — NOT every coupon or add-on the buyer tried",
|
|
1503
|
+
description: "Deliberate: the final coupon and add-on state already lives on the order. Replaying pricing churn would bury the handful of transitions anyone actually reads.",
|
|
1504
|
+
href: "/user/orders",
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
key: "order-history-carries-no-personal-data",
|
|
1508
|
+
label: "No timeline entry anywhere shows a buyer's name or email — only a role tag",
|
|
1509
|
+
description: "Security-relevant, not cosmetic. PII encryption does not descend into arrays, so a name written into an order or offer history would sit in the database in plain text and never be decrypted on the way out.",
|
|
1510
|
+
href: "/admin/orders",
|
|
1511
|
+
},
|
|
1199
1512
|
{
|
|
1200
1513
|
key: "my-returns",
|
|
1201
1514
|
label: "Requesting and viewing a return works",
|
|
@@ -1651,6 +1964,18 @@ const rawTesterChecklistItems = [
|
|
|
1651
1964
|
cases: [
|
|
1652
1965
|
{ key: "view-event", label: "Viewing an event detail page works", href: "/user/events" },
|
|
1653
1966
|
{ key: "events-listing-cards-images", label: "The events listing page shows each event's real cover image (not a generic icon placeholder) when one is set, and all cards in a row are the same height", href: "/events" },
|
|
1967
|
+
{
|
|
1968
|
+
key: "lottery-cover-image",
|
|
1969
|
+
label: "A lottery's cover image renders on both the lottery listing card and its detail page — not the 🎰 emoji placeholder",
|
|
1970
|
+
description: "Both views used to read a field the data never populates, so every lottery fell back to the emoji. Verify against \"Pokémon Number Draw — July 2026\" (event-pokemon-number-draw-july-2026), which has a real cover image.",
|
|
1971
|
+
href: "/lottery/event-pokemon-number-draw-july-2026",
|
|
1972
|
+
},
|
|
1973
|
+
{
|
|
1974
|
+
key: "lottery-prize-previews",
|
|
1975
|
+
label: "A lottery detail page shows a \"Prizes\" collage of prize photos above the numbered \"Slots\" grid, and the numbered grid itself still shows every slot as a plain number",
|
|
1976
|
+
description: "Only slots that actually have a photo get a collage tile — the seeded fixture has photos on the first 8 of its 25 slots, so expect 8 tiles above a 25-square grid. Claimed slots show a \"Claimed\" stamp. Prices and odds must never appear anywhere on this page.",
|
|
1977
|
+
href: "/lottery/event-pokemon-number-draw-july-2026",
|
|
1978
|
+
},
|
|
1654
1979
|
{
|
|
1655
1980
|
key: "related-events-section",
|
|
1656
1981
|
label: "An event's Overview tab shows a \"Related Events\" carousel of other active events sharing at least one tag, with real events (not empty)",
|
|
@@ -2071,7 +2396,16 @@ const rawTesterChecklistItems = [
|
|
|
2071
2396
|
{ key: "hero-carousel-arrows-flip", label: "With Left-hand mode ON, the homepage hero carousel's Prev/Next arrow pair appears in the bottom-left corner instead of bottom-right; the dots stay centered either way", href: "/" },
|
|
2072
2397
|
{ key: "gallery-arrows-unaffected", label: "Left-hand mode does NOT change a product image gallery/lightbox's Prev/Next arrows — Prev stays on the left edge and Next stays on the right edge in both modes" },
|
|
2073
2398
|
{ key: "homepage-section-buttons-mirror", label: "With Left-hand mode ON, homepage section header rows (e.g. Brands, Featured Bundles, Google Reviews) have their \"View All\" button on the opposite side from default — title and button swap sides", href: "/" },
|
|
2074
|
-
{ key: "
|
|
2399
|
+
{ key: "titlebar-actions-mirror", label: "With Left-hand mode ON, the top bar's action icons (search, Today's Deals, theme toggle, hamburger) move from the right edge to the LEFT edge and their order is mirrored — the hamburger ends up in the far-left corner — while the brand wordmark moves to the right edge; with it OFF (default), everything is the other way round", href: "/" },
|
|
2400
|
+
{ key: "titlebar-centre-mark-unaffected", label: "Left-hand mode does NOT move the centred logo mark in the middle of the desktop top bar — it stays exactly centred in both modes", href: "/" },
|
|
2401
|
+
{ key: "titlebar-row2-mirror", label: "On a phone-width viewport with Left-hand mode ON, the top bar's SECOND row (notifications / wishlist / cart / profile icons) packs against the LEFT edge in mirrored order with profile leftmost; with it OFF it packs against the right edge with notifications leftmost", href: "/" },
|
|
2402
|
+
{ key: "titlebar-actions-no-overflow-narrow", label: "With Left-hand mode ON at the narrowest phone width (~320px), no top-bar icon is clipped or pushed off-screen — the mirrored row fits exactly as well as the default row does", href: "/" },
|
|
2403
|
+
{ key: "bottom-nav-mirror", label: "With Left-hand mode ON, the mobile bottom tab bar's slots appear in reverse order (Profile leftmost, Home rightmost); with it OFF, Home is leftmost. Slot widths stay equal in both modes.", href: "/" },
|
|
2404
|
+
{ key: "dashboard-bottom-nav-mirror", label: "With Left-hand mode ON, the dashboard's own mobile bottom tab bar (on admin/store/user routes) mirrors the same way the public one does — both bars behave identically", href: "/user" },
|
|
2405
|
+
{ key: "count-badges-mirror", label: "With Left-hand mode ON, the red count bubbles on the cart / wishlist / notification icons sit on the TOP-LEFT corner of their icon instead of top-right — in BOTH the top bar and the mobile bottom tab bar — and neither is clipped by the icon's edge", href: "/" },
|
|
2406
|
+
{ key: "nav-scroll-arrows-unaffected", label: "Left-hand mode does NOT flip the main navigation bar's overflow scroll chevrons — the left chevron still scrolls the nav left and the right chevron still scrolls it right, in both modes", href: "/" },
|
|
2407
|
+
{ key: "header-tab-order-sane", label: "With Left-hand mode ON, pressing Tab repeatedly from the top of the page still reaches every top-bar control with none skipped or trapped", description: "The visual left-to-right order will NOT match the tab order in left-hand mode — that is expected and accepted (the mirror is visual only, DOM order is deliberately unchanged so screen-reader reading order stays stable). What must not happen is a control becoming unreachable.", href: "/" },
|
|
2408
|
+
{ key: "hand-mode-no-fouc", label: "On a hard page reload with Left-hand mode already ON, panels/sidebars AND the top bar / bottom tab bar render in their left-hand positions immediately — there is no visible flash of the header icons or tab bar briefly appearing in their default positions before snapping over" },
|
|
2075
2409
|
],
|
|
2076
2410
|
},
|
|
2077
2411
|
{
|
|
@@ -2232,6 +2566,12 @@ const rawTesterChecklistItems = [
|
|
|
2232
2566
|
description: "Updated 2026-08-20 — the founder card previously used a fictional placeholder name with no GitHub link. Confirm the founder card's name matches the real developer and the GitHub link opens their actual profile.",
|
|
2233
2567
|
href: "/about",
|
|
2234
2568
|
},
|
|
2569
|
+
{
|
|
2570
|
+
key: "about-values-expanded",
|
|
2571
|
+
label: "The About page's \"Our Values\" section shows six values, each with a second smaller paragraph, plus a \"How we hold ourselves to this →\" link that opens the Ethics page",
|
|
2572
|
+
description: "Added 2026-08-24 — the section previously had three values, no subtitle, and no onward link. Confirm the subtitle line renders under the heading and the link lands on /ethics.",
|
|
2573
|
+
href: "/about",
|
|
2574
|
+
},
|
|
2235
2575
|
{
|
|
2236
2576
|
key: "developer-page-loads",
|
|
2237
2577
|
label: "The Developer page loads correctly, is linked from the footer's Support column next to About Us, shows the real developer's name, and its \"GitHub ↗\" link opens their actual GitHub profile",
|
|
@@ -2362,7 +2702,37 @@ const rawTesterChecklistItems = [
|
|
|
2362
2702
|
href: "/help",
|
|
2363
2703
|
cases: [
|
|
2364
2704
|
{ key: "shipping-refund-policy", label: "Shipping-policy and refund-policy pages load correctly" },
|
|
2705
|
+
{
|
|
2706
|
+
key: "refund-policy-not-raw-json",
|
|
2707
|
+
label: "The Refund Policy page shows readable policy text — NOT a wall of raw JSON starting with {\"type\":\"doc\"",
|
|
2708
|
+
description: "Fixed 2026-08-24. The seeded siteSettings.legalPages.refundPolicy held a TipTap JSON document, but PolicyPageView injects that field as raw HTML — so the page rendered the JSON source as visible text. The seeded overrides are now empty strings, which makes the page fall back to its proper i18n copy. Re-seed before testing this one.",
|
|
2709
|
+
href: "/refund-policy",
|
|
2710
|
+
},
|
|
2365
2711
|
{ key: "privacy-cookies-security", label: "Privacy, cookies, and security pages load correctly" },
|
|
2712
|
+
{
|
|
2713
|
+
key: "ethics-page-loads",
|
|
2714
|
+
label: "The Our Ethics page loads, and its live-animal section describes vendor verification, a lawful-destination check, CITES paperwork, and specialist transport",
|
|
2715
|
+
description: "Added 2026-08-24. Reachable from the footer under Support, and from the Values section on the About page.",
|
|
2716
|
+
href: "/ethics",
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
key: "code-of-conduct-loads",
|
|
2720
|
+
label: "The Code of Conduct page loads and covers listing honestly, bidding in good faith, review integrity, and the enforcement/appeal ladder",
|
|
2721
|
+
description: "Added 2026-08-24. Reachable from the footer under Legal.",
|
|
2722
|
+
href: "/code-of-conduct",
|
|
2723
|
+
},
|
|
2724
|
+
{
|
|
2725
|
+
key: "policy-related-links-exclude-self",
|
|
2726
|
+
label: "On EVERY policy page, the \"Related Policies\" footer lists the other five policies and never links to the page you are already on",
|
|
2727
|
+
description: "All six pages (Terms, Privacy, Cookies, Refund, Ethics, Code of Conduct) share one renderer whose related-links list is derived from a single registry. Open each and confirm you see exactly five links and that none of them is the current page.",
|
|
2728
|
+
href: "/ethics",
|
|
2729
|
+
},
|
|
2730
|
+
{
|
|
2731
|
+
key: "policy-admin-html-override",
|
|
2732
|
+
label: "As an admin: pasting HTML into Site Settings → Legal → \"Our Ethics\" and saving replaces the default Ethics page content immediately (no waiting)",
|
|
2733
|
+
description: "Added 2026-08-24. Exercises the full chain — admin textarea → legalPages.ethics → PolicyPageView read → cache bust. These pages are cached for an hour, so saving now also revalidates them; if the change only appears after a long wait, the revalidation step regressed. Clear the textarea and save again to restore the default copy.",
|
|
2734
|
+
href: "/admin/site",
|
|
2735
|
+
},
|
|
2366
2736
|
],
|
|
2367
2737
|
},
|
|
2368
2738
|
{
|
|
@@ -2683,6 +3053,66 @@ const rawTesterChecklistItems = [
|
|
|
2683
3053
|
{ key: "support-tickets-triage-admin", label: "Admin can triage support tickets", href: "/admin/support-tickets" },
|
|
2684
3054
|
{ key: "item-requests-admin", label: "Admin can manage item requests", href: "/admin/item-requests" },
|
|
2685
3055
|
{ key: "reports-admin", label: "Admin reports queue works correctly", href: "/admin/reports" },
|
|
3056
|
+
{
|
|
3057
|
+
key: "moderation-reject-requires-reason",
|
|
3058
|
+
label: "Rejecting media in the moderation queue REFUSES an empty reason, with the error shown on the Reason field itself",
|
|
3059
|
+
description: "Fixed 2026-08-24 — all four review surfaces (the queue page's inline Reject and the detail page's Reject, on both moderation and reports) submitted an empty note happily, so media could be blocked with no record of why. Press Reject with the box empty: it must refuse inline, not toast, and not save. Check BOTH /admin/moderation and a single item's detail page — they used to be two separate copies of the same modal.",
|
|
3060
|
+
href: "/admin/moderation",
|
|
3061
|
+
},
|
|
3062
|
+
{
|
|
3063
|
+
key: "moderation-reject-keeps-note-on-failure",
|
|
3064
|
+
label: "If a reject fails to save, the modal STAYS OPEN with the typed reason intact",
|
|
3065
|
+
description: "The modal closed on any outcome before. A decision that did not save must not look like one that did — expect an error toast and the reason still in the box, not a closed modal.",
|
|
3066
|
+
href: "/admin/moderation",
|
|
3067
|
+
},
|
|
3068
|
+
{
|
|
3069
|
+
key: "report-dismiss-asks-why",
|
|
3070
|
+
label: "Dismissing a report ASKS for a reason instead of silently recording the word \"Dismissed\"",
|
|
3071
|
+
description: "Fixed 2026-08-24 — Dismiss used to send a hardcoded resolution of \"Dismissed\", which is the status restated rather than a reason, so a dismissed report carried no explanation for the reporter or the next admin. It now opens the same required-note modal that Action does.",
|
|
3072
|
+
href: "/admin/reports",
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
key: "report-close-stores-a-real-date",
|
|
3076
|
+
label: "Actioning or dismissing a report records a resolved date that renders as a DATE, not as raw text",
|
|
3077
|
+
description: "Fixed 2026-08-24 — both report surfaces sent `resolvedAt: new Date()`, which JSON turns into a string, and the route spread it straight into a field the document declares as a Date. Seeded reports held real timestamps, so the collection carried two shapes for one field. The server stamps it now and the client cannot send it. Close a report, then confirm via the admin detail page that the resolved date is present and well-formed.",
|
|
3078
|
+
href: "/admin/reports",
|
|
3079
|
+
},
|
|
3080
|
+
{
|
|
3081
|
+
key: "report-status-rejects-unknown-values",
|
|
3082
|
+
label: "A report or moderation item cannot be moved to a status outside its real set",
|
|
3083
|
+
description: "Both PATCH routes previously spread the raw request body into Firestore with no schema, so any key and any status string could be written. Confirm the normal Take / Action / Dismiss and Approve / Reject flows still all work — that is what the tightening must not have broken.",
|
|
3084
|
+
href: "/admin/reports",
|
|
3085
|
+
},
|
|
3086
|
+
{
|
|
3087
|
+
key: "homepage-section-all-types-creatable",
|
|
3088
|
+
label: "EVERY section type in the New Section dropdown can actually be created — especially Featured Bundles, Prize Draws, Event Raffles and Collection Cards",
|
|
3089
|
+
description: "Fixed 2026-08-24 — the create route validated `type` against a hand-written list of 21 values while the union (and the dropdown) had 25. Those four types could be chosen, configured in full through their own builders, and then failed with a 400 on Save. Walk the dropdown and create one of each of the four named types.",
|
|
3090
|
+
href: "/admin/sections",
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
key: "analytics-alert-threshold-is-numeric",
|
|
3094
|
+
label: "An analytics alert refuses a non-numeric threshold and a zero/blank time window",
|
|
3095
|
+
description: "Fixed 2026-08-24 — the create route spread the raw body into Firestore, so a threshold typed as text was stored as text and the rule then compared strings (\"9\" > \"10\"). The alert saved, listed, and looked configured while never firing correctly. Confirm a normal numeric alert still saves.",
|
|
3096
|
+
href: "/store/analytics/alerts",
|
|
3097
|
+
},
|
|
3098
|
+
{
|
|
3099
|
+
key: "item-request-requires-title-and-description",
|
|
3100
|
+
label: "An item request cannot be submitted with an empty title or description",
|
|
3101
|
+
description: "Fixed 2026-08-24 — this route spread the raw body into Firestore, and its list GET is PUBLIC (unauthenticated), so an unvalidated write here was an unvalidated publish. Confirm a normal request still submits and appears in the open list.",
|
|
3102
|
+
href: "/item-requests",
|
|
3103
|
+
},
|
|
3104
|
+
{
|
|
3105
|
+
key: "report-submit-requires-detail",
|
|
3106
|
+
label: "Reporting a listing or store refuses an empty description and still files a normal report correctly",
|
|
3107
|
+
description: "Fixed 2026-08-24 — the submit route accepted any body, so a report naming nothing and describing nothing could reach the moderation queue, and a caller could set reviewer-owned fields (`assignedTo`, `resolution`, `resolvedAt`) on their own report.",
|
|
3108
|
+
href: "/admin/reports",
|
|
3109
|
+
},
|
|
3110
|
+
{
|
|
3111
|
+
key: "scammer-removed-badge-readable",
|
|
3112
|
+
label: "A scammer profile with status \"Removed\" shows a readable grey badge in BOTH the list and the detail drawer, in light and dark themes",
|
|
3113
|
+
description: "Fixed 2026-08-24 — two separate copies of the status-colour map both gave `removed` two backgrounds and two inks on the same element. Tailwind emits all four and stylesheet order decides the winner, so the painted colour was not what either map said. Both copies now come from one module. Check the badge reads \"Removed\" (not \"removed\") and is legible in both themes.",
|
|
3114
|
+
href: "/admin/scammers",
|
|
3115
|
+
},
|
|
2686
3116
|
{ key: "payment-methods-clusters-admin", label: "Admin can manage payment methods and payment-method clusters", href: "/admin/payment-methods" },
|
|
2687
3117
|
{ key: "catalogue-approvals-admin", label: "Admin can approve/reject personal catalogue submissions", href: "/admin/catalogue-approvals" },
|
|
2688
3118
|
{
|
|
@@ -29,7 +29,7 @@ export declare function useWishlistWithGuest(userId: string | null | undefined,
|
|
|
29
29
|
productPrice: number;
|
|
30
30
|
productSlug: string;
|
|
31
31
|
addedAt: string | undefined;
|
|
32
|
-
type: "classified" | "auction" | "digital-code" | "live" | "
|
|
32
|
+
type: "classified" | "category" | "auction" | "digital-code" | "live" | "store" | "product" | "preorder";
|
|
33
33
|
}[];
|
|
34
34
|
total: number;
|
|
35
35
|
wishlistedIds: Set<string>;
|