@mohasinac/appkit 4.62.0 → 4.62.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 (204) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/checkout/actions.d.ts +80 -0
  3. package/dist/_internal/server/features/checkout/actions.js +542 -26
  4. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  5. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  6. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  7. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  8. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  9. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  10. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  11. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  12. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  13. package/dist/_internal/server/features/orders/actions.js +81 -8
  14. package/dist/_internal/server/features/orders/adapters.js +33 -0
  15. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  16. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  17. package/dist/_internal/server/features/points/award.js +46 -4
  18. package/dist/_internal/server/features/refunds/actions.js +26 -0
  19. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  20. package/dist/_internal/server/features/shipping/courier-block.js +239 -0
  21. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  22. package/dist/_internal/server/features/site-settings/adapters.js +15 -0
  23. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  24. package/dist/_internal/server/features/stores/adapters.js +51 -0
  25. package/dist/_internal/server/functions/scheduled.js +38 -1
  26. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +9 -2
  27. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  28. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  29. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  30. package/dist/_internal/server/jobs/core/index.js +2 -1
  31. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  32. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  33. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  34. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +62 -0
  35. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  36. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  37. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  38. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +10 -2
  39. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  40. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  41. package/dist/_internal/shared/actions/action-registry.js +28 -0
  42. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  43. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  44. package/dist/_internal/shared/checkout/order-math.d.ts +145 -0
  45. package/dist/_internal/shared/checkout/order-math.js +173 -0
  46. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  47. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  48. package/dist/_internal/shared/checkout/split.d.ts +87 -0
  49. package/dist/_internal/shared/checkout/split.js +100 -0
  50. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  51. package/dist/_internal/shared/content/disclaimers.js +217 -0
  52. package/dist/_internal/shared/content/published-values.d.ts +88 -0
  53. package/dist/_internal/shared/content/published-values.js +198 -0
  54. package/dist/_internal/shared/features/admin/integrations.d.ts +109 -0
  55. package/dist/_internal/shared/features/admin/integrations.js +253 -0
  56. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  57. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  58. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  59. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  60. package/dist/_internal/shared/features/points/accepts.d.ts +36 -0
  61. package/dist/_internal/shared/features/points/accepts.js +43 -0
  62. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  63. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  64. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  65. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  66. package/dist/_internal/shared/fees/calculator.js +32 -2
  67. package/dist/client.d.ts +11 -0
  68. package/dist/client.js +30 -0
  69. package/dist/constants/api-endpoints.d.ts +42 -0
  70. package/dist/constants/api-endpoints.js +14 -0
  71. package/dist/constants/field-names.d.ts +1 -0
  72. package/dist/constants/field-names.js +5 -0
  73. package/dist/contracts/index.d.ts +1 -1
  74. package/dist/contracts/shipping.d.ts +45 -0
  75. package/dist/contracts/shipping.js +15 -0
  76. package/dist/features/about/components/AboutView.js +1 -1
  77. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  78. package/dist/features/account/components/UserOrdersView.js +19 -33
  79. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  80. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  81. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  82. package/dist/features/admin/components/AdminOrderEditorView.d.ts +18 -1
  83. package/dist/features/admin/components/AdminOrderEditorView.js +11 -2
  84. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  85. package/dist/features/admin/components/AdminOrdersView.js +67 -5
  86. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  87. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  88. package/dist/features/admin/constants/filter-tabs.js +6 -0
  89. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  90. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  91. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  92. package/dist/features/admin/schemas/firestore.d.ts +30 -0
  93. package/dist/features/admin/schemas/firestore.js +5 -0
  94. package/dist/features/audit-log/schemas/firestore.d.ts +30 -0
  95. package/dist/features/audit-log/schemas/firestore.js +15 -0
  96. package/dist/features/auth/permissions/constants.js +13 -0
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +13 -0
  98. package/dist/features/cart/components/CartPriceBreakdown.js +6 -2
  99. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  100. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  101. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  102. package/dist/features/cart/components/index.d.ts +2 -0
  103. package/dist/features/cart/components/index.js +1 -0
  104. package/dist/features/cart/repository/cart.repository.d.ts +19 -0
  105. package/dist/features/cart/repository/cart.repository.js +27 -0
  106. package/dist/features/cart/schemas/firestore.d.ts +92 -0
  107. package/dist/features/contact/email.d.ts +27 -10
  108. package/dist/features/contact/email.js +20 -3
  109. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +38 -0
  110. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +80 -0
  111. package/dist/features/dispute-reasons/schemas/firestore.d.ts +64 -0
  112. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  113. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  114. package/dist/features/faq/components/FAQAccordion.js +29 -4
  115. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  116. package/dist/features/invoicing/schemas/firestore.js +45 -0
  117. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  118. package/dist/features/invoicing/utils/financial-year.js +53 -0
  119. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  120. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  121. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  122. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  123. package/dist/features/jobs/schemas/firestore.js +37 -0
  124. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  125. package/dist/features/media/MediaImage.js +22 -1
  126. package/dist/features/media/upload/ImageUpload.js +1 -1
  127. package/dist/features/obligations/constants/policies.js +24 -1
  128. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  129. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  130. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  131. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  132. package/dist/features/orders/components/RaiseDisputeForm.js +111 -0
  133. package/dist/features/orders/components/RefundRequestView.js +19 -1
  134. package/dist/features/orders/components/index.d.ts +4 -0
  135. package/dist/features/orders/components/index.js +2 -0
  136. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  137. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  138. package/dist/features/orders/repository/orders.repository.d.ts +57 -0
  139. package/dist/features/orders/repository/orders.repository.js +145 -0
  140. package/dist/features/orders/schemas/firestore.d.ts +196 -1
  141. package/dist/features/orders/schemas/index.d.ts +54 -6
  142. package/dist/features/orders/schemas/index.js +12 -0
  143. package/dist/features/orders/types/index.d.ts +26 -0
  144. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  145. package/dist/features/orders/utils/courier-block.js +23 -0
  146. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  147. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  148. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  149. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  150. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  151. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  152. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  153. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  154. package/dist/features/promotions/components/CouponCard.js +13 -0
  155. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  156. package/dist/features/promotions/constants/coupon-help.js +9 -1
  157. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  158. package/dist/features/promotions/schemas/firestore.js +4 -0
  159. package/dist/features/promotions/types/index.d.ts +19 -1
  160. package/dist/features/scams/components/ScamProfileView.js +2 -2
  161. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  162. package/dist/features/search/action-index/tab-entries.js +1 -1
  163. package/dist/features/seller/actions/seller-actions.js +33 -3
  164. package/dist/features/seller/components/SellerOrdersView.js +129 -27
  165. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  166. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  167. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +43 -0
  168. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +90 -0
  169. package/dist/features/shipping-boxes/schemas/firestore.d.ts +82 -0
  170. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  171. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  172. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  173. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  174. package/dist/features/stores/schemas/firestore.d.ts +71 -0
  175. package/dist/features/stores/types/index.d.ts +19 -0
  176. package/dist/features/support/schemas/index.d.ts +6 -6
  177. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  178. package/dist/index.d.ts +6 -1
  179. package/dist/index.js +14 -1
  180. package/dist/next/routing/route-map.d.ts +20 -0
  181. package/dist/next/routing/route-map.js +10 -0
  182. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  183. package/dist/providers/shipping-shiprocket/index.js +84 -1
  184. package/dist/schemas/registry.d.ts +47 -18
  185. package/dist/schemas/sieve.d.ts +2 -2
  186. package/dist/server-entry.d.ts +2 -2
  187. package/dist/server-entry.js +8 -1
  188. package/dist/server.d.ts +10 -1
  189. package/dist/server.js +39 -1
  190. package/dist/styles.css +64 -80
  191. package/dist/tailwind-utilities.css +1 -1
  192. package/dist/tokens/themes/default-dark.js +1 -0
  193. package/dist/tokens/themes/default-light.js +1 -0
  194. package/dist/tokens/themes/required.d.ts +1 -1
  195. package/dist/tokens/themes/required.js +1 -0
  196. package/dist/tokens/tokens.css +15 -0
  197. package/dist/ui/components/Disclaimer.d.ts +19 -0
  198. package/dist/ui/components/Disclaimer.js +74 -0
  199. package/dist/ui/components/tabs-overflow.js +64 -11
  200. package/dist/ui/index.d.ts +2 -0
  201. package/dist/ui/index.js +6 -0
  202. package/dist/ui/rich-text/RichText.style.css +48 -79
  203. package/package.json +1 -1
  204. package/scripts/seed-cli.mjs +1831 -1822
