@mohasinac/appkit 4.14.0 → 4.16.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 (206) hide show
  1. package/dist/_internal/server/features/auctions/actions.js +2 -2
  2. package/dist/_internal/server/features/cart/service.d.ts +3 -3
  3. package/dist/_internal/server/features/checkout/actions.js +19 -0
  4. package/dist/_internal/server/features/checkout/source-context.d.ts +5 -0
  5. package/dist/_internal/server/features/checkout/source-context.js +157 -0
  6. package/dist/_internal/server/features/offers/adapters.d.ts +103 -0
  7. package/dist/_internal/server/features/offers/adapters.js +88 -0
  8. package/dist/_internal/server/features/offers/index.d.ts +2 -0
  9. package/dist/_internal/server/features/offers/index.js +1 -0
  10. package/dist/_internal/server/features/orders/adapters.js +24 -0
  11. package/dist/_internal/server/jobs/core/offerExpiry.js +10 -10
  12. package/dist/_internal/shared/actions/action-registry.d.ts +9 -2
  13. package/dist/_internal/shared/actions/action-registry.js +458 -7
  14. package/dist/_internal/shared/features/auctions/schema.d.ts +14 -2
  15. package/dist/_internal/shared/features/auctions/schema.js +13 -1
  16. package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
  17. package/dist/_internal/shared/features/cart/schema.d.ts +25 -20
  18. package/dist/_internal/shared/features/cart/schema.js +15 -0
  19. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +22 -22
  20. package/dist/_internal/shared/features/orders/schema.d.ts +4 -4
  21. package/dist/_internal/shared/features/products/schema.d.ts +27 -27
  22. package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
  23. package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
  24. package/dist/_internal/shared/history/history.d.ts +22 -0
  25. package/dist/_internal/shared/history/history.js +41 -1
  26. package/dist/client.d.ts +13 -2
  27. package/dist/client.js +20 -2
  28. package/dist/constants/field-names.d.ts +8 -6
  29. package/dist/constants/field-names.js +48 -6
  30. package/dist/contracts/extend.d.ts +29 -0
  31. package/dist/contracts/extend.js +20 -0
  32. package/dist/contracts/index.d.ts +2 -1
  33. package/dist/contracts/index.js +2 -0
  34. package/dist/features/account/components/UserBidsView.js +12 -4
  35. package/dist/features/account/components/UserReturnsView.d.ts +3 -0
  36. package/dist/features/account/components/UserReturnsView.js +17 -1
  37. package/dist/features/admin/components/AdminAuditLogView.js +1 -0
  38. package/dist/features/admin/components/AdminBidsView.js +15 -2
  39. package/dist/features/admin/components/AdminBlogEditorView.js +65 -33
  40. package/dist/features/admin/components/AdminFeatureEditorView.js +35 -6
  41. package/dist/features/admin/components/AdminNavEditorView.js +15 -5
  42. package/dist/features/admin/components/AdminNewsletterView.js +18 -2
  43. package/dist/features/admin/components/AdminOffersView.js +62 -18
  44. package/dist/features/admin/components/AdminPaymentMethodsView.js +24 -4
  45. package/dist/features/admin/components/AdminScammerEditorView.d.ts +2 -1
  46. package/dist/features/admin/components/AdminScammerEditorView.js +3 -13
  47. package/dist/features/admin/components/AdminScammersView.js +3 -8
  48. package/dist/features/admin/components/AdminSectionsView.js +32 -23
  49. package/dist/features/admin/components/AdminSessionsView.js +17 -2
  50. package/dist/features/admin/components/AdminViewCards.js +24 -17
  51. package/dist/features/admin/components/DataListingView.js +15 -1
  52. package/dist/features/admin/components/DataTable.js +7 -17
  53. package/dist/features/admin/components/ViewAuditLogEntryModal.js +1 -0
  54. package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -2
  55. package/dist/features/admin/components/sections/adminSectionsTypes.js +45 -27
  56. package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
  57. package/dist/features/admin/constants/filter-tabs.js +1 -0
  58. package/dist/features/admin/schemas/homepage-section-form.d.ts +22 -0
  59. package/dist/features/admin/schemas/homepage-section-form.js +68 -0
  60. package/dist/features/admin/schemas/nav-item-form.d.ts +74 -0
  61. package/dist/features/admin/schemas/nav-item-form.js +72 -0
  62. package/dist/features/auctions/components/AuctionBidsTable.d.ts +10 -1
  63. package/dist/features/auctions/components/AuctionBidsTable.js +22 -4
  64. package/dist/features/auctions/components/bid-detail-fields.d.ts +29 -0
  65. package/dist/features/auctions/components/bid-detail-fields.js +103 -0
  66. package/dist/features/auctions/schemas/index.d.ts +14 -14
  67. package/dist/features/audit-log/schemas/firestore.d.ts +14 -0
  68. package/dist/features/audit-log/schemas/firestore.js +7 -0
  69. package/dist/features/auth/schemas/index.d.ts +2 -2
  70. package/dist/features/blog/actions/blog-actions.d.ts +7 -7
  71. package/dist/features/blog/schemas/blog-form.d.ts +80 -0
  72. package/dist/features/blog/schemas/blog-form.js +100 -0
  73. package/dist/features/blog/schemas/index.d.ts +10 -10
  74. package/dist/features/cart/schemas/index.d.ts +3 -3
  75. package/dist/features/catalogue/schemas/validation.d.ts +12 -12
  76. package/dist/features/categories/schemas/index.d.ts +16 -16
  77. package/dist/features/collections/schemas/index.d.ts +8 -8
  78. package/dist/features/events/components/AdminEventEditorView.js +32 -54
  79. package/dist/features/events/components/AdminEventEntriesView.js +22 -3
  80. package/dist/features/events/schemas/event-form.d.ts +113 -0
  81. package/dist/features/events/schemas/event-form.js +82 -0
  82. package/dist/features/events/schemas/index.d.ts +2 -2
  83. package/dist/features/faq/actions/faq-actions.d.ts +6 -6
  84. package/dist/features/faq/schemas/index.d.ts +6 -6
  85. package/dist/features/grouped/schemas/grouped-listing-form.d.ts +101 -0
  86. package/dist/features/grouped/schemas/grouped-listing-form.js +89 -0
  87. package/dist/features/grouped/schemas/index.d.ts +4 -4
  88. package/dist/features/homepage/actions/homepage-section-actions.d.ts +11 -3
  89. package/dist/features/homepage/actions/homepage-section-actions.js +33 -1
  90. package/dist/features/homepage/schemas/index.d.ts +71 -40
  91. package/dist/features/homepage/schemas/index.js +24 -0
  92. package/dist/features/messages/schemas/index.d.ts +2 -2
  93. package/dist/features/orders/components/OrderStatusTimeline.d.ts +5 -1
  94. package/dist/features/orders/components/OrderStatusTimeline.js +39 -20
  95. package/dist/features/orders/repository/orders.repository.js +5 -0
  96. package/dist/features/orders/schemas/firestore.d.ts +36 -1
  97. package/dist/features/orders/schemas/index.d.ts +24 -24
  98. package/dist/features/orders/types/index.d.ts +35 -7
  99. package/dist/features/pre-orders/schemas/index.d.ts +4 -4
  100. package/dist/features/products/components/GroupSettingsPanel.js +5 -1
  101. package/dist/features/products/schemas/index.d.ts +38 -38
  102. package/dist/features/products/schemas/product-features.validators.d.ts +75 -2
  103. package/dist/features/products/schemas/product-features.validators.js +63 -0
  104. package/dist/features/promotions/schemas/index.d.ts +14 -14
  105. package/dist/features/reviews/schemas/index.d.ts +14 -14
  106. package/dist/features/scams/constants/scammer-status-display.d.ts +28 -0
  107. package/dist/features/scams/constants/scammer-status-display.js +79 -0
  108. package/dist/features/scams/schemas/index.d.ts +2 -2
  109. package/dist/features/search/schemas/index.d.ts +2 -2
  110. package/dist/features/seller/actions/offer-actions.js +32 -2
  111. package/dist/features/seller/components/OfferPhaseTimeline.d.ts +59 -0
  112. package/dist/features/seller/components/OfferPhaseTimeline.js +107 -0
  113. package/dist/features/seller/components/SellerBidsView.js +11 -4
  114. package/dist/features/seller/components/SellerCouponEditorView.js +17 -17
  115. package/dist/features/seller/components/SellerOffersView.js +2 -1
  116. package/dist/features/seller/components/SellerPayoutSettingsView.js +38 -14
  117. package/dist/features/seller/repository/offer.repository.d.ts +69 -8
  118. package/dist/features/seller/repository/offer.repository.js +127 -23
  119. package/dist/features/seller/schemas/coupon-form.d.ts +72 -0
  120. package/dist/features/seller/schemas/coupon-form.js +116 -0
  121. package/dist/features/seller/schemas/firestore.d.ts +56 -2
  122. package/dist/features/seller/schemas/firestore.js +27 -0
  123. package/dist/features/seller/schemas/index.d.ts +2 -2
  124. package/dist/features/seller/schemas/offer-forms.d.ts +21 -0
  125. package/dist/features/seller/schemas/offer-forms.js +21 -0
  126. package/dist/features/shell/build-sections.d.ts +63 -0
  127. package/dist/features/shell/build-sections.js +207 -0
  128. package/dist/features/shell/field-ui-meta.d.ts +115 -0
  129. package/dist/features/shell/field-ui-meta.js +324 -0
  130. package/dist/features/shell/index.d.ts +4 -0
  131. package/dist/features/shell/index.js +2 -0
  132. package/dist/features/shipments/schemas/validation.d.ts +22 -22
  133. package/dist/features/status-history/components/StatusTimeline.d.ts +74 -0
  134. package/dist/features/status-history/components/StatusTimeline.js +46 -0
  135. package/dist/features/status-history/index.d.ts +11 -0
  136. package/dist/features/status-history/index.js +10 -0
  137. package/dist/features/store-extensions/components/ReviewDecisionModal.d.ts +27 -0
  138. package/dist/features/store-extensions/components/ReviewDecisionModal.js +82 -0
  139. package/dist/features/store-extensions/index.d.ts +12 -0
  140. package/dist/features/store-extensions/index.js +12 -0
  141. package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +36 -0
  142. package/dist/features/store-extensions/schemas/admin-notification-form.js +114 -0
  143. package/dist/features/store-extensions/schemas/analytics-forms.d.ts +57 -0
  144. package/dist/features/store-extensions/schemas/analytics-forms.js +158 -0
  145. package/dist/features/store-extensions/schemas/custom-role-form.d.ts +85 -0
  146. package/dist/features/store-extensions/schemas/custom-role-form.js +118 -0
  147. package/dist/features/store-extensions/schemas/firestore.d.ts +21 -1
  148. package/dist/features/store-extensions/schemas/firestore.js +60 -0
  149. package/dist/features/store-extensions/schemas/google-config-form.d.ts +53 -0
  150. package/dist/features/store-extensions/schemas/google-config-form.js +105 -0
  151. package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +28 -0
  152. package/dist/features/store-extensions/schemas/item-request-create-form.js +80 -0
  153. package/dist/features/store-extensions/schemas/listing-template-form.d.ts +78 -0
  154. package/dist/features/store-extensions/schemas/listing-template-form.js +87 -0
  155. package/dist/features/store-extensions/schemas/moderation-review-form.d.ts +49 -0
  156. package/dist/features/store-extensions/schemas/moderation-review-form.js +101 -0
  157. package/dist/features/store-extensions/schemas/payout-method-form.d.ts +153 -0
  158. package/dist/features/store-extensions/schemas/payout-method-form.js +155 -0
  159. package/dist/features/store-extensions/schemas/report-create-form.d.ts +25 -0
  160. package/dist/features/store-extensions/schemas/report-create-form.js +79 -0
  161. package/dist/features/store-extensions/schemas/report-review-form.d.ts +47 -0
  162. package/dist/features/store-extensions/schemas/report-review-form.js +111 -0
  163. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +148 -0
  164. package/dist/features/store-extensions/schemas/shipping-config-form.js +104 -0
  165. package/dist/features/store-extensions/schemas/store-category-form.d.ts +54 -0
  166. package/dist/features/store-extensions/schemas/store-category-form.js +73 -0
  167. package/dist/features/stores/schemas/index.d.ts +4 -4
  168. package/dist/features/support/schemas/index.d.ts +4 -4
  169. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +350 -0
  170. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  171. package/dist/index.d.ts +12 -2
  172. package/dist/index.js +12 -2
  173. package/dist/next/routing/route-map.d.ts +16 -2
  174. package/dist/next/routing/route-map.js +9 -2
  175. package/dist/schemas/firestore-value.d.ts +8 -0
  176. package/dist/schemas/firestore-value.js +44 -0
  177. package/dist/schemas/index.d.ts +1 -1
  178. package/dist/schemas/index.js +1 -1
  179. package/dist/schemas/registry.d.ts +734 -101
  180. package/dist/schemas/registry.js +64 -1
  181. package/dist/seed/bids-seed-data.js +30 -0
  182. package/dist/seed/offers-seed-data.js +212 -7
  183. package/dist/seed/orders-seed-data.js +336 -1
  184. package/dist/seed/products-auctions-seed-data.js +41 -0
  185. package/dist/server.d.ts +2 -0
  186. package/dist/server.js +5 -0
  187. package/dist/styles.css +1 -1
  188. package/dist/tailwind-utilities.css +1 -1
  189. package/dist/ui/DataTable.js +4 -2
  190. package/dist/ui/columns/build-columns.d.ts +6 -1
  191. package/dist/ui/columns/build-columns.js +53 -0
  192. package/dist/ui/columns/cell-renderers.d.ts +68 -0
  193. package/dist/ui/columns/cell-renderers.js +111 -0
  194. package/dist/ui/columns/column-renderers.d.ts +6 -1
  195. package/dist/ui/columns/column-renderers.js +6 -1
  196. package/dist/ui/columns/index.d.ts +2 -1
  197. package/dist/ui/columns/index.js +5 -1
  198. package/dist/ui/components/Button.js +27 -2
  199. package/dist/ui/components/RecordDetailModal.d.ts +10 -1
  200. package/dist/ui/components/RecordDetailModal.js +2 -2
  201. package/dist/ui/icons/icon-registry.d.ts +65 -0
  202. package/dist/ui/icons/icon-registry.js +115 -0
  203. package/package.json +2 -1
  204. package/scripts/node-esm-loader.mjs +65 -0
  205. package/scripts/seed-cli-loader.mjs +6 -49
  206. package/scripts/seed-cli.mjs +1 -1
