@mohasinac/appkit 4.9.4 → 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 (160) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +7 -2
  2. package/dist/_internal/client/features/layout/SidebarCollapseToggle.d.ts +5 -1
  3. package/dist/_internal/client/features/layout/SidebarCollapseToggle.js +8 -2
  4. package/dist/_internal/client/features/layout/sidebarPositionClasses.d.ts +20 -0
  5. package/dist/_internal/client/features/layout/sidebarPositionClasses.js +20 -0
  6. package/dist/_internal/client/hand-mode/HandModeProvider.d.ts +21 -0
  7. package/dist/_internal/client/hand-mode/HandModeProvider.js +81 -0
  8. package/dist/_internal/client/hand-mode/index.d.ts +2 -0
  9. package/dist/_internal/client/hand-mode/index.js +1 -0
  10. package/dist/_internal/server/features/auctions/actions.js +3 -2
  11. package/dist/_internal/server/features/auctions/service.d.ts +4 -3
  12. package/dist/_internal/server/features/auctions/service.js +6 -6
  13. package/dist/_internal/server/features/bundles/data.d.ts +9 -0
  14. package/dist/_internal/server/features/bundles/data.js +14 -0
  15. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  16. package/dist/_internal/server/features/bundles/index.js +1 -1
  17. package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
  18. package/dist/_internal/server/features/catalogue/og.js +27 -0
  19. package/dist/_internal/server/features/checkout/actions.d.ts +43 -0
  20. package/dist/_internal/server/features/checkout/actions.js +172 -81
  21. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  22. package/dist/_internal/server/features/checkout/index.js +1 -1
  23. package/dist/_internal/server/features/grouped/data.d.ts +12 -0
  24. package/dist/_internal/server/features/grouped/data.js +26 -1
  25. package/dist/_internal/server/features/grouped/index.d.ts +1 -1
  26. package/dist/_internal/server/features/grouped/index.js +1 -1
  27. package/dist/_internal/server/features/products/data.d.ts +23 -0
  28. package/dist/_internal/server/features/products/data.js +159 -0
  29. package/dist/_internal/server/features/products/index.d.ts +1 -1
  30. package/dist/_internal/server/features/products/index.js +1 -1
  31. package/dist/_internal/server/features/seo/robots.js +3 -2
  32. package/dist/_internal/server/features/seo/sitemap.js +70 -5
  33. package/dist/_internal/shared/config/schema.d.ts +1 -0
  34. package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
  35. package/dist/_internal/shared/features/auctions/config.js +31 -1
  36. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
  37. package/dist/_internal/shared/listing-types/art/config.js +1 -1
  38. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
  39. package/dist/_internal/shared/listing-types/classified/config.js +2 -2
  40. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
  41. package/dist/_internal/shared/listing-types/digital-code/config.js +2 -2
  42. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
  43. package/dist/_internal/shared/listing-types/live/config.js +2 -2
  44. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
  45. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  46. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
  47. package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
  48. package/dist/client.d.ts +4 -6
  49. package/dist/client.js +10 -4
  50. package/dist/constants/api-endpoints.d.ts +6 -0
  51. package/dist/constants/api-endpoints.js +2 -0
  52. package/dist/features/about/components/AboutView.js +2 -2
  53. package/dist/features/about/components/DeveloperView.js +2 -2
  54. package/dist/features/about/schemas/firestore.d.ts +1 -0
  55. package/dist/features/account/components/UserSidebar.js +8 -2
  56. package/dist/features/account/hooks/useProfile.d.ts +2 -0
  57. package/dist/features/admin/components/AdminSidebar.js +8 -2
  58. package/dist/features/admin/components/AdminSiteSettingsView.js +12 -4
  59. package/dist/features/admin/schemas/firestore.d.ts +9 -0
  60. package/dist/features/admin/schemas/firestore.js +6 -0
  61. package/dist/features/auctions/actions/bid-actions.js +4 -1
  62. package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
  63. package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
  64. package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
  65. package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
  66. package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
  67. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
  68. package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
  69. package/dist/features/auth/schemas/firestore.d.ts +3 -0
  70. package/dist/features/cart/components/CartDrawer.js +4 -1
  71. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
  72. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
  73. package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
  74. package/dist/features/catalogue/index.d.ts +2 -0
  75. package/dist/features/catalogue/index.js +1 -0
  76. package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
  77. package/dist/features/categories/components/BundleDetailView.js +3 -2
  78. package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
  79. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
  80. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
  81. package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
  82. package/dist/features/contact/components/ContactPageView.js +8 -2
  83. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
  84. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
  85. package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
  86. package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
  87. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +8 -0
  88. package/dist/features/grouped/repository/grouped-listings.repository.js +16 -0
  89. package/dist/features/homepage/components/BrandsSection.js +3 -1
  90. package/dist/features/homepage/components/FeaturedBundlesSection.js +12 -1
  91. package/dist/features/homepage/components/GoogleReviewsSection.js +2 -2
  92. package/dist/features/homepage/components/HeroCarousel.js +3 -1
  93. package/dist/features/homepage/components/SectionCarousel.js +5 -2
  94. package/dist/features/homepage/components/SocialFeedSection.js +2 -2
  95. package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -1
  96. package/dist/features/layout/BackToTop.js +3 -1
  97. package/dist/features/layout/BottomActions.js +4 -3
  98. package/dist/features/layout/BottomActionsContext.d.ts +10 -0
  99. package/dist/features/layout/BottomActionsContext.js +5 -1
  100. package/dist/features/layout/SidebarLayout.js +7 -1
  101. package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
  102. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  103. package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
  104. package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
  105. package/dist/features/media/MediaVideo.js +17 -1
  106. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
  107. package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
  108. package/dist/features/products/components/ProductDetailPageView.js +11 -116
  109. package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
  110. package/dist/features/products/components/RelatedItemsSection.js +17 -0
  111. package/dist/features/seller/components/SellerProductShell.js +1 -1
  112. package/dist/features/seller/components/SellerSidebar.js +8 -2
  113. package/dist/features/shell/QuickFormDrawer.js +3 -1
  114. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +114 -3
  115. package/dist/hand-mode/index.d.ts +12 -0
  116. package/dist/hand-mode/index.js +11 -0
  117. package/dist/index.d.ts +2 -0
  118. package/dist/index.js +1 -0
  119. package/dist/next/routing/route-map.d.ts +2 -0
  120. package/dist/next/routing/route-map.js +7 -0
  121. package/dist/react/contexts/SessionContext.d.ts +5 -0
  122. package/dist/react/contexts/SessionContext.js +2 -0
  123. package/dist/seed/bids-seed-data.js +48 -3
  124. package/dist/seed/grouped-listings-seed-data.js +167 -0
  125. package/dist/seed/payouts-seed-data.js +4 -4
  126. package/dist/seed/products-art-seed-data.js +188 -5
  127. package/dist/seed/products-auctions-seed-data.js +215 -6
  128. package/dist/seed/products-classifieds-seed-data.js +255 -8
  129. package/dist/seed/products-digital-codes-seed-data.js +258 -19
  130. package/dist/seed/products-live-items-seed-data.js +143 -10
  131. package/dist/seed/products-preorders-seed-data.js +213 -8
  132. package/dist/seed/products-prize-draws-seed-data.js +198 -0
  133. package/dist/seed/products-standard-seed-data.js +141 -0
  134. package/dist/seed/products-stickers-seed-data.js +178 -5
  135. package/dist/seed/site-settings-seed-data.js +13 -31
  136. package/dist/seed/store-extensions-seed-data.js +1 -1
  137. package/dist/server-entry.d.ts +5 -2
  138. package/dist/server-entry.js +5 -2
  139. package/dist/server.d.ts +4 -2
  140. package/dist/server.js +4 -2
  141. package/dist/styles.css +30 -1
  142. package/dist/tailwind-utilities.css +1 -1
  143. package/dist/ui/components/Drawer.js +7 -4
  144. package/dist/ui/components/FilterDrawer.js +1 -1
  145. package/dist/ui/components/HandModeRow.d.ts +12 -0
  146. package/dist/ui/components/HandModeRow.js +18 -0
  147. package/dist/ui/components/ImageLightbox.js +37 -3
  148. package/dist/ui/components/ImageLightbox.style.css +28 -0
  149. package/dist/ui/components/Layout.d.ts +5 -1
  150. package/dist/ui/components/Layout.js +2 -1
  151. package/dist/ui/components/Layout.style.css +1 -0
  152. package/dist/ui/components/ListingFilterDrawer.js +3 -1
  153. package/dist/ui/components/Modal.js +3 -1
  154. package/dist/ui/components/SideDrawer.js +8 -5
  155. package/dist/ui/components/SideModal.js +7 -4
  156. package/dist/ui/index.d.ts +1 -0
  157. package/dist/ui/index.js +1 -0
  158. package/dist/utils/media-url.d.ts +9 -0
  159. package/dist/utils/media-url.js +39 -0
  160. package/package.json +1 -1