@@ -0,0 +1,43 @@
1
+ import type { FirebaseSieveFields, FirebaseSieveResult, SieveModel } from "../../../providers/db-firebase";
2
+ import { BaseRepository } from "../../../providers/db-firebase";
3
+ import { type ShippingBoxDocument } from "../schemas/firestore";
4
+ /**
5
+ * The shared carton library. See the schema header for why it is global.
6
+ */
7
+ export declare class ShippingBoxesRepository extends BaseRepository<ShippingBoxDocument> {
8
+ static readonly SIEVE_FIELDS: FirebaseSieveFields;
9
+ constructor();
10
+ /**
11
+ * The picker's list. Active only, by name.
12
+ *
13
+ * 🛑 Retired presets are excluded here and NOT deleted, so a draft shipment
14
+ * holding one does not lose it mid-dispatch.
15
+ */
16
+ listActive(model: SieveModel): Promise<FirebaseSieveResult<ShippingBoxDocument>>;
17
+ /**
18
+ * Create a preset, keyed on a slug of its name.
19
+ *
20
+ * 🛑 `box-<slug>` as the document id, so the SAME carton name cannot be added
21
+ * twice by two sellers. That is the whole value of a shared library — two
22
+ * rows called "Standard carton" with different numbers is worse than one
23
+ * row, because the picker gives no way to tell them apart.
24
+ *
25
+ * A colliding create is reported to the caller rather than silently
26
+ * overwriting: the existing row has an author and may be in use, and the
27
+ * second seller's intent ("I want a preset for this") is already satisfied
28
+ * by the row that exists.
29
+ */
30
+ createPreset(input: {
31
+ name: string;
32
+ length: number;
33
+ width: number;
34
+ height: number;
35
+ tareWeight?: number;
36
+ createdByUid: string;
37
+ createdByName: string;
38
+ }): Promise<{
39
+ box: ShippingBoxDocument;
40
+ created: boolean;
41
+ }>;
42
+ }
43
+ export declare const shippingBoxesRepository: ShippingBoxesRepository;
@@ -0,0 +1,90 @@
1
+ import { BaseRepository } from "../../../providers/db-firebase/index.js";
2
+ import { slugify } from "../../../utils/string.formatter.js";
3
+ import { SHIPPING_BOX_COLLECTION, SHIPPING_BOX_FIELDS, SHIPPING_BOX_LIMITS, } from "../schemas/firestore.js";
4
+ /**
5
+ * The shared carton library. See the schema header for why it is global.
6
+ */
7
+ export class ShippingBoxesRepository extends BaseRepository {
8
+ constructor() {
9
+ super(SHIPPING_BOX_COLLECTION);
10
+ }
11
+ /**
12
+ * The picker's list. Active only, by name.
13
+ *
14
+ * 🛑 Retired presets are excluded here and NOT deleted, so a draft shipment
15
+ * holding one does not lose it mid-dispatch.
16
+ */
17
+ async listActive(model) {
18
+ const baseQuery = this.getCollection().where(SHIPPING_BOX_FIELDS.IS_ACTIVE, "==", true);
19
+ return this.sieveQuery(model, ShippingBoxesRepository.SIEVE_FIELDS, {
20
+ baseQuery,
21
+ defaultPageSize: 20,
22
+ maxPageSize: 50,
23
+ });
24
+ }
25
+ /**
26
+ * Create a preset, keyed on a slug of its name.
27
+ *
28
+ * 🛑 `box-<slug>` as the document id, so the SAME carton name cannot be added
29
+ * twice by two sellers. That is the whole value of a shared library — two
30
+ * rows called "Standard carton" with different numbers is worse than one
31
+ * row, because the picker gives no way to tell them apart.
32
+ *
33
+ * A colliding create is reported to the caller rather than silently
34
+ * overwriting: the existing row has an author and may be in use, and the
35
+ * second seller's intent ("I want a preset for this") is already satisfied
36
+ * by the row that exists.
37
+ */
38
+ async createPreset(input) {
39
+ const name = input.name.trim();
40
+ const id = `box-${slugify(name)}`;
41
+ const existing = await this.findById(id);
42
+ if (existing)
43
+ return { box: existing, created: false };
44
+ const now = new Date();
45
+ const box = {
46
+ id,
47
+ name,
48
+ length: clampCm(input.length),
49
+ width: clampCm(input.width),
50
+ height: clampCm(input.height),
51
+ ...(input.tareWeight === undefined ? {} : { tareWeight: clampKg(input.tareWeight) }),
52
+ createdByUid: input.createdByUid,
53
+ createdByName: input.createdByName,
54
+ isActive: true,
55
+ createdAt: now,
56
+ updatedAt: now,
57
+ };
58
+ await this.createWithId(id, box);
59
+ return { box, created: true };
60
+ }
61
+ }
62
+ ShippingBoxesRepository.SIEVE_FIELDS = {
63
+ /*
64
+ * `name` is sortable AND filterable because this list is picked from by
65
+ * typing — `PaginatedSelect` searches it. A field the picker searches that
66
+ * is not allowlisted here would have its clause silently DROPPED and the
67
+ * search would return the whole library while looking like it filtered
68
+ * (Root Cause #62).
69
+ */
70
+ name: { canFilter: true, canSort: true },
71
+ isActive: { canFilter: true, canSort: false },
72
+ createdByUid: { canFilter: true, canSort: false },
73
+ };
74
+ /*
75
+ * Clamped rather than rejected. These bounds exist so a typo cannot reach a
76
+ * courier API as a 4-metre parcel; they are not a tariff, and refusing a
77
+ * legitimate large parcel client-side is worse than letting it through to be
78
+ * priced by `checkServiceability` against the real figures.
79
+ */
80
+ function clampCm(v) {
81
+ if (!Number.isFinite(v))
82
+ return SHIPPING_BOX_LIMITS.minCm;
83
+ return Math.min(SHIPPING_BOX_LIMITS.maxCm, Math.max(SHIPPING_BOX_LIMITS.minCm, v));
84
+ }
85
+ function clampKg(v) {
86
+ if (!Number.isFinite(v))
87
+ return SHIPPING_BOX_LIMITS.minKg;
88
+ return Math.min(SHIPPING_BOX_LIMITS.maxKg, Math.max(SHIPPING_BOX_LIMITS.minKg, v));
89
+ }
90
+ export const shippingBoxesRepository = new ShippingBoxesRepository();
@@ -0,0 +1,82 @@
1
+ /**
2
+ * `shippingBoxes` — a GLOBAL library of named carton presets.
3
+ *
4
+ * ## Why global rather than per-store
5
+ *
6
+ * A box is a real physical carton size. Scoping presets per store would give
7
+ * every seller their own private copy of "Medium", each with slightly
8
+ * different numbers, and the second seller to ship a Beyblade in a standard
9
+ * carton would re-measure instead of picking what already exists.
10
+ *
11
+ * `createdByName` is what keeps a shared library accountable: a wrong preset
12
+ * has an author, and the next seller can see who added the one they are about
13
+ * to trust.
14
+ *
15
+ * ## 🛑 A preset is a DEFAULT, never a lock
16
+ *
17
+ * The dimensions are COPIED onto the shipment when a seller uses one. Editing
18
+ * a preset later must not retroactively change what an already-dispatched
19
+ * parcel was declared as — the courier billed against the figures at dispatch,
20
+ * and a stored reference would make a past declaration mutable. Same snapshot
21
+ * discipline as the checkout's fee terms (D61).
22
+ *
23
+ * ## 🛑 Weight is not a formality
24
+ *
25
+ * An understated weight is re-billed by the courier AFTER delivery as a
26
+ * weight-discrepancy adjustment — real money, arriving on a reconciliation we
27
+ * cannot dispute without the parcel. The form says so rather than treating it
28
+ * as a required field to get past.
29
+ */
30
+ /** `box-` prefixed slug, so the id reads as what it is. */
31
+ export declare const SHIPPING_BOX_COLLECTION = "shippingBoxes";
32
+ export interface ShippingBoxDocument {
33
+ id: string;
34
+ /** What a seller picks it by: "Standard Beyblade carton", "Poly mailer S". */
35
+ name: string;
36
+ /** cm. */
37
+ length: number;
38
+ width: number;
39
+ height: number;
40
+ /**
41
+ * kg, the EMPTY box. The parcel's weight is this plus contents, entered on
42
+ * the dispatch form — a preset cannot know what went inside it.
43
+ *
44
+ * 🛑 Separate from the shipment's `weight` for exactly that reason. Storing
45
+ * one "weight" on a preset and reusing it as the parcel weight is how every
46
+ * parcel gets declared at the same figure regardless of contents.
47
+ */
48
+ tareWeight?: number;
49
+ /** Who added it. Display name, so a seller can see whose preset this is. */
50
+ createdByName: string;
51
+ /** The uid, for moderation. Never rendered. */
52
+ createdByUid: string;
53
+ /**
54
+ * Soft-retire rather than delete. A preset in use by a draft shipment must
55
+ * not vanish mid-dispatch, and a deleted row takes its author with it.
56
+ */
57
+ isActive: boolean;
58
+ createdAt: Date;
59
+ updatedAt: Date;
60
+ }
61
+ export declare const SHIPPING_BOX_FIELDS: {
62
+ readonly ID: "id";
63
+ readonly NAME: "name";
64
+ readonly IS_ACTIVE: "isActive";
65
+ readonly CREATED_BY_UID: "createdByUid";
66
+ readonly CREATED_AT: "createdAt";
67
+ };
68
+ /**
69
+ * Bounds, so a typo cannot reach a courier API as a 4-metre parcel.
70
+ *
71
+ * 🛑 Generous on purpose — these are a sanity check, not a tariff. India Post
72
+ * and most couriers cap a single parcel well below these, and the right place
73
+ * to learn a real limit is `checkServiceability`, which quotes against the
74
+ * actual weight. A client-side rule that refuses a legitimate large parcel is
75
+ * worse than one that lets it through to be priced.
76
+ */
77
+ export declare const SHIPPING_BOX_LIMITS: {
78
+ readonly minCm: 1;
79
+ readonly maxCm: 200;
80
+ readonly minKg: 0;
81
+ readonly maxKg: 50;
82
+ };
@@ -0,0 +1,53 @@
1
+ /**
2
+ * `shippingBoxes` — a GLOBAL library of named carton presets.
3
+ *
4
+ * ## Why global rather than per-store
5
+ *
6
+ * A box is a real physical carton size. Scoping presets per store would give
7
+ * every seller their own private copy of "Medium", each with slightly
8
+ * different numbers, and the second seller to ship a Beyblade in a standard
9
+ * carton would re-measure instead of picking what already exists.
10
+ *
11
+ * `createdByName` is what keeps a shared library accountable: a wrong preset
12
+ * has an author, and the next seller can see who added the one they are about
13
+ * to trust.
14
+ *
15
+ * ## 🛑 A preset is a DEFAULT, never a lock
16
+ *
17
+ * The dimensions are COPIED onto the shipment when a seller uses one. Editing
18
+ * a preset later must not retroactively change what an already-dispatched
19
+ * parcel was declared as — the courier billed against the figures at dispatch,
20
+ * and a stored reference would make a past declaration mutable. Same snapshot
21
+ * discipline as the checkout's fee terms (D61).
22
+ *
23
+ * ## 🛑 Weight is not a formality
24
+ *
25
+ * An understated weight is re-billed by the courier AFTER delivery as a
26
+ * weight-discrepancy adjustment — real money, arriving on a reconciliation we
27
+ * cannot dispute without the parcel. The form says so rather than treating it
28
+ * as a required field to get past.
29
+ */
30
+ /** `box-` prefixed slug, so the id reads as what it is. */
31
+ export const SHIPPING_BOX_COLLECTION = "shippingBoxes";
32
+ export const SHIPPING_BOX_FIELDS = {
33
+ ID: "id",
34
+ NAME: "name",
35
+ IS_ACTIVE: "isActive",
36
+ CREATED_BY_UID: "createdByUid",
37
+ CREATED_AT: "createdAt",
38
+ };
39
+ /**
40
+ * Bounds, so a typo cannot reach a courier API as a 4-metre parcel.
41
+ *
42
+ * 🛑 Generous on purpose — these are a sanity check, not a tariff. India Post
43
+ * and most couriers cap a single parcel well below these, and the right place
44
+ * to learn a real limit is `checkServiceability`, which quotes against the
45
+ * actual weight. A client-side rule that refuses a legitimate large parcel is
46
+ * worse than one that lets it through to be priced.
47
+ */
48
+ export const SHIPPING_BOX_LIMITS = {
49
+ minCm: 1,
50
+ maxCm: 200,
51
+ minKg: 0,
52
+ maxKg: 50,
53
+ };
@@ -12,14 +12,14 @@ export declare const reportCreateSchema: z.ZodObject<{
12
12
  }, "strict", z.ZodTypeAny, {
13
13
  entityId: string;
14
14
  entityType: import("./firestore").ReportEntityType;
15
- detail: string;
16
15
  reason: import("./firestore").ReportReason;
16
+ detail: string;
17
17
  evidenceUrls?: string[] | undefined;
18
18
  }, {
19
19
  entityId: string;
20
20
  entityType: import("./firestore").ReportEntityType;
21
- detail: string;
22
21
  reason: import("./firestore").ReportReason;
22
+ detail: string;
23
23
  evidenceUrls?: string[] | undefined;
24
24
  }>;
