@mohasinac/appkit 4.62.1 → 4.63.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +8 -29
  3. package/dist/_internal/client/features/layout/filterNavItems.d.ts +28 -0
  4. package/dist/_internal/client/features/layout/filterNavItems.js +35 -0
  5. package/dist/_internal/server/features/ads/booking.d.ts +118 -0
  6. package/dist/_internal/server/features/ads/booking.js +326 -0
  7. package/dist/_internal/server/features/checkout/actions.d.ts +51 -11
  8. package/dist/_internal/server/features/checkout/actions.js +335 -80
  9. package/dist/_internal/server/features/checkout/expand-order-items.d.ts +1 -2
  10. package/dist/_internal/server/features/checkout/expand-order-items.js +32 -0
  11. package/dist/_internal/server/features/checkout/freeze-parts.d.ts +50 -0
  12. package/dist/_internal/server/features/checkout/freeze-parts.js +94 -0
  13. package/dist/_internal/server/features/checkout/value-otp-gate.d.ts +55 -0
  14. package/dist/_internal/server/features/checkout/value-otp-gate.js +60 -0
  15. package/dist/_internal/server/features/dashboard/attention.d.ts +128 -0
  16. package/dist/_internal/server/features/dashboard/attention.js +183 -0
  17. package/dist/_internal/server/features/dashboard/data.d.ts +47 -0
  18. package/dist/_internal/server/features/dashboard/data.js +82 -0
  19. package/dist/_internal/server/features/inventory/reservations.d.ts +99 -0
  20. package/dist/_internal/server/features/inventory/reservations.js +273 -0
  21. package/dist/_internal/server/features/offers/destinations.d.ts +40 -0
  22. package/dist/_internal/server/features/offers/destinations.js +65 -0
  23. package/dist/_internal/server/features/orders/adapters.js +21 -0
  24. package/dist/_internal/server/features/orders/amend-delivery.d.ts +56 -0
  25. package/dist/_internal/server/features/orders/amend-delivery.js +124 -0
  26. package/dist/_internal/server/features/orders/balance.d.ts +89 -0
  27. package/dist/_internal/server/features/orders/balance.js +256 -0
  28. package/dist/_internal/server/features/pricing/actions.d.ts +58 -0
  29. package/dist/_internal/server/features/pricing/actions.js +144 -0
  30. package/dist/_internal/server/features/shipping/book-split.d.ts +86 -0
  31. package/dist/_internal/server/features/shipping/book-split.js +130 -0
  32. package/dist/_internal/server/features/shipping/book.d.ts +61 -0
  33. package/dist/_internal/server/features/shipping/book.js +176 -0
  34. package/dist/_internal/server/features/shipping/courier-block.js +26 -1
  35. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  36. package/dist/_internal/server/features/site-settings/adapters.js +14 -0
  37. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  38. package/dist/_internal/server/features/stores/adapters.js +14 -0
  39. package/dist/_internal/server/functions/scheduled.d.ts +2 -1
  40. package/dist/_internal/server/functions/scheduled.js +57 -1
  41. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +2 -0
  42. package/dist/_internal/server/jobs/core/jobRunners.js +45 -0
  43. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +4 -1
  44. package/dist/_internal/server/jobs/core/reservationExpiry.d.ts +17 -0
  45. package/dist/_internal/server/jobs/core/reservationExpiry.js +40 -0
  46. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +15 -0
  47. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  48. package/dist/_internal/server/jobs/handlers/index.js +1 -0
  49. package/dist/_internal/server/jobs/handlers/reservationExpiry.d.ts +2 -0
  50. package/dist/_internal/server/jobs/handlers/reservationExpiry.js +2 -0
  51. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  52. package/dist/_internal/shared/actions/action-registry.js +268 -0
  53. package/dist/_internal/shared/checkout/order-math.d.ts +31 -2
  54. package/dist/_internal/shared/checkout/order-math.js +22 -36
  55. package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
  56. package/dist/_internal/shared/checkout/rules/index.js +1 -1
  57. package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +18 -0
  58. package/dist/_internal/shared/checkout/rules/payment-gate.js +25 -0
  59. package/dist/_internal/shared/checkout/split.d.ts +0 -12
  60. package/dist/_internal/shared/checkout/split.js +22 -2
  61. package/dist/_internal/shared/content/disclaimers.js +7 -7
  62. package/dist/_internal/shared/content/published-values.d.ts +6 -1
  63. package/dist/_internal/shared/content/published-values.js +8 -0
  64. package/dist/_internal/shared/features/admin/integrations.d.ts +32 -2
  65. package/dist/_internal/shared/features/admin/integrations.js +19 -9
  66. package/dist/_internal/shared/features/dashboard/hub-sections.d.ts +72 -0
  67. package/dist/_internal/shared/features/dashboard/hub-sections.js +75 -0
  68. package/dist/_internal/shared/features/emi/choice.d.ts +98 -0
  69. package/dist/_internal/shared/features/emi/choice.js +69 -0
  70. package/dist/_internal/shared/features/emi/group.d.ts +84 -0
  71. package/dist/_internal/shared/features/emi/group.js +126 -0
  72. package/dist/_internal/shared/features/ledger/posting.d.ts +107 -0
  73. package/dist/_internal/shared/features/ledger/posting.js +165 -0
  74. package/dist/_internal/shared/features/ledger/reports.d.ts +76 -0
  75. package/dist/_internal/shared/features/ledger/reports.js +127 -0
  76. package/dist/_internal/shared/features/ledger/rules.d.ts +170 -0
  77. package/dist/_internal/shared/features/ledger/rules.js +221 -0
  78. package/dist/_internal/shared/features/offers/coordination.d.ts +122 -0
  79. package/dist/_internal/shared/features/offers/coordination.js +80 -0
  80. package/dist/_internal/shared/features/orders/delivery-snapshot.d.ts +114 -0
  81. package/dist/_internal/shared/features/orders/delivery-snapshot.js +116 -0
  82. package/dist/_internal/shared/features/payouts/pay-period.d.ts +91 -0
  83. package/dist/_internal/shared/features/payouts/pay-period.js +104 -0
  84. package/dist/_internal/shared/features/points/accepts.d.ts +1 -8
  85. package/dist/_internal/shared/features/points/accepts.js +12 -6
  86. package/dist/_internal/shared/features/pricing/rate-registry.d.ts +150 -0
  87. package/dist/_internal/shared/features/pricing/rate-registry.js +246 -0
  88. package/dist/_internal/shared/features/shipping/parcel.d.ts +123 -0
  89. package/dist/_internal/shared/features/shipping/parcel.js +139 -0
  90. package/dist/_internal/shared/features/site-settings/fees.d.ts +16 -8
  91. package/dist/_internal/shared/features/site-settings/fees.js +12 -8
  92. package/dist/_internal/shared/fees/explain.d.ts +81 -0
  93. package/dist/_internal/shared/fees/explain.js +101 -0
  94. package/dist/_internal/shared/history/index.d.ts +1 -1
  95. package/dist/_internal/shared/history/index.js +1 -1
  96. package/dist/_internal/shared/history/types.d.ts +7 -1
  97. package/dist/_internal/shared/history/types.js +25 -0
  98. package/dist/client.d.ts +11 -1
  99. package/dist/client.js +13 -0
  100. package/dist/constants/api-endpoints.d.ts +72 -0
  101. package/dist/constants/api-endpoints.js +41 -0
  102. package/dist/constants/field-names.d.ts +41 -0
  103. package/dist/constants/field-names.js +47 -0
  104. package/dist/features/account/components/UserOrdersView.js +28 -2
  105. package/dist/features/admin/components/AdminIntegrationsView.d.ts +55 -0
  106. package/dist/features/admin/components/AdminIntegrationsView.js +74 -0
  107. package/dist/features/admin/components/AdminOrderEditorView.d.ts +16 -1
  108. package/dist/features/admin/components/AdminOrderEditorView.js +72 -3
  109. package/dist/features/admin/components/AdminOrdersView.js +20 -1
  110. package/dist/features/admin/schemas/firestore.d.ts +32 -0
  111. package/dist/features/ads/schemas/booking-write.d.ts +157 -0
  112. package/dist/features/ads/schemas/booking-write.js +88 -0
  113. package/dist/features/ads/schemas/creative-form.d.ts +18 -0
  114. package/dist/features/ads/schemas/creative-form.js +51 -0
  115. package/dist/features/ads/schemas/firestore.d.ts +140 -0
  116. package/dist/features/ads/schemas/firestore.js +109 -0
  117. package/dist/features/auctions/repository/bid.repository.js +3 -1
  118. package/dist/features/audit-log/schemas/firestore.d.ts +110 -0
  119. package/dist/features/audit-log/schemas/firestore.js +74 -0
  120. package/dist/features/auth/actions/profile-actions.d.ts +69 -1
  121. package/dist/features/auth/actions/profile-actions.js +62 -1
  122. package/dist/features/auth/schemas/firestore.d.ts +16 -2
  123. package/dist/features/auth/schemas/firestore.js +2 -1
  124. package/dist/features/blog/actions/blog-actions.d.ts +6 -0
  125. package/dist/features/blog/actions/blog-actions.js +17 -2
  126. package/dist/features/blog/api/route.js +4 -1
  127. package/dist/features/blog/columns/index.js +5 -0
  128. package/dist/features/blog/components/BlogIndexPageView.js +2 -1
  129. package/dist/features/blog/repository/blog.repository.d.ts +4 -0
  130. package/dist/features/blog/repository/blog.repository.js +5 -0
  131. package/dist/features/blog/schemas/blog-form.d.ts +3 -0
  132. package/dist/features/blog/schemas/blog-form.js +1 -0
  133. package/dist/features/blog/schemas/firestore.d.ts +38 -1
  134. package/dist/features/blog/schemas/firestore.js +23 -0
  135. package/dist/features/blog/schemas/index.d.ts +6 -0
  136. package/dist/features/blog/schemas/index.js +2 -0
  137. package/dist/features/blog/types/index.d.ts +2 -0
  138. package/dist/features/cart/components/CartPriceBreakdown.d.ts +12 -1
  139. package/dist/features/cart/components/CartPriceBreakdown.js +24 -5
  140. package/dist/features/cart/repository/cart.repository.d.ts +14 -0
  141. package/dist/features/cart/repository/cart.repository.js +20 -0
  142. package/dist/features/cart/schemas/firestore.d.ts +24 -0
  143. package/dist/features/dashboard/components/DashboardHubView.d.ts +83 -0
  144. package/dist/features/dashboard/components/DashboardHubView.js +56 -0
  145. package/dist/features/dashboard/components/DashboardSectionsClient.d.ts +23 -0
  146. package/dist/features/dashboard/components/DashboardSectionsClient.js +66 -0
  147. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.d.ts +55 -0
  148. package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +175 -0
  149. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +24 -0
  150. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +28 -0
  151. package/dist/features/dispute-reasons/schemas/firestore.d.ts +3 -5
  152. package/dist/features/events/components/EventSaleBanner.js +1 -1
  153. package/dist/features/faq/components/FAQPageContent.js +2 -2
  154. package/dist/features/gateway-events/schemas/index.d.ts +2 -2
  155. package/dist/features/homepage/schemas/index.d.ts +8 -8
  156. package/dist/features/inventory/schemas/stock-reservation.d.ts +114 -0
  157. package/dist/features/inventory/schemas/stock-reservation.js +103 -0
  158. package/dist/features/layout/AppLayoutShell.d.ts +9 -1
  159. package/dist/features/layout/AppLayoutShell.js +12 -4
  160. package/dist/features/layout/BottomActions.js +2 -1
  161. package/dist/features/layout/BottomNavbar.d.ts +10 -2
  162. package/dist/features/layout/SideActionDock.js +52 -2
  163. package/dist/features/layout/TitleBarLayout.js +13 -4
  164. package/dist/features/layout/TitleBarLayout.style.css +59 -0
  165. package/dist/features/layout/useCtaReveal.d.ts +16 -1
  166. package/dist/features/layout/useCtaReveal.js +17 -26
  167. package/dist/features/ledger/repository/journal.repository.d.ts +110 -0
  168. package/dist/features/ledger/repository/journal.repository.js +312 -0
  169. package/dist/features/ledger/schemas/expenses.d.ts +87 -0
  170. package/dist/features/ledger/schemas/expenses.js +27 -0
  171. package/dist/features/ledger/schemas/firestore.d.ts +183 -0
  172. package/dist/features/ledger/schemas/firestore.js +69 -0
  173. package/dist/features/orders/components/BalancePaymentPanel.d.ts +12 -0
  174. package/dist/features/orders/components/BalancePaymentPanel.js +94 -0
  175. package/dist/features/orders/components/RaiseDisputeForm.js +19 -11
  176. package/dist/features/orders/repository/orders.repository.d.ts +28 -1
  177. package/dist/features/orders/repository/orders.repository.js +60 -6
  178. package/dist/features/orders/schemas/balance.d.ts +40 -0
  179. package/dist/features/orders/schemas/balance.js +47 -0
  180. package/dist/features/orders/schemas/firestore.d.ts +202 -0
  181. package/dist/features/orders/schemas/firestore.js +43 -0
  182. package/dist/features/orders/schemas/index.d.ts +2 -2
  183. package/dist/features/orders/types/index.d.ts +21 -0
  184. package/dist/features/payments/repository/payout.repository.js +3 -2
  185. package/dist/features/payments/schemas/firestore.d.ts +92 -1
  186. package/dist/features/payments/schemas/firestore.js +23 -0
  187. package/dist/features/pricing/components/AdminPricingView.d.ts +13 -0
  188. package/dist/features/pricing/components/AdminPricingView.js +157 -0
  189. package/dist/features/products/schemas/firestore.d.ts +26 -1
  190. package/dist/features/products/schemas/firestore.js +2 -0
  191. package/dist/features/products/schemas/index.d.ts +2 -2
  192. package/dist/features/reviews/repository/reviews.repository.d.ts +14 -0
  193. package/dist/features/reviews/repository/reviews.repository.js +16 -0
  194. package/dist/features/scams/repository/scammer.repository.js +2 -1
  195. package/dist/features/scams/schemas/firestore.d.ts +2 -1
  196. package/dist/features/scams/schemas/firestore.js +2 -1
  197. package/dist/features/seller/actions/offer-actions.js +56 -0
  198. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  199. package/dist/features/seller/actions/seller-actions.js +4 -0
  200. package/dist/features/seller/components/DispatchForm.d.ts +11 -0
  201. package/dist/features/seller/components/DispatchForm.js +190 -0
  202. package/dist/features/seller/components/SellerOrdersView.js +94 -2
  203. package/dist/features/seller/components/index.d.ts +1 -0
  204. package/dist/features/seller/components/index.js +1 -0
  205. package/dist/features/seller/repository/offer.repository.js +4 -3
  206. package/dist/features/seller/schemas/firestore.d.ts +23 -2
  207. package/dist/features/seller/schemas/firestore.js +3 -2
  208. package/dist/features/seller/schemas/index.d.ts +4 -4
  209. package/dist/features/seller/schemas/order-forms.d.ts +61 -4
  210. package/dist/features/seller/schemas/order-forms.js +41 -8
  211. package/dist/features/shipments/schemas/firestore.d.ts +25 -0
  212. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +39 -0
  213. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +55 -0
  214. package/dist/features/shipping-boxes/schemas/firestore.d.ts +2 -4
  215. package/dist/features/stores/repository/store.repository.d.ts +18 -0
  216. package/dist/features/stores/repository/store.repository.js +27 -1
  217. package/dist/features/stores/schemas/firestore.d.ts +41 -0
  218. package/dist/features/stores/schemas/firestore.js +20 -0
  219. package/dist/features/stores/schemas/index.d.ts +6 -6
  220. package/dist/features/support/repository/support.repository.js +72 -6
  221. package/dist/features/support/schemas/firestore.d.ts +17 -0
  222. package/dist/features/support/schemas/index.d.ts +2 -2
  223. package/dist/index.d.ts +5 -0
  224. package/dist/index.js +19 -0
  225. package/dist/next/routing/route-map.d.ts +92 -0
  226. package/dist/next/routing/route-map.js +53 -0
  227. package/dist/react/contexts/SessionContext.d.ts +17 -1
  228. package/dist/schemas/registry.d.ts +22 -16
  229. package/dist/security/pii-schemas.d.ts +1 -1
  230. package/dist/security/pii-schemas.js +45 -0
  231. package/dist/server-entry.d.ts +1 -1
  232. package/dist/server-entry.js +10 -1
  233. package/dist/server.d.ts +29 -1
  234. package/dist/server.js +158 -0
  235. package/dist/styles.css +349 -1
  236. package/dist/tailwind-utilities.css +1 -1
  237. package/dist/ui/components/Button.d.ts +10 -1
  238. package/dist/ui/components/Button.js +25 -3
  239. package/dist/ui/components/Chart.d.ts +63 -0
  240. package/dist/ui/components/Chart.js +169 -0
  241. package/dist/ui/components/Chart.style.css +214 -0
  242. package/dist/ui/components/Disclaimer.js +10 -1
  243. package/dist/ui/components/OverflowRow.js +54 -2
  244. package/dist/ui/components/OverflowRow.style.css +38 -0
  245. package/dist/ui/components/RichTextEditor.js +99 -8
  246. package/dist/ui/components/chart-spec.d.ts +68 -0
  247. package/dist/ui/components/chart-spec.js +140 -0
  248. package/dist/ui/components/index.style.css +1 -0
  249. package/dist/ui/components/surface-tokens.d.ts +1 -1
  250. package/dist/ui/components/surface-tokens.js +9 -0
  251. package/dist/ui/components/toolbar-collapse.d.ts +13 -0
  252. package/dist/ui/components/toolbar-collapse.js +10 -1
  253. package/dist/ui/index.d.ts +6 -0
  254. package/dist/ui/index.js +3 -0
  255. package/dist/ui/rich-text/RichText.d.ts +10 -1
  256. package/dist/ui/rich-text/RichText.js +33 -2
  257. package/dist/ui/rich-text/RichText.style.css +35 -0
  258. package/dist/ui/rich-text/RichTextRenderer.d.ts +30 -1
  259. package/dist/ui/rich-text/RichTextRenderer.js +34 -2
  260. package/dist/ui/rich-text/chart-blocks.d.ts +62 -0
  261. package/dist/ui/rich-text/chart-blocks.js +87 -0
  262. package/package.json +1 -1
  263. package/scripts/seed-cli.mjs +3 -0