@@ -2,6 +2,30 @@
2
2
  * WHY: Seeds purchase orders representing completed transactions across Beyblade marketplace buyers and sellers.
3
3
  * WHAT: Exports 50 orders across 3 buyer/store combos. All statuses distributed. Order IDs: order-{itemCount}-{YYYYMMDD}-{rand6}.
4
4
  *
5
+ * ## One fixture per acquisition path
6
+ *
7
+ * The six `acquisitionOrders` below exist so every branch of the
8
+ * `OrderSourceContext` union has real data behind it. `orderType` has five
9
+ * values and cannot separate a settled auction win from a buyout — both are
10
+ * "auction" — which is exactly why `sourceContext` keys on its own
11
+ * discriminator.
12
+ *
13
+ * Every FK in a `sourceContext` points at a real seeded document: the winning
14
+ * bid, the buyout bid, the accepted offer. A provenance record pointing at
15
+ * nothing is worse than none, because it reads as evidence (Root Cause #26).
16
+ *
17
+ * ## `statusHistory` is a DELTA log, never a snapshot
18
+ *
19
+ * Each entry records only the tracked fields that changed. Money is
20
+ * deliberately absent: the final coupon and add-on state already lives on the
21
+ * order document, and replaying pricing churn buries the handful of
22
+ * transitions anyone actually reads. Refunds ARE here — a partial refund
23
+ * changes no tracked field, so it is contributed explicitly.
24
+ *
25
+ * `actorUid` is the only identity an entry may carry. Never a name or an
26
+ * email: `encryptPiiFields` never descends into arrays, so PII inside
27
+ * `statusHistory` would be stored in plaintext.
28
+ *
5
29
  * EXPORTS:
6
30
  * ordersSeedData — Array of 50 order documents with full transactional metadata
7
31
  *
@@ -384,8 +408,319 @@ function withOrderImages(order) {
384
408
  })),