25
25
  export type ReportCreateValues = z.infer<typeof reportCreateSchema>;
@@ -133,8 +133,8 @@ export declare const shippingConfigUpdateSchema: z.ZodObject<{
133
133
  label?: string | undefined;
134
134
  isActive?: boolean | undefined;
135
135
  isDefault?: boolean | undefined;
136
- method?: ShippingMethod | undefined;
137
136
  estimatedDays?: number | undefined;
137
+ method?: ShippingMethod | undefined;
138
138
  flatRate?: number | undefined;
139
139
  pricePerKg?: number | undefined;
140
140
  freeAbove?: number | undefined;
@@ -144,8 +144,8 @@ export declare const shippingConfigUpdateSchema: z.ZodObject<{
144
144
  label?: string | undefined;
145
145
  isActive?: boolean | undefined;
146
146
  isDefault?: boolean | undefined;
147
- method?: ShippingMethod | undefined;
148
147
  estimatedDays?: number | undefined;
148
+ method?: ShippingMethod | undefined;
149
149
  flatRate?: number | undefined;
150
150
  pricePerKg?: number | undefined;
151
151
  freeAbove?: number | undefined;
@@ -2,6 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ArrowLeft } from "lucide-react";
3
3
  import { Accordion, Alert, Code, Div, Heading, Li, Ol, Row, Section, Span, Stack, Table, Tbody, Td, Text, TextLink, Th, Thead, Tr, Ul } from "../../../ui/index.js";
4
4
  import { ROUTES } from "../../../next/routing/route-map.js";
5
+ import { resolvePublishedValues } from "../../../_internal/shared/content/published-values.js";
6
+ /* Phase 9 — one definition of the refund timeline. */
7
+ const { refundBusinessDaysMin: REFUND_DAYS_MIN, refundBusinessDaysMax: REFUND_DAYS_MAX } = resolvePublishedValues();
5
8
  const SUBHEADING = "mb-1 font-semibold text-[var(--appkit-color-text)]";
6
9
  const LIST_DISC = "list-disc leading-relaxed";
7
10
  const SECTION_BODY = "space-y-4 text-[length:var(--appkit-text-sm)] text-[var(--appkit-color-text-muted)]";
@@ -41,7 +44,9 @@ const STATUS_ROWS = [
41
44
  {
42
45
  status: "CANCELLED",
43
46
  meaning: "Order was cancelled before shipping (by buyer or seller).",
44
- action: "Refund is automatic via Razorpay (3–7 business days).",
47
+ // Phase 9 — one definition, and no gateway name. See the identical note in
48
+ // AdminOrdersGuideView.
49
+ action: `Refund is automatic (${REFUND_DAYS_MIN}–${REFUND_DAYS_MAX} business days).`,
45
50
  },
46
51
  {
47
52
  status: "RETURN_REQUESTED",
@@ -233,6 +233,77 @@ export interface StoreDocument extends BaseDocument {
233
233
  */
234
234
  supportsShippingProtection?: boolean;
235
235
  supportsSaleProtection?: boolean;
236
+ /**
237
+ * This store accepts buyer points as part-payment.
238
+ *
239
+ * ## 🛑 OPT-IN, because the accepting store ABSORBS the redemption
240
+ *
241
+ * Decision 3: a redeemed point reduces THAT store's payout for THAT order.
242
+ * Earning is mandatory (it costs the seller nothing at issue time); accepting
243
+ * is optional, because accepting is where the money actually moves. So this
244
+ * follows `supportsSaleProtection` above exactly — **absent means NOT
245
+ * accepted, never "unknown"** — and for the identical reason: defaulting it
246
+ * `true` would enrol every existing seller in funding discounts they never
247
+ * agreed to, and retrofitting consent later means switching a working feature
248
+ * off for them.
249
+ *
250
+ * 🛑 Live currently has ONE store, so this flag is inert today. It is still
251
+ * built now rather than later: the day a second seller exists, enabling
252
+ * redemption for them without asking is taking their money, and the cost of
253
+ * the field today is one boolean and one check.
254
+ *
255
+ * `store-letitrip-official` is always treated as accepting — the platform's
256
+ * own storefront cannot decline to fund its own programme. That is resolved
257
+ * in code rather than seeded, so it cannot be switched off by an edit.
258
+ */
259
+ acceptsPoints?: boolean;
260
+ /**
261
+ * ── S5a: this store allows a SHARED PURCHASE (one payer, N destinations) ──
262
+ *
263
+ * The coordinator buys everything and assigns a destination per item, so the
264
+ * seller packs one order into several parcels. That is real extra work —
265
+ * picking, packing and labelling N shipments instead of one — which is why
266
+ * it is an opt-in with its own fees rather than a free platform behaviour.
267
+ *
268
+ * 🛑 **Absent means NOT allowed**, matching `supportsSaleProtection` and
269
+ * `acceptsPoints` above, and for the same reason: the cost falls on the
270
+ * seller, so enrolling them without asking is taking their labour. Every
271
+ * existing store therefore starts with it off, which is the correct state
272
+ * rather than a migration problem.
273
+ *
274
+ * 🛑 This is S5a ONLY — one payer. It is NOT the N-party flow (S5b), which
275
+ * needs multi-party payment, a coordinator deposit, an approval cascade, a
276
+ * stock-reservation primitive that does not exist, and per-buyer invoicing
277
+ * and GST. A seller enabling this is agreeing to split one paid order across
278
+ * destinations, not to be paid by several people.
279
+ */
280
+ allowSharedPurchase?: boolean;
281
+ /**
282
+ * Flat fee per shared-purchase arrangement, in decimal rupees.
283
+ *
284
+ * Covers picking, packing and labelling one order into N parcels. Borne by
285
+ * the COORDINATOR — they chose the arrangement — which keeps each
286
+ * destination's own cost to goods plus that destination's shipping.
287
+ *
288
+ * 🛑 SNAPSHOTTED onto the order at checkout, never re-read later. The
289
+ * precedent is exact: the refund path reads `finalSale` from the ORDER
290
+ * snapshot rather than the live product, because "re-reading the live
291
+ * product would let a seller flip the switch afterwards" (D61). A fee read
292
+ * late is the same hole.
293
+ */
294
+ sharedPurchaseHandlingFee?: number;
295
+ /**
296
+ * Extra shipping per destination BEYOND THE FIRST, in decimal rupees.
297
+ *
298
+ * The first destination is the shipping the order would have paid anyway;
299
+ * this is the marginal cost of each additional parcel. Borne by the buyer at
300
+ * that destination in the full N-party flow — in S5a there is one payer, so
301
+ * the coordinator pays all of it, which is correct because they are the
302
+ * person who asked for the extra legs.
303
+ *
304
+ * Snapshotted with the handling fee, for the same reason.
305
+ */
306
+ sharedPurchaseExtraShippingPerDestination?: number;
236
307
  /**
237
308
  * ── C5g: ADMIN-GRANTED trust. Routes even a protected claim to the seller ──
238
309
  *
@@ -24,6 +24,25 @@ export interface StoreListItem {
24
24
  */
25
25
  supportsShippingProtection: boolean;
26
26
  supportsSaleProtection: boolean;
27
+ /**
28
+ * S5a — this seller will split one paid order across several destinations.
29
+ *
30
+ * Not optional, for the same reason as the two above: the projection
31
+ * resolves absence to `false`, so the client never decides what `undefined`
32
+ * means.
33
+ */
34
+ allowSharedPurchase: boolean;
35
+ /**
36
+ * The two shared-purchase fees, in decimal rupees.
37
+ *
38
+ * 🛑 OPTIONAL here where `allowSharedPurchase` is not, and the asymmetry is
39
+ * the point: a flag's absence means "no", but a fee's absence means "not
40
+ * configured" — which is not ₹0. A client that defaulted these to zero would
41
+ * quote a free arrangement from a store that has simply not priced one, and
42
+ * the coordinator commits against that quote.
43
+ */
44
+ sharedPurchaseHandlingFee?: number;
45
+ sharedPurchaseExtraShippingPerDestination?: number;
27
46
  createdAt?: string;
28
47
  }
29
48
  export interface StoreDetail extends StoreListItem {
@@ -175,11 +175,11 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
175
175
  attachments?: string[] | undefined;
176
176
  }[];
177
177
  orderId?: string | undefined;
178
- assignedTo?: string | undefined;
179
- resolvedAt?: string | Date | z.objectOutputType<{
178
+ closedAt?: string | Date | z.objectOutputType<{
180
179
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
181
180
  }, z.ZodTypeAny, "passthrough"> | undefined;
182
- closedAt?: string | Date | z.objectOutputType<{
181
+ assignedTo?: string | undefined;
182
+ resolvedAt?: string | Date | z.objectOutputType<{
183
183
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
184
184
  }, z.ZodTypeAny, "passthrough"> | undefined;
185
185
  assignedToName?: string | undefined;
@@ -218,11 +218,11 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
218
218
  attachments?: string[] | undefined;
219
219
  }[];
220
220
  orderId?: string | undefined;
221
- assignedTo?: string | undefined;
222
- resolvedAt?: string | Date | z.objectInputType<{
221
+ closedAt?: string | Date | z.objectInputType<{
223
222
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
224
223
  }, z.ZodTypeAny, "passthrough"> | undefined;
225
- closedAt?: string | Date | z.objectInputType<{
224
+ assignedTo?: string | undefined;
225
+ resolvedAt?: string | Date | z.objectInputType<{
226
226
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
227
227
  }, z.ZodTypeAny, "passthrough"> | undefined;
228
228
  assignedToName?: string | undefined;
@@ -29,7 +29,7 @@ export declare function useWishlistWithGuest(userId: string | null | undefined,
29
29
  productPrice: number;
30
30
  productSlug: string;
31
31
  addedAt: string | undefined;
32
- type: "category" | "store" | "classified" | "auction" | "digital-code" | "live" | "product" | "preorder";
32
+ type: "category" | "store" | "classified" | "auction" | "digital-code" | "live" | "preorder" | "product";
33
33
  }[];
34
34
  total: number;
35
35
  wishlistedIds: Set<string>;
package/dist/index.d.ts CHANGED
@@ -1962,6 +1962,8 @@ export type { OrderSiblingPaymentsProps } from "./features/orders/index";
1962
1962
  export { OrderPaymentSummary } from "./features/orders/index";
1963
1963
  export type { OrderPaymentSummaryProps } from "./features/orders/index";
1964
1964
  export { OrderStatusTimeline } from "./features/orders/index";
1965
+ export { OrderProvenanceCard } from "./features/orders/index";
1966
+ export type { OrderProvenanceCardProps } from "./features/orders/index";
1965
1967
  export { OrderCompletionPanel } from "./features/orders/index";
1966
1968
  export { StatusTimeline, stepsFromEntries } from "./features/status-history/index";
1967
1969
  export type { StatusTimelineProps, TimelineEntry, TimelineStep } from "./features/status-history/index";
@@ -2000,6 +2002,7 @@ export type { OrderAdminUpdateInput } from "./features/orders/index";
2000
2002
  export type { AppliedOrderDiscount } from "./features/orders/index";
2001
2003
  export type { OrderCreateInput } from "./features/orders/index";
2002
2004
  export type { OrderDocument } from "./features/orders/index";
2005
+ export type { OrderSourceContext } from "./features/orders/index";
2003
2006
  export type { OrderRefundEvent, RefundType } from "./features/orders/schemas/firestore";
2004
2007
  export { MANUAL_PAYMENT_METHODS, isManualPaymentMethod, PAYMENT_REVIEW_QUEUE_MODES, isPaymentReviewQueueMode, PAYMENT_REVIEW_QUEUE_SCAN_LIMIT, } from "./features/orders/constants/payment-window";
2005
2008
  export type { PaymentReviewQueueMode } from "./features/orders/constants/payment-window";
@@ -2190,7 +2193,7 @@ export { actionTracker, setActionTrackerSink, resetActionTrackerSink, type Actio
2190
2193
  export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_internal/shared/listing-types/cart-shipping";
2191
2194
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, type ActionDef, type ActionKind, type ActionResource, type ActionTree, type ActionConfirmation, } from "./_internal/shared/actions/action-registry";
2192
2195
  export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers";
2193
- export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, calculateGst, } from "./_internal/shared/fees/calculator";
2196
+ export { computeCheckoutFees, allocateCheckoutFees, computePayoutDeduction, computeCodHandlingFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, calculateGst, } from "./_internal/shared/fees/calculator";
2194
2197
  export { searchPriceIndex, PRICE_INDEX_SEARCH_LIMIT, PRICE_INDEX_MIN_QUERY_LENGTH } from "./_internal/server/features/price-index/search";
2195
2198
  export type { PriceIndexSearchResponse, PriceIndexSearchResult, PriceIndexSearchResultBand, } from "./_internal/server/features/price-index/search";
2196
2199
  export { protectionAvailability, computeProtectionFees, adjudicateClaim, badgesFor, showsRiskNotice, showsSafetyBadge, returnDestination, rtoDestination, PROTECTION_KINDS, } from "./_internal/shared/features/shipping/protections";
@@ -2852,6 +2855,8 @@ export { BUNDLE_COPY, BUNDLE_STOCK_VARIANT, } from "./_internal/shared/features/
2852
2855
  export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy";
2853
2856
  export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons";
2854
2857
  export type { ReturnReason } from "./_internal/shared/features/orders/return-reasons";
2858
+ export { DISPUTE_KIND, DISPUTE_KIND_LABEL, DISPUTE_GATE, DISPUTE_TRANSIT_WINDOW_DAYS, DISPUTE_NOT_REACHED_GRACE_DAYS, isDisputeKind, checkDisputeGate, resolveDisputeEtd, disputeNotReachedFilableFrom, } from "./_internal/shared/features/orders/dispute-reasons";
2859
+ export type { DisputeKind, DisputeGateOrder, DisputeGateResult, } from "./_internal/shared/features/orders/dispute-reasons";
2855
2860
  export { bundleCreateSchema, bundleUpdateSchema, bundleQueryRuleSchema, bundleDisplaySchema, type BundleCreateBody, type BundleUpdateBody, } from "./_internal/shared/features/categories/bundle-schemas";
2856
2861
  export type { GroupedListingDocument, GroupTheme, GroupVisibility } from "./features/grouped/schemas/firestore";
2857
2862
  export { navItemFormSchema, navItemCreateSchema, navItemUpdateSchema, type NavItemFormValues, } from "./features/admin/schemas/nav-item-form";
package/dist/index.js CHANGED
@@ -3691,6 +3691,9 @@ export { OrdersList } from "./features/orders/index.js";
3691
3691
  export { OrderSiblingPayments } from "./features/orders/index.js";
3692
3692
  export { OrderPaymentSummary } from "./features/orders/index.js";
3693
3693
  export { OrderStatusTimeline } from "./features/orders/index.js";
3694
+ // OrderProvenanceCard — renders sourceContext, the record of HOW the buyer
3695
+ // earned this price. Mounted on the buyer, seller AND admin order detail.
3696
+ export { OrderProvenanceCard } from "./features/orders/index.js";
3694
3697
  // OrderCompletionPanel - Per-line ratings + Mark complete, the buyer's fast path.
3695
3698
  export { OrderCompletionPanel } from "./features/orders/index.js";
3696
3699
  // [CLIENT] StatusTimeline — the ONE rail both orders and offers render.
@@ -4075,7 +4078,14 @@ export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_int
4075
4078
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, } from "./_internal/shared/actions/action-registry.js";
4076
4079
  export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers.js";
4077
4080
  // Shared fee calculator — platform/gateway/GST/COD handling/addon fee math (pure, client-safe).
4078
- export { computeCheckoutFees, computePayoutDeduction, computeCodHandlingFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, calculateGst, } from "./_internal/shared/fees/calculator.js";
4081
+ export { computeCheckoutFees,
4082
+ // The per-group split of the ONE capped commission. Exported for the capture
4083
+ // route's points tender: the tender is applied per order group against the
4084
+ // same base the order path uses, and that base includes this share. Without
4085
+ // it the route would have to re-derive the apportionment — and the allocator
4086
+ // also carries the `minimumTransactionFee` floor (D41), which already spent
4087
+ // a release being re-implemented by hand in that very file.
4088
+ allocateCheckoutFees, computePayoutDeduction, computeCodHandlingFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, calculateGst, } from "./_internal/shared/fees/calculator.js";
4079
4089
  // C5e buyer protections — the pure three-tier gate plus the one fee pair
4080
4090
  // every money path must agree on. Public API because the capture route
4081
4091
  // (/api/payment/create-order) is one of the three sites that must agree.
@@ -5121,6 +5131,9 @@ export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy.js";
5121
5131
  // See the module docstring for why the exempt set is "seller or carrier fault"
5122
5132
  // rather than "serious reasons".
5123
5133
  export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons.js";
5134
+ // Dispute KINDS and their gates. `_internal/*` is not a subpath export, so a
5135
+ // consumer route reaches these only through a barrel.
5136
+ export { DISPUTE_KIND, DISPUTE_KIND_LABEL, DISPUTE_GATE, DISPUTE_TRANSIT_WINDOW_DAYS, DISPUTE_NOT_REACHED_GRACE_DAYS, isDisputeKind, checkDisputeGate, resolveDisputeEtd, disputeNotReachedFilableFrom, } from "./_internal/shared/features/orders/dispute-reasons.js";
5124
5137
  // S-SBUNI-4 follow-up â€" shared admin bundle zod schemas.
5125
5138
  export { bundleCreateSchema, bundleUpdateSchema, bundleQueryRuleSchema, bundleDisplaySchema, } from "./_internal/shared/features/categories/bundle-schemas.js";
5126
5139
  export { navItemFormSchema, navItemCreateSchema, navItemUpdateSchema, } from "./features/admin/schemas/nav-item-form.js";
@@ -377,6 +377,16 @@ export declare const DEFAULT_ROUTE_MAP: {
377
377
  readonly AUDIT_LOG: "/admin/audit-log";
378
378
  readonly MONEY_CASES: "/admin/money-cases";
379
379
  readonly MONEY_CASE_DETAIL: (id: string) => string;
380
+ /**
381
+ * Phase 7 — the GSTR-1 draft export.
382
+ *
383
+ * 🛑 Under Finance for the same reason `MONEY_CASES` is, and the reason is
384
+ * stronger here: the export contains the company's tax position for a
385
+ * quarter plus every buyer's place of supply. That is not a maintenance
386
+ * diagnostic, and it is admin-only — deliberately not granted to
387
+ * `maintenance_employee`.
388
+ */
389
+ readonly INVOICING: "/admin/invoicing";
380
390
  readonly PROTECTION_CLAIMS: "/admin/protection-claims";
381
391
  readonly MAINTENANCE_GATEWAY_EVENTS: "/admin/maintenance/gateway-events";
382
392
  readonly MAINTENANCE_OBLIGATIONS: "/admin/maintenance/obligations";
@@ -831,6 +841,16 @@ export declare const ROUTES: {
831
841
  readonly AUDIT_LOG: "/admin/audit-log";
832
842
  readonly MONEY_CASES: "/admin/money-cases";
833
843
  readonly MONEY_CASE_DETAIL: (id: string) => string;
844
+ /**
845
+ * Phase 7 — the GSTR-1 draft export.
846
+ *
847
+ * 🛑 Under Finance for the same reason `MONEY_CASES` is, and the reason is
848
+ * stronger here: the export contains the company's tax position for a
849
+ * quarter plus every buyer's place of supply. That is not a maintenance
850
+ * diagnostic, and it is admin-only — deliberately not granted to
851
+ * `maintenance_employee`.
852
+ */
853
+ readonly INVOICING: "/admin/invoicing";
834
854
  readonly PROTECTION_CLAIMS: "/admin/protection-claims";
835
855
  readonly MAINTENANCE_GATEWAY_EVENTS: "/admin/maintenance/gateway-events";
836
856
  readonly MAINTENANCE_OBLIGATIONS: "/admin/maintenance/obligations";
@@ -579,6 +579,16 @@ export const DEFAULT_ROUTE_MAP = {
579
579
  */
580
580
  MONEY_CASES: "/admin/money-cases",
581
581
  MONEY_CASE_DETAIL: (id) => `/admin/money-cases/${id}`,
582
+ /**
583
+ * Phase 7 — the GSTR-1 draft export.
584
+ *
585
+ * 🛑 Under Finance for the same reason `MONEY_CASES` is, and the reason is
586
+ * stronger here: the export contains the company's tax position for a
587
+ * quarter plus every buyer's place of supply. That is not a maintenance
588
+ * diagnostic, and it is admin-only — deliberately not granted to
589
+ * `maintenance_employee`.
590
+ */
591
+ INVOICING: "/admin/invoicing",
582
592
  PROTECTION_CLAIMS: "/admin/protection-claims",
583
593
  MAINTENANCE_GATEWAY_EVENTS: "/admin/maintenance/gateway-events",
584
594
  MAINTENANCE_OBLIGATIONS: "/admin/maintenance/obligations",
@@ -66,7 +66,7 @@
66
66
  * @tag access:server-only
67
67
  */
68
68
  import { IShippingProvider } from "../../contracts";
69
- import type { CreateShipmentInput, Shipment, TrackingInfo, ServiceabilityResult } from "../../contracts";
69
+ import type { CreateShipmentInput, Shipment, TrackingInfo, ServiceabilityResult, WalletBalance } from "../../contracts";
70
70
  export interface ShiprocketConfig {
71
71
  /** The API user's email. See the header on why this is not a "login id". */
72
72
  email: string;
@@ -74,6 +74,21 @@ export interface ShiprocketConfig {
74
74
  /** Shiprocket pickup-location nickname, as registered in their dashboard. */
75
75
  pickupLocation?: string;
76
76
  }
77
+ /**
78
+ * Does this upstream error body look like "your wallet is empty"?
79
+ *
80
+ * 🛑 The substring list is UNVERIFIED and that is acceptable, because of where
81
+ * it sits in the design: a funding failure and any other booking failure take
82
+ * the SAME path — the order gets a `courierBlock`, the admin is alerted, the
83
+ * seller is offered retry-or-self-ship. Classifying only changes the WORDING
84
+ * of the operator's alert. So a false negative costs a less specific message
85
+ * and never a wrong action, which is why this is allowed to be a heuristic
86
+ * rather than something this plan pretended to have confirmed.
87
+ *
88
+ * Triggering the real error would mean deliberately booking a shipment against
89
+ * a drained wallet, which is not a probe anyone should run on a live account.
90
+ */
91
+ export declare function looksLikeInsufficientFunds(body: string): boolean;
77
92
  export declare class ShiprocketShippingProvider extends IShippingProvider {
78
93
  private readonly config;
79
94
  readonly name = "shiprocket";
@@ -119,6 +134,17 @@ export declare class ShiprocketShippingProvider extends IShippingProvider {
119
134
  */
120
135
  createShipment(data: CreateShipmentInput): Promise<Shipment>;
121
136
  trackShipment(trackingId: string): Promise<TrackingInfo>;
137
+ /**
138
+ * The prepaid wallet balance. Read-only; never charges anything.
139
+ *
140
+ * 🛑 Returns `{ known: false, supported: true }` on ANY failure rather than
141
+ * `0`. Shiprocket HAS a wallet, so `supported` is true regardless — the
142
+ * caller must treat "unreadable" as "attempt the booking anyway and let the
143
+ * attempt's own failure decide", because refusing on an unreadable balance
144
+ * would block every order on a transient network blip. A `0` here is a real
145
+ * decision to skip; an unreadable balance is not.
146
+ */
147
+ getWalletBalance(): Promise<WalletBalance>;
122
148
  cancelShipment(shipmentId: string): Promise<void>;
123
149
  checkServiceability(pincode: string, weight: number): Promise<ServiceabilityResult>;
124
150
  generateLabel(shipmentId: string): Promise<ArrayBuffer>;