@mohasinac/appkit 4.2.0 → 4.3.1
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/navActive.d.ts +17 -0
- package/dist/_internal/client/features/layout/navActive.js +33 -0
- package/dist/_internal/server/features/auth/actions.d.ts +0 -1
- package/dist/_internal/server/features/auth/actions.js +0 -1
- package/dist/_internal/server/features/bundles/data.d.ts +22 -4
- package/dist/_internal/server/features/bundles/data.js +41 -4
- 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/checkout/actions.js +7 -78
- package/dist/_internal/server/features/checkout/prize-bundle-gates.d.ts +5 -16
- package/dist/_internal/server/features/checkout/prize-bundle-gates.js +5 -30
- package/dist/_internal/server/features/orders/adapters.js +1 -14
- package/dist/_internal/server/features/products/actions.js +8 -3
- package/dist/_internal/server/features/products/service.d.ts +15 -0
- package/dist/_internal/server/features/products/service.js +41 -0
- package/dist/_internal/server/functions/firestore.d.ts +3 -1
- package/dist/_internal/server/functions/firestore.js +17 -1
- package/dist/_internal/server/functions/scheduled.d.ts +2 -5
- package/dist/_internal/server/functions/scheduled.js +6 -30
- package/dist/_internal/server/jobs/core/bundleStockSync.js +25 -7
- package/dist/_internal/server/jobs/core/countersReconcile.js +7 -1
- package/dist/_internal/server/jobs/core/index.d.ts +4 -4
- package/dist/_internal/server/jobs/core/index.js +4 -4
- package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.d.ts +19 -0
- package/dist/_internal/server/jobs/core/onPrizeDrawPaymentConfirmed.js +30 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.d.ts +2 -2
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +2 -2
- package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.d.ts +20 -0
- package/dist/_internal/server/jobs/core/prizeDrawAssignWinner.js +113 -0
- package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.d.ts +14 -0
- package/dist/_internal/server/jobs/core/prizeDrawExpiryReveal.js +74 -0
- package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.d.ts +22 -0
- package/dist/_internal/server/jobs/core/prizeDrawSoldOutReveal.js +68 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +3 -4
- package/dist/_internal/server/jobs/handlers/index.js +8 -6
- package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/onPrizeDrawPaymentConfirmed.js +11 -0
- package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/prizeDrawExpiryReveal.js +2 -0
- package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/prizeDrawSoldOutReveal.js +4 -0
- package/dist/_internal/shared/actions/action-registry.js +40 -10
- package/dist/_internal/shared/checkout/rules/_defaults.js +1 -2
- package/dist/_internal/shared/checkout/rules/_limits.d.ts +3 -0
- package/dist/_internal/shared/checkout/rules/_limits.js +3 -0
- package/dist/_internal/shared/checkout/rules/_registry.d.ts +2 -1
- package/dist/_internal/shared/checkout/rules/_registry.js +2 -2
- package/dist/_internal/shared/checkout/rules/classified.rule.js +0 -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/prize-draw.rule.js +20 -1
- package/dist/_internal/shared/checkout/rules/types.d.ts +17 -7
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +2 -0
- package/dist/_internal/shared/features/categories/bundle-copy.js +2 -0
- package/dist/_internal/shared/features/categories/bundle-pricing.d.ts +23 -0
- package/dist/_internal/shared/features/categories/bundle-pricing.js +25 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
- package/dist/constants/api-endpoints.d.ts +6 -9
- package/dist/constants/api-endpoints.js +5 -5
- package/dist/constants/field-names.d.ts +17 -1
- package/dist/constants/field-names.js +17 -1
- package/dist/features/account/components/UserSidebar.js +21 -9
- package/dist/features/account/hooks/useNotifications.js +5 -0
- package/dist/features/admin/actions/admin-actions.js +6 -0
- package/dist/features/admin/actions/notification-actions.js +1 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminGuideHubView.js +15 -1
- package/dist/features/admin/components/AdminPaymentsGuideView.d.ts +2 -0
- package/dist/features/admin/components/AdminPaymentsGuideView.js +36 -0
- package/dist/features/admin/components/AdminPrizeDrawsView.js +3 -3
- package/dist/features/admin/components/AdminSidebar.js +18 -9
- package/dist/features/admin/components/AdminSiteSettingsView.js +33 -6
- package/dist/features/admin/components/AdminTesterChecklistView.js +74 -22
- package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +2 -0
- package/dist/features/admin/components/AdminWhatsAppGuideView.js +35 -0
- package/dist/features/admin/hooks/useAdminListing.d.ts +4 -0
- package/dist/features/admin/hooks/useAdminListing.js +4 -2
- package/dist/features/admin/schemas/firestore.d.ts +13 -5
- package/dist/features/admin/schemas/firestore.js +1 -2
- package/dist/features/auctions/actions/bid-actions.js +3 -1
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +6 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +8 -4
- package/dist/features/auctions/components/AuctionDetailPageView.js +10 -13
- package/dist/features/auctions/components/CollapsibleBidHistory.d.ts +23 -2
- package/dist/features/auctions/components/CollapsibleBidHistory.js +22 -3
- package/dist/features/auctions/components/LiveBidPrice.d.ts +19 -0
- package/dist/features/auctions/components/LiveBidPrice.js +17 -0
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +16 -1
- package/dist/features/auctions/hooks/useBids.d.ts +33 -0
- package/dist/features/auctions/hooks/useBids.js +32 -0
- package/dist/features/auctions/hooks/useLiveAuctionBid.d.ts +20 -0
- package/dist/features/auctions/hooks/useLiveAuctionBid.js +23 -0
- package/dist/features/auth/checkout-value-otp.d.ts +7 -10
- package/dist/features/auth/checkout-value-otp.js +14 -10
- package/dist/features/auth/server.d.ts +0 -1
- package/dist/features/auth/server.js +0 -1
- package/dist/features/blog/api/[slug]/route.d.ts +5 -0
- package/dist/features/blog/api/[slug]/route.js +12 -3
- package/dist/features/blog/components/BlogPostView.d.ts +2 -0
- package/dist/features/blog/components/BlogPostView.js +5 -4
- package/dist/features/blog/hooks/useBlog.d.ts +2 -0
- package/dist/features/blog/hooks/useBlog.js +2 -0
- package/dist/features/blog/repository/blog.repository.d.ts +7 -0
- package/dist/features/blog/repository/blog.repository.js +44 -0
- package/dist/features/blog/schemas/firestore.d.ts +3 -0
- package/dist/features/blog/schemas/firestore.js +1 -0
- package/dist/features/blog/types/index.d.ts +2 -0
- package/dist/features/cart/components/index.d.ts +0 -2
- package/dist/features/cart/components/index.js +0 -1
- package/dist/features/cart/hooks/useCartCount.js +22 -5
- package/dist/features/cart/hooks/useGuestCart.js +11 -1
- package/dist/features/cart/utils/guest-cart.d.ts +4 -0
- package/dist/features/cart/utils/guest-cart.js +10 -0
- package/dist/features/cart/utils/pending-ops.d.ts +17 -0
- package/dist/features/cart/utils/pending-ops.js +46 -5
- package/dist/features/categories/components/BrandDetailPageView.js +6 -2
- package/dist/features/categories/components/BundleDetailView.js +4 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +10 -2
- package/dist/features/categories/schemas/firestore.d.ts +7 -0
- package/dist/features/checkout/actions/index.d.ts +0 -1
- package/dist/features/checkout/actions/index.js +0 -1
- package/dist/features/checkout/schemas/firestore.d.ts +2 -2
- package/dist/features/events/actions/event-actions.d.ts +2 -0
- package/dist/features/events/actions/event-actions.js +5 -0
- package/dist/features/events/components/EventCard.js +2 -3
- package/dist/features/events/components/RelatedEventsCarousel.d.ts +15 -0
- package/dist/features/events/components/RelatedEventsCarousel.js +13 -0
- package/dist/features/events/components/index.d.ts +2 -0
- package/dist/features/events/components/index.js +1 -0
- package/dist/features/events/repository/events.repository.d.ts +6 -0
- package/dist/features/events/repository/events.repository.js +21 -0
- package/dist/features/history/repository/user-history.repository.d.ts +1 -1
- package/dist/features/history/utils/guest-history.d.ts +1 -1
- package/dist/features/homepage/components/FeaturedBundlesSection.js +4 -2
- package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/layout/AppLayoutShell.js +44 -10
- package/dist/features/layout/NavbarLayout.js +1 -1
- package/dist/features/layout/TitleBarLayout.js +2 -2
- package/dist/features/media/MediaVideo.d.ts +7 -0
- package/dist/features/media/MediaVideo.js +36 -5
- package/dist/features/orders/components/OrdersList.js +1 -5
- package/dist/features/orders/schemas/firestore.d.ts +2 -8
- package/dist/features/orders/schemas/index.d.ts +3 -32
- package/dist/features/orders/schemas/index.js +1 -4
- package/dist/features/orders/types/index.d.ts +6 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
- package/dist/features/products/actions/product-actions.js +13 -10
- package/dist/features/products/components/MarketplaceBundleCard.d.ts +1 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +7 -4
- package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeDrawWinnerMappingView.d.ts +14 -0
- package/dist/features/products/components/PrizeDrawWinnerMappingView.js +37 -0
- package/dist/features/products/components/PrizeRevealModal.d.ts +10 -23
- package/dist/features/products/components/PrizeRevealModal.js +18 -147
- package/dist/features/products/components/ProductDetailPageView.js +72 -30
- package/dist/features/products/components/ProductForm.js +7 -14
- package/dist/features/products/components/ProductGalleryClient.d.ts +10 -1
- package/dist/features/products/components/ProductGalleryClient.js +29 -10
- package/dist/features/products/components/ProductsIndexListing.js +2 -1
- package/dist/features/products/components/RelatedProductsCarousel.js +2 -2
- package/dist/features/products/components/ShowGroupSection.js +2 -2
- package/dist/features/products/components/SublistingCarouselSection.js +1 -1
- package/dist/features/products/components/index.d.ts +4 -2
- package/dist/features/products/components/index.js +1 -0
- package/dist/features/products/constants/action-defs.d.ts +1 -3
- package/dist/features/products/constants/action-defs.js +0 -5
- package/dist/features/products/repository/products.repository.d.ts +6 -0
- package/dist/features/products/repository/products.repository.js +20 -1
- package/dist/features/products/schemas/firestore.d.ts +28 -3
- package/dist/features/products/schemas/index.d.ts +11 -3
- package/dist/features/products/schemas/index.js +10 -2
- package/dist/features/products/types/index.d.ts +2 -1
- package/dist/features/reviews/actions/review-actions.js +1 -0
- package/dist/features/reviews/components/ReviewDetailPageView.js +8 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +2 -1
- package/dist/features/reviews/components/ReviewsList.js +2 -1
- package/dist/features/reviews/schemas/firestore.d.ts +3 -0
- package/dist/features/reviews/schemas/index.d.ts +6 -0
- package/dist/features/reviews/schemas/index.js +2 -0
- package/dist/features/reviews/types/index.d.ts +3 -0
- package/dist/features/scams/actions/scam-actions.d.ts +3 -0
- package/dist/features/scams/actions/scam-actions.js +3 -2
- package/dist/features/scams/components/ScamProfileView.d.ts +2 -1
- package/dist/features/scams/components/ScamProfileView.js +2 -2
- package/dist/features/scams/repository/scammer.repository.d.ts +6 -0
- package/dist/features/scams/repository/scammer.repository.js +24 -0
- package/dist/features/seller/actions/seller-actions.js +8 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.js +4 -0
- package/dist/features/seller/components/SellerSidebar.js +20 -9
- package/dist/features/stores/components/StoreDetailLayoutView.js +6 -6
- package/dist/features/stores/components/StoreGuideHubView.js +7 -1
- package/dist/features/stores/components/StoreNavTabs.d.ts +10 -1
- package/dist/features/stores/components/StoreNavTabs.js +22 -9
- package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +3 -0
- package/dist/features/stores/components/StoreWhatsAppGuideView.js +12 -0
- package/dist/features/stores/components/index.d.ts +2 -0
- package/dist/features/stores/components/index.js +1 -0
- package/dist/features/tester/actions/index.d.ts +1 -0
- package/dist/features/tester/actions/index.js +1 -0
- package/dist/features/tester/actions/leaderboard-actions.d.ts +3 -0
- package/dist/features/tester/actions/leaderboard-actions.js +5 -0
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +26 -4
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +13 -0
- package/dist/features/tester/components/BugHunterLeaderboardView.d.ts +23 -0
- package/dist/features/tester/components/BugHunterLeaderboardView.js +18 -0
- package/dist/features/tester/components/index.d.ts +2 -0
- package/dist/features/tester/components/index.js +1 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +12 -1
- package/dist/features/tester/repository/tester-checklist-item.repository.js +80 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.d.ts +4 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.js +4 -0
- package/dist/features/tester/schemas/firestore.d.ts +22 -1
- package/dist/features/tester/schemas/firestore.js +8 -0
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +42 -7
- package/dist/features/tester/seed-data/events-tester-seed-data.js +23 -0
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +69 -31
- package/dist/features/tester/seed-data/products-tester-seed-data.js +154 -9
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +252 -15
- package/dist/features/wishlist/hooks/useGuestWishlist.js +11 -1
- package/dist/features/wishlist/hooks/useWishlistCount.js +16 -2
- package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -0
- package/dist/features/wishlist/utils/guest-wishlist.js +11 -0
- package/dist/index.d.ts +23 -22
- package/dist/index.js +31 -58
- package/dist/jobs.d.ts +1 -1
- package/dist/jobs.js +2 -2
- package/dist/next/routing/route-map.d.ts +9 -2
- package/dist/next/routing/route-map.js +4 -1
- package/dist/schemas/registry.d.ts +6 -26
- package/dist/seed/bids-seed-data.js +14 -2
- package/dist/seed/blog-posts-seed-data.js +2 -1
- package/dist/seed/categories-seed-data.js +11 -2
- package/dist/seed/events-seed-data.js +11 -11
- package/dist/seed/faq-seed-data.js +5 -1
- package/dist/seed/products-auctions-seed-data.js +2 -2
- package/dist/seed/products-preorders-seed-data.d.ts +2 -1
- package/dist/seed/products-prize-draws-seed-data.js +56 -10
- package/dist/seed/products-standard-seed-data.js +80 -3
- package/dist/seed/scammers-seed-data.js +75 -2
- package/dist/seed/site-settings-seed-data.js +5 -2
- package/dist/server-entry.d.ts +0 -1
- package/dist/server-entry.js +0 -1
- package/dist/server.d.ts +4 -20
- package/dist/server.js +10 -57
- package/dist/styles.css +1 -277
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/BaseListingCard.js +1 -1
- package/dist/ui/components/ImageLightbox.d.ts +9 -0
- package/dist/ui/components/ImageLightbox.js +6 -3
- package/dist/ui/components/ListingToolbar.d.ts +18 -1
- package/dist/ui/components/ListingToolbar.js +5 -2
- package/dist/ui/components/StickyToolbar.js +13 -8
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Div, Row, Span, Stack, Text } from "../../../ui";
|
|
4
|
+
export function BugHunterLeaderboardView({ isLoading = false, isEmpty = false, renderList, renderEntry, entries = [], renderEmpty, renderSkeleton, labels = {}, className = "", }) {
|
|
5
|
+
if (isLoading) {
|
|
6
|
+
if (renderSkeleton)
|
|
7
|
+
return _jsx(_Fragment, { children: renderSkeleton() });
|
|
8
|
+
return _jsx(Row, { justify: "center", padding: "y-xl", children: "Loading\u2026" });
|
|
9
|
+
}
|
|
10
|
+
if (isEmpty) {
|
|
11
|
+
if (renderEmpty)
|
|
12
|
+
return _jsx(_Fragment, { children: renderEmpty() });
|
|
13
|
+
return (_jsx(Text, { paddingY: "md", variant: "secondary", size: "sm", align: "start", children: labels.noEntries ?? "No confirmed bugs yet." }));
|
|
14
|
+
}
|
|
15
|
+
if (renderList)
|
|
16
|
+
return _jsx(Div, { className: className, children: renderList() });
|
|
17
|
+
return (_jsx(Stack, { className: `${className}`, gap: "sm", children: entries.map((entry, i) => renderEntry ? (_jsx(React.Fragment, { children: renderEntry(entry, i) }, entry.hunterId)) : (_jsxs(Div, { layout: "flex", align: "center", justify: "between", rounded: "xl", padding: "sm", className: "border", "data-section": "bughunterleaderboard-div", children: [_jsxs(Span, { weight: "medium", children: ["#", entry.rank, " ", entry.hunterName] }), _jsxs(Span, { children: [entry.bugCount, " ", labels.bugs ?? "bugs"] })] }, entry.hunterId))) }));
|
|
18
|
+
}
|
|
@@ -9,3 +9,5 @@ export { AdminTesterFeedbackReportView } from "./AdminTesterFeedbackReportView";
|
|
|
9
9
|
export { AdminTesterFeedbackIssuesView } from "./AdminTesterFeedbackIssuesView";
|
|
10
10
|
export { AdminTesterFeedbackListView } from "./AdminTesterFeedbackListView";
|
|
11
11
|
export type { AdminTesterFeedbackListViewProps } from "./AdminTesterFeedbackListView";
|
|
12
|
+
export { BugHunterLeaderboardView } from "./BugHunterLeaderboardView";
|
|
13
|
+
export type { BugHunterLeaderboardViewProps } from "./BugHunterLeaderboardView";
|
|
@@ -5,3 +5,4 @@ export { AdminTesterFeedbackView } from "./AdminTesterFeedbackView";
|
|
|
5
5
|
export { AdminTesterFeedbackReportView } from "./AdminTesterFeedbackReportView";
|
|
6
6
|
export { AdminTesterFeedbackIssuesView } from "./AdminTesterFeedbackIssuesView";
|
|
7
7
|
export { AdminTesterFeedbackListView } from "./AdminTesterFeedbackListView";
|
|
8
|
+
export { BugHunterLeaderboardView } from "./BugHunterLeaderboardView";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseRepository } from "../../../providers/db-firebase";
|
|
2
2
|
import type { FirebaseSieveFields, FirebaseSieveResult, SieveModel } from "../../../providers/db-firebase";
|
|
3
|
-
import { type TesterChecklistItemDocument, type TesterChecklistItemCreateInput, type TesterChecklistItemUpdateInput } from "../schemas/firestore";
|
|
3
|
+
import { type TesterChecklistItemDocument, type TesterChecklistItemCreateInput, type TesterChecklistItemUpdateInput, type BugHunterLeaderboardEntry } from "../schemas/firestore";
|
|
4
4
|
export declare class TesterChecklistItemRepository extends BaseRepository<TesterChecklistItemDocument> {
|
|
5
5
|
static readonly SIEVE_FIELDS: FirebaseSieveFields;
|
|
6
6
|
constructor();
|
|
@@ -9,5 +9,16 @@ export declare class TesterChecklistItemRepository extends BaseRepository<Tester
|
|
|
9
9
|
update(id: string, data: TesterChecklistItemUpdateInput): Promise<TesterChecklistItemDocument>;
|
|
10
10
|
listActive(): Promise<TesterChecklistItemDocument[]>;
|
|
11
11
|
list(model: SieveModel): Promise<FirebaseSieveResult<TesterChecklistItemDocument>>;
|
|
12
|
+
/** Confirms a reported "No" as a real bug: credits the reporting tester and
|
|
13
|
+
* disables the case for all other testers. Credit is permanent — never
|
|
14
|
+
* touched again by reopenAsNewVersion(). */
|
|
15
|
+
confirmBug(id: string, hunterId: string, hunterName: string): Promise<TesterChecklistItemDocument>;
|
|
16
|
+
/** Reopens a fixed, bug-confirmed case as a new, active version for retest.
|
|
17
|
+
* The old item stays disabled forever with its bug-hunter credit intact. */
|
|
18
|
+
reopenAsNewVersion(oldItemId: string): Promise<TesterChecklistItemDocument>;
|
|
19
|
+
/** Single-query, in-memory aggregation of bug credits per hunter — mirrors
|
|
20
|
+
* EventEntryRepository.getLeaderboard()'s shape. Includes old/disabled/
|
|
21
|
+
* superseded items, since bug credit is permanent. */
|
|
22
|
+
getBugHunterLeaderboard(limit?: number): Promise<BugHunterLeaderboardEntry[]>;
|
|
12
23
|
}
|
|
13
24
|
export declare const testerChecklistItemRepository: TesterChecklistItemRepository;
|
|
@@ -42,6 +42,85 @@ export class TesterChecklistItemRepository extends BaseRepository {
|
|
|
42
42
|
async list(model) {
|
|
43
43
|
return this.sieveQuery(model, TesterChecklistItemRepository.SIEVE_FIELDS);
|
|
44
44
|
}
|
|
45
|
+
/** Confirms a reported "No" as a real bug: credits the reporting tester and
|
|
46
|
+
* disables the case for all other testers. Credit is permanent — never
|
|
47
|
+
* touched again by reopenAsNewVersion(). */
|
|
48
|
+
async confirmBug(id, hunterId, hunterName) {
|
|
49
|
+
const current = await this.findById(id);
|
|
50
|
+
if (!current) {
|
|
51
|
+
throw new DatabaseError(`Failed to confirm bug: missing checklist item ${id}`);
|
|
52
|
+
}
|
|
53
|
+
if (current.bugConfirmed) {
|
|
54
|
+
throw new DatabaseError(`Checklist item ${id} already has a confirmed bug`);
|
|
55
|
+
}
|
|
56
|
+
return this.update(id, {
|
|
57
|
+
isActive: false,
|
|
58
|
+
bugConfirmed: true,
|
|
59
|
+
bugHunterId: hunterId,
|
|
60
|
+
bugHunterName: hunterName,
|
|
61
|
+
bugConfirmedAt: new Date(),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Reopens a fixed, bug-confirmed case as a new, active version for retest.
|
|
65
|
+
* The old item stays disabled forever with its bug-hunter credit intact. */
|
|
66
|
+
async reopenAsNewVersion(oldItemId) {
|
|
67
|
+
const old = await this.findById(oldItemId);
|
|
68
|
+
if (!old) {
|
|
69
|
+
throw new DatabaseError(`Failed to reopen checklist item: missing document ${oldItemId}`);
|
|
70
|
+
}
|
|
71
|
+
if (!old.bugConfirmed) {
|
|
72
|
+
throw new DatabaseError(`Checklist item ${oldItemId} has no confirmed bug to reopen`);
|
|
73
|
+
}
|
|
74
|
+
if (old.supersededByItemId) {
|
|
75
|
+
throw new DatabaseError(`Checklist item ${oldItemId} has already been reopened`);
|
|
76
|
+
}
|
|
77
|
+
const nextVersion = (old.version ?? 1) + 1;
|
|
78
|
+
const newId = `${old.id}-v${nextVersion}`;
|
|
79
|
+
const newItem = await this.createWithId(newId, {
|
|
80
|
+
groupKey: old.groupKey,
|
|
81
|
+
groupLabel: old.groupLabel,
|
|
82
|
+
pageKey: old.pageKey,
|
|
83
|
+
pageLabel: old.pageLabel,
|
|
84
|
+
label: old.label,
|
|
85
|
+
description: old.description,
|
|
86
|
+
href: old.href,
|
|
87
|
+
order: old.order,
|
|
88
|
+
phase: old.phase,
|
|
89
|
+
adminOnly: old.adminOnly,
|
|
90
|
+
isActive: true,
|
|
91
|
+
version: nextVersion,
|
|
92
|
+
previousVersionId: old.id,
|
|
93
|
+
searchTokens: this.buildSearchTokens(old),
|
|
94
|
+
});
|
|
95
|
+
await this.update(old.id, { supersededByItemId: newId });
|
|
96
|
+
return newItem;
|
|
97
|
+
}
|
|
98
|
+
/** Single-query, in-memory aggregation of bug credits per hunter — mirrors
|
|
99
|
+
* EventEntryRepository.getLeaderboard()'s shape. Includes old/disabled/
|
|
100
|
+
* superseded items, since bug credit is permanent. */
|
|
101
|
+
async getBugHunterLeaderboard(limit = 50) {
|
|
102
|
+
const snapshot = await this.db
|
|
103
|
+
.collection(this.collection)
|
|
104
|
+
.where(TESTER_CHECKLIST_ITEM_FIELDS.BUG_CONFIRMED, "==", true)
|
|
105
|
+
.get();
|
|
106
|
+
const byHunter = new Map();
|
|
107
|
+
for (const doc of snapshot.docs) {
|
|
108
|
+
const item = this.mapDoc(doc);
|
|
109
|
+
if (!item.bugHunterId)
|
|
110
|
+
continue;
|
|
111
|
+
const entry = byHunter.get(item.bugHunterId) ?? {
|
|
112
|
+
name: item.bugHunterName ?? "Unknown tester",
|
|
113
|
+
count: 0,
|
|
114
|
+
};
|
|
115
|
+
entry.count += 1;
|
|
116
|
+
byHunter.set(item.bugHunterId, entry);
|
|
117
|
+
}
|
|
118
|
+
return Array.from(byHunter.entries())
|
|
119
|
+
.map(([hunterId, v]) => ({ hunterId, hunterName: v.name, bugCount: v.count }))
|
|
120
|
+
.sort((a, b) => b.bugCount - a.bugCount)
|
|
121
|
+
.slice(0, limit)
|
|
122
|
+
.map((entry, index) => ({ ...entry, rank: index + 1 }));
|
|
123
|
+
}
|
|
45
124
|
}
|
|
46
125
|
TesterChecklistItemRepository.SIEVE_FIELDS = {
|
|
47
126
|
groupKey: { canFilter: true, canSort: true },
|
|
@@ -52,5 +131,6 @@ TesterChecklistItemRepository.SIEVE_FIELDS = {
|
|
|
52
131
|
isActive: { canFilter: true, canSort: false },
|
|
53
132
|
searchTokens: { canFilter: true, canSort: false },
|
|
54
133
|
createdAt: { canFilter: true, canSort: true },
|
|
134
|
+
bugConfirmed: { canFilter: true, canSort: false },
|
|
55
135
|
};
|
|
56
136
|
export const testerChecklistItemRepository = new TesterChecklistItemRepository();
|
|
@@ -27,6 +27,10 @@ export type CoverageIssue = TesterChecklistResponseDocument & {
|
|
|
27
27
|
groupLabel: string;
|
|
28
28
|
pageLabel: string;
|
|
29
29
|
label: string;
|
|
30
|
+
bugConfirmed?: boolean;
|
|
31
|
+
bugHunterId?: string;
|
|
32
|
+
bugHunterName?: string;
|
|
33
|
+
supersededByItemId?: string;
|
|
30
34
|
};
|
|
31
35
|
export interface CoverageReport {
|
|
32
36
|
itemCoverage: ChecklistItemCoverage[];
|
|
@@ -105,6 +105,10 @@ export class TesterChecklistResponseRepository extends BaseRepository {
|
|
|
105
105
|
groupLabel,
|
|
106
106
|
pageLabel,
|
|
107
107
|
label: catalogItem?.label ?? doc.checklistItemId,
|
|
108
|
+
bugConfirmed: catalogItem?.bugConfirmed,
|
|
109
|
+
bugHunterId: catalogItem?.bugHunterId,
|
|
110
|
+
bugHunterName: catalogItem?.bugHunterName,
|
|
111
|
+
supersededByItemId: catalogItem?.supersededByItemId,
|
|
108
112
|
});
|
|
109
113
|
}
|
|
110
114
|
}
|
|
@@ -19,18 +19,32 @@ export interface TesterChecklistItemDocument extends BaseDocument {
|
|
|
19
19
|
isActive: boolean;
|
|
20
20
|
searchTokens: string[];
|
|
21
21
|
adminOnly?: boolean;
|
|
22
|
+
bugConfirmed?: boolean;
|
|
23
|
+
bugHunterId?: string;
|
|
24
|
+
bugHunterName?: string;
|
|
25
|
+
bugConfirmedAt?: Date;
|
|
26
|
+
version?: number;
|
|
27
|
+
previousVersionId?: string;
|
|
28
|
+
supersededByItemId?: string;
|
|
22
29
|
}
|
|
23
30
|
export declare const TESTER_CHECKLIST_ITEM_COLLECTION: "testerChecklistItems";
|
|
24
31
|
export declare const TESTER_CHECKLIST_ITEM_ID_PREFIX: "checklist-";
|
|
25
32
|
export declare const TESTER_CHECKLIST_ITEM_INDEXED_FIELDS: readonly ["groupKey", "pageKey", "phase", "order", "isActive", "searchTokens", "createdAt"];
|
|
26
33
|
export declare const DEFAULT_TESTER_CHECKLIST_ITEM_DATA: Partial<TesterChecklistItemDocument>;
|
|
27
34
|
export type TesterChecklistItemCreateInput = Omit<TesterChecklistItemDocument, "id" | "createdAt" | "updatedAt" | "searchTokens">;
|
|
28
|
-
export type TesterChecklistItemUpdateInput = Partial<Pick<TesterChecklistItemDocument, "groupKey" | "groupLabel" | "pageKey" | "pageLabel" | "label" | "description" | "href" | "order" | "phase" | "isActive" | "adminOnly">>;
|
|
35
|
+
export type TesterChecklistItemUpdateInput = Partial<Pick<TesterChecklistItemDocument, "groupKey" | "groupLabel" | "pageKey" | "pageLabel" | "label" | "description" | "href" | "order" | "phase" | "isActive" | "adminOnly" | "bugConfirmed" | "bugHunterId" | "bugHunterName" | "bugConfirmedAt" | "version" | "previousVersionId" | "supersededByItemId">>;
|
|
29
36
|
export declare const testerChecklistItemQueryHelpers: {
|
|
30
37
|
readonly byGroup: (groupKey: string) => readonly ["groupKey", "==", string];
|
|
31
38
|
readonly byPage: (pageKey: string) => readonly ["pageKey", "==", string];
|
|
32
39
|
readonly active: () => readonly ["isActive", "==", true];
|
|
40
|
+
readonly confirmedBugs: () => readonly ["bugConfirmed", "==", true];
|
|
33
41
|
};
|
|
42
|
+
export interface BugHunterLeaderboardEntry {
|
|
43
|
+
rank: number;
|
|
44
|
+
hunterId: string;
|
|
45
|
+
hunterName: string;
|
|
46
|
+
bugCount: number;
|
|
47
|
+
}
|
|
34
48
|
export declare function slugifyChecklistLabel(label: string): string;
|
|
35
49
|
export declare function createChecklistItemId(groupKey: string, pageKey: string, label: string): string;
|
|
36
50
|
export type TesterAnswer = "yes" | "no";
|
|
@@ -72,6 +86,13 @@ export declare const TESTER_CHECKLIST_ITEM_FIELDS: {
|
|
|
72
86
|
readonly IS_ACTIVE: "isActive";
|
|
73
87
|
readonly SEARCH_TOKENS: "searchTokens";
|
|
74
88
|
readonly ADMIN_ONLY: "adminOnly";
|
|
89
|
+
readonly BUG_CONFIRMED: "bugConfirmed";
|
|
90
|
+
readonly BUG_HUNTER_ID: "bugHunterId";
|
|
91
|
+
readonly BUG_HUNTER_NAME: "bugHunterName";
|
|
92
|
+
readonly BUG_CONFIRMED_AT: "bugConfirmedAt";
|
|
93
|
+
readonly VERSION: "version";
|
|
94
|
+
readonly PREVIOUS_VERSION_ID: "previousVersionId";
|
|
95
|
+
readonly SUPERSEDED_BY_ITEM_ID: "supersededByItemId";
|
|
75
96
|
readonly CREATED_AT: "createdAt";
|
|
76
97
|
readonly UPDATED_AT: "updatedAt";
|
|
77
98
|
};
|
|
@@ -28,6 +28,7 @@ export const testerChecklistItemQueryHelpers = {
|
|
|
28
28
|
byGroup: (groupKey) => ["groupKey", "==", groupKey],
|
|
29
29
|
byPage: (pageKey) => ["pageKey", "==", pageKey],
|
|
30
30
|
active: () => ["isActive", "==", true],
|
|
31
|
+
confirmedBugs: () => ["bugConfirmed", "==", true],
|
|
31
32
|
};
|
|
32
33
|
export function slugifyChecklistLabel(label) {
|
|
33
34
|
return label
|
|
@@ -81,6 +82,13 @@ export const TESTER_CHECKLIST_ITEM_FIELDS = {
|
|
|
81
82
|
IS_ACTIVE: "isActive",
|
|
82
83
|
SEARCH_TOKENS: "searchTokens",
|
|
83
84
|
ADMIN_ONLY: "adminOnly",
|
|
85
|
+
BUG_CONFIRMED: "bugConfirmed",
|
|
86
|
+
BUG_HUNTER_ID: "bugHunterId",
|
|
87
|
+
BUG_HUNTER_NAME: "bugHunterName",
|
|
88
|
+
BUG_CONFIRMED_AT: "bugConfirmedAt",
|
|
89
|
+
VERSION: "version",
|
|
90
|
+
PREVIOUS_VERSION_ID: "previousVersionId",
|
|
91
|
+
SUPERSEDED_BY_ITEM_ID: "supersededByItemId",
|
|
84
92
|
CREATED_AT: "createdAt",
|
|
85
93
|
UPDATED_AT: "updatedAt",
|
|
86
94
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* WHY: Shared tester sandbox — a small self-contained category tree (root +
|
|
3
|
-
* 1 brand row, and 1 bundle row so testers
|
|
4
|
-
* flows without touching real catalog data.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* WHY: Shared tester sandbox — a small self-contained category tree (root + 3 leaves,
|
|
3
|
+
* one leaf deliberately isActive:false), 1 brand row, and 1 bundle row so testers
|
|
4
|
+
* can exercise browsing/filtering/bundle flows without touching real catalog data.
|
|
5
|
+
* Auto-expires after 7 days.
|
|
6
|
+
* WHAT: Exports categoriesTesterSeedData — 4 plain categories + 1 categoryType:"brand" +
|
|
7
|
+
* 1 categoryType:"bundle" (bundleProductIds + bundleOriginalTotal reference
|
|
8
|
+
* products-tester-seed-data.ts).
|
|
7
9
|
*
|
|
8
10
|
* EXPORTS:
|
|
9
11
|
* categoriesTesterSeedData — Array of Partial<CategoryDocument> for the seed runner
|
|
@@ -37,13 +39,13 @@ export const categoriesTesterSeedData = [
|
|
|
37
39
|
description: "Disposable test category tree for the tester QA program.",
|
|
38
40
|
rootId: "category-tester-sandbox",
|
|
39
41
|
parentIds: [],
|
|
40
|
-
childrenIds: ["category-tester-gadgets", "category-tester-collectibles"],
|
|
42
|
+
childrenIds: ["category-tester-gadgets", "category-tester-collectibles", "category-tester-inactive"],
|
|
41
43
|
tier: 0,
|
|
42
44
|
path: "tester-sandbox",
|
|
43
45
|
order: 999,
|
|
44
46
|
isLeaf: false,
|
|
45
47
|
position: 0,
|
|
46
|
-
subtreeSize:
|
|
48
|
+
subtreeSize: 3,
|
|
47
49
|
metrics: emptyMetrics,
|
|
48
50
|
isFeatured: false,
|
|
49
51
|
isBrand: false,
|
|
@@ -110,6 +112,36 @@ export const categoriesTesterSeedData = [
|
|
|
110
112
|
createdAt: new Date(),
|
|
111
113
|
updatedAt: new Date(),
|
|
112
114
|
},
|
|
115
|
+
{
|
|
116
|
+
// Deliberately isActive:false — the entire real seed dataset (17 categories
|
|
117
|
+
// before this) has isActive:true on every single row, so the admin Categories
|
|
118
|
+
// dashboard's "isActive" toggle (backed by the categories(isActive, name ASC)
|
|
119
|
+
// composite index) had nothing to show when toggled to the inactive branch.
|
|
120
|
+
id: "category-tester-inactive",
|
|
121
|
+
slug: "category-tester-inactive",
|
|
122
|
+
name: "Test Inactive Category",
|
|
123
|
+
description: "Disposable test category deliberately seeded as inactive, for verifying the admin Categories isActive toggle. Auto-expires in 7 days.",
|
|
124
|
+
rootId: "category-tester-sandbox",
|
|
125
|
+
parentIds: ["category-tester-sandbox"],
|
|
126
|
+
childrenIds: [],
|
|
127
|
+
tier: 1,
|
|
128
|
+
path: "tester-sandbox/inactive",
|
|
129
|
+
order: 3,
|
|
130
|
+
isLeaf: true,
|
|
131
|
+
position: 2,
|
|
132
|
+
subtreeSize: 0,
|
|
133
|
+
metrics: emptyMetrics,
|
|
134
|
+
isFeatured: false,
|
|
135
|
+
isBrand: false,
|
|
136
|
+
isActive: false,
|
|
137
|
+
isSearchable: false,
|
|
138
|
+
showOnHomepage: false,
|
|
139
|
+
createdBy: "user-admin-letitrip",
|
|
140
|
+
isTestData: true,
|
|
141
|
+
testDataExpiresAt: testDataExpiresAt(),
|
|
142
|
+
createdAt: new Date(),
|
|
143
|
+
updatedAt: new Date(),
|
|
144
|
+
},
|
|
113
145
|
// ── BRAND ────────────────────────────────────────────────────────────────
|
|
114
146
|
{
|
|
115
147
|
id: "brand-tester-sandbox",
|
|
@@ -153,6 +185,9 @@ export const categoriesTesterSeedData = [
|
|
|
153
185
|
type: "static",
|
|
154
186
|
productIds: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
155
187
|
},
|
|
188
|
+
bundleProductIds: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
189
|
+
bundleOriginalTotal: 348, // 199 + 149
|
|
190
|
+
bundleStockStatus: "in_stock",
|
|
156
191
|
rootId: "bundle-tester-sandbox",
|
|
157
192
|
parentIds: [],
|
|
158
193
|
childrenIds: [],
|
|
@@ -95,4 +95,27 @@ export const eventsTesterSeedData = [
|
|
|
95
95
|
createdAt: new Date(),
|
|
96
96
|
updatedAt: new Date(),
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
id: "event-tester-sandbox-offer",
|
|
100
|
+
slug: "tester-sandbox-offer",
|
|
101
|
+
type: EVENT_FIELDS.TYPE_VALUES.OFFER,
|
|
102
|
+
title: "Tester Sandbox — Offer Coupon",
|
|
103
|
+
description: "Disposable test event for the tester QA program. Verify the Overview tab shows the coupon code and the Copy code button copies it to the clipboard.",
|
|
104
|
+
status: EVENT_FIELDS.STATUS_VALUES.ACTIVE,
|
|
105
|
+
startsAt: new Date(),
|
|
106
|
+
endsAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
107
|
+
coverImage: { type: "image", url: seedExtMedia("https://picsum.photos/seed/event-cover-tester-sandbox-offer-20260101/1200/600"), alt: TEST_EVENT_COVER_ALT },
|
|
108
|
+
tags: ["test"],
|
|
109
|
+
offerConfig: {
|
|
110
|
+
couponId: "coupon-rehan10",
|
|
111
|
+
displayCode: "REHAN10",
|
|
112
|
+
bannerText: "Test offer — not a real discount.",
|
|
113
|
+
},
|
|
114
|
+
stats: { totalEntries: 0, approvedEntries: 0, flaggedEntries: 0 },
|
|
115
|
+
createdBy: "user-admin-letitrip",
|
|
116
|
+
isTestData: true,
|
|
117
|
+
testDataExpiresAt: testDataExpiresAt(),
|
|
118
|
+
createdAt: new Date(),
|
|
119
|
+
updatedAt: new Date(),
|
|
120
|
+
},
|
|
98
121
|
];
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
* without manually driving each one through the full checkout/shipping/return
|
|
6
6
|
* flow first. Buyer is the dedicated user-tester-qa persona. Auto-expires in 7
|
|
7
7
|
* days via testerSandboxCleanup (orders aren't cascade-deleted — see note below).
|
|
8
|
-
*
|
|
8
|
+
* Also includes one 5-item order specifically to exercise the "My Orders" /
|
|
9
|
+
* dashboard Recent Orders item-summary UI (thumbnails/title/qty for the first 3
|
|
10
|
+
* items + a "+N more" badge beyond that) — the other fixtures here are all
|
|
11
|
+
* single- or 2-item orders, which never trigger the "+N more" badge at all.
|
|
12
|
+
* WHAT: Exports ordersTesterSeedData — 14 Partial<OrderDocument> for the seed runner.
|
|
9
13
|
*
|
|
10
14
|
* NOTE: OrderDocument does not currently carry isTestData/testDataExpiresAt (unlike
|
|
11
15
|
* categories/stores/products/blogPosts/events) — testerSandboxCleanup does not
|
|
@@ -14,7 +18,7 @@
|
|
|
14
18
|
* orders is a follow-up, not blocking.
|
|
15
19
|
*
|
|
16
20
|
* EXPORTS:
|
|
17
|
-
* ordersTesterSeedData — Array of
|
|
21
|
+
* ordersTesterSeedData — Array of 14 Partial<OrderDocument> for the seed runner
|
|
18
22
|
*
|
|
19
23
|
* @tag domain:orders,tester
|
|
20
24
|
* @tag layer:seed
|
|
@@ -139,11 +143,16 @@ export const ordersTesterSeedData = [
|
|
|
139
143
|
createdAt: daysAgo(1),
|
|
140
144
|
updatedAt: NOW,
|
|
141
145
|
},
|
|
142
|
-
// ── Bundle purchase —
|
|
146
|
+
// ── Bundle purchase — a real checkout produces ONE order item for the whole
|
|
147
|
+
// bundle (see addBundleToCartAction / checkout/actions.ts bundle-expansion),
|
|
148
|
+
// not one item per member product. Previously mis-modeled against
|
|
149
|
+
// "group-tester-sandbox-bundle" (a real standalone product that separately
|
|
150
|
+
// demonstrates the Tier-GP product-group "Set" feature, not a bundle at
|
|
151
|
+
// all) — the actual bundle is the categories row "bundle-tester-sandbox".
|
|
143
152
|
{
|
|
144
153
|
id: "order-tester-sandbox-bundle",
|
|
145
|
-
productId: "
|
|
146
|
-
productTitle: "Test Bundle
|
|
154
|
+
productId: "bundle-tester-sandbox",
|
|
155
|
+
productTitle: "Test Bundle",
|
|
147
156
|
userId: BUYER_ID,
|
|
148
157
|
userName: BUYER_NAME,
|
|
149
158
|
userEmail: BUYER_EMAIL,
|
|
@@ -151,32 +160,22 @@ export const ordersTesterSeedData = [
|
|
|
151
160
|
storeName: STORE_NAME,
|
|
152
161
|
items: [
|
|
153
162
|
{
|
|
154
|
-
productId: "
|
|
155
|
-
productTitle: "Test
|
|
163
|
+
productId: "bundle-tester-sandbox",
|
|
164
|
+
productTitle: "Test Bundle",
|
|
156
165
|
listingType: "standard",
|
|
157
166
|
quantity: 1,
|
|
158
167
|
unitPrice: 199,
|
|
159
168
|
totalPrice: 199,
|
|
160
|
-
bundleCategorySlug: "
|
|
161
|
-
bundleProductIds: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
productId: "product-tester-standard-2",
|
|
165
|
-
productTitle: "Test Collectible — Standard Listing #2",
|
|
166
|
-
listingType: "standard",
|
|
167
|
-
quantity: 1,
|
|
168
|
-
unitPrice: 149,
|
|
169
|
-
totalPrice: 149,
|
|
170
|
-
bundleCategorySlug: "group-tester-sandbox-bundle",
|
|
169
|
+
bundleCategorySlug: "bundle-tester-sandbox",
|
|
171
170
|
bundleProductIds: ["product-tester-standard-1", "product-tester-standard-2"],
|
|
172
171
|
},
|
|
173
172
|
],
|
|
174
173
|
orderType: "standard",
|
|
175
|
-
bundleId: "
|
|
174
|
+
bundleId: "bundle-tester-sandbox",
|
|
176
175
|
isNonRefundable: true,
|
|
177
|
-
quantity:
|
|
178
|
-
unitPrice:
|
|
179
|
-
totalPrice:
|
|
176
|
+
quantity: 1,
|
|
177
|
+
unitPrice: 199,
|
|
178
|
+
totalPrice: 199,
|
|
180
179
|
currency: "INR",
|
|
181
180
|
status: "processing",
|
|
182
181
|
paymentStatus: "paid",
|
|
@@ -206,13 +205,12 @@ export const ordersTesterSeedData = [
|
|
|
206
205
|
unitPrice: 50,
|
|
207
206
|
totalPrice: 50,
|
|
208
207
|
prizeRevealStatus: "revealed",
|
|
209
|
-
revealedItemNumber: 1,
|
|
210
208
|
},
|
|
211
209
|
],
|
|
212
210
|
orderType: "prize-draw",
|
|
213
211
|
prizeDrawProductId: PRIZEDRAW_PRODUCT_ID,
|
|
212
|
+
prizeRevealMode: "scheduled",
|
|
214
213
|
prizeWon: { itemNumber: 1, title: "Test Prize — Grand", images: [], wonAt: daysAgo(1) },
|
|
215
|
-
prizeRevealDeadline: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
|
|
216
214
|
isNonRefundable: true,
|
|
217
215
|
quantity: 1,
|
|
218
216
|
unitPrice: 50,
|
|
@@ -225,7 +223,11 @@ export const ordersTesterSeedData = [
|
|
|
225
223
|
createdAt: daysAgo(1),
|
|
226
224
|
updatedAt: daysAgo(1),
|
|
227
225
|
},
|
|
228
|
-
// ── Prize draw —
|
|
226
|
+
// ── Prize draw — a second entry on the same closed draw, revealed to a
|
|
227
|
+
// different item. Every paid entry on a prize draw is eventually
|
|
228
|
+
// assigned some item (prizeMaxEntries === item count) — there's no
|
|
229
|
+
// "losing" outcome under the automatic-reveal model, unlike a lottery
|
|
230
|
+
// with fewer prizes than tickets. ─────────────────────────────────────
|
|
229
231
|
{
|
|
230
232
|
id: "order-tester-sandbox-prizedraw-lose",
|
|
231
233
|
productId: PRIZEDRAW_PRODUCT_ID,
|
|
@@ -243,23 +245,59 @@ export const ordersTesterSeedData = [
|
|
|
243
245
|
quantity: 1,
|
|
244
246
|
unitPrice: 50,
|
|
245
247
|
totalPrice: 50,
|
|
246
|
-
prizeRevealStatus: "
|
|
248
|
+
prizeRevealStatus: "revealed",
|
|
247
249
|
},
|
|
248
250
|
],
|
|
249
251
|
orderType: "prize-draw",
|
|
250
252
|
prizeDrawProductId: PRIZEDRAW_PRODUCT_ID,
|
|
253
|
+
prizeRevealMode: "scheduled",
|
|
254
|
+
prizeWon: { itemNumber: 2, title: "Test Prize — Runner-up", images: [], wonAt: daysAgo(1) },
|
|
255
|
+
isNonRefundable: true,
|
|
251
256
|
quantity: 1,
|
|
252
257
|
unitPrice: 50,
|
|
253
258
|
totalPrice: 50,
|
|
254
259
|
currency: "INR",
|
|
255
|
-
status: "
|
|
256
|
-
paymentStatus: "
|
|
260
|
+
status: "delivered",
|
|
261
|
+
paymentStatus: "paid",
|
|
257
262
|
paymentMethod: "upi_manual",
|
|
258
|
-
refundAmount: 50,
|
|
259
|
-
refundStatus: "completed",
|
|
260
|
-
refundNote: "Disposable test — non-winning prize-draw entry auto-refunded after reveal.",
|
|
261
263
|
orderDate: daysAgo(1),
|
|
262
264
|
createdAt: daysAgo(1),
|
|
263
265
|
updatedAt: NOW,
|
|
264
266
|
},
|
|
267
|
+
// ── Multi-item order — 5 line items so the "My Orders" list / dashboard Recent
|
|
268
|
+
// Orders widget shows real thumbnails+title+qty for the first 3 and a genuine
|
|
269
|
+
// "+2 more" badge for the rest (every other fixture above tops out at 2 items).
|
|
270
|
+
{
|
|
271
|
+
id: "order-tester-sandbox-multi-item",
|
|
272
|
+
productId: STANDARD_PRODUCT_ID,
|
|
273
|
+
productTitle: STANDARD_PRODUCT_TITLE,
|
|
274
|
+
userId: BUYER_ID,
|
|
275
|
+
userName: BUYER_NAME,
|
|
276
|
+
userEmail: BUYER_EMAIL,
|
|
277
|
+
storeId: STORE_ID,
|
|
278
|
+
storeName: STORE_NAME,
|
|
279
|
+
items: [
|
|
280
|
+
{ productId: "product-tester-standard-1", productTitle: "Test Gadget — Standard Listing #1", listingType: "standard", quantity: 1, unitPrice: 199, totalPrice: 199 },
|
|
281
|
+
{ productId: "product-tester-standard-2", productTitle: "Test Collectible — Standard Listing #2", listingType: "standard", quantity: 1, unitPrice: 149, totalPrice: 149 },
|
|
282
|
+
{ productId: "product-tester-standard-accessory-case", productTitle: "Test Accessory — Carry Case", listingType: "standard", quantity: 1, unitPrice: 99, totalPrice: 99 },
|
|
283
|
+
{ productId: "product-tester-standard-accessory-stand", productTitle: "Test Accessory — Display Stand", listingType: "standard", quantity: 2, unitPrice: 49, totalPrice: 98 },
|
|
284
|
+
{ productId: "product-tester-standard-accessory-stickers", productTitle: "Test Accessory — Sticker Set", listingType: "standard", quantity: 3, unitPrice: 19, totalPrice: 57 },
|
|
285
|
+
],
|
|
286
|
+
orderType: "standard",
|
|
287
|
+
quantity: 8,
|
|
288
|
+
unitPrice: 199,
|
|
289
|
+
totalPrice: 602,
|
|
290
|
+
currency: "INR",
|
|
291
|
+
status: "delivered",
|
|
292
|
+
paymentStatus: "paid",
|
|
293
|
+
paymentMethod: "upi_manual",
|
|
294
|
+
shippingAddress: "addr-tester-qa-home",
|
|
295
|
+
trackingNumber: "TEST-TRACK-MULTI-001",
|
|
296
|
+
shippingCarrier: "Test Carrier",
|
|
297
|
+
shippingDate: daysAgo(2),
|
|
298
|
+
deliveryDate: daysAgo(1),
|
|
299
|
+
orderDate: daysAgo(3),
|
|
300
|
+
createdAt: daysAgo(3),
|
|
301
|
+
updatedAt: daysAgo(1),
|
|
302
|
+
},
|
|
265
303
|
];
|