385
409
  };
386
410
  }
411
+ /**
412
+ * One history entry, in the same delta shape `withHistory()` writes at runtime,
413
+ * so a seeded timeline and a real one render identically.
414
+ */
415
+ function entry(at, actorRole, trigger, changes, extra = {}) {
416
+ return { at, actorRole, trigger, changes, ...extra };
417
+ }
418
+ const BUYER_YUGI = "user-yugi-muto";
419
+ const BUYER_KAIBA = "user-seto-kaiba";
420
+ const BUYER_ADMIN = "user-admin-letitrip";
421
+ const ARENA = "store-beyblade-arena";
422
+ /**
423
+ * Six orders, one per `OrderSourceContext` path.
424
+ *
425
+ * The two auction fixtures are the point of the set: they are the pair
426
+ * `orderType` alone cannot tell apart.
427
+ */
428
+ const acquisitionOrders = [
429
+ // ── standard ──────────────────────────────────────────────────────────
430
+ {
431
+ id: "order-1-20260818-stdctx",
432
+ productId: "product-beyblade-burst-valkyrie",
433
+ productTitle: "Beyblade Burst B-01 Valkyrie",
434
+ userId: BUYER_YUGI,
435
+ userName: "Mock User 3",
436
+ userEmail: "rehan.sheikh@gmail.com",
437
+ storeId: ARENA,
438
+ quantity: 1,
439
+ unitPrice: 999,
440
+ totalPrice: 999,
441
+ currency: "INR",
442
+ status: "delivered",
443
+ paymentStatus: "paid",
444
+ paymentMethod: "cash",
445
+ orderType: "standard",
446
+ shippingAddress: "addr-yugi-home",
447
+ trackingNumber: "LIR-TRK-88213004",
448
+ shippingCarrier: "Delhivery",
449
+ orderDate: daysAgo(12),
450
+ shippingDate: daysAgo(9),
451
+ deliveryDate: daysAgo(6),
452
+ createdAt: daysAgo(12),
453
+ updatedAt: daysAgo(6),
454
+ sourceContext: { path: "standard", listPrice: 999 },
455
+ statusHistory: [
456
+ entry(daysAgo(12), "buyer", "createCheckoutOrder", {
457
+ status: { from: null, to: "pending" },
458
+ }, { actorUid: BUYER_YUGI }),
459
+ entry(daysAgo(11), "seller", "updateOrderStatus", {
460
+ status: { from: "pending", to: "confirmed" },
461
+ paymentStatus: { from: "pending", to: "paid" },
462
+ }, { actorUid: ARENA }),
463
+ entry(daysAgo(9), "seller", "customShipOrder", {
464
+ status: { from: "confirmed", to: "shipped" },
465
+ trackingNumber: { from: null, to: "LIR-TRK-88213004" },
466
+ }, { actorUid: ARENA }),
467
+ entry(daysAgo(6), "system", "deliveryConfirmation", {
468
+ status: { from: "shipped", to: "delivered" },
469
+ }),
470
+ ],
471
+ },
472
+ // ── auction-won — settled at close, against a real ladder ─────────────
473
+ {
474
+ id: "order-1-20260822-aucwon",
475
+ productId: "auction-beyblade-metal-diablo-nemesis",
476
+ productTitle: "Metal Fight Beyblade BB-122 Diablo Nemesis (Ended — Sold)",
477
+ userId: BUYER_KAIBA,
478
+ userName: "Mock User 2",
479
+ userEmail: "vivaan.kapoor@gmail.com",
480
+ storeId: ARENA,
481
+ quantity: 1,
482
+ unitPrice: 6200,
483
+ totalPrice: 6200,
484
+ currency: "INR",
485
+ status: "processing",
486
+ paymentStatus: "paid",
487
+ paymentMethod: "upi_manual",
488
+ orderType: "auction",
489
+ shippingAddress: "addr-kaiba-mansion",
490
+ orderDate: daysAgo(2),
491
+ createdAt: daysAgo(2),
492
+ updatedAt: daysAgo(1),
493
+ sourceContext: {
494
+ path: "auction-won",
495
+ auctionId: "auction-beyblade-metal-diablo-nemesis",
496
+ bidId: "bid-beyblade-metal-diablo-nemesis-rohit-collector-20260601-005",
497
+ winningBidAmount: 6200,
498
+ bidCount: 6,
499
+ startingBid: 3499,
500
+ // No reserve on this auction, so the reserve cannot fail to be met.
501
+ reserveMet: true,
502
+ auctionEndedAt: daysAgo(2),
503
+ runnerUpAmount: 5428,
504
+ },
505
+ statusHistory: [
506
+ entry(daysAgo(2), "system", "auctionSettlement", {
507
+ status: { from: null, to: "pending" },
508
+ }, { reason: "Won at auction close" }),
509
+ entry(daysAgo(1), "admin", "adminVerifyPayment", {
510
+ status: { from: "pending", to: "processing" },
511
+ paymentStatus: { from: "pending", to: "paid" },
512
+ paymentReviewOutcome: { from: null, to: "verified" },
513
+ }, { actorUid: BUYER_ADMIN }),
514
+ ],
515
+ },
516
+ // ── auction-buy-now — a buyout ENDED a live auction ───────────────────
517
+ {
518
+ // Referenced back by the buyout bid's `orderId`, so the link resolves in
519
+ // both directions.
520
+ id: "order-1-20260820-buyout",
521
+ productId: "auction-beyblade-burst-spriggan-requiem-bought-out",
522
+ productTitle: "Beyblade Burst B-128 Spriggan Requiem (Ended — Bought Out)",
523
+ userId: BUYER_KAIBA,
524
+ userName: "Mock User 2",
525
+ userEmail: "vivaan.kapoor@gmail.com",
526
+ storeId: ARENA,
527
+ quantity: 1,
528
+ unitPrice: 4999,
529
+ totalPrice: 4999,
530
+ currency: "INR",
531
+ status: "shipped",
532
+ paymentStatus: "paid",
533
+ paymentMethod: "cash",
534
+ orderType: "auction",
535
+ // What separates this from the win above. Both are orderType "auction";
536
+ // only a buyout gets the 24h admin-review window.
537
+ isBuyout: true,
538
+ shippingAddress: "addr-kaiba-mansion",
539
+ trackingNumber: "LIR-TRK-77410992",
540
+ shippingCarrier: "Blue Dart",
541
+ orderDate: daysAgo(4),
542
+ shippingDate: daysAgo(2),
543
+ createdAt: daysAgo(4),
544
+ updatedAt: daysAgo(2),
545
+ sourceContext: {
546
+ path: "auction-buy-now",
547
+ auctionId: "auction-beyblade-burst-spriggan-requiem-bought-out",
548
+ bidId: "bid-beyblade-burst-spriggan-requiem-seto-kaiba-20260820-buyout",
549
+ buyNowPrice: 4999,
550
+ listPrice: 5499,
551
+ // The highest NON-buyout bid the buyout beat.
552
+ standingBidAtBuyout: 3100,
553
+ // Three, not zero. The old type asserted "zero bids by definition"
554
+ // because Buy Now used to be gated on `!bidsHaveStarted`; that gate was
555
+ // removed, and recording 0 would bake a falsehood into an audit record.
556
+ bidCount: 3,
557
+ boughtAt: daysAgo(4),
558
+ checkoutDeadline: daysAgo(4),
559
+ },
560
+ statusHistory: [
561
+ entry(daysAgo(4), "buyer", "claimAuctionForCheckout", {
562
+ status: { from: null, to: "pending" },
563
+ }, { actorUid: BUYER_KAIBA, reason: "Buy Now claim won" }),
564
+ entry(daysAgo(3), "seller", "updateOrderStatus", {
565
+ status: { from: "pending", to: "confirmed" },
566
+ paymentStatus: { from: "pending", to: "paid" },
567
+ }, { actorUid: ARENA }),
568
+ entry(daysAgo(2), "seller", "customShipOrder", {
569
+ status: { from: "confirmed", to: "shipped" },
570
+ trackingNumber: { from: null, to: "LIR-TRK-77410992" },
571
+ }, { actorUid: ARENA }),
572
+ ],
573
+ },
574
+ // ── offer-accepted — the end of a real negotiation ────────────────────
575
+ {
576
+ id: "order-1-20260813-offerctx",
577
+ productId: "product-beyblade-x-knife-shinobi",
578
+ productTitle: "Beyblade X Knife Shinobi",
579
+ userId: BUYER_ADMIN,
580
+ userName: "Mock User 1",
581
+ userEmail: "admin@letitrip.in",
582
+ storeId: ARENA,
583
+ quantity: 1,
584
+ unitPrice: 800,
585
+ totalPrice: 800,
586
+ currency: "INR",
587
+ status: "delivered",
588
+ paymentStatus: "paid",
589
+ paymentMethod: "cash",
590
+ orderType: "offer",
591
+ // The offer this order settled — its own status is `paid`, and this is the
592
+ // order id it points at.
593
+ offerId: "offer-admin-x-knife-shinobi-paid",
594
+ shippingAddress: "addr-letitrip-hq",
595
+ orderDate: daysAgo(11),
596
+ shippingDate: daysAgo(9),
597
+ deliveryDate: daysAgo(7),
598
+ createdAt: daysAgo(11),
599
+ updatedAt: daysAgo(7),
600
+ sourceContext: {
601
+ path: "offer-accepted",
602
+ offerId: "offer-admin-x-knife-shinobi-paid",
603
+ offeredAmount: 800,
604
+ listPriceAtOffer: 949,
605
+ // Accepted outright — no counter rounds. Compare the Metal Storm
606
+ // Pegasus chain in offers-seed-data.ts, which reaches round 3.
607
+ counterRounds: 1,
608
+ acceptedBy: ARENA,
609
+ acceptedAt: daysAgo(12),
610
+ checkoutDeadline: daysAgo(10),
611
+ },
612
+ statusHistory: [
613
+ entry(daysAgo(11), "buyer", "createCheckoutOrder", {
614
+ status: { from: null, to: "pending" },
615
+ }, { actorUid: BUYER_ADMIN }),
616
+ entry(daysAgo(10), "seller", "updateOrderStatus", {
617
+ status: { from: "pending", to: "confirmed" },
618
+ paymentStatus: { from: "pending", to: "paid" },
619
+ }, { actorUid: ARENA }),
620
+ entry(daysAgo(9), "seller", "customShipOrder", {
621
+ status: { from: "confirmed", to: "shipped" },
622
+ trackingNumber: { from: null, to: "LIR-TRK-30028841" },
623
+ }, { actorUid: ARENA }),
624
+ entry(daysAgo(7), "system", "deliveryConfirmation", {
625
+ status: { from: "shipped", to: "delivered" },
626
+ }),
627
+ // A PARTIAL refund. It changes no tracked field, so it can only reach the
628
+ // timeline as an explicit contribution — diffing `refunds[]` would render
629
+ // as "an array of 0 became an array of 1", which is true and useless.
630
+ entry(daysAgo(6), "admin", "postRefundEvent", {
631
+ refund: {
632
+ from: null,
633
+ to: { refundId: "refund-x-knife-shinobi-1", type: "partial", amount: 120, reason: "Minor box damage in transit" },
634
+ },
635
+ }, { actorUid: BUYER_ADMIN, reason: "Minor box damage in transit" }),
636
+ ],
637
+ trackingNumber: "LIR-TRK-30028841",
638
+ shippingCarrier: "Delhivery",
639
+ },
640
+ // ── pre-order — deposit taken, balance outstanding ────────────────────
641
+ {
642
+ id: "order-1-20260819-preordr",
643
+ productId: "preorder-beyblade-x-bx-08-wave",
644
+ productTitle: "Beyblade X BX-08 Wave (Pre-Order)",
645
+ userId: BUYER_YUGI,
646
+ userName: "Mock User 3",
647
+ userEmail: "rehan.sheikh@gmail.com",
648
+ storeId: ARENA,
649
+ quantity: 1,
650
+ unitPrice: 799,
651
+ totalPrice: 799,
652
+ currency: "INR",
653
+ status: "confirmed",
654
+ paymentStatus: "pending",
655
+ paymentMethod: "cash",
656
+ orderType: "preorder",
657
+ // 25% of ₹799 — matches `preOrderDepositPercent` on the product.
658
+ depositAmount: 199.75,
659
+ shippingAddress: "addr-yugi-home",
660
+ orderDate: daysAgo(5),
661
+ createdAt: daysAgo(5),
662
+ updatedAt: daysAgo(5),
663
+ sourceContext: {
664
+ path: "pre-order",
665
+ depositAmount: 199.75,
666
+ balanceDue: 599.25,
667
+ },
668
+ statusHistory: [
669
+ entry(daysAgo(5), "buyer", "createCheckoutOrder", {
670
+ status: { from: null, to: "pending" },
671
+ }, { actorUid: BUYER_YUGI }),
672
+ entry(daysAgo(5), "seller", "updateOrderStatus", {
673
+ status: { from: "pending", to: "confirmed" },
674
+ }, { actorUid: ARENA, note: "Deposit received — balance due on dispatch." }),
675
+ ],
676
+ },
677
+ // ── prize-draw — several entries bought in one order ──────────────────
678
+ {
679
+ id: "order-1-20260821-prizedr",
680
+ productId: "prizedraw-beyblade-mystery-box",
681
+ productTitle: "Beyblade Mystery Box — Prize Draw",
682
+ userId: BUYER_KAIBA,
683
+ userName: "Mock User 2",
684
+ userEmail: "vivaan.kapoor@gmail.com",
685
+ storeId: ARENA,
686
+ quantity: 3,
687
+ unitPrice: 99,
688
+ totalPrice: 297,
689
+ currency: "INR",
690
+ status: "confirmed",
691
+ paymentStatus: "paid",
692
+ paymentMethod: "cash",
693
+ orderType: "prize-draw",
694
+ shippingAddress: "addr-kaiba-mansion",
695
+ orderDate: daysAgo(3),
696
+ createdAt: daysAgo(3),
697
+ updatedAt: daysAgo(3),
698
+ sourceContext: {
699
+ path: "prize-draw",
700
+ prizeDrawProductId: "prizedraw-beyblade-mystery-box",
701
+ pricePerEntry: 99,
702
+ entryCount: 3,
703
+ // `prizeDrawMode` is reveal-vs-lottery, a different axis. This records
704
+ // the reveal TIMING: no reveal window means it reveals on sell-out.
705
+ revealMode: "instant",
706
+ },
707
+ statusHistory: [
708
+ entry(daysAgo(3), "buyer", "createCheckoutOrder", {
709
+ status: { from: null, to: "pending" },
710
+ }, { actorUid: BUYER_KAIBA }),
711
+ entry(daysAgo(3), "seller", "updateOrderStatus", {
712
+ status: { from: "pending", to: "confirmed" },
713
+ paymentStatus: { from: "pending", to: "paid" },
714
+ }, { actorUid: ARENA }),
715
+ ],
716
+ },
717
+ ];
387
718
  export const ordersSeedData = [
388
719
  cashOrderPendingProof,
389
720
  cashOrderVerified,
390
- ...[..._rawOrdersSeedData, ...expandedOrders].slice(0, 48),
721
+ ...acquisitionOrders,
722
+ // The slice keeps the fixture count stable as fixtures are added above it —
723
+ // it used to be 48 for the two manual-payment orders, and now also absorbs
724
+ // the six acquisition-path orders.
725
+ ...[..._rawOrdersSeedData, ...expandedOrders].slice(0, 42),
391
726
  ].map(withOrderImages);
