@mohasinac/appkit 4.42.18 → 4.44.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 (263) hide show
  1. package/dist/_internal/client/features/lottery/LotteryDetailView.js +22 -1
  2. package/dist/_internal/server/features/categories/adapters.d.ts +47 -0
  3. package/dist/_internal/server/features/categories/adapters.js +235 -0
  4. package/dist/_internal/server/features/checkout/actions.js +161 -22
  5. package/dist/_internal/server/features/checkout/expand-order-items.js +34 -0
  6. package/dist/_internal/server/features/orders/adapters.js +21 -0
  7. package/dist/_internal/server/features/products/list-public.d.ts +24 -0
  8. package/dist/_internal/server/features/products/list-public.js +10 -2
  9. package/dist/_internal/server/features/refunds/actions.js +1 -1
  10. package/dist/_internal/server/features/seo/sitemap.js +54 -15
  11. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  12. package/dist/_internal/server/features/stores/adapters.js +6 -0
  13. package/dist/_internal/server/functions/scheduled.d.ts +4 -2
  14. package/dist/_internal/server/functions/scheduled.js +64 -6
  15. package/dist/_internal/server/jobs/core/adminAnalytics.d.ts +0 -1
  16. package/dist/_internal/server/jobs/core/adminAnalytics.js +9 -1
  17. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.d.ts +47 -0
  18. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +468 -0
  19. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +14 -1
  20. package/dist/_internal/server/jobs/core/countersReconcile.js +24 -8
  21. package/dist/_internal/server/jobs/core/onCategoryWrite.js +59 -0
  22. package/dist/_internal/server/jobs/core/onProductWrite.js +31 -0
  23. package/dist/_internal/server/jobs/core/onReviewWrite.js +8 -0
  24. package/dist/_internal/server/jobs/core/onStoreWrite.d.ts +1 -1
  25. package/dist/_internal/server/jobs/core/onStoreWrite.js +8 -2
  26. package/dist/_internal/server/jobs/core/priceIndexRollup.d.ts +47 -0
  27. package/dist/_internal/server/jobs/core/priceIndexRollup.js +234 -0
  28. package/dist/_internal/server/jobs/core/revalidateNotify.d.ts +28 -0
  29. package/dist/_internal/server/jobs/core/revalidateNotify.js +125 -0
  30. package/dist/_internal/server/jobs/core/{testerSandboxCleanup.d.ts → testDataCleanup.d.ts} +3 -3
  31. package/dist/_internal/server/jobs/core/{testerSandboxCleanup.js → testDataCleanup.js} +3 -3
  32. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -1
  33. package/dist/_internal/server/jobs/handlers/analyticsAlertEvaluate.d.ts +2 -0
  34. package/dist/_internal/server/jobs/handlers/analyticsAlertEvaluate.js +2 -0
  35. package/dist/_internal/server/jobs/handlers/index.d.ts +3 -1
  36. package/dist/_internal/server/jobs/handlers/index.js +3 -1
  37. package/dist/_internal/server/jobs/handlers/messages.d.ts +5 -2
  38. package/dist/_internal/server/jobs/handlers/messages.js +5 -2
  39. package/dist/_internal/server/jobs/handlers/priceIndexRollup.d.ts +2 -0
  40. package/dist/_internal/server/jobs/handlers/priceIndexRollup.js +2 -0
  41. package/dist/_internal/server/jobs/handlers/testDataCleanup.d.ts +2 -0
  42. package/dist/_internal/server/jobs/handlers/testDataCleanup.js +2 -0
  43. package/dist/_internal/shared/actions/action-registry.js +34 -0
  44. package/dist/_internal/shared/cache/revalidate-targets.d.ts +49 -0
  45. package/dist/_internal/shared/cache/revalidate-targets.js +157 -0
  46. package/dist/_internal/shared/checkout/order-math.d.ts +113 -3
  47. package/dist/_internal/shared/checkout/order-math.js +194 -7
  48. package/dist/_internal/shared/features/categories/price-guidance.d.ts +110 -0
  49. package/dist/_internal/shared/features/categories/price-guidance.js +136 -0
  50. package/dist/_internal/shared/features/site-settings/gst-registration.d.ts +90 -0
  51. package/dist/_internal/shared/features/site-settings/gst-registration.js +126 -0
  52. package/dist/_internal/shared/fees/calculator.d.ts +105 -0
  53. package/dist/_internal/shared/fees/calculator.js +143 -0
  54. package/dist/_internal/shared/listing-types/art/config.d.ts +0 -6
  55. package/dist/_internal/shared/listing-types/classified/config.d.ts +0 -6
  56. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +0 -6
  57. package/dist/_internal/shared/listing-types/live/config.d.ts +0 -6
  58. package/dist/_internal/shared/listing-types/standard/config.d.ts +0 -6
  59. package/dist/_internal/shared/listing-types/stickers/config.d.ts +0 -6
  60. package/dist/_internal/shared/templating/placeholders.d.ts +70 -0
  61. package/dist/_internal/shared/templating/placeholders.js +73 -0
  62. package/dist/client.d.ts +2 -0
  63. package/dist/client.js +1 -0
  64. package/dist/constants/api-endpoints.d.ts +42 -0
  65. package/dist/constants/api-endpoints.js +14 -0
  66. package/dist/features/admin/actions/admin-actions.d.ts +1 -1
  67. package/dist/features/admin/actions/admin-actions.js +1 -1
  68. package/dist/features/admin/components/AdminCategoryEditorView.js +269 -3
  69. package/dist/features/admin/components/AdminProductEditorView.js +8 -1
  70. package/dist/features/admin/components/AdminProductsView.js +78 -7
  71. package/dist/features/admin/components/AdminSiteSettingsView.js +20 -1
  72. package/dist/features/admin/components/AdminTaxCodeEditorView.d.ts +10 -0
  73. package/dist/features/admin/components/AdminTaxCodeEditorView.js +160 -0
  74. package/dist/features/admin/components/AdminTaxCodesView.d.ts +13 -0
  75. package/dist/features/admin/components/AdminTaxCodesView.js +86 -0
  76. package/dist/features/admin/components/AdminTesterChecklistView.js +1 -1
  77. package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
  78. package/dist/features/auctions/components/AuctionBottomActions.js +10 -1
  79. package/dist/features/auctions/components/AuctionDetailPageView.js +2 -1
  80. package/dist/features/auctions/components/AuctionLiveStatusBadge.d.ts +20 -0
  81. package/dist/features/auctions/components/AuctionLiveStatusBadge.js +21 -0
  82. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -1
  83. package/dist/features/auctions/components/PlaceBidFormClient.js +20 -2
  84. package/dist/features/auctions/hooks/useIsAuctionEnded.d.ts +41 -0
  85. package/dist/features/auctions/hooks/useIsAuctionEnded.js +76 -0
  86. package/dist/features/auth/schemas/firestore.d.ts +0 -1
  87. package/dist/features/blog/api/route.js +16 -1
  88. package/dist/features/blog/schemas/firestore.d.ts +2 -2
  89. package/dist/features/catalogue/components/CatalogueItemEditorView.js +14 -3
  90. package/dist/features/categories/actions/category-actions.d.ts +2 -2
  91. package/dist/features/categories/actions/category-actions.js +22 -10
  92. package/dist/features/categories/api/[id]/description-template/route.d.ts +45 -0
  93. package/dist/features/categories/api/[id]/description-template/route.js +252 -0
  94. package/dist/features/categories/api/route.js +156 -11
  95. package/dist/features/categories/components/CategoriesIndexListing.d.ts +1 -3
  96. package/dist/features/categories/components/CategoriesIndexListing.js +1 -1
  97. package/dist/features/categories/components/CategoriesIndexPageView.d.ts +27 -1
  98. package/dist/features/categories/components/CategoriesIndexPageView.js +24 -33
  99. package/dist/features/categories/components/CategoryDetailPageView.js +43 -10
  100. package/dist/features/categories/components/CategoryTemplatePicker.d.ts +65 -0
  101. package/dist/features/categories/components/CategoryTemplatePicker.js +170 -0
  102. package/dist/features/categories/constants/listing-categories.d.ts +17 -0
  103. package/dist/features/categories/constants/listing-categories.js +53 -0
  104. package/dist/features/categories/hooks/useCategoryTree.js +28 -2
  105. package/dist/features/categories/repository/categories.repository.d.ts +73 -12
  106. package/dist/features/categories/repository/categories.repository.js +203 -42
  107. package/dist/features/categories/repository/price-index.repository.d.ts +115 -0
  108. package/dist/features/categories/repository/price-index.repository.js +85 -0
  109. package/dist/features/categories/schemas/category-content.d.ts +206 -0
  110. package/dist/features/categories/schemas/category-content.js +28 -0
  111. package/dist/features/categories/schemas/firestore.d.ts +74 -5
  112. package/dist/features/categories/schemas/firestore.js +74 -3
  113. package/dist/features/categories/schemas/index.d.ts +1047 -0
  114. package/dist/features/categories/schemas/index.js +96 -0
  115. package/dist/features/categories/server.d.ts +1 -0
  116. package/dist/features/categories/server.js +7 -0
  117. package/dist/features/categories/types/index.d.ts +9 -0
  118. package/dist/features/events/schemas/firestore.d.ts +2 -2
  119. package/dist/features/faq/schemas/firestore.d.ts +2 -1
  120. package/dist/features/faq/schemas/firestore.js +20 -8
  121. package/dist/features/faq/utils/getHomepageFaqsCached.d.ts +20 -0
  122. package/dist/features/faq/utils/getHomepageFaqsCached.js +22 -0
  123. package/dist/features/homepage/components/MarketplaceHomepageView.js +13 -3
  124. package/dist/features/homepage/lib/live-stats.js +18 -8
  125. package/dist/features/media/MediaImage.js +19 -2
  126. package/dist/features/orders/schemas/firestore.d.ts +70 -0
  127. package/dist/features/orders/types/index.d.ts +55 -0
  128. package/dist/features/products/actions/product-actions.d.ts +0 -9
  129. package/dist/features/products/actions/product-actions.js +25 -0
  130. package/dist/features/products/columns/index.d.ts +0 -1
  131. package/dist/features/products/columns/index.js +5 -1
  132. package/dist/features/products/components/ArtStickersListView.js +7 -1
  133. package/dist/features/products/components/PrizeDrawsSection.js +5 -0
  134. package/dist/features/products/components/ProductFilters.d.ts +0 -9
  135. package/dist/features/products/components/ProductForm.d.ts +27 -1
  136. package/dist/features/products/components/ProductForm.js +26 -12
  137. package/dist/features/products/components/ProductsIndexPageView.js +1 -1
  138. package/dist/features/products/constants/sieve.d.ts +0 -6
  139. package/dist/features/products/constants/sieve.js +35 -2
  140. package/dist/features/products/repository/products.repository.d.ts +115 -1
  141. package/dist/features/products/repository/products.repository.js +491 -39
  142. package/dist/features/products/schemas/firestore.d.ts +65 -5
  143. package/dist/features/products/schemas/firestore.js +9 -0
  144. package/dist/features/products/schemas/product-features.d.ts +140 -2
  145. package/dist/features/products/schemas/product-features.js +62 -1
  146. package/dist/features/promotions/repository/coupons.repository.js +6 -1
  147. package/dist/features/promotions/schemas/firestore.d.ts +44 -1
  148. package/dist/features/promotions/schemas/firestore.js +76 -2
  149. package/dist/features/reviews/repository/reviews.repository.d.ts +22 -0
  150. package/dist/features/reviews/repository/reviews.repository.js +35 -0
  151. package/dist/features/seller/actions/seller-actions.js +17 -2
  152. package/dist/features/seller/components/PrintCenterView.d.ts +3 -2
  153. package/dist/features/seller/components/PrintCenterView.js +3 -2
  154. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +21 -11
  155. package/dist/features/seller/components/SellerOrdersView.js +6 -1
  156. package/dist/features/seller/components/SellerPayoutSettingsView.js +19 -3
  157. package/dist/features/seller/components/SellerProductShell.d.ts +50 -2
  158. package/dist/features/seller/components/SellerProductShell.js +101 -9
  159. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +13 -1
  160. package/dist/features/seller/components/SellerProductsFilterDrawer.js +2 -2
  161. package/dist/features/seller/components/SellerProductsView.js +108 -3
  162. package/dist/features/seller/types/index.d.ts +17 -0
  163. package/dist/features/seller/utils/product-draft-mapping.d.ts +13 -0
  164. package/dist/features/seller/utils/product-draft-mapping.js +17 -0
  165. package/dist/features/store-extensions/constants/alert-metrics.d.ts +86 -0
  166. package/dist/features/store-extensions/constants/alert-metrics.js +142 -0
  167. package/dist/features/store-extensions/schemas/firestore.d.ts +19 -1
  168. package/dist/features/stores/schemas/firestore.d.ts +31 -2
  169. package/dist/features/tax-codes/repository/tax-codes.repository.d.ts +55 -0
  170. package/dist/features/tax-codes/repository/tax-codes.repository.js +131 -0
  171. package/dist/features/tax-codes/schemas/firestore.d.ts +125 -0
  172. package/dist/features/tax-codes/schemas/firestore.js +82 -0
  173. package/dist/features/tax-codes/schemas/tax-code-form.d.ts +63 -0
  174. package/dist/features/tax-codes/schemas/tax-code-form.js +152 -0
  175. package/dist/features/tax-codes/schemas/tax-codes.validators.d.ts +107 -0
  176. package/dist/features/tax-codes/schemas/tax-codes.validators.js +85 -0
  177. package/dist/features/tester/actions/index.d.ts +0 -1
  178. package/dist/features/tester/actions/index.js +0 -1
  179. package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +1 -1
  180. package/dist/features/tester/components/AdminTesterFeedbackListView.js +1 -1
  181. package/dist/features/tester/components/index.d.ts +0 -4
  182. package/dist/features/tester/components/index.js +0 -2
  183. package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +1 -20
  184. package/dist/features/tester/repository/tester-checklist-item.repository.js +0 -52
  185. package/dist/features/tester/schemas/firestore.d.ts +0 -6
  186. package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.js +3 -3
  187. package/dist/features/tester/seed-data/authored/admin__site-system.js +4 -5
  188. package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.js +2 -2
  189. package/dist/features/tester/seed-data/authored/index.js +0 -2
  190. package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +0 -19
  191. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +10 -29
  192. package/dist/index.d.ts +21 -7
  193. package/dist/index.js +53 -7
  194. package/dist/next/routing/route-map.d.ts +2 -4
  195. package/dist/next/routing/route-map.js +1 -2
  196. package/dist/repositories/index.d.ts +1 -0
  197. package/dist/repositories/index.js +1 -0
  198. package/dist/schemas/registry.d.ts +506 -0
  199. package/dist/seed/_helpers/brand-rows.d.ts +35 -0
  200. package/dist/seed/_helpers/brand-rows.js +576 -0
  201. package/dist/seed/_helpers/category-content.d.ts +39 -0
  202. package/dist/seed/_helpers/category-content.js +634 -0
  203. package/dist/seed/_helpers/category-forest.d.ts +2 -0
  204. package/dist/seed/_helpers/category-forest.js +585 -243
  205. package/dist/seed/_helpers/category-models.d.ts +5 -0
  206. package/dist/seed/_helpers/category-models.js +1364 -0
  207. package/dist/seed/_helpers/category-tree.js +17 -1
  208. package/dist/seed/_helpers/character-features.d.ts +10 -0
  209. package/dist/seed/_helpers/character-features.js +118 -0
  210. package/dist/seed/_helpers/media.d.ts +1 -1
  211. package/dist/seed/_helpers/media.js +44 -8
  212. package/dist/seed/_helpers/search-txt-wrappers.d.ts +10 -0
  213. package/dist/seed/_helpers/search-txt-wrappers.js +12 -1
  214. package/dist/seed/categories-seed-data.js +147 -169
  215. package/dist/seed/index.d.ts +1 -0
  216. package/dist/seed/index.js +1 -0
  217. package/dist/seed/manifest.d.ts +1 -1
  218. package/dist/seed/manifest.js +5 -0
  219. package/dist/seed/orders-seed-data.js +5 -3
  220. package/dist/seed/product-features-seed-data.d.ts +1 -8
  221. package/dist/seed/product-features-seed-data.js +358 -154
  222. package/dist/seed/products-art-seed-data.js +16 -4
  223. package/dist/seed/products-auctions-seed-data.js +6 -6
  224. package/dist/seed/products-classifieds-seed-data.js +17 -7
  225. package/dist/seed/products-digital-codes-seed-data.js +12 -12
  226. package/dist/seed/products-preorders-seed-data.js +8 -8
  227. package/dist/seed/products-prize-draws-seed-data.js +25 -8
  228. package/dist/seed/products-standard-seed-data.js +10 -60
  229. package/dist/seed/products-stickers-seed-data.js +6 -6
  230. package/dist/seed/site-settings-seed-data.js +24 -0
  231. package/dist/seed/store-extensions-seed-data.js +10 -4
  232. package/dist/seed/tax-codes-seed-data.d.ts +34 -0
  233. package/dist/seed/tax-codes-seed-data.js +100 -0
  234. package/dist/seed/test-data-ttl.d.ts +29 -0
  235. package/dist/seed/test-data-ttl.js +31 -0
  236. package/dist/server-entry.d.ts +1 -1
  237. package/dist/server-entry.js +6 -1
  238. package/dist/server.d.ts +4 -1
  239. package/dist/server.js +11 -2
  240. package/dist/styles.css +40 -0
  241. package/dist/ui/components/PaginatedSelect.d.ts +14 -0
  242. package/dist/ui/components/PaginatedSelect.js +0 -0
  243. package/dist/ui/components/PaginatedSelect.style.css +40 -0
  244. package/dist/utils/media-url.d.ts +26 -0
  245. package/dist/utils/media-url.js +144 -0
  246. package/dist/utils/physical-location.d.ts +23 -0
  247. package/dist/utils/physical-location.js +52 -0
  248. package/dist/utils/search-txt-builders.d.ts +20 -0
  249. package/dist/utils/search-txt-builders.js +36 -0
  250. package/package.json +1 -1
  251. package/scripts/seed-cli.mjs +4 -1
  252. package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.d.ts +0 -2
  253. package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.js +0 -2
  254. package/dist/features/tester/actions/leaderboard-actions.d.ts +0 -3
  255. package/dist/features/tester/actions/leaderboard-actions.js +0 -5
  256. package/dist/features/tester/components/BugHunterLeaderboardView.d.ts +0 -23
  257. package/dist/features/tester/components/BugHunterLeaderboardView.js +0 -18
  258. package/dist/features/tester/components/TesterHubView.d.ts +0 -5
  259. package/dist/features/tester/components/TesterHubView.js +0 -110
  260. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.d.ts +0 -2
  261. package/dist/features/tester/seed-data/authored/public-pages__bug-hunters.js +0 -78
  262. package/dist/features/tester/seed-data/tester-ttl.d.ts +0 -4
  263. package/dist/features/tester/seed-data/tester-ttl.js +0 -6
