@mohasinac/appkit 4.9.5 → 4.10.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.
Files changed (108) hide show
  1. package/dist/_internal/server/features/auctions/actions.js +3 -2
  2. package/dist/_internal/server/features/auctions/service.d.ts +4 -3
  3. package/dist/_internal/server/features/auctions/service.js +6 -6
  4. package/dist/_internal/server/features/bundles/data.d.ts +9 -0
  5. package/dist/_internal/server/features/bundles/data.js +14 -0
  6. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  7. package/dist/_internal/server/features/bundles/index.js +1 -1
  8. package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
  9. package/dist/_internal/server/features/catalogue/og.js +27 -0
  10. package/dist/_internal/server/features/grouped/data.d.ts +12 -0
  11. package/dist/_internal/server/features/grouped/data.js +26 -1
  12. package/dist/_internal/server/features/grouped/index.d.ts +1 -1
  13. package/dist/_internal/server/features/grouped/index.js +1 -1
  14. package/dist/_internal/server/features/products/data.d.ts +23 -0
  15. package/dist/_internal/server/features/products/data.js +159 -0
  16. package/dist/_internal/server/features/products/index.d.ts +1 -1
  17. package/dist/_internal/server/features/products/index.js +1 -1
  18. package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
  19. package/dist/_internal/shared/features/auctions/config.js +31 -1
  20. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
  21. package/dist/_internal/shared/listing-types/art/config.js +1 -1
  22. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
  23. package/dist/_internal/shared/listing-types/classified/config.js +1 -1
  24. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
  25. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -1
  26. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
  27. package/dist/_internal/shared/listing-types/live/config.js +1 -1
  28. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
  29. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  30. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
  31. package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
  32. package/dist/client.d.ts +0 -6
  33. package/dist/client.js +1 -4
  34. package/dist/constants/api-endpoints.d.ts +3 -0
  35. package/dist/constants/api-endpoints.js +1 -0
  36. package/dist/features/admin/components/AdminSiteSettingsView.js +12 -4
  37. package/dist/features/admin/schemas/firestore.d.ts +9 -0
  38. package/dist/features/admin/schemas/firestore.js +6 -0
  39. package/dist/features/auctions/actions/bid-actions.js +4 -1
  40. package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
  41. package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
  42. package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
  43. package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
  44. package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
  45. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
  46. package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
  47. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
  48. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
  49. package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
  50. package/dist/features/catalogue/index.d.ts +2 -0
  51. package/dist/features/catalogue/index.js +1 -0
  52. package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
  53. package/dist/features/categories/components/BundleDetailView.js +3 -2
  54. package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
  55. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
  56. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
  57. package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
  58. package/dist/features/contact/components/ContactPageView.js +8 -2
  59. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
  60. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
  61. package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
  62. package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
  63. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +8 -0
  64. package/dist/features/grouped/repository/grouped-listings.repository.js +16 -0
  65. package/dist/features/layout/BottomActions.js +4 -3
  66. package/dist/features/layout/BottomActionsContext.d.ts +10 -0
  67. package/dist/features/layout/BottomActionsContext.js +5 -1
  68. package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
  69. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  70. package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
  71. package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
  72. package/dist/features/media/MediaVideo.js +17 -1
  73. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
  74. package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
  75. package/dist/features/products/components/ProductDetailPageView.js +11 -116
  76. package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
  77. package/dist/features/products/components/RelatedItemsSection.js +17 -0
  78. package/dist/features/seller/components/SellerProductShell.js +1 -1
  79. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +83 -3
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.js +1 -0
  82. package/dist/next/routing/route-map.d.ts +2 -0
  83. package/dist/next/routing/route-map.js +7 -0
  84. package/dist/seed/bids-seed-data.js +48 -3
  85. package/dist/seed/grouped-listings-seed-data.js +167 -0
  86. package/dist/seed/payouts-seed-data.js +4 -4
  87. package/dist/seed/products-art-seed-data.js +188 -5
  88. package/dist/seed/products-auctions-seed-data.js +215 -6
  89. package/dist/seed/products-classifieds-seed-data.js +255 -8
  90. package/dist/seed/products-digital-codes-seed-data.js +258 -19
  91. package/dist/seed/products-live-items-seed-data.js +143 -10
  92. package/dist/seed/products-preorders-seed-data.js +213 -8
  93. package/dist/seed/products-prize-draws-seed-data.js +198 -0
  94. package/dist/seed/products-standard-seed-data.js +141 -0
  95. package/dist/seed/products-stickers-seed-data.js +178 -5
  96. package/dist/seed/site-settings-seed-data.js +10 -29
  97. package/dist/seed/store-extensions-seed-data.js +1 -1
  98. package/dist/server-entry.d.ts +4 -1
  99. package/dist/server-entry.js +4 -1
  100. package/dist/server.d.ts +4 -2
  101. package/dist/server.js +4 -2
  102. package/dist/styles.css +29 -1
  103. package/dist/tailwind-utilities.css +1 -1
  104. package/dist/ui/components/ImageLightbox.js +37 -3
  105. package/dist/ui/components/ImageLightbox.style.css +28 -0
  106. package/dist/utils/media-url.d.ts +9 -0
  107. package/dist/utils/media-url.js +39 -0
  108. package/package.json +1 -1