@@ -279,6 +279,47 @@ const _rawProductsAuctionsSeedData = [
279
279
  createdAt: new Date("2026-08-01"),
280
280
  updatedAt: new Date("2026-08-10"),
281
281
  },
282
+ // --- Closed by BUY NOW: ended early, a real buyout bid won it ---
283
+ // Nothing in the seed demonstrated a buyout before W2, so the only fixture
284
+ // for `sourceContext.path === "auction-buy-now"` would have been a dangling
285
+ // FK. A buyout is a REAL bid (`isBuyout: true`), so `bidCount` counts the
286
+ // competitive ladder AND the buyout that ended it — 3 + 1 here.
287
+ {
288
+ id: "auction-beyblade-burst-spriggan-requiem-bought-out",
289
+ slug: "auction-beyblade-burst-spriggan-requiem-bought-out",
290
+ title: "Beyblade Burst B-128 Spriggan Requiem (Ended — Bought Out)",
291
+ description: "Spriggan Requiem, the dual-spin legend of Burst Super Z. Bidding had reached ₹3,100 when a buyer took the ₹4,999 Buy Now price and ended the auction early.",
292
+ categorySlugs: ["category-burst-tops", "category-beyblade-burst", "category-spinning-tops"],
293
+ categoryNames: ["Burst Tops", "Beyblade Burst", "Spinning Tops"],
294
+ brandSlug: "brand-takara-tomy",
295
+ brand: "Takara-Tomy",
296
+ startingBid: 2499,
297
+ currentBid: 3100,
298
+ buyNowPrice: 4999,
299
+ currency: "INR",
300
+ auctionEndDate: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000),
301
+ bidCount: 4,
302
+ bidsHaveStarted: true,
303
+ leadingBidderId: "user-seto-kaiba",
304
+ isSold: true,
305
+ mainImage: seedExtMedia("https://picsum.photos/seed/auction-image-beyblade-burst-spriggan-requiem-1-20260810/900/900"),
306
+ images: [
307
+ seedExtMedia("https://picsum.photos/seed/auction-image-beyblade-burst-spriggan-requiem-1-20260810/900/900"),
308
+ seedExtMedia("https://picsum.photos/seed/auction-image-beyblade-burst-spriggan-requiem-2-20260810/900/900"),
309
+ ],
310
+ status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
311
+ condition: PRODUCT_FIELDS.CONDITION_VALUES.LIKE_NEW,
312
+ tags: ["balance-type", "dual-spin"],
313
+ specifications: [
314
+ { name: "Spin Direction", value: "Dual (Left / Right)" },
315
+ { name: "Type", value: "Balance" },
316
+ { name: "Weight", value: "51.2", unit: "g" },
317
+ ],
318
+ storeId: "store-beyblade-arena",
319
+ storeName: "Beyblade Arena",
320
+ createdAt: new Date("2026-08-01"),
321
+ updatedAt: new Date("2026-08-20"),
322
+ },
282
323
  // --- Additional active auctions, varied end dates + bid activity ---