@@ -1,12 +1,14 @@
1
1
  /*
2
- * WHY: Real (non-tester-sandbox) digital-code listing so testers and shoppers can exercise
3
- * the auto-claim digital delivery flow against permanent catalog content. Previously an
4
- * empty stub "out of scope for the minimal Beyblade-focused demo catalog" — now
5
- * populated with one companion-app unlock code, on-theme for the spinning-tops catalog.
6
- * WHAT: Exports 1 digital-code listing on Beyblade Arena — auto-claim delivery.
2
+ * WHY: Seeds a Beyblade digital-code catalog with real pool/redemption variety. The
3
+ * original 1-fixture file only ever exercised `codeDeliveryMethod:"auto-claim"` with
4
+ * `codesAvailable === codePoolSize` (i.e. no fixture ever showed a partially-redeemed
5
+ * or sold-out pool, and `manual-email` delivery was never exercised at all) — see
6
+ * CLAUDE.md seed-data blandness sweep, 2026-08-20 session.
7
+ * WHAT: Exports 7 digital-code listings on Beyblade Arena — mixed auto-claim/manual-email
8
+ * delivery, partially-redeemed and fully-sold-out pools, and expiring codes.
7
9
  *
8
10
  * EXPORTS:
9
- * productsDigitalCodesSeedData — Array of 1 Partial<ProductDocument> with listingType:"digital-code"
11
+ * productsDigitalCodesSeedData — Array of 7 Partial<ProductDocument> with listingType:"digital-code"
10
12
  *
11
13
  * @tag domain:products,digital-codes
12
14
  * @tag layer:seed
@@ -20,12 +22,12 @@ import { buildSearchTokens } from "../utils/search-tokens";
20
22
  import { seedExtMedia } from "./_helpers/media";
21
23
  export const productsDigitalCodesSeedData = [
22
24
  {
23
- id: "digitalcode-beyblade-x-app-unlock",
24
- slug: "digitalcode-beyblade-x-app-unlock",
25
- title: "Beyblade X Companion App — Premium Unlock Code",
26
- description: "Digital unlock code for the Beyblade X companion app's premium tournament tracker and battle-log features. Delivered instantly after payment.",
27
- categorySlugs: ["category-spinning-tops"],
28
- categoryNames: ["Spinning Tops"],
25
+ id: "digitalcode-beyblade-x-app-starter-pack",
26
+ slug: "digitalcode-beyblade-x-app-starter-pack",
27
+ title: "Beyblade X App — Starter Pack Code",
28
+ description: "Digital redemption code for the Beyblade X companion app's Starter Pack instantly unlocks 5 exclusive digital tops.",
29
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
30
+ categoryNames: ["Beyblade X", "Spinning Tops"],
29
31
  brandSlug: "brand-takara-tomy",
30
32
  brand: "Takara-Tomy",
31
33
  price: 199,
@@ -33,8 +35,11 @@ export const productsDigitalCodesSeedData = [
33
35
  stockQuantity: 25,
34
36
  availableQuantity: 25,
35
37
  isSold: false,
36
- mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-app-unlock-1-20260101/900/900"),
37
- images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-app-unlock-1-20260101/900/900")],
38
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-starter-1-20260101/900/900"),
39
+ images: [
40
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-starter-1-20260101/900/900"),
41
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-starter-2-20260101/900/900"),
42
+ ],
38
43
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
39
44
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
40
45
  listingType: "digital-code",
@@ -44,16 +49,250 @@ export const productsDigitalCodesSeedData = [
44
49
  codeDeliveryMethod: "auto-claim",
45
50
  codePoolSize: 25,
46
51
  codesAvailable: 25,
47
- redemptionInstructions: "Open the Beyblade X companion app, go to Settings → Redeem Code, and enter your code to unlock premium features.",
52
+ redemptionInstructions: "Open the Beyblade X app, go to Settings → Redeem Code, and paste your code to unlock the Starter Pack instantly.",
48
53
  },
49
54
  customFields: [],
50
55
  customSections: [],
51
56
  featured: false,
52
57
  isPromoted: false,
53
58
  isOnSale: false,
54
- tags: ["digital-code", "app-unlock"],
55
- createdAt: new Date("2026-05-05"),
56
- updatedAt: new Date("2026-05-05"),
57
- searchTokens: buildSearchTokens("Beyblade X Companion App — Premium Unlock Code", "Digital unlock code for the Beyblade X companion app.", "Takara-Tomy", "brand-takara-tomy", ["Spinning Tops"], ["digital-code", "app-unlock"]),
59
+ tags: ["digital-code", "app-content"],
60
+ createdAt: new Date("2026-05-06"),
61
+ updatedAt: new Date("2026-05-06"),
62
+ searchTokens: buildSearchTokens("Beyblade X App — Starter Pack Code", "Digital redemption code for the Beyblade X companion app.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade X", "Spinning Tops"], ["digital-code", "app-content"]),
63
+ },
64
+ {
65
+ id: "digitalcode-beyblade-x-app-legendary-pack",
66
+ slug: "digitalcode-beyblade-x-app-legendary-pack",
67
+ title: "Beyblade X App — Legendary Pack Code (Partially Claimed)",
68
+ description: "Unlocks 3 legendary digital tops in the companion app. Popular pack — most of the batch has already been claimed.",
69
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
70
+ categoryNames: ["Beyblade X", "Spinning Tops"],
71
+ brandSlug: "brand-takara-tomy",
72
+ brand: "Takara-Tomy",
73
+ price: 349,
74
+ currency: "INR",
75
+ stockQuantity: 40,
76
+ availableQuantity: 6,
77
+ isSold: false,
78
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-legendary-1-20260814/900/900"),
79
+ images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-legendary-1-20260814/900/900")],
80
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
81
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
82
+ listingType: "digital-code",
83
+ storeId: "store-beyblade-arena",
84
+ storeName: "Beyblade Arena",
85
+ digitalCode: {
86
+ codeDeliveryMethod: "auto-claim",
87
+ codePoolSize: 40,
88
+ codesAvailable: 6,
89
+ redemptionInstructions: "Open the Beyblade X app, go to Settings → Redeem Code, and paste your code to unlock the Legendary Pack instantly.",
90
+ expiresAt: new Date(Date.now() + 60 * 24 * 60 * 60 * 1000),
91
+ },
92
+ customFields: [],
93
+ customSections: [],
94
+ featured: true,
95
+ isPromoted: true,
96
+ isOnSale: false,
97
+ tags: ["digital-code", "app-content"],
98
+ createdAt: new Date("2026-08-14"),
99
+ updatedAt: new Date("2026-08-19"),
100
+ searchTokens: buildSearchTokens("Beyblade X App — Legendary Pack Code (Partially Claimed)", "Unlocks 3 legendary digital tops, most of the batch already claimed.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade X", "Spinning Tops"], ["digital-code", "app-content"]),
101
+ },
102
+ {
103
+ id: "digitalcode-beyblade-burst-app-sold-out",
104
+ slug: "digitalcode-beyblade-burst-app-sold-out",
105
+ title: "Beyblade Burst App — Anniversary Pack Code (Sold Out)",
106
+ description: "Limited-run anniversary code pack for the Beyblade Burst app — every code in this batch has been claimed.",
107
+ categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
108
+ categoryNames: ["Beyblade Burst", "Spinning Tops"],
109
+ brandSlug: "brand-beyblade",
110
+ brand: "Beyblade",
111
+ price: 299,
112
+ currency: "INR",
113
+ stockQuantity: 15,
114
+ availableQuantity: 0,
115
+ isSold: false,
116
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-burst-sold-out-1-20260810/900/900"),
117
+ images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-burst-sold-out-1-20260810/900/900")],
118
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
119
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
120
+ listingType: "digital-code",
121
+ storeId: "store-beyblade-arena",
122
+ storeName: "Beyblade Arena",
123
+ digitalCode: {
124
+ codeDeliveryMethod: "auto-claim",
125
+ codePoolSize: 15,
126
+ codesAvailable: 0,
127
+ redemptionInstructions: "Open the Beyblade Burst app, go to Settings → Redeem Code, and paste your code to unlock the Anniversary Pack.",
128
+ },
129
+ customFields: [],
130
+ customSections: [],
131
+ featured: false,
132
+ isPromoted: false,
133
+ isOnSale: false,
134
+ tags: ["digital-code", "app-content", "limited-run"],
135
+ createdAt: new Date("2026-08-01"),
136
+ updatedAt: new Date("2026-08-10"),
137
+ searchTokens: buildSearchTokens("Beyblade Burst App — Anniversary Pack Code (Sold Out)", "Limited-run anniversary code pack, every code claimed.", "Beyblade", "brand-beyblade", ["Beyblade Burst", "Spinning Tops"], ["digital-code", "app-content", "limited-run"]),
138
+ },
139
+ {
140
+ id: "digitalcode-beyblade-x-manual-tournament-pass",
141
+ slug: "digitalcode-beyblade-x-manual-tournament-pass",
142
+ title: "Beyblade X Regional Tournament — Digital Entry Pass",
143
+ description: "Digital entry pass for the next regional tournament, emailed manually by the organizer within 24 hours of purchase.",
144
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
145
+ categoryNames: ["Beyblade X", "Spinning Tops"],
146
+ brandSlug: "brand-takara-tomy",
147
+ brand: "Takara-Tomy",
148
+ price: 499,
149
+ currency: "INR",
150
+ stockQuantity: 50,
151
+ availableQuantity: 32,
152
+ isSold: false,
153
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-tournament-1-20260815/900/900"),
154
+ images: [
155
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-tournament-1-20260815/900/900"),
156
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-tournament-2-20260815/900/900"),
157
+ ],
158
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
159
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
160
+ listingType: "digital-code",
161
+ storeId: "store-beyblade-arena",
162
+ storeName: "Beyblade Arena",
163
+ digitalCode: {
164
+ codeDeliveryMethod: "manual-email",
165
+ codePoolSize: 50,
166
+ codesAvailable: 32,
167
+ redemptionInstructions: "Your tournament entry pass will be emailed within 24 hours of purchase. Check your spam folder if it doesn't arrive.",
168
+ expiresAt: new Date(Date.now() + 20 * 24 * 60 * 60 * 1000),
169
+ },
170
+ customFields: [{ key: "Manual Fulfillment", type: "boolean", value: "true" }],
171
+ customSections: [],
172
+ featured: false,
173
+ isPromoted: false,
174
+ isOnSale: false,
175
+ tags: ["digital-code", "tournament-grade"],
176
+ createdAt: new Date("2026-08-15"),
177
+ updatedAt: new Date("2026-08-15"),
178
+ searchTokens: buildSearchTokens("Beyblade X Regional Tournament — Digital Entry Pass", "Digital entry pass, emailed manually by the organizer.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade X", "Spinning Tops"], ["digital-code", "tournament-grade"]),
179
+ },
180
+ {
181
+ id: "digitalcode-beyblade-metal-app-classic-pack",
182
+ slug: "digitalcode-beyblade-metal-app-classic-pack",
183
+ title: "Beyblade Metal Fight App — Classic Pack Code",
184
+ description: "Unlocks the Metal Fight classic-era top roster in the companion app — Storm Pegasus, Lightning L-Drago, and more.",
185
+ categorySlugs: ["category-beyblade-metal", "category-spinning-tops"],
186
+ categoryNames: ["Beyblade Metal Fight", "Spinning Tops"],
187
+ brandSlug: "brand-takara-tomy",
188
+ brand: "Takara-Tomy",
189
+ price: 249,
190
+ currency: "INR",
191
+ stockQuantity: 30,
192
+ availableQuantity: 30,
193
+ isSold: false,
194
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-metal-classic-1-20260816/900/900"),
195
+ images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-metal-classic-1-20260816/900/900")],
196
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
197
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
198
+ listingType: "digital-code",
199
+ storeId: "store-beyblade-arena",
200
+ storeName: "Beyblade Arena",
201
+ digitalCode: {
202
+ codeDeliveryMethod: "auto-claim",
203
+ codePoolSize: 30,
204
+ codesAvailable: 30,
205
+ redemptionInstructions: "Open the Beyblade Metal Fight app, go to Settings → Redeem Code, and paste your code to unlock the Classic Pack instantly.",
206
+ },
207
+ customFields: [],
208
+ customSections: [],
209
+ featured: false,
210
+ isPromoted: false,
211
+ isOnSale: false,
212
+ tags: ["digital-code", "app-content"],
213
+ createdAt: new Date("2026-08-16"),
214
+ updatedAt: new Date("2026-08-16"),
215
+ searchTokens: buildSearchTokens("Beyblade Metal Fight App — Classic Pack Code", "Unlocks the Metal Fight classic-era top roster.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade Metal Fight", "Spinning Tops"], ["digital-code", "app-content"]),
216
+ },
217
+ {
218
+ id: "digitalcode-beyblade-burst-app-avatar-skins",
219
+ slug: "digitalcode-beyblade-burst-app-avatar-skins",
220
+ title: "Beyblade Burst App — Avatar Skin Bundle Code",
221
+ description: "Cosmetic-only code bundle — unlocks 8 exclusive player avatar skins in the Beyblade Burst app, no gameplay advantage.",
222
+ categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
223
+ categoryNames: ["Beyblade Burst", "Spinning Tops"],
224
+ brandSlug: "brand-beyblade",
225
+ brand: "Beyblade",
226
+ price: 149,
227
+ currency: "INR",
228
+ stockQuantity: 60,
229
+ availableQuantity: 41,
230
+ isSold: false,
231
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-burst-avatar-1-20260817/900/900"),
232
+ images: [seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-burst-avatar-1-20260817/900/900")],
233
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
234
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
235
+ listingType: "digital-code",
236
+ storeId: "store-beyblade-arena",
237
+ storeName: "Beyblade Arena",
238
+ digitalCode: {
239
+ codeDeliveryMethod: "auto-claim",
240
+ codePoolSize: 60,
241
+ codesAvailable: 41,
242
+ redemptionInstructions: "Open the Beyblade Burst app, go to Settings → Redeem Code, and paste your code to unlock all 8 avatar skins instantly.",
243
+ },
244
+ customFields: [{ key: "Cosmetic Only", type: "boolean", value: "true" }],
245
+ customSections: [],
246
+ featured: false,
247
+ isPromoted: false,
248
+ isOnSale: true,
249
+ tags: ["digital-code", "app-content", "cosmetic"],
250
+ createdAt: new Date("2026-08-17"),
251
+ updatedAt: new Date("2026-08-19"),
252
+ searchTokens: buildSearchTokens("Beyblade Burst App — Avatar Skin Bundle Code", "Cosmetic-only code bundle, 8 exclusive player avatar skins.", "Beyblade", "brand-beyblade", ["Beyblade Burst", "Spinning Tops"], ["digital-code", "app-content", "cosmetic"]),
253
+ },
254
+ {
255
+ id: "digitalcode-beyblade-x-manual-coaching-session",
256
+ slug: "digitalcode-beyblade-x-manual-coaching-session",
257
+ title: "1-on-1 Beyblade X Coaching Session — Digital Booking Code",
258
+ description: "Redeem this code for a 30-minute 1-on-1 video coaching session with a tournament-ranked Beyblade X player. Booking link emailed manually.",
259
+ categorySlugs: ["category-beyblade-x", "category-spinning-tops"],
260
+ categoryNames: ["Beyblade X", "Spinning Tops"],
261
+ brandSlug: "brand-takara-tomy",
262
+ brand: "Takara-Tomy",
263
+ price: 799,
264
+ currency: "INR",
265
+ stockQuantity: 10,
266
+ availableQuantity: 3,
267
+ isSold: false,
268
+ mainImage: seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-coaching-1-20260818/900/900"),
269
+ images: [
270
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-coaching-1-20260818/900/900"),
271
+ seedExtMedia("https://picsum.photos/seed/digitalcode-image-beyblade-x-coaching-2-20260818/900/900"),
272
+ ],
273
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
274
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
275
+ listingType: "digital-code",
276
+ storeId: "store-beyblade-arena",
277
+ storeName: "Beyblade Arena",
278
+ digitalCode: {
279
+ codeDeliveryMethod: "manual-email",
280
+ codePoolSize: 10,
281
+ codesAvailable: 3,
282
+ redemptionInstructions: "Your booking link and coach's availability calendar will be emailed within 24 hours of purchase.",
283
+ expiresAt: new Date(Date.now() + 45 * 24 * 60 * 60 * 1000),
284
+ },
285
+ customFields: [
286
+ { key: "Session Length", type: "text", value: "30 minutes" },
287
+ { key: "Manual Fulfillment", type: "boolean", value: "true" },
288
+ ],
289
+ customSections: [],
290
+ featured: true,
291
+ isPromoted: false,
292
+ isOnSale: false,
293
+ tags: ["digital-code", "coaching"],
294
+ createdAt: new Date("2026-08-18"),
295
+ updatedAt: new Date("2026-08-18"),
296
+ searchTokens: buildSearchTokens("1-on-1 Beyblade X Coaching Session — Digital Booking Code", "30-minute 1-on-1 video coaching session, booking link emailed manually.", "Takara-Tomy", "brand-takara-tomy", ["Beyblade X", "Spinning Tops"], ["digital-code", "coaching"]),
58
297
  },
59
298
  ];
@@ -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
+ ];