@@ -1,15 +1,21 @@
1
1
  /*
2
- * WHY: `listingType: "live"` is schema-specific to animals/plants (ProductLiveItemMeta:
3
- * species, ageMonths, sex, jurisdictionAllowed, vendor verification, CITES permit)
4
- * genuinely inapplicable to this catalog's spinning-tops/collectibles theme, so left
5
- * deliberately empty in the real seed rather than forcing a nonsensical example.
6
- * Testers can still exercise the live-item buyer flow against the disposable
7
- * tester-sandbox fixture in appkit/src/features/tester/seed-data/products-tester-seed-data.ts.
8
- * WHAT: Exports an empty array — kept as a stub so seed/index.ts and the seed API route's
9
- * SEED_DATA_MAP.products concatenation keep working without a code change elsewhere.
2
+ * WHY: `listingType: "live"` requires ProductLiveItemMeta (species, age, sex, jurisdiction,
3
+ * CITES, vendor verification) fields that only make sense for live animals/plants,
4
+ * genuinely inapplicable to this catalog's spinning-tops theme. The type was
5
+ * previously left as an empty stub, meaning it had ZERO permanent-catalog examples —
6
+ * only the disposable 7-day tester sandbox ever exercised it (see CLAUDE.md seed-data
7
+ * blandness sweep, 2026-08-20 session). This file adds a small set of real fixtures,
8
+ * explicitly off-catalog-theme, so the feature (species/jurisdiction/transport/CITES
9
+ * panels, the Phase 4 full-parity detail page) has permanent data to exercise —
10
+ * following the shape already established by the tester-sandbox's dog fixture.
11
+ * Deliberately kept small (3 items) since this doesn't fit the demo brand.
12
+ * WHAT: Exports 3 live listings on Beyblade Arena — a dog, a reptile, and a plant —
13
+ * covering varied transport methods, vendor-verification states, and one CITES-
14
+ * restricted example. No categorySlugs (the Beyblade-only category tree has no
15
+ * applicable leaf for live animals/plants).
10
16
  *
11
17
  * EXPORTS:
12
- * productsLiveItemsSeedData — empty array
18
+ * productsLiveItemsSeedData — Array of 3 Partial<ProductDocument> with listingType:"live"
13
19
  *
14
20
  * @tag domain:products,live-items
15
21
  * @tag layer:seed
@@ -18,4 +24,131 @@
18
24
  * @tag consumers:seed/index.ts,seed/runner.ts
19
25
  * @tag sideEffects:none
20
26
  */