@@ -33,10 +33,20 @@ const _rawproductsClassifiedsSeedData = [
33
33
  {
34
34
  id: "classified-beyblade-stadium-set",
35
35
  slug: "classified-beyblade-stadium-set",
36
- title: "Used Beyblade Stadium Set — Local Pickup Only",
36
+ title: "Used Beyblade Burst Stadium Set — Local Pickup Only",
37
37
  description: "Well-loved Beyblade stadium with 6 tops and 2 launchers, sold as-is. Meet up locally — price is negotiable.",
38
- categorySlugs: ["category-storage-cases", "category-gear-storage", "category-battle-gear", "category-spinning-tops"],
39
- categoryNames: ["Cases & Trays", "Storage & Care", "Battle Gear", "Spinning Tops"],
38
+ /*
39
+ * 🛑 Re-filed in B5. A stadium is GENERATION-SPECIFIC — a BX-10 Xtreme
40
+ * Stadium is a Beyblade X product and a BB-10 Attack Type is Metal Fight —
41
+ * so stadiums moved out of the one `battle-gear` bucket into four
42
+ * per-generation nodes. The old chain's three ids no longer exist.
43
+ *
44
+ * The title now says Burst too. Filing a generically-titled stadium under
45
+ * a specific generation while the title stays silent makes the data
46
+ * disagree with itself, and the title is the half a buyer reads.
47
+ */
48
+ categorySlugs: ["category-burst-standard-stadiums", "category-burst-stadiums", "category-beyblade-burst", "category-spinning-tops"],
49
+ categoryNames: ["Standard BeyStadiums", "Burst Stadiums", "Beyblade Burst", "Spinning Tops"],
40
50
  brandSlug: "brand-beyblade",
41
51
  brand: "Beyblade",
42
52
  price: 1200,
@@ -133,8 +143,8 @@ const _rawproductsClassifiedsSeedData = [
133
143
  slug: "classified-beyblade-x-starter-pune",
134
144
  title: "Beyblade X Starter Pack — Pune, Phone Contact Only",
135
145
  description: "Barely used Beyblade X starter pack, selling because I upgraded to a full set. Call or WhatsApp only, no chat.",
136
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
137
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
146
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
147
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
138
148
  brandSlug: "brand-takara-tomy",
139
149
  brand: "Takara-Tomy",
140
150
  price: 650,
@@ -281,8 +291,8 @@ const _rawproductsClassifiedsSeedData = [
281
291
  slug: "classified-beyblade-x-tournament-kit-hyderabad",
282
292
  title: "Tournament-Ready Beyblade X Kit — Hyderabad",
283
293
  description: "Complete tournament-legal kit including 3 tops, stadium, and a scorecard pad from our last local meetup event.",
284
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
285
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
294
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
295
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
286
296
  brandSlug: "brand-takara-tomy",
287
297
  brand: "Takara-Tomy",
288
298
  price: 2400,
@@ -28,8 +28,8 @@ const _rawproductsDigitalCodesSeedData = [
28
28
  slug: "digitalcode-beyblade-x-app-starter-pack",
29
29
  title: "Beyblade X App — Starter Pack Code",
30
30
  description: "Digital redemption code for the Beyblade X companion app's Starter Pack — instantly unlocks 5 exclusive digital tops.",
31
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
32
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
31
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
32
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
33
33
  brandSlug: "brand-takara-tomy",
34
34
  brand: "Takara-Tomy",
35
35
  price: 199,
@@ -75,8 +75,8 @@ const _rawproductsDigitalCodesSeedData = [
75
75
  slug: "digitalcode-beyblade-x-app-legendary-pack",
76
76
  title: "Beyblade X App — Legendary Pack Code (Partially Claimed)",
77
77
  description: "Unlocks 3 legendary digital tops in the companion app. Popular pack — most of the batch has already been claimed.",
78
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
79
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
78
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
79
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
80
80
  brandSlug: "brand-takara-tomy",
81
81
  brand: "Takara-Tomy",
82
82
  price: 349,
@@ -169,8 +169,8 @@ const _rawproductsDigitalCodesSeedData = [
169
169
  slug: "digitalcode-beyblade-x-manual-tournament-pass",
170
170
  title: "Beyblade X Regional Tournament — Digital Entry Pass",
171
171
  description: "Digital entry pass for the next regional tournament, emailed manually by the organizer within 24 hours of purchase.",
172
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
173
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
172
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
173
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
174
174
  brandSlug: "brand-takara-tomy",
175
175
  brand: "Takara-Tomy",
176
176
  price: 499,
@@ -217,8 +217,8 @@ const _rawproductsDigitalCodesSeedData = [
217
217
  slug: "digitalcode-beyblade-metal-app-classic-pack",
218
218
  title: "Beyblade Metal Fight App — Classic Pack Code",
219
219
  description: "Unlocks the Metal Fight classic-era top roster in the companion app — Storm Pegasus, Lightning L-Drago, and more.",
220
- categorySlugs: ["category-metal-fury", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
221
- categoryNames: ["Metal Fury", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
220
+ categorySlugs: ["category-metal-fury-4d", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
221
+ categoryNames: ["Metal Fury (4D)", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
222
222
  brandSlug: "brand-takara-tomy",
223
223
  brand: "Takara-Tomy",
224
224
  price: 249,
@@ -305,8 +305,8 @@ const _rawproductsDigitalCodesSeedData = [
305
305
  slug: "digitalcode-beyblade-x-manual-coaching-session",
306
306
  title: "1-on-1 Beyblade X Coaching Session — Digital Booking Code",
307
307
  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.",
308
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
309
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
308
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
309
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
310
310
  brandSlug: "brand-takara-tomy",
311
311
  brand: "Takara-Tomy",
312
312
  price: 799,
@@ -363,8 +363,8 @@ const _rawproductsDigitalCodesSeedData = [
363
363
  slug: "digitalcode-beyblade-x-app-launch-codes-depleted",
364
364
  title: "Beyblade X App — Launch Bonus Code (Pool Empty)",
365
365
  description: "Launch-bonus codes for the Beyblade X app. Every code in the pool has been claimed; restock pending.",
366
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
367
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
366
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
367
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
368
368
  brandSlug: "brand-takara-tomy",
369
369
  brand: "Takara-Tomy",
370
370
  price: 399,
@@ -36,8 +36,8 @@ const _rawPreordersSeedData = [
36
36
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
37
37
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
38
38
  listingType: "pre-order",
39
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
40
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
39
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
40
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
41
41
  brand: "Takara-Tomy",
42
42
  images: [
43
43
  seedPhoto("preorder-image-beyblade-x-bx-08-wave-1-20260101", 900, 900),
@@ -78,8 +78,8 @@ const _rawPreordersSeedData = [
78
78
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
79
79
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
80
80
  listingType: "pre-order",
81
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
82
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
81
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
82
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
83
83
  brand: "Takara-Tomy",
84
84
  images: [
85
85
  seedPhoto("preorder-image-beyblade-x-bx-09-glide-ring-1-20260814", 900, 900),
@@ -153,8 +153,8 @@ const _rawPreordersSeedData = [
153
153
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
154
154
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
155
155
  listingType: "pre-order",
156
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
157
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
156
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
157
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
158
158
  brand: "Takara-Tomy",
159
159
  images: [
160
160
  seedPhoto("preorder-image-beyblade-x-bx-11-sold-out-1-20260812", 900, 900),
@@ -273,8 +273,8 @@ const _rawPreordersSeedData = [
273
273
  condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
274
274
  status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
275
275
  listingType: "pre-order",
276
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
277
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
276
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
277
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
278
278
  brand: "Takara-Tomy",
279
279
  images: [
280
280
  seedPhoto("preorder-image-beyblade-x-bx-12-closed-1-20260824", 900, 900),
@@ -29,8 +29,19 @@ const _rawproductsPrizeDrawsSeedData = [
29
29
  slug: "prizedraw-beyblade-mystery-box",
30
30
  title: "Beyblade Mystery Box — Prize Draw",
31
31
  description: "Buy an entry for ₹99 and reveal your prize instantly — win anything from a rare limited-edition Beyblade down to a spare launcher grip. 4 prizes available, revealed on a first-come basis.",
32
- categorySlugs: ["category-storage-cases", "category-gear-storage", "category-battle-gear", "category-spinning-tops"],
33
- categoryNames: ["Cases & Trays", "Storage & Care", "Battle Gear", "Spinning Tops"],
32
+ /*
33
+ * 🛑 Re-filed in B5, and it files at the ROOT on purpose. Its own
34
+ * description says the prizes run "from a rare limited-edition Beyblade
35
+ * down to a spare launcher grip" — so it spans generations and part
36
+ * families, and there is no leaf that honestly describes it. The old chain
37
+ * put it under Cases & Trays, which described none of its contents.
38
+ *
39
+ * A root-level chain is valid and is what a mixed-content listing should
40
+ * have: `deriveTaxonomy` resolves a root leaf to a one-element chain, the
41
+ * root page matches it, and no leaf page claims it.
42
+ */
43
+ categorySlugs: ["category-spinning-tops"],
44
+ categoryNames: ["Spinning Tops"],
34
45
  brandSlug: "brand-beyblade",
35
46
  brand: "Beyblade",
36
47
  price: 99,
@@ -82,8 +93,14 @@ const _rawproductsPrizeDrawsSeedData = [
82
93
  slug: "prizedraw-beyblade-scheduled-demo",
83
94
  title: "Beyblade Champion's Draw — Prize Draw",
84
95
  description: "Two entries, two prizes — the winners are revealed automatically the moment the draw closes (3 days) or sells out, whichever comes first.",
85
- categorySlugs: ["category-stadiums-standard", "category-gear-stadiums", "category-battle-gear", "category-spinning-tops"],
86
- categoryNames: ["Standard Stadiums", "Stadiums", "Battle Gear", "Spinning Tops"],
96
+ /*
97
+ * Re-filed in B5 from the removed `battle-gear` stadium chain. Both its
98
+ * prizes are Beyblade X (a Champion Set and a tip multipack), so it
99
+ * belongs on the X tops branch rather than under stadiums — which it was
100
+ * never a stadium to be under.
101
+ */
102
+ categorySlugs: ["category-x-tops", "category-beyblade-x", "category-spinning-tops"],
103
+ categoryNames: ["Beyblade X Tops", "Beyblade X", "Spinning Tops"],
87
104
  brandSlug: "brand-beyblade",
88
105
  brand: "Beyblade",
89
106
  price: 149,
@@ -134,8 +151,8 @@ const _rawproductsPrizeDrawsSeedData = [
134
151
  slug: "prizedraw-beyblade-x-legendary-vault",
135
152
  title: "Beyblade X Legendary Vault — Prize Draw",
136
153
  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.",
137
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
138
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
154
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
155
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
139
156
  brandSlug: "brand-takara-tomy",
140
157
  brand: "Takara-Tomy",
141
158
  price: 199,
@@ -365,8 +382,8 @@ const _rawproductsPrizeDrawsSeedData = [
365
382
  slug: "prizedraw-beyblade-x-vault-closed-pending-reveal",
366
383
  title: "Beyblade X Vault Draw — Closed Early",
367
384
  description: "The seller closed this draw before every slot sold. Remaining entries were refunded; no further entries are accepted.",
368
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
369
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
385
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
386
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
370
387
  brandSlug: "brand-takara-tomy",
371
388
  brand: "Takara-Tomy",
372
389
  price: 249,
@@ -226,56 +226,6 @@ const _rawProductsStandardSeedData = [
226
226
  * isTestData marks them for the sandbox cleanup sweep; keep the expiry far
227
227
  * enough out that a run cannot outlive them.
228
228
  */
229
- {
230
- id: "product-tester-crossstore-a",
231
- slug: "product-tester-crossstore-a",
232
- title: "QA Cross-store A — Beyblade Arena",
233
- description: "Tester fixture. Paired with product-tester-crossstore-b, which belongs to a DIFFERENT store, so that a bundle spanning both must be refused at save time.",
234
- categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
235
- categoryNames: ["Beyblade Burst", "Spinning Tops"],
236
- brandSlug: "brand-beyblade",
237
- brand: "Beyblade",
238
- price: 499,
239
- currency: "INR",
240
- stockQuantity: 5,
241
- availableQuantity: 5,
242
- isSold: false,
243
- mainImage: seedPhoto("product-image-tester-crossstore-a-1-20261003", 900, 900),
244
- images: [seedPhoto("product-image-tester-crossstore-a-1-20261003", 900, 900)],
245
- status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
246
- condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
247
- tags: ["qa-fixture"],
248
- storeId: "store-beyblade-arena",
249
- storeName: "Beyblade Arena",
250
- isTestData: true,
251
- createdAt: new Date("2026-10-03"),
252
- updatedAt: new Date("2026-10-03"),
253
- },
254
- {
255
- id: "product-tester-crossstore-b",
256
- slug: "product-tester-crossstore-b",
257
- title: "QA Cross-store B — LetItRip Official",
258
- description: "Tester fixture. Paired with product-tester-crossstore-a, which belongs to a DIFFERENT store, so that a bundle spanning both must be refused at save time.",
259
- categorySlugs: ["category-beyblade-burst", "category-spinning-tops"],
260
- categoryNames: ["Beyblade Burst", "Spinning Tops"],
261
- brandSlug: "brand-beyblade",
262
- brand: "Beyblade",
263
- price: 499,
264
- currency: "INR",
265
- stockQuantity: 5,
266
- availableQuantity: 5,
267
- isSold: false,
268
- mainImage: seedPhoto("product-image-tester-crossstore-b-1-20261003", 900, 900),
269
- images: [seedPhoto("product-image-tester-crossstore-b-1-20261003", 900, 900)],
270
- status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
271
- condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
272
- tags: ["qa-fixture"],
273
- storeId: "store-letitrip-official",
274
- storeName: "LetItRip Official",
275
- isTestData: true,
276
- createdAt: new Date("2026-10-03"),
277
- updatedAt: new Date("2026-10-03"),
278
- },
279
229
  {
280
230
  id: "product-beyblade-original-driger-v",
281
231
  slug: "product-beyblade-original-driger-v",
@@ -346,8 +296,8 @@ const _rawProductsStandardSeedData = [
346
296
  barcodeId: "LIR-BEY-META-002",
347
297
  title: "Metal Fight Beyblade BB-43 Flame Sagittario",
348
298
  description: "Flame Sagittario C145S, a balance-type top from the Metal Masters generation.",
349
- categorySlugs: ["category-metal-fury", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
350
- categoryNames: ["Metal Fury", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
299
+ categorySlugs: ["category-metal-fury-4d", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
300
+ categoryNames: ["Metal Fury (4D)", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
351
301
  brandSlug: "brand-takara-tomy",
352
302
  brand: "Takara-Tomy",
353
303
  price: 1199,
@@ -442,8 +392,8 @@ const _rawProductsStandardSeedData = [
442
392
  barcodeId: "LIR-BEY-X-001",
443
393
  title: "Beyblade X BX-01 Wizard Arrow",
444
394
  description: "Wizard Arrow 4-60F, a starter top from the Beyblade X Xtreme Gear generation.",
445
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
446
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
395
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
396
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
447
397
  brandSlug: "brand-takara-tomy",
448
398
  brand: "Takara-Tomy",
449
399
  price: 899,
@@ -474,8 +424,8 @@ const _rawProductsStandardSeedData = [
474
424
  barcodeId: "LIR-BEY-X-002",
475
425
  title: "Beyblade X BX-05 Knife Shinobi",
476
426
  description: "Knife Shinobi 3-60GF, a balance-type top with tournament-grade stamina parts.",
477
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
478
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
427
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
428
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
479
429
  brandSlug: "brand-takara-tomy",
480
430
  brand: "Takara-Tomy",
481
431
  price: 949,
@@ -539,8 +489,8 @@ const _rawProductsStandardSeedData = [
539
489
  barcodeId: "LIR-BEY-VID-002",
540
490
  title: "Beyblade X BX-02 Dran Sword (Video Demo)",
541
491
  description: "Dran Sword 3-60F attack-type top from the Beyblade X Xtreme Gear generation. Listed with a battle-test video for gallery testing.",
542
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
543
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
492
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
493
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
544
494
  brandSlug: "brand-takara-tomy",
545
495
  brand: "Takara-Tomy",
546
496
  price: 949,
@@ -660,8 +610,8 @@ const _rawProductsStandardSeedData = [
660
610
  description: "The BX-34 Dran Buster attack type — this batch is fully sold. Watch for the next restock.",
661
611
  price: 1499,
662
612
  currency: "INR",
663
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
664
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
613
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
614
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
665
615
  brandSlug: "brand-takara-tomy",
666
616
  brand: "Takara-Tomy",
667
617
  stockQuantity: 0,
@@ -65,8 +65,8 @@ const _rawProductsStickersSeedData = [
65
65
  slug: "stickers-beyblade-x-holographic-pack",
66
66
  title: "Beyblade X Holographic Sticker Pack",
67
67
  description: "A holographic-finish sticker pack featuring the current Beyblade X lineup — catches the light with a rainbow shimmer.",
68
- categorySlugs: ["category-x-starters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
69
- categoryNames: ["Starter Sets", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
68
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
69
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
70
70
  brandSlug: "brand-takara-tomy",
71
71
  brand: "Takara-Tomy",
72
72
  price: 199,
@@ -185,8 +185,8 @@ const _rawProductsStickersSeedData = [
185
185
  slug: "stickers-beyblade-x-glow-in-dark",
186
186
  title: "Beyblade X Glow-in-the-Dark Sticker Pack",
187
187
  description: "Charge these stickers under light and watch the Beyblade X logos glow in the dark. Great for stadium cases and water bottles.",
188
- categorySlugs: ["category-x-boosters", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
189
- categoryNames: ["Boosters", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
188
+ categorySlugs: ["category-x-basic", "category-x-tops", "category-beyblade-x", "category-spinning-tops"],
189
+ categoryNames: ["Basic Line", "Beyblade X Tops", "Beyblade X", "Spinning Tops"],
190
190
  brandSlug: "brand-takara-tomy",
191
191
  brand: "Takara-Tomy",
192
192
  price: 229,
@@ -228,8 +228,8 @@ const _rawProductsStickersSeedData = [
228
228
  slug: "sticker-beyblade-metal-fight-sold-out",
229
229
  title: "Beyblade Metal Fight Sticker Sheet (Sold Out)",
230
230
  description: "The original Metal Fight sticker sheet run, now fully sold out. Restock TBD.",
231
- categorySlugs: ["category-metal-fury", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
232
- categoryNames: ["Metal Fury", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
231
+ categorySlugs: ["category-metal-fury-4d", "category-metal-tops", "category-beyblade-metal", "category-spinning-tops"],
232
+ categoryNames: ["Metal Fury (4D)", "Metal Fight Tops", "Beyblade Metal Fight", "Spinning Tops"],
233
233
  brandSlug: "brand-beyblade",
234
234
  brand: "Beyblade",
235
235
  price: 199,
@@ -429,6 +429,30 @@ export const siteSettingsSeedData = {
429
429
  autoExtendWindowMinutes: 5,
430
430
  settlementGracePeriodHours: 24,
431
431
  },
432
+ /*
433
+ * 🛑 There is deliberately NO `gst` block here, and it must stay that way.
434
+ *
435
+ * It looks like the `auctionConfig` defect one block up — a key the schema
436
+ * default declares and the seed does not, so `appkit-seed load` can never
437
+ * create it — but the two are opposite cases, and seeding this one would be
438
+ * destructive rather than corrective.
439
+ *
440
+ * `auctionConfig` was broken BY its absence: every reader resolved
441
+ * `?? []` and fell back to a ₹1 bid increment, so the feature was
442
+ * measurably wrong until the key existed.
443
+ *
444
+ * `gst` is CORRECT when absent: readers do `settings.gst?.enabled ??
445
+ * false`, which is the intended default — product GST off until a real
446
+ * registration is entered.
447
+ *
448
+ * And the seed writes `set(..., { merge: true })`, so declaring
449
+ * `gst: { gstin: "", ... }` here would overwrite a live GSTIN with an empty
450
+ * string on **every** subsequent `appkit-seed load`. A registration number
451
+ * is admin-entered identity, not platform config; the only writer is the
452
+ * Site Settings → Gst tab, and `/api/admin/site` now refuses to enable GST
453
+ * until the GSTIN passes its own check digit and the legal name and address
454
+ * are present (see `validateGstEnablement`).
455
+ */
432
456
  commissions: {
433
457
  platformFeePercent: 5,
434
458
  gstPercent: 18,
@@ -125,10 +125,16 @@ export const analyticsCardsSeedData = [
125
125
  ];
126
126
  // ───── analyticsAlerts (4 records) ────────────────────────────────────────
127
127
  export const analyticsAlertsSeedData = [
128
- { id: "alert-low-stock-arena", scope: "seller", ownerId: "user-tyson-blader", label: "Low stock", metric: "min-stock", operator: "<", threshold: 5, windowHours: 24, isActive: true, notifyChannels: ["in-app", "email"] },
129
- { id: "alert-no-sales-arena", scope: "seller", ownerId: "user-tyson-blader", label: "Zero sales 48h", metric: "orders-window", operator: "==", threshold: 0, windowHours: 48, isActive: true, notifyChannels: ["in-app"] },
130
- { id: "alert-platform-error-rate", scope: "admin", ownerId: "user-admin-letitrip", label: "API error rate > 5%", metric: "api-error-rate", operator: ">", threshold: 0.05, windowHours: 1, isActive: true, notifyChannels: ["in-app", "email", "whatsapp"] },
131
- { id: "alert-fraud-surge", scope: "admin", ownerId: "user-admin-letitrip", label: "Fraud reports surge", metric: "reports-1h", operator: ">", threshold: 10, windowHours: 1, isActive: true, notifyChannels: ["in-app", "email"] },
128
+ // 🛑 Re-keyed in C3a. These four carried `min-stock`, `orders-window`,
129
+ // `api-error-rate` and `reports-1h` — four kebab-case values that shared ZERO
130
+ // tokens with the seven snake_case ones the seller picker offered, and which
131
+ // nothing read because no evaluator existed. `api-error-rate` is gone rather
132
+ // than renamed: a RATE needs a denominator this platform does not record, so
133
+ // seeding it would be re-promising what the first version could not keep.
134
+ { id: "alert-low-stock-arena", scope: "seller", ownerId: "user-tyson-blader", label: "Low stock", metric: "low_stock", operator: ">", threshold: 0, windowHours: 24, isActive: true, notifyChannels: ["in-app", "email"] },
135
+ { id: "alert-no-sales-arena", scope: "seller", ownerId: "user-tyson-blader", label: "Zero sales 48h", metric: "orders_count", operator: "==", threshold: 0, windowHours: 48, isActive: true, notifyChannels: ["in-app"] },
136
+ { id: "alert-platform-pending-moderation", scope: "admin", ownerId: "user-admin-letitrip", label: "Listings awaiting review", metric: "pending_moderation", operator: ">", threshold: 5, windowHours: 1, isActive: true, notifyChannels: ["in-app", "email"] },
137
+ { id: "alert-fraud-surge", scope: "admin", ownerId: "user-admin-letitrip", label: "Open reports surge", metric: "open_reports", operator: ">", threshold: 10, windowHours: 1, isActive: true, notifyChannels: ["in-app", "email"] },
132
138
  ];
133
139
  // ───── storeCategories (4 records) ────────────────────────────────────────
134
140
  export const storeCategoriesSeedData = [
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Tax Codes Seed Data
3
+ *
4
+ * The HSN codes this catalogue actually needs, and nothing speculative.
5
+ *
6
+ * ## 🛑 Only chapter 9503 is VERIFIED
7
+ *
8
+ * The four 9503 rates below were confirmed against the current schedule. The
9
+ * chapters for printed matter (4911) and playing cards (9504) are correct
10
+ * chapters for merchandise we sell, and their RATES ARE NOT CONFIRMED — the
11
+ * toys rates themselves moved in the 2025 revision. They are deliberately NOT
12
+ * seeded: a wrong HSN on a real invoice is worse than an absent one, and an
13
+ * absent code leaves `gstRate` undefined, which every reader already handles.
14
+ *
15
+ * Add them as a one-line seed change once someone has checked the schedule.
16
+ *
17
+ * ## The 18% row is load-bearing
18
+ *
19
+ * `tax-hsn-95030010` exists so the catalogue has at least one rate that is not
20
+ * 5%. Without it a 5%-only dataset cannot distinguish "the rate is being
21
+ * applied" from "the rate is hardcoded", and the B6 gate — the Tax row
22
+ * rendering on a real order for the first time — would pass either way.
23
+ *
24
+ * ## The 0% row is an EXEMPTION, not a missing value
25
+ *
26
+ * `tax-exempt-0` carries no HSN, which is legal only at rate 0 (enforced in
27
+ * both the form schema and the repository). It covers the live
28
+ * plants/animals listings. `gstRate: 0` and `gstRate: undefined` mean
29
+ * different things throughout — see the field's own comment.
30
+ *
31
+ * id === slug, prefix: tax-
32
+ */
33
+ import type { TaxCodeDocument } from "../features/tax-codes/schemas/firestore";
34
+ export declare const taxCodesSeedData: TaxCodeDocument[];
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Tax Codes Seed Data
3
+ *
4
+ * The HSN codes this catalogue actually needs, and nothing speculative.
5
+ *
6
+ * ## 🛑 Only chapter 9503 is VERIFIED
7
+ *
8
+ * The four 9503 rates below were confirmed against the current schedule. The
9
+ * chapters for printed matter (4911) and playing cards (9504) are correct
10
+ * chapters for merchandise we sell, and their RATES ARE NOT CONFIRMED — the
11
+ * toys rates themselves moved in the 2025 revision. They are deliberately NOT
12
+ * seeded: a wrong HSN on a real invoice is worse than an absent one, and an
13
+ * absent code leaves `gstRate` undefined, which every reader already handles.
14
+ *
15
+ * Add them as a one-line seed change once someone has checked the schedule.
16
+ *
17
+ * ## The 18% row is load-bearing
18
+ *
19
+ * `tax-hsn-95030010` exists so the catalogue has at least one rate that is not
20
+ * 5%. Without it a 5%-only dataset cannot distinguish "the rate is being
21
+ * applied" from "the rate is hardcoded", and the B6 gate — the Tax row
22
+ * rendering on a real order for the first time — would pass either way.
23
+ *
24
+ * ## The 0% row is an EXEMPTION, not a missing value
25
+ *
26
+ * `tax-exempt-0` carries no HSN, which is legal only at rate 0 (enforced in
27
+ * both the form schema and the repository). It covers the live
28
+ * plants/animals listings. `gstRate: 0` and `gstRate: undefined` mean
29
+ * different things throughout — see the field's own comment.
30
+ *
31
+ * id === slug, prefix: tax-
32
+ */
33
+ /*
34
+ * A FIXED date, not `Date.now()`. Seed files are re-imported on every
35
+ * `appkit-seed` invocation, so a moving timestamp makes `load` non-idempotent
36
+ * and `status`/`delete` unable to see what a prior run wrote — Root Cause #25.
37
+ */
38
+ const SEEDED_AT = new Date("2026-10-10T00:00:00.000Z");
39
+ export const taxCodesSeedData = [
40
+ {
41
+ id: "tax-hsn-95030020",
42
+ hsnCode: "95030020",
43
+ label: "Toys, non-electronic incl. spinning tops (HSN 9503 0020) — 5%",
44
+ description: "The default for this catalogue: every Beyblade, part, launcher and stadium.",
45
+ gstRate: 5,
46
+ chapter: "9503",
47
+ isActive: true,
48
+ notes: "Verified against the current GST schedule. Spinning tops are named explicitly in this sub-heading, which is why it is the default rather than 9503 0099.",
49
+ createdAt: SEEDED_AT,
50
+ updatedAt: SEEDED_AT,
51
+ },
52
+ {
53
+ id: "tax-hsn-95030099",
54
+ hsnCode: "95030099",
55
+ label: "Other toys (HSN 9503 0099) — 5%",
56
+ description: "Toys and collectibles that are not spinning tops and not electronic — figures, model kits, diecast.",
57
+ gstRate: 5,
58
+ chapter: "9503",
59
+ isActive: true,
60
+ notes: "Verified. The catch-all within chapter 9503 for non-electronic toys.",
61
+ createdAt: SEEDED_AT,
62
+ updatedAt: SEEDED_AT,
63
+ },
64
+ {
65
+ id: "tax-hsn-95030010",
66
+ hsnCode: "95030010",
67
+ label: "Electronic toys (HSN 9503 0010) — 18%",
68
+ description: "Toys whose function depends on electronics — anything battery-driven or with a screen.",
69
+ gstRate: 18,
70
+ chapter: "9503",
71
+ isActive: true,
72
+ notes: "Verified. 🛑 Keep at least one product on this code: it is the only row that proves the 18% branch is applied rather than a 5% rate being hardcoded.",
73
+ createdAt: SEEDED_AT,
74
+ updatedAt: SEEDED_AT,
75
+ },
76
+ {
77
+ id: "tax-hsn-95030091",
78
+ hsnCode: "95030091",
79
+ label: "Parts of electronic toys (HSN 9503 0091) — 18%",
80
+ description: "Components and spares for electronic toys.",
81
+ gstRate: 18,
82
+ chapter: "9503",
83
+ isActive: true,
84
+ notes: "Verified. Follows the parent heading's rate.",
85
+ createdAt: SEEDED_AT,
86
+ updatedAt: SEEDED_AT,
87
+ },
88
+ {
89
+ id: "tax-exempt-0",
90
+ hsnCode: "",
91
+ label: "Exempt — 0% (no HSN)",
92
+ description: "Live plants and live animals. An exemption, deliberately recorded rather than left unset.",
93
+ gstRate: 0,
94
+ chapter: "exempt",
95
+ isActive: true,
96
+ notes: "🛑 Rate 0 is a DECISION; `gstRate: undefined` is 'nobody has said'. Every reader tests `== null` rather than falsiness precisely so this row survives a default being applied elsewhere.",
97
+ createdAt: SEEDED_AT,
98
+ updatedAt: SEEDED_AT,
99
+ },
100
+ ];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The TTL stamp every disposable test fixture must carry.
3
+ *
4
+ * 🛑 `isTestData: true` WITHOUT `testDataExpiresAt` means PERMANENT — nothing
5
+ * ever reclaims it (see `jobs/handlers/_helpers.ts`, which documents the same
6
+ * rule from the sweep's side). That is not a theoretical hazard: until
7
+ * 2026-10-10 the only two `isTestData` rows in the whole seed,
8
+ * `product-tester-crossstore-a` / `-b`, were in exactly that state — live in
9
+ * the public catalogue of 72 products, never purged, and one of them was
10
+ * `store-letitrip-official`'s ONLY buyable standard product, so it was hidden
11
+ * from every real buyer by `hidePublicTestData` while being the only thing
12
+ * that store had to sell. Both are deleted.
13
+ *
14
+ * And the reason they were permanent is that **this module had zero callers**.
15
+ * The helper that enforces the rule existed, was documented as the rule that
16
+ * matters most, and no fixture used it. So: a fixture's three obligations are
17
+ * an id containing `-test-`, `isTestData: true`, and an expiry FROM HERE.
18
+ *
19
+ * Recomputed fresh on every seed run (seed files are re-imported per
20
+ * invocation), so re-seeding naturally refreshes the expiry rather than
21
+ * leaving a fixture that expired between runs.
22
+ *
23
+ * 🛑 Do NOT re-declare the day count elsewhere. It used to be declared twice —
24
+ * here and in `jobs/handlers/messages.ts` — with a comment as the only thing
25
+ * keeping them equal, which is the drift shape Root Cause #42 describes.
26
+ * `messages.ts` now re-exports this one.
27
+ */
28
+ export declare const TEST_DATA_TTL_DAYS = 7;
29
+ export declare function testDataExpiresAt(): Date;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The TTL stamp every disposable test fixture must carry.
3
+ *
4
+ * 🛑 `isTestData: true` WITHOUT `testDataExpiresAt` means PERMANENT — nothing
5
+ * ever reclaims it (see `jobs/handlers/_helpers.ts`, which documents the same
6
+ * rule from the sweep's side). That is not a theoretical hazard: until
7
+ * 2026-10-10 the only two `isTestData` rows in the whole seed,
8
+ * `product-tester-crossstore-a` / `-b`, were in exactly that state — live in
9
+ * the public catalogue of 72 products, never purged, and one of them was
10
+ * `store-letitrip-official`'s ONLY buyable standard product, so it was hidden
11
+ * from every real buyer by `hidePublicTestData` while being the only thing
12
+ * that store had to sell. Both are deleted.
13
+ *
14
+ * And the reason they were permanent is that **this module had zero callers**.
15
+ * The helper that enforces the rule existed, was documented as the rule that
16
+ * matters most, and no fixture used it. So: a fixture's three obligations are
17
+ * an id containing `-test-`, `isTestData: true`, and an expiry FROM HERE.
18
+ *
19
+ * Recomputed fresh on every seed run (seed files are re-imported per
20
+ * invocation), so re-seeding naturally refreshes the expiry rather than
21
+ * leaving a fixture that expired between runs.
22
+ *
23
+ * 🛑 Do NOT re-declare the day count elsewhere. It used to be declared twice —
24
+ * here and in `jobs/handlers/messages.ts` — with a comment as the only thing
25
+ * keeping them equal, which is the drift shape Root Cause #42 describes.
26
+ * `messages.ts` now re-exports this one.
27
+ */
28
+ export const TEST_DATA_TTL_DAYS = 7;
29
+ export function testDataExpiresAt() {
30
+ return new Date(Date.now() + TEST_DATA_TTL_DAYS * 24 * 60 * 60 * 1000);
31
+ }