@@ -59,6 +59,32 @@ export class StoreRepository extends BaseRepository {
59
59
  async findBySlug(storeSlug) {
60
60
  return this.findById(storeSlug);
61
61
  }
62
+ /**
63
+ * The slugs of every store paid at shipping rather than at delivery.
64
+ *
65
+ * 🛑 A `Set` of IDS, not the documents. The payout sweep needs only
66
+ * membership, and loading full store documents for a question answered by a
67
+ * string would spend the ~3-round-trip budget (Rule #6) on data it discards.
68
+ *
69
+ * 🛑 An EQUALITY on `trustedSeller == true`, never `!= false`. A Firestore
70
+ * inequality excludes every document that LACKS the field — which is every
71
+ * store, since the flag is new and optional — so `!=` would return the
72
+ * trusted set and nothing else, or everything, depending on which way you
73
+ * wrote it. Both are wrong and neither raises.
74
+ *
75
+ * Bounded at 500: trust is granted by hand, one store at a time, on risk
76
+ * grounds. If this ever saturates, the grant has stopped being deliberate
77
+ * and that is the thing to fix rather than the limit.
78
+ */
79
+ async findTrustedStoreIds() {
80
+ const snap = await this.db
81
+ .collection(this.collection)
82
+ .where(STORE_FIELDS.TRUSTED_SELLER, "==", true)
83
+ .select()
84
+ .limit(500)
85
+ .get();
86
+ return new Set(snap.docs.map((d) => d.id));
87
+ }
62
88
  /**
63
89
  * Find the store owned by a specific user UID.
64
90
  */
@@ -117,7 +143,7 @@ export class StoreRepository extends BaseRepository {
117
143
  trigger: ctx?.trigger ?? defaultTrigger,
118
144
  reason: ctx?.reason,
119
145
  note: ctx?.note,
120
- // `encryptPiiFields` never descends into arrays, so a nested secret
146
+ // `encryptPiiFields` covers only NAMED paths, so an undeclared nested secret
121
147
  // would be stored in plaintext — the list below is the scrub.
122
148
  piiFields: STORE_HISTORY_PII_FIELDS,
123
149
  });