21
- export const productsLiveItemsSeedData = [];
27
+ import { PRODUCT_FIELDS } from "../constants/field-names";
28
+ import { buildSearchTokens } from "../utils/search-tokens";
29
+ import { seedExtMedia } from "./_helpers/media";
30
+ export const productsLiveItemsSeedData = [
31
+ {
32
+ id: "live-golden-retriever-puppy",
33
+ slug: "live-golden-retriever-puppy",
34
+ title: "Golden Retriever Puppy — 6 Months, Vaccinated",
35
+ description: "Friendly, vaccinated Golden Retriever puppy from a verified breeder. Comes with vaccination records and a starter care guide.",
36
+ categorySlugs: [],
37
+ categoryNames: [],
38
+ brand: "Beyblade Arena",
39
+ price: 25000,
40
+ currency: "INR",
41
+ stockQuantity: 1,
42
+ availableQuantity: 1,
43
+ isSold: false,
44
+ mainImage: seedExtMedia("https://picsum.photos/seed/live-image-golden-retriever-1-20260816/900/900"),
45
+ images: [
46
+ seedExtMedia("https://picsum.photos/seed/live-image-golden-retriever-1-20260816/900/900"),
47
+ seedExtMedia("https://picsum.photos/seed/live-image-golden-retriever-2-20260816/900/900"),
48
+ ],
49
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
50
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
51
+ listingType: "live",
52
+ storeId: "store-beyblade-arena",
53
+ storeName: "Beyblade Arena",
54
+ liveItem: {
55
+ species: "Dog (Golden Retriever)",
56
+ ageMonths: 6,
57
+ sex: "male",
58
+ careInfo: "Feed twice daily with vet-recommended puppy food. Vaccination records included; next booster due at 8 months.",
59
+ transport: { method: "in-person", insuranceIncluded: false },
60
+ jurisdictionAllowed: ["IN-MH", "IN-KA", "IN-DL"],
61
+ vendorVerified: true,
62
+ },
63
+ customFields: [],
64
+ customSections: [],
65
+ featured: false,
66
+ isPromoted: false,
67
+ isOnSale: false,
68
+ tags: ["live-item"],
69
+ createdAt: new Date("2026-08-16"),
70
+ updatedAt: new Date("2026-08-16"),
71
+ searchTokens: buildSearchTokens("Golden Retriever Puppy — 6 Months, Vaccinated", "Friendly, vaccinated Golden Retriever puppy from a verified breeder.", "Beyblade Arena", undefined, [], ["live-item"]),
72
+ },
73
+ {
74
+ id: "live-bearded-dragon-juvenile",
75
+ slug: "live-bearded-dragon-juvenile",
76
+ title: "Bearded Dragon — Juvenile, Captive-Bred",
77
+ description: "Healthy captive-bred bearded dragon, eating well on a staple diet of greens and insects. Specialist courier transport only.",
78
+ categorySlugs: [],
79
+ categoryNames: [],
80
+ brand: "Beyblade Arena",
81
+ price: 6500,
82
+ currency: "INR",
83
+ stockQuantity: 1,
84
+ availableQuantity: 1,
85
+ isSold: false,
86
+ mainImage: seedExtMedia("https://picsum.photos/seed/live-image-bearded-dragon-1-20260817/900/900"),
87
+ images: [seedExtMedia("https://picsum.photos/seed/live-image-bearded-dragon-1-20260817/900/900")],
88
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
89
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
90
+ listingType: "live",
91
+ storeId: "store-beyblade-arena",
92
+ storeName: "Beyblade Arena",
93
+ liveItem: {
94
+ species: "Bearded Dragon (Pogona vitticeps)",
95
+ ageMonths: 4,
96
+ sex: "unknown",
97
+ careInfo: "Requires a UVB-lit terrarium at 35-40°C basking zone. Staple diet: leafy greens + gut-loaded insects 3x/week.",
98
+ transport: { method: "specialist", handlingFee: 800, insuranceIncluded: true },
99
+ jurisdictionAllowed: ["IN-MH", "IN-KA"],
100
+ vendorVerified: false,
101
+ cites: "CITES-II-2026-0417",
102
+ },
103
+ customFields: [],
104
+ customSections: [],
105
+ featured: false,
106
+ isPromoted: false,
107
+ isOnSale: false,
108
+ tags: ["live-item"],
109
+ createdAt: new Date("2026-08-17"),
110
+ updatedAt: new Date("2026-08-17"),
111
+ searchTokens: buildSearchTokens("Bearded Dragon — Juvenile, Captive-Bred", "Healthy captive-bred bearded dragon, specialist courier transport only.", "Beyblade Arena", undefined, [], ["live-item"]),
112
+ },
113
+ {
114
+ id: "live-bonsai-juniper-10yr",
115
+ slug: "live-bonsai-juniper-10yr",
116
+ title: "Juniper Bonsai — 10 Years Trained",
117
+ description: "A 10-year trained juniper bonsai in a glazed ceramic pot. Low-maintenance, shipped by courier with root-ball protection.",
118
+ categorySlugs: [],
119
+ categoryNames: [],
120
+ brand: "Beyblade Arena",
121
+ price: 3200,
122
+ currency: "INR",
123
+ stockQuantity: 1,
124
+ availableQuantity: 1,
125
+ isSold: false,
126
+ mainImage: seedExtMedia("https://picsum.photos/seed/live-image-bonsai-juniper-1-20260818/900/900"),
127
+ images: [
128
+ seedExtMedia("https://picsum.photos/seed/live-image-bonsai-juniper-1-20260818/900/900"),
129
+ seedExtMedia("https://picsum.photos/seed/live-image-bonsai-juniper-2-20260818/900/900"),
130
+ ],
131
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
132
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
133
+ listingType: "live",
134
+ storeId: "store-beyblade-arena",
135
+ storeName: "Beyblade Arena",
136
+ liveItem: {
137
+ species: "Juniper (Juniperus procumbens)",
138
+ sex: "n/a",
139
+ careInfo: "Keep outdoors in indirect sunlight, water when topsoil is dry to the touch. Prune new growth every spring.",
140
+ transport: { method: "courier", handlingFee: 300, insuranceIncluded: false },
141
+ jurisdictionAllowed: ["IN-MH", "IN-KA", "IN-DL", "IN-TN", "IN-TG"],
142
+ vendorVerified: true,
143
+ },
144
+ customFields: [{ key: "Training Age", type: "text", value: "10 years" }],
145
+ customSections: [],
146
+ featured: false,
147
+ isPromoted: false,
148
+ isOnSale: false,
149
+ tags: ["live-item"],
150
+ createdAt: new Date("2026-08-18"),
151
+ updatedAt: new Date("2026-08-18"),
152
+ searchTokens: buildSearchTokens("Juniper Bonsai — 10 Years Trained", "A 10-year trained juniper bonsai in a glazed ceramic pot.", "Beyblade Arena", undefined, [], ["live-item"]),
153
+ },
154
+ ];
@@ -1,10 +1,16 @@
1
1
  /*
2
- * WHY: Seeds a minimal pre-order listing for the demo Beyblade catalog.
3
- * WHAT: Exports 1 pre-order product (Beyblade X seasonal wave) with listingType:"pre-order",
4
- * from the Beyblade Arena store.
2
+ * WHY: Seeds a Beyblade pre-order catalog with real state variety. The original 1-fixture
3
+ * file only ever exercised `preOrderProductionStatus:"in_production"` the other two
4
+ * enum values ("upcoming"/"ready_to_ship"), a sold-out reservation, and a
5
+ * non-cancellable pre-order were structurally impossible to test against permanent
6
+ * data (see CLAUDE.md seed-data blandness sweep, 2026-08-20 session).
7
+ * WHAT: Exports 7 pre-order products with listingType:"pre-order" — the original fixture
8
+ * (now with multiple images + customFields/customSections populated) plus 6 new
9
+ * ones covering every production-status value, a sold-out reservation, and a
10
+ * non-cancellable deposit-only pre-order.
5
11
  *
6
12
  * EXPORTS:
7
- * productsPreordersSeedData — Array of 1 pre-order product with listingType:"pre-order"
13
+ * productsPreordersSeedData — Array of 7 pre-order products with listingType:"pre-order"
8
14
  *
9
15
  * @tag domain:products,pre-orders
10
16
  * @tag layer:seed
@@ -34,23 +40,222 @@ const _rawPreordersSeedData = [
34
40
  brand: "Takara-Tomy",
35
41
  images: [
36
42
  seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-x-bx-08-wave-1-20260101/900/900"),
43
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-x-bx-08-wave-2-20260101/900/900"),
37
44
  ],
38
45
  isSold: false,
39
46
  availableQuantity: 1,
40
- customFields: [],
41
- customSections: [],
47
+ tags: ["booster-wave"],
48
+ customFields: [{ key: "Randomized Contents", type: "boolean", value: "true" }],
49
+ customSections: [
50
+ {
51
+ id: "whats-included",
52
+ title: "What's Included",
53
+ text: "1x randomized BX-08 top, 1x Xtreme Gear accessory, official Takara-Tomy packaging. Exact top assortment is randomized per case — no duplicate guarantee.",
54
+ },
55
+ ],
42
56
  featured: false,
43
57
  isPromoted: false,
44
58
  isOnSale: false,
45
- preOrderDeliveryDate: new Date(Date.now() + 45 * 24 * 60 * 60 * 1000), // +45 days
59
+ preOrderDeliveryDate: new Date(Date.now() + 45 * 24 * 60 * 60 * 1000),
46
60
  preOrderProductionStatus: "in_production",
47
61
  preOrderDepositPercent: 25,
48
62
  preOrderMaxQuantity: 100,
49
63
  preOrderCurrentCount: 18,
50
64
  preOrderCancellable: true,
51
- createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // -7 days
65
+ createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
52
66
  updatedAt: new Date(),
53
67
  },
68
+ {
69
+ id: "preorder-beyblade-x-bx-09-glide-ring",
70
+ storeId: "store-beyblade-arena",
71
+ brandSlug: "brand-takara-tomy",
72
+ title: "Beyblade X BX-09 Glide Ring Booster — Coming Soon",
73
+ slug: "preorder-beyblade-x-bx-09-glide-ring",
74
+ description: "Announced but not yet in production — lock in your spot for the BX-09 Glide Ring wave before it goes into manufacturing.",
75
+ price: 849,
76
+ currency: "INR",
77
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
78
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
79
+ listingType: "pre-order",
80
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
81
+ categoryNames: ["Beyblade X", "Spinning Tops"],
82
+ brand: "Takara-Tomy",
83
+ images: [
84
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-x-bx-09-glide-ring-1-20260814/900/900"),
85
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-x-bx-09-glide-ring-2-20260814/900/900"),
86
+ ],
87
+ isSold: false,
88
+ availableQuantity: 1,
89
+ tags: ["booster-wave"],
90
+ customFields: [],
91
+ customSections: [],
92
+ featured: false,
93
+ isPromoted: false,
94
+ isOnSale: false,
95
+ preOrderDeliveryDate: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000),
96
+ preOrderProductionStatus: "upcoming",
97
+ preOrderDepositPercent: 20,
98
+ preOrderMaxQuantity: 80,
99
+ preOrderCurrentCount: 6,
100
+ preOrderCancellable: true,
101
+ createdAt: new Date("2026-08-14"),
102
+ updatedAt: new Date("2026-08-14"),
103
+ },
104
+ {
105
+ id: "preorder-beyblade-burst-b-210-union",
106
+ storeId: "store-beyblade-arena",
107
+ brandSlug: "brand-beyblade",
108
+ title: "Beyblade Burst B-210 Union Achilles — Ready to Ship",
109
+ slug: "preorder-beyblade-burst-b-210-union",
110
+ description: "Production complete — Union Achilles Cover Change Loaded reservations are boxed and ready to ship as soon as the wave closes.",
111
+ price: 1099,
112
+ currency: "INR",
113
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
114
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
115
+ listingType: "pre-order",
116
+ categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
117
+ categoryNames: ["Beyblade Burst", "Spinning Tops"],
118
+ brand: "Beyblade",
119
+ images: [
120
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-burst-b-210-union-1-20260814/900/900"),
121
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-burst-b-210-union-2-20260814/900/900"),
122
+ ],
123
+ isSold: false,
124
+ availableQuantity: 1,
125
+ tags: ["stamina-type"],
126
+ specifications: [
127
+ { name: "Layer / Disc / Driver", value: "Union Achilles / Cover Change / Loaded" },
128
+ ],
129
+ customFields: [{ key: "Production Complete", type: "boolean", value: "true" }],
130
+ customSections: [],
131
+ featured: true,
132
+ isPromoted: false,
133
+ isOnSale: false,
134
+ preOrderDeliveryDate: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000),
135
+ preOrderProductionStatus: "ready_to_ship",
136
+ preOrderDepositPercent: 100,
137
+ preOrderMaxQuantity: 40,
138
+ preOrderCurrentCount: 33,
139
+ preOrderCancellable: false,
140
+ createdAt: new Date("2026-08-01"),
141
+ updatedAt: new Date("2026-08-18"),
142
+ },
143
+ {
144
+ id: "preorder-beyblade-x-bx-11-sold-out",
145
+ storeId: "store-beyblade-arena",
146
+ brandSlug: "brand-takara-tomy",
147
+ title: "Beyblade X BX-11 Limited Wave (Sold Out)",
148
+ slug: "preorder-beyblade-x-bx-11-sold-out",
149
+ description: "This limited-run pre-order wave is fully reserved — all slots claimed. Join the waitlist for the next drop.",
150
+ price: 999,
151
+ currency: "INR",
152
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
153
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
154
+ listingType: "pre-order",
155
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
156
+ categoryNames: ["Beyblade X", "Spinning Tops"],
157
+ brand: "Takara-Tomy",
158
+ images: [
159
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-x-bx-11-sold-out-1-20260812/900/900"),
160
+ ],
161
+ isSold: false,
162
+ availableQuantity: 0,
163
+ tags: ["limited-run"],
164
+ customFields: [],
165
+ customSections: [],
166
+ featured: false,
167
+ isPromoted: false,
168
+ isOnSale: false,
169
+ preOrderDeliveryDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
170
+ preOrderProductionStatus: "in_production",
171
+ preOrderDepositPercent: 25,
172
+ preOrderMaxQuantity: 25,
173
+ preOrderCurrentCount: 25,
174
+ preOrderCancellable: true,
175
+ createdAt: new Date("2026-08-12"),
176
+ updatedAt: new Date("2026-08-19"),
177
+ },
178
+ {
179
+ id: "preorder-beyblade-burst-b-215-hells-scythe",
180
+ storeId: "store-beyblade-arena",
181
+ brandSlug: "brand-beyblade",
182
+ title: "Beyblade Burst B-215 Hells Scythe — Deposit Locked",
183
+ slug: "preorder-beyblade-burst-b-215-hells-scythe",
184
+ description: "Hells Scythe Giga Reboost, a full-payment pre-order — no cancellation once reserved, guaranteeing your slot in a strictly limited case allocation.",
185
+ price: 1299,
186
+ currency: "INR",
187
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
188
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
189
+ listingType: "pre-order",
190
+ categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
191
+ categoryNames: ["Beyblade Burst", "Spinning Tops"],
192
+ brand: "Beyblade",
193
+ images: [
194
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-burst-b-215-hells-scythe-1-20260817/900/900"),
195
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-burst-b-215-hells-scythe-2-20260817/900/900"),
196
+ ],
197
+ isSold: false,
198
+ availableQuantity: 1,
199
+ tags: ["attack-type", "limited-run"],
200
+ specifications: [
201
+ { name: "Layer / Disc / Driver", value: "Hells Scythe / Giga / Reboost" },
202
+ ],
203
+ customFields: [{ key: "Full Payment Required", type: "boolean", value: "true" }],
204
+ customSections: [],
205
+ featured: false,
206
+ isPromoted: false,
207
+ isOnSale: false,
208
+ preOrderDeliveryDate: new Date(Date.now() + 60 * 24 * 60 * 60 * 1000),
209
+ preOrderProductionStatus: "in_production",
210
+ preOrderDepositPercent: 100,
211
+ preOrderMaxQuantity: 20,
212
+ preOrderCurrentCount: 9,
213
+ preOrderCancellable: false,
214
+ createdAt: new Date("2026-08-17"),
215
+ updatedAt: new Date("2026-08-17"),
216
+ },
217
+ {
218
+ id: "preorder-beyblade-original-remaster",
219
+ storeId: "store-beyblade-arena",
220
+ brandSlug: "brand-beyblade",
221
+ title: "Beyblade Original Remaster Set — Announced",
222
+ slug: "preorder-beyblade-original-remaster",
223
+ description: "A 25th-anniversary remaster of the original 1999 lineup, freshly announced. Production hasn't started — early reservations lock in launch pricing.",
224
+ price: 1899,
225
+ currency: "INR",
226
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
227
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
228
+ listingType: "pre-order",
229
+ categorySlugs: ["category-beyblade-original", "category-spinning-tops"],
230
+ categoryNames: ["Beyblade Original", "Spinning Tops"],
231
+ brand: "Beyblade",
232
+ images: [
233
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-original-remaster-1-20260818/900/900"),
234
+ seedExtMedia("https://picsum.photos/seed/preorder-image-beyblade-original-remaster-2-20260818/900/900"),
235
+ ],
236
+ isSold: false,
237
+ availableQuantity: 1,
238
+ tags: ["vintage-collectible", "limited-run"],
239
+ customFields: [{ key: "Anniversary Edition", type: "boolean", value: "true" }],
240
+ customSections: [
241
+ {
242
+ id: "whats-included",
243
+ title: "What's Included",
244
+ text: "Remastered Dranzer S + Driger V pair, commemorative case, and a numbered certificate of authenticity.",
245
+ },
246
+ ],
247
+ featured: true,
248
+ isPromoted: true,
249
+ isOnSale: false,
250
+ preOrderDeliveryDate: new Date(Date.now() + 120 * 24 * 60 * 60 * 1000),
251
+ preOrderProductionStatus: "upcoming",
252
+ preOrderDepositPercent: 15,
253
+ preOrderMaxQuantity: 200,
254
+ preOrderCurrentCount: 47,
255
+ preOrderCancellable: true,
256
+ createdAt: new Date("2026-08-18"),
257
+ updatedAt: new Date("2026-08-18"),
258
+ },
54
259
  ];
55
260
  export const productsPreordersSeedData = _rawPreordersSeedData.map((p) => ({
56
261
  tags: [],
@@ -112,4 +112,202 @@ export const productsPrizeDrawsSeedData = [
112
112
  updatedAt: new Date("2026-05-01"),
113
113
  searchTokens: buildSearchTokens("Beyblade Champion's Draw — Prize Draw", "Two entries, two prizes, revealed automatically at close or sellout.", "Beyblade", "brand-beyblade", ["Spinning Tops"], ["prize-draw", "mystery-box"]),
114
114
  },
115
+ // --- Partially sold: prizeCurrentEntries > 0, main seed never exercised this before ---
116
+ {
117
+ id: "prizedraw-beyblade-x-legendary-vault",
118
+ slug: "prizedraw-beyblade-x-legendary-vault",
119
+ title: "Beyblade X Legendary Vault — Prize Draw",
120
+ description: "6 entries, 6 prizes ranging from a legendary chase top to spare parts — over half the draw is already sold, don't miss the remaining slots.",
121
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
122
+ categoryNames: ["Beyblade X", "Spinning Tops"],
123
+ brandSlug: "brand-takara-tomy",
124
+ brand: "Takara-Tomy",
125
+ price: 199,
126
+ currency: "INR",
127
+ stockQuantity: 6,
128
+ availableQuantity: 2,
129
+ isSold: false,
130
+ mainImage: seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-x-legendary-vault-1-20260815/900/900"),
131
+ images: [
132
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-x-legendary-vault-1-20260815/900/900"),
133
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-x-legendary-vault-2-20260815/900/900"),
134
+ ],
135
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
136
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
137
+ listingType: "prize-draw",
138
+ storeId: "store-letitrip-official",
139
+ storeName: "LetItRip Official",
140
+ prizeDrawMode: "reveal",
141
+ prizeRevealMode: "instant",
142
+ pricePerEntry: 199,
143
+ prizeMaxEntries: 6,
144
+ prizeCurrentEntries: 4,
145
+ prizeDrawDurationDays: 10,
146
+ prizeRevealWindowStart: new Date("2026-08-15"),
147
+ prizeRevealWindowEnd: new Date("2026-08-25"),
148
+ prizeRevealStatus: "open",
149
+ prizeDrawItems: [
150
+ { itemNumber: 1, title: "Legendary Wizard Fafnir (Chase Top)", description: "The grand-prize chase top for this draw.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-1-20260815/600/600"), seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-1b-20260815/600/600")], condition: "new", estimatedValue: 4999, isWon: false },
151
+ { itemNumber: 2, title: "Beyblade X Starter Set", description: "Full starter set with launcher.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-2-20260815/600/600")], condition: "new", estimatedValue: 1299, isWon: false },
152
+ { itemNumber: 3, title: "Xtreme Gear Stadium", description: "Official X-format battle stadium.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-3-20260815/600/600")], condition: "new", estimatedValue: 999, isWon: false },
153
+ { itemNumber: 4, title: "Ratchet & Bit Multipack", description: "Assorted performance ratchets and bits.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-4-20260815/600/600")], condition: "new", estimatedValue: 599, isWon: false },
154
+ { itemNumber: 5, title: "Carry Case", description: "6-slot hard-shell carry case.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-5-20260815/600/600")], condition: "new", estimatedValue: 349, isWon: false },
155
+ { itemNumber: 6, title: "Spare Launcher Grip", description: "Standard replacement launcher grip.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-legendary-vault-6-20260815/600/600")], condition: "new", estimatedValue: 149, isWon: false },
156
+ ],
157
+ customFields: [],
158
+ customSections: [],
159
+ featured: true,
160
+ isPromoted: true,
161
+ isOnSale: false,
162
+ tags: ["prize-draw", "mystery-box", "chase-top"],
163
+ createdAt: new Date("2026-08-15"),
164
+ updatedAt: new Date("2026-08-19"),
165
+ searchTokens: buildSearchTokens("Beyblade X Legendary Vault — Prize Draw", "6 entries, 6 prizes, over half already sold.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade X", "Spinning Tops"], ["prize-draw", "mystery-box", "chase-top"]),
166
+ },
167
+ // --- Closed + revealed: real winners, isWon:true — permanent-catalog example (previously only in tester sandbox) ---
168
+ {
169
+ id: "prizedraw-beyblade-metal-closed-revealed",
170
+ slug: "prizedraw-beyblade-metal-closed-revealed",
171
+ title: "Metal Fight Mystery Draw — Ended (Revealed)",
172
+ description: "This draw has closed and every prize has been revealed to its winner. Browse the results below.",
173
+ categorySlugs: ["category-beyblade-metal", "category-spinning-tops"],
174
+ categoryNames: ["Beyblade Metal Fight", "Spinning Tops"],
175
+ brandSlug: "brand-takara-tomy",
176
+ brand: "Takara-Tomy",
177
+ price: 129,
178
+ currency: "INR",
179
+ stockQuantity: 3,
180
+ availableQuantity: 0,
181
+ isSold: true,
182
+ mainImage: seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-metal-closed-1-20260805/900/900"),
183
+ images: [seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-metal-closed-1-20260805/900/900")],
184
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
185
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
186
+ listingType: "prize-draw",
187
+ storeId: "store-letitrip-official",
188
+ storeName: "LetItRip Official",
189
+ prizeDrawMode: "reveal",
190
+ prizeRevealMode: "instant",
191
+ pricePerEntry: 129,
192
+ prizeMaxEntries: 3,
193
+ prizeCurrentEntries: 3,
194
+ prizeDrawDurationDays: 7,
195
+ prizeRevealWindowStart: new Date("2026-08-05"),
196
+ prizeRevealWindowEnd: new Date("2026-08-12"),
197
+ prizeRevealStatus: "closed",
198
+ prizeDrawItems: [
199
+ { itemNumber: 1, title: "Lightning L-Drago 100HF/S", description: "Metal Fury era attack top.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-metal-closed-1-20260805/600/600")], condition: "new", estimatedValue: 2299, isWon: true, wonByOrderId: "order-1-20260812-a1b2c3" },
200
+ { itemNumber: 2, title: "Storm Pegasus 105RF", description: "Metal Fusion era attack top.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-metal-closed-2-20260805/600/600")], condition: "new", estimatedValue: 1299, isWon: true, wonByOrderId: "order-1-20260812-d4e5f6" },
201
+ { itemNumber: 3, title: "Spare Parts Bundle", description: "Assorted spare tips and rings.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-metal-closed-3-20260805/600/600")], condition: "new", estimatedValue: 399, isWon: true, wonByOrderId: "order-1-20260812-g7h8i9" },
202
+ ],
203
+ customFields: [],
204
+ customSections: [],
205
+ featured: false,
206
+ isPromoted: false,
207
+ isOnSale: false,
208
+ tags: ["prize-draw", "mystery-box"],
209
+ createdAt: new Date("2026-08-05"),
210
+ updatedAt: new Date("2026-08-12"),
211
+ searchTokens: buildSearchTokens("Metal Fight Mystery Draw — Ended (Revealed)", "This draw has closed and every prize has been revealed.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade Metal Fight", "Spinning Tops"], ["prize-draw", "mystery-box"]),
212
+ },
213
+ // --- Nearly sold out, scheduled reveal ---
214
+ {
215
+ id: "prizedraw-beyblade-burst-collectors-draw",
216
+ slug: "prizedraw-beyblade-burst-collectors-draw",
217
+ title: "Beyblade Burst Collector's Draw — Almost Sold Out",
218
+ description: "Only 1 entry left — 4 of 5 slots are already claimed for this Burst-generation collector's draw. Winners revealed the moment the draw closes.",
219
+ categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
220
+ categoryNames: ["Beyblade Burst", "Spinning Tops"],
221
+ brandSlug: "brand-beyblade",
222
+ brand: "Beyblade",
223
+ price: 179,
224
+ currency: "INR",
225
+ stockQuantity: 5,
226
+ availableQuantity: 1,
227
+ isSold: false,
228
+ mainImage: seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-burst-collectors-1-20260817/900/900"),
229
+ images: [
230
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-burst-collectors-1-20260817/900/900"),
231
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-burst-collectors-2-20260817/900/900"),
232
+ ],
233
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
234
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
235
+ listingType: "prize-draw",
236
+ storeId: "store-letitrip-official",
237
+ storeName: "LetItRip Official",
238
+ prizeDrawMode: "reveal",
239
+ prizeRevealMode: "scheduled",
240
+ pricePerEntry: 179,
241
+ prizeMaxEntries: 5,
242
+ prizeCurrentEntries: 4,
243
+ prizeDrawDurationDays: 4,
244
+ prizeRevealWindowStart: new Date("2026-08-17"),
245
+ prizeRevealWindowEnd: new Date("2026-08-21"),
246
+ prizeRevealStatus: "open",
247
+ prizeDrawItems: [
248
+ { itemNumber: 1, title: "Cho-Z Achilles.Ow.Zn'", description: "Super Zeta stamina-type top.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-burst-collectors-1-20260817/600/600")], condition: "new", estimatedValue: 1799, isWon: false },
249
+ { itemNumber: 2, title: "Regalia Genesis.Zt", description: "Attack-type top with switch launcher compatibility.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-burst-collectors-2-20260817/600/600")], condition: "new", estimatedValue: 1399, isWon: false },
250
+ { itemNumber: 3, title: "Union Achilles Cover Change", description: "Stamina-type with cover-change layer.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-burst-collectors-3-20260817/600/600")], condition: "new", estimatedValue: 1099, isWon: false },
251
+ { itemNumber: 4, title: "Beystadium Attack Type", description: "Compact battle stadium.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-burst-collectors-4-20260817/600/600")], condition: "new", estimatedValue: 699, isWon: false },
252
+ { itemNumber: 5, title: "Spare Driver Multipack", description: "Assorted performance drivers.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-burst-collectors-5-20260817/600/600")], condition: "new", estimatedValue: 349, isWon: false },
253
+ ],
254
+ customFields: [],
255
+ customSections: [],
256
+ featured: false,
257
+ isPromoted: false,
258
+ isOnSale: false,
259
+ tags: ["prize-draw", "mystery-box"],
260
+ createdAt: new Date("2026-08-17"),
261
+ updatedAt: new Date("2026-08-19"),
262
+ searchTokens: buildSearchTokens("Beyblade Burst Collector's Draw — Almost Sold Out", "Only 1 entry left, 4 of 5 slots already claimed.", "Beyblade", "brand-beyblade", ["Beyblade Burst", "Spinning Tops"], ["prize-draw", "mystery-box"]),
263
+ },
264
+ // --- High-value vintage vault, multi-image collage per prize ---
265
+ {
266
+ id: "prizedraw-beyblade-original-vintage-vault",
267
+ slug: "prizedraw-beyblade-original-vintage-vault",
268
+ title: "Beyblade Original Vintage Vault — Prize Draw",
269
+ description: "A high-value original-series vault — 3 entries, each prize photographed from multiple angles so you know exactly what you might win.",
270
+ categorySlugs: ["category-beyblade-original", "category-spinning-tops"],
271
+ categoryNames: ["Beyblade Original", "Spinning Tops"],
272
+ brandSlug: "brand-beyblade",
273
+ brand: "Beyblade",
274
+ price: 299,
275
+ currency: "INR",
276
+ stockQuantity: 3,
277
+ availableQuantity: 3,
278
+ isSold: false,
279
+ mainImage: seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-original-vault-1-20260818/900/900"),
280
+ images: [
281
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-original-vault-1-20260818/900/900"),
282
+ seedExtMedia("https://picsum.photos/seed/prizedraw-image-beyblade-original-vault-2-20260818/900/900"),
283
+ ],
284
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
285
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
286
+ listingType: "prize-draw",
287
+ storeId: "store-letitrip-official",
288
+ storeName: "LetItRip Official",
289
+ prizeDrawMode: "reveal",
290
+ prizeRevealMode: "instant",
291
+ pricePerEntry: 299,
292
+ prizeMaxEntries: 3,
293
+ prizeCurrentEntries: 0,
294
+ prizeDrawDurationDays: 14,
295
+ prizeRevealWindowStart: new Date("2026-08-18"),
296
+ prizeRevealWindowEnd: new Date("2026-09-01"),
297
+ prizeRevealStatus: "open",
298
+ prizeDrawItems: [
299
+ { itemNumber: 1, title: "Sealed Dragoon Storm (Grail Piece)", description: "Sealed, unopened — the rarest prize in this vault.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-1a-20260818/600/600"), seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-1b-20260818/600/600"), seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-1c-20260818/600/600")], condition: "new", estimatedValue: 5999, isWon: false },
300
+ { itemNumber: 2, title: "Seaborg 2000 (Defense)", description: "Rare original-series defense-type top.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-2a-20260818/600/600"), seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-2b-20260818/600/600")], condition: "good", estimatedValue: 3499, isWon: false },
301
+ { itemNumber: 3, title: "Original-Series Launcher Set", description: "Complete launcher + ripcord set.", images: [seedExtMedia("https://picsum.photos/seed/prizedraw-item-original-vault-3-20260818/600/600")], condition: "new", estimatedValue: 599, isWon: false },
302
+ ],
303
+ customFields: [{ key: "Authenticity Verified", type: "boolean", value: "true" }],
304
+ customSections: [],
305
+ featured: true,
306
+ isPromoted: false,
307
+ isOnSale: false,
308
+ tags: ["prize-draw", "mystery-box", "vintage-collectible"],
309
+ createdAt: new Date("2026-08-18"),
310
+ updatedAt: new Date("2026-08-18"),
311
+ searchTokens: buildSearchTokens("Beyblade Original Vintage Vault — Prize Draw", "High-value original-series vault, multi-angle photos per prize.", "Beyblade", "brand-beyblade", ["Beyblade Original", "Spinning Tops"], ["prize-draw", "mystery-box", "vintage-collectible"]),
312
+ },
115
313
  ];