283
324
  {
284
325
  id: "auction-beyblade-burst-cho-z-achilles",
package/dist/server.d.ts CHANGED
@@ -527,6 +527,8 @@ export { renderFaqOg, renderFaqOgImage, type FaqOgData } from "./_internal/serve
527
527
  export { renderScamOg, renderScamOgImage, type ScamOgData } from "./_internal/server/features/scams/og";
528
528
  export { getScammerForDetail, getScammerProfilePageData as getScammerProfilePageDataCached } from "./_internal/server/features/scams/data";
529
529
  export { orderDocumentToOrder } from "./_internal/server/features/orders/adapters";
530
+ export { offerDocumentToOffer, offerToChainRound } from "./_internal/server/features/offers/adapters";
531
+ export type { Offer, OfferAdapterOptions, OfferChainRound, OfferTimelineEntry } from "./_internal/server/features/offers/adapters";
530
532
  export { LISTING_TYPE_CAPABILITIES, capabilityFor, canAddToCart, canBid, supportsShipping, requiresVendorVerified, requiresJurisdictionCheck, hasInstantFulfillment, assertNever, } from "./_internal/shared/listing-types/capabilities";
531
533
  export type { ListingTypeCapability } from "./_internal/shared/listing-types/capabilities";
532
534
  export { LISTING_TYPE_REGISTRY, pluginFor, detectListingTypeFromSlug } from "./_internal/shared/listing-types/_registry";
package/dist/server.js CHANGED
@@ -1385,6 +1385,11 @@ export { renderScamOg, renderScamOgImage } from "./_internal/server/features/sca
1385
1385
  export { getScammerForDetail, getScammerProfilePageData as getScammerProfilePageDataCached } from "./_internal/server/features/scams/data";
1386
1386
  // Adapters
1387
1387
  export { orderDocumentToOrder } from "./_internal/server/features/orders/adapters";
1388
+ // Offers had NO adapter at all — all three routes returned raw OfferDocuments
1389
+ // with live Date objects. `offerDocumentToOffer` gates buyer identity behind
1390
+ // an explicit flag so a route that forgets `maskOfferForSeller` under-shares
1391
+ // rather than leaking.
1392
+ export { offerDocumentToOffer, offerToChainRound } from "./_internal/server/features/offers/adapters";
1388
1393
  // Listing-type capability registry — SB-UNI X1.
1389
1394
  export { LISTING_TYPE_CAPABILITIES, capabilityFor, canAddToCart, canBid, supportsShipping, requiresVendorVerified, requiresJurisdictionCheck, hasInstantFulfillment, assertNever, } from "./_internal/shared/listing-types/capabilities";
1390
1395
  export { LISTING_TYPE_REGISTRY, pluginFor, detectListingTypeFromSlug } from "./_internal/shared/listing-types/_registry";