@@ -107,6 +107,27 @@ export interface StoreDocument extends BaseDocument {
107
107
  adminNotes?: string;
108
108
  /** Admin "verified store" badge — distinct from `status`/`isPublic`. */
109
109
  isVerified?: boolean;
110
+ /**
111
+ * Paid at SHIPPING rather than at delivery.
112
+ *
113
+ * 🛑 **A risk transfer, not a courtesy or a badge.** Paying before delivery
114
+ * means the platform carries a lost parcel and a non-delivery dispute with
115
+ * the money already gone. Admin-granted only, `recordAdminAction`-logged,
116
+ * revocable — and **PRIVATE in the public projection**, because it describes
117
+ * our risk posture rather than anything a buyer should weigh. A store does
118
+ * not get to display that we trust it.
119
+ *
120
+ * 🛑 A faster path through the SAME machinery, never a second one. The
121
+ * eligibility sweep moves the delivered-status test, not the payout, the
122
+ * hold, the deductions or the dispatch.
123
+ *
124
+ * 🛑 **A refund after a trusted payout has no money left to net against.**
125
+ * The ordinary path deducts from a still-`pending` payout; once paid there
126
+ * is nothing to deduct from, so it becomes a `manual_refund_due` case —
127
+ * which already exists and already means exactly this. Never a negative
128
+ * payout.
129
+ */
130
+ trustedSeller?: boolean;
110
131
  /** Reason recorded when `status` is set to "suspended". */
111
132
  suspensionReason?: string;
112
133
  stats?: {
@@ -386,6 +407,7 @@ export declare const STORE_FIELDS: {
386
407
  readonly ADMIN_NOTES: "adminNotes";
387
408
  readonly IS_FEATURED: "isFeatured";
388
409
  readonly IS_VERIFIED: "isVerified";
410
+ readonly TRUSTED_SELLER: "trustedSeller";
389
411
  readonly SUSPENSION_REASON: "suspensionReason";
390
412
  readonly CAPABILITIES: "capabilities";
391
413
  readonly STATUS_VALUES: {
@@ -404,3 +426,22 @@ export type StoreAddressUpdateInput = _AddrUpdate;
404
426
  export { ADDRESS_FIELDS as STORE_ADDRESS_FIELDS, ADDRESS_INDEXED_FIELDS as STORE_ADDRESS_INDEXED_FIELDS, ADDRESS_PUBLIC_FIELDS as STORE_ADDRESS_PUBLIC_FIELDS, ADDRESS_UPDATABLE_FIELDS as STORE_ADDRESS_UPDATABLE_FIELDS, DEFAULT_ADDRESS_DATA as DEFAULT_STORE_ADDRESS_DATA, } from "../../addresses/schemas";
405
427
  /** @deprecated SB-UNI-A — literal alias only. Use ADDRESSES_COLLECTION. */
406
428
  export declare const STORE_ADDRESS_SUBCOLLECTION: "addresses";
429
+ /**
430
+ * The platform's own storefront.
431
+ *
432
+ * An IDENTITY, not a setting — it is the same id the seed's `REAL_STORE_IDS`
433
+ * and `realListingsOnly` already treat as the platform's own, and resolving it
434
+ * in code is what stops it being switched off by an edit, a reseed, or a
435
+ * mis-clicked admin toggle. `storeAcceptsPoints` is the motivating reader: the
436
+ * one store the points programme is advertised on cannot be allowed to decline
437
+ * to fund it.
438
+ *
439
+ * 🛑 It lives HERE, in `features/`, and not beside its reader in
440
+ * `_internal/shared/features/points/` — `audit-ssr-in-appkit` Rule 3 forbids a
441
+ * brand-bearing literal inside `_internal/`, because a consumer of appkit would
442
+ * inherit OUR store id with no way to override it. `features/` is where the
443
+ * same literal already lives legitimately (`CONSIGNMENT_STORE_ID` in
444
+ * `features/catalogue/utils/product-from-item.ts`), and this file is the one
445
+ * that already documents the rule on `acceptsPoints` above.
446
+ */
447
+ export declare const PLATFORM_STORE_ID = "store-letitrip-official";
@@ -74,6 +74,7 @@ export const STORE_FIELDS = {
74
74
  ADMIN_NOTES: "adminNotes",
75
75
  IS_FEATURED: "isFeatured",
76
76
  IS_VERIFIED: "isVerified",
77
+ TRUSTED_SELLER: "trustedSeller",
77
78
  SUSPENSION_REASON: "suspensionReason",
78
79
  CAPABILITIES: "capabilities",
79
80
  STATUS_VALUES: {
@@ -101,3 +102,22 @@ export function generateStoreSlug(storeName, ownerDisplayName) {
101
102
  export { ADDRESS_FIELDS as STORE_ADDRESS_FIELDS, ADDRESS_INDEXED_FIELDS as STORE_ADDRESS_INDEXED_FIELDS, ADDRESS_PUBLIC_FIELDS as STORE_ADDRESS_PUBLIC_FIELDS, ADDRESS_UPDATABLE_FIELDS as STORE_ADDRESS_UPDATABLE_FIELDS, DEFAULT_ADDRESS_DATA as DEFAULT_STORE_ADDRESS_DATA, } from "../../addresses/schemas/index.js";
102
103
  /** @deprecated SB-UNI-A — literal alias only. Use ADDRESSES_COLLECTION. */
103
104
  export const STORE_ADDRESS_SUBCOLLECTION = "addresses";
105
+ /**
106
+ * The platform's own storefront.
107
+ *
108
+ * An IDENTITY, not a setting — it is the same id the seed's `REAL_STORE_IDS`
109
+ * and `realListingsOnly` already treat as the platform's own, and resolving it
110
+ * in code is what stops it being switched off by an edit, a reseed, or a
111
+ * mis-clicked admin toggle. `storeAcceptsPoints` is the motivating reader: the
112
+ * one store the points programme is advertised on cannot be allowed to decline
113
+ * to fund it.
114
+ *
115
+ * 🛑 It lives HERE, in `features/`, and not beside its reader in
116
+ * `_internal/shared/features/points/` — `audit-ssr-in-appkit` Rule 3 forbids a
117
+ * brand-bearing literal inside `_internal/`, because a consumer of appkit would
118
+ * inherit OUR store id with no way to override it. `features/` is where the
119
+ * same literal already lives legitimately (`CONSIGNMENT_STORE_ID` in
120
+ * `features/catalogue/utils/product-from-item.ts`), and this file is the one
121
+ * that already documents the rule on `acceptsPoints` above.
122
+ */
123
+ export const PLATFORM_STORE_ID = "store-letitrip-official";
@@ -218,13 +218,13 @@ export declare const storeFirestoreSchema: z.ZodObject<{
218
218
  totalReviews: z.ZodNumber;
219
219
  averageRating: z.ZodOptional<z.ZodNumber>;
220
220
  }, "strip", z.ZodTypeAny, {
221
- itemsSold: number;
222
221
  totalProducts: number;
222
+ itemsSold: number;
223
223
  totalReviews: number;
224
224
  averageRating?: number | undefined;
225
225
  }, {
226
- itemsSold: number;
227
226
  totalProducts: number;
227
+ itemsSold: number;
228
228
  totalReviews: number;
229
229
  averageRating?: number | undefined;
230
230
  }>>;
@@ -363,8 +363,8 @@ export declare const storeFirestoreSchema: z.ZodObject<{
363
363
  location?: string | undefined;
364
364
  returnPolicy?: string | undefined;
365
365
  stats?: {
366
- itemsSold: number;
367
366
  totalProducts: number;
367
+ itemsSold: number;
368
368
  totalReviews: number;
369
369
  averageRating?: number | undefined;
370
370
  } | undefined;
@@ -432,8 +432,8 @@ export declare const storeFirestoreSchema: z.ZodObject<{
432
432
  location?: string | undefined;
433
433
  returnPolicy?: string | undefined;
434
434
  stats?: {
435
- itemsSold: number;
436
435
  totalProducts: number;
436
+ itemsSold: number;
437
437
  totalReviews: number;
438
438
  averageRating?: number | undefined;
439
439
  } | undefined;
@@ -530,8 +530,8 @@ export declare const storeListItemSchema: z.ZodObject<{
530
530
  storeDescription?: string | undefined;
531
531
  storeLogoURL?: string | undefined;
532
532
  storeBannerURL?: string | undefined;
533
- itemsSold?: number | undefined;
534
533
  totalProducts?: number | undefined;
534
+ itemsSold?: number | undefined;
535
535
  totalReviews?: number | undefined;
536
536
  averageRating?: number | undefined;
537
537
  }, {
@@ -546,8 +546,8 @@ export declare const storeListItemSchema: z.ZodObject<{
546
546
  storeDescription?: string | undefined;
547
547
  storeLogoURL?: string | undefined;
548
548
  storeBannerURL?: string | undefined;
549
- itemsSold?: number | undefined;
550
549
  totalProducts?: number | undefined;
550
+ itemsSold?: number | undefined;
551
551
  totalReviews?: number | undefined;
552
552
  averageRating?: number | undefined;
553
553
  }>;
@@ -9,6 +9,41 @@ import { sieveAnd, sieveFilter, SIEVE_OP } from "../../../utils/sieve-builder.js
9
9
  import { maskPii, revealPii } from "../../../security/pii-accessors.js";
10
10
  import { SUPPORT_TICKET_COLLECTION, SUPPORT_TICKET_PII_FIELDS, SUPPORT_TICKET_TRACKED_FIELDS, TicketStatusValues, ACTIVE_TICKET_STATUSES, } from "../schemas/firestore.js";
11
11
  import { withHistory } from "../../../_internal/shared/history/index.js";
12
+ /**
13
+ * Who, if anyone, gets credited with resolving this ticket.
14
+ *
15
+ * 🛑 **A BUYER is never the resolver**, even though a buyer can drive the
16
+ * transition — replying "that's sorted, thanks" is a legitimate way for a
17
+ * ticket to reach `resolved`, and crediting it would put a customer's uid in
18
+ * a field a payslip is computed from. `system` has no uid at all, which is
19
+ * the other case that must not be paid.
20
+ *
21
+ * Returning `undefined` is correct and expected: the ticket is still resolved,
22
+ * it simply earns nobody wages. A fabricated fallback — the assignee, the
23
+ * ticket owner — would be a wage attributed to someone who did not do the
24
+ * work, and it would look exactly like a real one.
25
+ */
26
+ const WAGE_EARNING_ACTOR_ROLES = new Set(["seller", "admin"]);
27
+ function resolverUid(ctx) {
28
+ const actor = ctx?.actor;
29
+ if (!actor?.uid)
30
+ return undefined;
31
+ /*
32
+ * An ALLOW-LIST, not `role !== "buyer"`. A tenth actor role added later
33
+ * would silently start earning wages under a deny-list, which is the
34
+ * `Record<Union, T>`-over-`Set<string>` argument this codebase makes
35
+ * everywhere else — and the roles that can be credited is the shorter,
36
+ * more stable list.
37
+ *
38
+ * 🛑 `HistoryActorRole` has no `employee` member, and that is FINE: this
39
+ * field records WHO resolved it, and the payroll decides whether that
40
+ * person is on it. A seller resolving their own store's ticket is recorded
41
+ * here and appears on no payslip, because they are not an employee.
42
+ */
43
+ if (!WAGE_EARNING_ACTOR_ROLES.has(actor.role))
44
+ return undefined;
45
+ return actor.uid;
46
+ }
12
47
  export class SupportRepository extends BaseRepository {
13
48
  constructor() {
14
49
  super(SUPPORT_TICKET_COLLECTION);
@@ -210,7 +245,7 @@ export class SupportRepository extends BaseRepository {
210
245
  // `piiFields`, which is what encrypts `assignedToName` on the way down.
211
246
  const patch = {
212
247
  ...update,
213
- ...this.resolutionStamps(current, update.status),
248
+ ...this.resolutionStamps(current, update.status, resolverUid(ctx)),
214
249
  updatedAt: new Date(),
215
250
  };
216
251
  return this.update(ticketId, this.withTicketHistory(current, patch, ctx, "updateTicketStatus"));
@@ -233,14 +268,45 @@ export class SupportRepository extends BaseRepository {
233
268
  * against the document would poison that patch's inferred type with
234
269
  * `Encrypted<string>` members it never actually sets.
235
270
  */
236
- resolutionStamps(current, next) {
271
+ resolutionStamps(current, next, actorUid) {
237
272
  if (!next || next === current?.status)
238
273
  return {};
239
274
  const now = new Date();
240
- if (next === TicketStatusValues.RESOLVED && !current?.resolvedAt)
241
- return { resolvedAt: now };
275
+ if (next === TicketStatusValues.RESOLVED && !current?.resolvedAt) {
276
+ /*
277
+ * 🛑 `resolvedBy` is stamped HERE and is not the same thing as
278
+ * `assignedTo`.
279
+ *
280
+ * `assignedTo` is the CURRENT assignee: reassign a resolved ticket for
281
+ * follow-up and it moves, so paying from it credits whoever happens to
282
+ * hold the ticket at month end rather than whoever did the work. That is
283
+ * the whole reason this field exists.
284
+ *
285
+ * Absent when the caller supplied no actor — a system transition has no
286
+ * person to pay, and a fabricated uid would be a wage attributed to
287
+ * somebody who did nothing.
288
+ */
289
+ return actorUid ? { resolvedAt: now, resolvedBy: actorUid } : { resolvedAt: now };
290
+ }
242
291
  if (next === TicketStatusValues.CLOSED && !current?.closedAt)
243
292
  return { closedAt: now };
293
+ /*
294
+ * 🛑 A REOPEN clears both, and clearing `resolvedBy` is load-bearing.
295
+ *
296
+ * Pay is computed from tickets STILL RESOLVED at period end, so a ticket
297
+ * that goes back to open must stop counting — otherwise close-it,
298
+ * let-it-reopen, close-it-again pays twice for one problem.
299
+ *
300
+ * Cleared rather than left in place with the status as the only signal,
301
+ * because `resolvedTicketsForPeriod` filters on all three and a stale
302
+ * `resolvedAt` surviving a reopen is a row that looks payable to anything
303
+ * that checks fewer of them.
304
+ */
305
+ const reopened = current?.resolvedAt != null &&
306
+ next !== TicketStatusValues.RESOLVED &&
307
+ next !== TicketStatusValues.CLOSED;
308
+ if (reopened)
309
+ return { resolvedAt: undefined, resolvedBy: undefined };
244
310
  return {};
245
311
  }
246
312
  /** Append a timeline entry when the patch touches a tracked field. */
@@ -259,7 +325,7 @@ export class SupportRepository extends BaseRepository {
259
325
  trigger: ctx?.trigger ?? defaultTrigger,
260
326
  reason: ctx?.reason,
261
327
  note: ctx?.note,
262
- // `encryptPiiFields` never descends into arrays, so a PII-named value
328
+ // `encryptPiiFields` covers only NAMED paths, so an undeclared PII-named value
263
329
  // reaching `changes` would persist in PLAINTEXT inside statusHistory.
264
330
  piiFields: SUPPORT_TICKET_PII_FIELDS,
265
331
  });
@@ -288,7 +354,7 @@ export class SupportRepository extends BaseRepository {
288
354
  };
289
355
  if (newStatus) {
290
356
  const current = prior !== undefined ? prior : await this.getTicketById(ticketId);
291
- Object.assign(updateData, this.withTicketHistory(current, { status: newStatus, ...this.resolutionStamps(current, newStatus) }, ctx, "addMessage"));
357
+ Object.assign(updateData, this.withTicketHistory(current, { status: newStatus, ...this.resolutionStamps(current, newStatus, resolverUid(ctx)) }, ctx, "addMessage"));
292
358
  }
293
359
  await ref.update(updateData);
294
360
  }
@@ -196,6 +196,23 @@ export interface SupportTicketDocument extends BaseDocument {
196
196
  * `Date` field and split the collection into two shapes.
197
197
  */
198
198
  resolvedAt?: Date;
199
+ /**
200
+ * The uid of whoever moved the ticket to `resolved`.
201
+ *
202
+ * 🛑 **Not `assignedTo`.** That is the CURRENT assignee and moves on
203
+ * reassignment, so paying from it credits whoever holds the ticket at period
204
+ * end rather than whoever did the work. Employee pay is computed from this
205
+ * field; see `resolvedTicketsForPeriod`.
206
+ *
207
+ * Server-stamped, never client-sent, and **cleared on reopen** — pay counts
208
+ * tickets still resolved at period end, so a reopened ticket must stop
209
+ * counting or closing it twice pays twice.
210
+ *
211
+ * Absent on a system transition and on a buyer-driven one: both are real
212
+ * resolutions that earn nobody wages, and a fallback to the assignee would
213
+ * be a wage attributed to someone who did nothing.
214
+ */
215
+ resolvedBy?: string;
199
216
  closedAt?: Date;
200
217
  /** When we acknowledged receipt. Server-stamped at intake. */
201
218
  acknowledgedAt?: Date;
@@ -157,7 +157,7 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
157
157
  updatedAt: string | Date | z.objectOutputType<{
158
158
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
159
159
  }, z.ZodTypeAny, "passthrough">;
160
- category: "general" | "order_issue" | "billing_payment" | "account" | "listing_dispute" | "scam_report" | "refund_request" | "auction_dispute" | "store_change_request" | "order_modification_request" | "unban_request";
160
+ category: "general" | "account" | "order_issue" | "billing_payment" | "listing_dispute" | "scam_report" | "refund_request" | "auction_dispute" | "store_change_request" | "order_modification_request" | "unban_request";
161
161
  priority: "normal" | "high" | "low" | "urgent";
162
162
  description: string;
163
163
  userId: string;
@@ -200,7 +200,7 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
200
200
  updatedAt: string | Date | z.objectInputType<{
201
201
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
202
202
  }, z.ZodTypeAny, "passthrough">;
203
- category: "general" | "order_issue" | "billing_payment" | "account" | "listing_dispute" | "scam_report" | "refund_request" | "auction_dispute" | "store_change_request" | "order_modification_request" | "unban_request";
203
+ category: "general" | "account" | "order_issue" | "billing_payment" | "listing_dispute" | "scam_report" | "refund_request" | "auction_dispute" | "store_change_request" | "order_modification_request" | "unban_request";
204
204
  priority: "normal" | "high" | "low" | "urgent";
205
205
  description: string;
206
206
  userId: string;
package/dist/index.d.ts CHANGED
@@ -550,6 +550,8 @@ export { scammerRepository } from "./repositories/index";
550
550
  export { supportRepository, SupportRepository } from "./repositories/index";
551
551
  export type { SupportTicketDocument, SupportTicketCreateInput, SupportTicketUpdateInput, TicketMessage, TicketCategory, TicketStatus, TicketPriority, } from "./repositories/index";
552
552
  export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, SUPPORT_TICKET_FIELDS, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
553
+ export { AdminIntegrationsView } from "./features/admin/components/AdminIntegrationsView";
554
+ export type { AdminIntegrationsViewProps } from "./features/admin/components/AdminIntegrationsView";
553
555
  export { AdminTaxCodesView } from "./features/admin/components/AdminTaxCodesView";
554
556
  export type { AdminTaxCodesViewProps } from "./features/admin/components/AdminTaxCodesView";
555
557
  export { AdminTaxCodeEditorView } from "./features/admin/components/AdminTaxCodeEditorView";
@@ -2201,6 +2203,9 @@ export type { ProtectionKind, ProtectionAvailability, ProtectionTierInput, Prote
2201
2203
  export type { FeeCommissionRates, CheckoutFees, PayoutDeduction, CodHandlingFeeRates, GiftWrapFeeRates, ShipmentProtectionFeeRates, SaleProtectionFeeRates, GstBreakdown, } from "./_internal/shared/fees/calculator";
2202
2204
  export { checkEmiEligibility, computeEmiSchedule, computeBuyerEmiQuote } from "./_internal/shared/features/emi/schedule";
2203
2205
  export type { BuyerEmiQuote } from "./_internal/shared/features/emi/schedule";
2206
+ export { amountDueNow, groupEmiGate, groupEmiQuote, groupEmiSchedule, emiOrderFields } from "./_internal/shared/features/emi/group";
2207
+ export { emiTenderFor, resolveEmiChoice, emiTenderBlockReason, isTenderCompatibleWithEmi } from "./_internal/shared/features/emi/choice";
2208
+ export type { EmiChoice, EmiTender } from "./_internal/shared/features/emi/choice";
2204
2209
  export { toBuyerFacingFees, toBuyerEmiSettings, } from "./_internal/shared/features/site-settings/fees";
2205
2210
  export type { BuyerFacingFees, BuyerEmiSettings, } from "./_internal/shared/features/site-settings/fees";
2206
2211
  export { GSTIN_PATTERN, gstinCheckCharacter, isValidGstin, validateGstEnablement, canEnableGst, } from "./_internal/shared/features/site-settings/gst-registration";
package/dist/index.js CHANGED
@@ -1090,6 +1090,15 @@ export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_T
1090
1090
  // SB-UNI-B â€" sublistingCategoriesRepository + SublistingCategoryDocument deleted.
1091
1091
  // Use categoriesRepository.findBySlugAndType(slug, "sublisting") and CategoryDocument with categoryType:"sublisting".
1092
1092
  // [DB]-Database layer â€" uses firebase-admin; server-only.
1093
+ /*
1094
+ * AdminIntegrationsView (12b) — /admin/integrations.
1095
+ *
1096
+ * The caller `INTEGRATIONS` / `integrationPatch` / `allIntegrationsPatch` were
1097
+ * missing: the model landed with every route guard resolving through it and
1098
+ * nothing in the UI reading it, which made those three exports speculative
1099
+ * infra. This is what reads them.
1100
+ */
1101
+ export { AdminIntegrationsView } from "./features/admin/components/AdminIntegrationsView.js";
1093
1102
  // AdminTaxCodesView / AdminTaxCodeEditorView (B3) — /admin/tax-codes.
1094
1103
  export { AdminTaxCodesView } from "./features/admin/components/AdminTaxCodesView.js";
1095
1104
  export { AdminTaxCodeEditorView } from "./features/admin/components/AdminTaxCodeEditorView.js";
@@ -4097,6 +4106,16 @@ export { searchPriceIndex, PRICE_INDEX_SEARCH_LIMIT, PRICE_INDEX_MIN_QUERY_LENGT
4097
4106
  export { protectionAvailability, computeProtectionFees, adjudicateClaim, badgesFor, showsRiskNotice, showsSafetyBadge, returnDestination, rtoDestination, PROTECTION_KINDS, } from "./_internal/shared/features/shipping/protections.js";
4098
4107
  // EMI eligibility + schedule computation (pure, client-safe — used for checkout quotes).
4099
4108
  export { checkEmiEligibility, computeEmiSchedule, computeBuyerEmiQuote } from "./_internal/shared/features/emi/schedule.js";
4109
+ /*
4110
+ * 0f — the per-group instalment helpers. Exported because the CAPTURE amount
4111
+ * is computed in a consumer route (`/api/payment/create-order`), and that
4112
+ * route is one of the four money paths that must agree about an EMI order.
4113
+ * There is no `./_internal/*` subpath, deliberately, so the barrel is how a
4114
+ * consumer reaches shared checkout maths — exactly as `lineTotalFor` and
4115
+ * `resolveShippingCost` already are.
4116
+ */
4117
+ export { amountDueNow, groupEmiGate, groupEmiQuote, groupEmiSchedule, emiOrderFields } from "./_internal/shared/features/emi/group.js";
4118
+ export { emiTenderFor, resolveEmiChoice, emiTenderBlockReason, isTenderCompatibleWithEmi } from "./_internal/shared/features/emi/choice.js";
4100
4119
  // Buyer-facing projections of siteSettings.commissions / .emi — the single
4101
4120
  // definition of "safe to send to a browser" for fee data. See fees.ts header.
4102
4121
  export { toBuyerFacingFees, toBuyerEmiSettings, } from "./_internal/shared/features/site-settings/fees.js";
@@ -21,6 +21,8 @@ export declare const DEFAULT_ROUTE_MAP: {
21
21
  readonly AUCTIONS: "/auctions";
22
22
  readonly AUCTION_DETAIL: (id: string) => string;
23
23
  readonly PRE_ORDERS: "/pre-orders";
24
+ /** D56 — the public rate card + self-serve booking form. */
25
+ readonly ADVERTISE: "/advertise";
24
26
  readonly PRE_ORDER_DETAIL: (id: string) => string;
25
27
  readonly BUNDLES: "/bundles";
26
28
  readonly BUNDLE_DETAIL: (slug: string) => string;
@@ -157,6 +159,16 @@ export declare const DEFAULT_ROUTE_MAP: {
157
159
  };
158
160
  readonly USER: {
159
161
  readonly DASHBOARD: "/user";
162
+ /**
163
+ * A dashboard SECTION hub — the screens of one sidebar group, each with a
164
+ * sentence on what it is for.
165
+ *
166
+ * One parametric route serves every section of the portal; the slug is
167
+ * `hubSectionSlug(group.title)` and is DERIVED, so there is no list of
168
+ * section keys here to drift from the nav. `audit-dashboard-hub-coverage`
169
+ * cross-checks the two.
170
+ */
171
+ readonly SECTION: (slug: string) => string;
160
172
  readonly PROFILE: "/user/profile";
161
173
  readonly SETTINGS: "/user/settings";
162
174
  readonly ORDERS: "/user/orders";
@@ -177,6 +189,17 @@ export declare const DEFAULT_ROUTE_MAP: {
177
189
  readonly ORDER_CLAIM: (id: string) => string;
178
190
  readonly ORDER_INVOICE: (id: string) => string;
179
191
  readonly ORDER_PAYMENT: (id: string) => string;
192
+ /**
193
+ * Raise a dispute on one order.
194
+ *
195
+ * Deep-linkable on purpose: a notification `actionUrl` points here, and
196
+ * `/user/orders/view/{id}` carries a "Report a problem" button to the same
197
+ * place. One surface, two ways in — an email link that works only while
198
+ * the buyer still has the email is the shape Root Cause #57 records,
199
+ * where `ORDER_PAYMENT` had exactly ONE caller and a buyer who navigated
200
+ * away could not get back.
201
+ */
202
+ readonly ORDER_DISPUTE: (id: string) => string;
180
203
  readonly NOTIFICATIONS: "/user/notifications";
181
204
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
182
205
  readonly CLAIMED_COUPONS: "/user/coupons";
@@ -198,6 +221,8 @@ export declare const DEFAULT_ROUTE_MAP: {
198
221
  readonly SUPPORT_NEW: "/user/support/new";
199
222
  readonly SUPPORT_TICKET: (id: string) => string;
200
223
  readonly PRE_ORDERS: "/user/pre-orders";
224
+ /** D56 — the advertiser's own bookings and their moderation state. */
225
+ readonly AD_BOOKINGS: "/user/ad-bookings";
201
226
  readonly DIGITAL_CODES: "/user/digital-codes";
202
227
  readonly PRIZE_DRAWS: "/user/prize-draws";
203
228
  readonly EVENTS: "/user/events";
@@ -210,6 +235,8 @@ export declare const DEFAULT_ROUTE_MAP: {
210
235
  };
211
236
  readonly STORE: {
212
237
  readonly DASHBOARD: "/store";
238
+ /** A dashboard SECTION hub — see `USER.SECTION` for the derivation. */
239
+ readonly SECTION: (slug: string) => string;
213
240
  readonly PRODUCTS: "/store/products";
214
241
  readonly PRODUCTS_NEW: "/store/products/new";
215
242
  readonly PRODUCTS_EDIT: (id: string) => string;
@@ -300,6 +327,18 @@ export declare const DEFAULT_ROUTE_MAP: {
300
327
  };
301
328
  readonly ADMIN: {
302
329
  readonly DASHBOARD: "/admin/dashboard";
330
+ /**
331
+ * The sectioned landing at `/admin` — what used to `redirect()` to
332
+ * `DASHBOARD`.
333
+ *
334
+ * 🛑 `DASHBOARD` is `/admin/dashboard` and stays a separate page: it is the
335
+ * metrics screen, and the sidebar's "Dashboard" entry points at it. This
336
+ * key is the index that lists the twelve sections. Collapsing the two would
337
+ * either bury the metrics or make the index unreachable.
338
+ */
339
+ readonly HOME: "/admin";
340
+ /** A dashboard SECTION hub — see `USER.SECTION` for the derivation. */
341
+ readonly SECTION: (slug: string) => string;
303
342
  readonly SHIPMENTS: "/admin/shipments";
304
343
  readonly INVENTORY_BOXES: "/admin/inventory/boxes";
305
344
  readonly INVENTORY_BOX_DETAIL: (id: string) => string;
@@ -315,6 +354,7 @@ export declare const DEFAULT_ROUTE_MAP: {
315
354
  readonly USER_DETAIL: (id: string) => string;
316
355
  readonly USER_EDIT: (id: string) => string;
317
356
  readonly SITE: "/admin/site";
357
+ readonly INTEGRATIONS: "/admin/integrations";
318
358
  readonly CAROUSEL: "/admin/carousel";
319
359
  readonly CAROUSEL_NEW: "/admin/carousel/new";
320
360
  readonly CAROUSEL_EDIT: (id: string) => string;
@@ -374,6 +414,7 @@ export declare const DEFAULT_ROUTE_MAP: {
374
414
  readonly ANALYTICS: "/admin/analytics";
375
415
  readonly PAYOUTS: "/admin/payouts";
376
416
  readonly PAYOUT_DETAIL: (id: string) => string;
417
+ readonly PRICING: "/admin/pricing";
377
418
  readonly AUDIT_LOG: "/admin/audit-log";
378
419
  readonly MONEY_CASES: "/admin/money-cases";
379
420
  readonly MONEY_CASE_DETAIL: (id: string) => string;
@@ -399,6 +440,8 @@ export declare const DEFAULT_ROUTE_MAP: {
399
440
  readonly ADS: "/admin/ads";
400
441
  readonly ADS_NEW: "/admin/ads/new";
401
442
  readonly ADS_EDIT: (id: string) => string;
443
+ /** D56 — the self-serve creative moderation queue. */
444
+ readonly AD_BOOKINGS: "/admin/ads/bookings";
402
445
  readonly NEWSLETTER: "/admin/newsletter";
403
446
  readonly CONTACT: "/admin/contact";
404
447
  readonly SESSIONS: "/admin/sessions";
@@ -433,6 +476,8 @@ export declare const DEFAULT_ROUTE_MAP: {
433
476
  readonly TEAM_NEW: "/admin/team/new";
434
477
  readonly TEAM_EDIT: (id: string) => string;
435
478
  readonly SUPPORT_TICKETS: "/admin/support-tickets";
479
+ /** Staff curation of the reasons a buyer can pick when disputing. */
480
+ readonly DISPUTE_REASONS: "/admin/dispute-reasons";
436
481
  readonly SUPPORT_TICKET_BY_ID: (id: string) => string;
437
482
  readonly SCAMMERS: "/admin/scammers";
438
483
  readonly SCAMMER_BY_ID: (id: string) => string;
@@ -485,6 +530,8 @@ export declare const ROUTES: {
485
530
  readonly AUCTIONS: "/auctions";
486
531
  readonly AUCTION_DETAIL: (id: string) => string;
487
532
  readonly PRE_ORDERS: "/pre-orders";
533
+ /** D56 — the public rate card + self-serve booking form. */
534
+ readonly ADVERTISE: "/advertise";
488
535
  readonly PRE_ORDER_DETAIL: (id: string) => string;
489
536
  readonly BUNDLES: "/bundles";
490
537
  readonly BUNDLE_DETAIL: (slug: string) => string;
@@ -621,6 +668,16 @@ export declare const ROUTES: {
621
668
  };
622
669
  readonly USER: {
623
670
  readonly DASHBOARD: "/user";
671
+ /**
672
+ * A dashboard SECTION hub — the screens of one sidebar group, each with a
673
+ * sentence on what it is for.
674
+ *
675
+ * One parametric route serves every section of the portal; the slug is
676
+ * `hubSectionSlug(group.title)` and is DERIVED, so there is no list of
677
+ * section keys here to drift from the nav. `audit-dashboard-hub-coverage`
678
+ * cross-checks the two.
679
+ */
680
+ readonly SECTION: (slug: string) => string;
624
681
  readonly PROFILE: "/user/profile";
625
682
  readonly SETTINGS: "/user/settings";
626
683
  readonly ORDERS: "/user/orders";
@@ -641,6 +698,17 @@ export declare const ROUTES: {
641
698
  readonly ORDER_CLAIM: (id: string) => string;
642
699
  readonly ORDER_INVOICE: (id: string) => string;
643
700
  readonly ORDER_PAYMENT: (id: string) => string;
701
+ /**
702
+ * Raise a dispute on one order.
703
+ *
704
+ * Deep-linkable on purpose: a notification `actionUrl` points here, and
705
+ * `/user/orders/view/{id}` carries a "Report a problem" button to the same
706
+ * place. One surface, two ways in — an email link that works only while
707
+ * the buyer still has the email is the shape Root Cause #57 records,
708
+ * where `ORDER_PAYMENT` had exactly ONE caller and a buyer who navigated
709
+ * away could not get back.
710
+ */
711
+ readonly ORDER_DISPUTE: (id: string) => string;
644
712
  readonly NOTIFICATIONS: "/user/notifications";
645
713
  /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
646
714
  readonly CLAIMED_COUPONS: "/user/coupons";
@@ -662,6 +730,8 @@ export declare const ROUTES: {
662
730
  readonly SUPPORT_NEW: "/user/support/new";
663
731
  readonly SUPPORT_TICKET: (id: string) => string;
664
732
  readonly PRE_ORDERS: "/user/pre-orders";
733
+ /** D56 — the advertiser's own bookings and their moderation state. */
734
+ readonly AD_BOOKINGS: "/user/ad-bookings";
665
735
  readonly DIGITAL_CODES: "/user/digital-codes";
666
736
  readonly PRIZE_DRAWS: "/user/prize-draws";
667
737
  readonly EVENTS: "/user/events";
@@ -674,6 +744,8 @@ export declare const ROUTES: {
674
744
  };
675
745
  readonly STORE: {
676
746
  readonly DASHBOARD: "/store";
747
+ /** A dashboard SECTION hub — see `USER.SECTION` for the derivation. */
748
+ readonly SECTION: (slug: string) => string;
677
749
  readonly PRODUCTS: "/store/products";
678
750
  readonly PRODUCTS_NEW: "/store/products/new";
679
751
  readonly PRODUCTS_EDIT: (id: string) => string;
@@ -764,6 +836,18 @@ export declare const ROUTES: {
764
836
  };
765
837
  readonly ADMIN: {
766
838
  readonly DASHBOARD: "/admin/dashboard";
839
+ /**
840
+ * The sectioned landing at `/admin` — what used to `redirect()` to
841
+ * `DASHBOARD`.
842
+ *
843
+ * 🛑 `DASHBOARD` is `/admin/dashboard` and stays a separate page: it is the
844
+ * metrics screen, and the sidebar's "Dashboard" entry points at it. This
845
+ * key is the index that lists the twelve sections. Collapsing the two would
846
+ * either bury the metrics or make the index unreachable.
847
+ */
848
+ readonly HOME: "/admin";
849
+ /** A dashboard SECTION hub — see `USER.SECTION` for the derivation. */
850
+ readonly SECTION: (slug: string) => string;
767
851
  readonly SHIPMENTS: "/admin/shipments";
768
852
  readonly INVENTORY_BOXES: "/admin/inventory/boxes";
769
853
  readonly INVENTORY_BOX_DETAIL: (id: string) => string;
@@ -779,6 +863,7 @@ export declare const ROUTES: {
779
863
  readonly USER_DETAIL: (id: string) => string;
780
864
  readonly USER_EDIT: (id: string) => string;
781
865
  readonly SITE: "/admin/site";
866
+ readonly INTEGRATIONS: "/admin/integrations";
782
867
  readonly CAROUSEL: "/admin/carousel";
783
868
  readonly CAROUSEL_NEW: "/admin/carousel/new";
784
869
  readonly CAROUSEL_EDIT: (id: string) => string;
@@ -838,6 +923,7 @@ export declare const ROUTES: {
838
923
  readonly ANALYTICS: "/admin/analytics";
839
924
  readonly PAYOUTS: "/admin/payouts";
840
925
  readonly PAYOUT_DETAIL: (id: string) => string;
926
+ readonly PRICING: "/admin/pricing";
841
927
  readonly AUDIT_LOG: "/admin/audit-log";
842
928
  readonly MONEY_CASES: "/admin/money-cases";
843
929
  readonly MONEY_CASE_DETAIL: (id: string) => string;
@@ -863,6 +949,8 @@ export declare const ROUTES: {
863
949
  readonly ADS: "/admin/ads";
864
950
  readonly ADS_NEW: "/admin/ads/new";
865
951
  readonly ADS_EDIT: (id: string) => string;
952
+ /** D56 — the self-serve creative moderation queue. */
953
+ readonly AD_BOOKINGS: "/admin/ads/bookings";
866
954
  readonly NEWSLETTER: "/admin/newsletter";
867
955
  readonly CONTACT: "/admin/contact";
868
956
  readonly SESSIONS: "/admin/sessions";
@@ -897,6 +985,8 @@ export declare const ROUTES: {
897
985
  readonly TEAM_NEW: "/admin/team/new";
898
986
  readonly TEAM_EDIT: (id: string) => string;
899
987
  readonly SUPPORT_TICKETS: "/admin/support-tickets";
988
+ /** Staff curation of the reasons a buyer can pick when disputing. */
989
+ readonly DISPUTE_REASONS: "/admin/dispute-reasons";
900
990
  readonly SUPPORT_TICKET_BY_ID: (id: string) => string;
901
991
  readonly SCAMMERS: "/admin/scammers";
902
992
  readonly SCAMMER_BY_ID: (id: string) => string;
@@ -940,6 +1030,8 @@ export declare const ROUTES: {
940
1030
  /** @deprecated Use ROUTES.STORE instead */
941
1031
  export declare const SELLER_ROUTES: {
942
1032
  readonly DASHBOARD: "/store";
1033
+ /** A dashboard SECTION hub — see `USER.SECTION` for the derivation. */
1034
+ readonly SECTION: (slug: string) => string;
943
1035
  readonly PRODUCTS: "/store/products";
944
1036
  readonly PRODUCTS_NEW: "/store/products/new";
945
1037
  readonly PRODUCTS_EDIT: (id: string) => string;