@mohasinac/appkit 4.60.1 → 4.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +19 -3
  3. package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +1 -1
  4. package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +1 -1
  5. package/dist/_internal/server/features/auctions/actions.d.ts +1 -1
  6. package/dist/_internal/server/features/auctions/actions.js +12 -1
  7. package/dist/_internal/server/features/blog/actions.d.ts +1 -1
  8. package/dist/_internal/server/features/blog/actions.js +12 -1
  9. package/dist/_internal/server/features/brands/actions.d.ts +1 -1
  10. package/dist/_internal/server/features/brands/actions.js +12 -1
  11. package/dist/_internal/server/features/cart/actions.d.ts +1 -1
  12. package/dist/_internal/server/features/cart/actions.js +12 -1
  13. package/dist/_internal/server/features/checkout/actions.js +0 -1
  14. package/dist/_internal/server/features/events/actions.d.ts +1 -1
  15. package/dist/_internal/server/features/events/actions.js +12 -1
  16. package/dist/_internal/server/features/gateway-events/redact.js +14 -2
  17. package/dist/_internal/server/features/history/actions.d.ts +1 -1
  18. package/dist/_internal/server/features/history/actions.js +12 -1
  19. package/dist/_internal/server/features/lottery/actions.d.ts +1 -1
  20. package/dist/_internal/server/features/lottery/actions.js +12 -1
  21. package/dist/_internal/server/features/orders/actions.d.ts +1 -1
  22. package/dist/_internal/server/features/orders/actions.js +12 -1
  23. package/dist/_internal/server/features/orders/cancellation-refund.js +0 -1
  24. package/dist/_internal/server/features/orders/service.js +31 -1
  25. package/dist/_internal/server/features/payouts/actions.d.ts +1 -1
  26. package/dist/_internal/server/features/payouts/actions.js +12 -1
  27. package/dist/_internal/server/features/points/award.js +9 -1
  28. package/dist/_internal/server/features/pre-orders/actions.d.ts +1 -1
  29. package/dist/_internal/server/features/pre-orders/actions.js +12 -1
  30. package/dist/_internal/server/features/prize-draws/actions.d.ts +1 -1
  31. package/dist/_internal/server/features/prize-draws/actions.js +12 -1
  32. package/dist/_internal/server/features/products/actions.d.ts +1 -1
  33. package/dist/_internal/server/features/products/actions.js +12 -1
  34. package/dist/_internal/server/features/promotions/actions.d.ts +1 -1
  35. package/dist/_internal/server/features/promotions/actions.js +12 -1
  36. package/dist/_internal/server/features/protection-claims/actions.d.ts +2 -2
  37. package/dist/_internal/server/features/protection-claims/actions.js +21 -12
  38. package/dist/_internal/server/features/raffle/actions.d.ts +1 -1
  39. package/dist/_internal/server/features/raffle/actions.js +12 -1
  40. package/dist/_internal/server/features/refunds/actions.d.ts +1 -3
  41. package/dist/_internal/server/features/refunds/actions.js +14 -2
  42. package/dist/_internal/server/features/reviews/actions.d.ts +1 -1
  43. package/dist/_internal/server/features/reviews/actions.js +12 -1
  44. package/dist/_internal/server/features/wishlist/actions.d.ts +1 -1
  45. package/dist/_internal/server/features/wishlist/actions.js +12 -1
  46. package/dist/_internal/server/jobs/core/obligationSweep.js +0 -1
  47. package/dist/_internal/server/jobs/core/paymentReconcile.js +93 -76
  48. package/dist/_internal/server/jobs/core/testDataCleanup.d.ts +1 -1
  49. package/dist/_internal/server/jobs/core/testDataCleanup.js +22 -1
  50. package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +16 -4
  51. package/dist/_internal/shared/actions/action-registry.js +149 -9
  52. package/dist/_internal/shared/features/promotions/schema.d.ts +66 -0
  53. package/dist/_internal/shared/features/promotions/schema.js +7 -0
  54. package/dist/_internal/shared/media/limits.d.ts +10 -0
  55. package/dist/_internal/shared/media/limits.js +10 -0
  56. package/dist/_internal/shared/obligations/deadlines.js +11 -1
  57. package/dist/_internal/shared/tester/window.d.ts +25 -0
  58. package/dist/_internal/shared/tester/window.js +66 -0
  59. package/dist/_internal/shared/types/action-result.js +15 -1
  60. package/dist/client/api/surface-error.js +16 -2
  61. package/dist/client/api/useApiMutation.js +17 -1
  62. package/dist/client.d.ts +1 -1
  63. package/dist/client.js +1 -1
  64. package/dist/constants/api-endpoints.d.ts +3 -0
  65. package/dist/constants/api-endpoints.js +1 -0
  66. package/dist/constants/field-names.d.ts +17 -0
  67. package/dist/constants/field-names.js +23 -0
  68. package/dist/core/server-action.js +19 -3
  69. package/dist/core/unit-of-work.js +15 -1
  70. package/dist/errors/error-mapping.js +26 -1
  71. package/dist/errors/firestore-codes.d.ts +37 -0
  72. package/dist/errors/firestore-codes.js +52 -0
  73. package/dist/errors/index.d.ts +0 -1
  74. package/dist/errors/index.js +12 -2
  75. package/dist/features/account/components/UserOffersPanel.js +5 -3
  76. package/dist/features/admin/components/AdminActionIndexView.js +100 -5
  77. package/dist/features/admin/components/AdminAddressClustersView.js +21 -2
  78. package/dist/features/admin/components/AdminBlogEditorView.js +8 -8
  79. package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
  80. package/dist/features/admin/components/AdminCarouselView.js +96 -4
  81. package/dist/features/admin/components/AdminCouponEditorView.js +8 -0
  82. package/dist/features/admin/components/AdminFulfillmentView.js +3 -2
  83. package/dist/features/admin/components/AdminGatewayEventsView.js +2 -2
  84. package/dist/features/admin/components/AdminMediaView.js +36 -3
  85. package/dist/features/admin/components/AdminNavigationView.js +4 -1
  86. package/dist/features/admin/components/AdminOffersView.js +2 -1
  87. package/dist/features/admin/components/AdminPaymentClustersView.js +19 -2
  88. package/dist/features/admin/components/AdminProductEditorView.js +2 -2
  89. package/dist/features/admin/components/AdminSectionsView.d.ts +10 -0
  90. package/dist/features/admin/components/AdminSectionsView.js +486 -224
  91. package/dist/features/admin/components/DataListingView.js +2 -0
  92. package/dist/features/admin/components/ReferenceRecordEditor.js +1 -1
  93. package/dist/features/admin/components/analytics/AdminStatCard.js +4 -1
  94. package/dist/features/admin/hooks/useOptimisticRowFlag.d.ts +33 -0
  95. package/dist/features/admin/hooks/useOptimisticRowFlag.js +87 -0
  96. package/dist/features/admin/repository/notification.repository.d.ts +15 -0
  97. package/dist/features/admin/repository/notification.repository.js +32 -0
  98. package/dist/features/admin/repository/site-settings.repository.d.ts +2 -1
  99. package/dist/features/admin/repository/site-settings.repository.js +7 -0
  100. package/dist/features/admin/schemas/action-index-form.d.ts +34 -0
  101. package/dist/features/admin/schemas/action-index-form.js +115 -0
  102. package/dist/features/auctions/components/MarketplaceAuctionCard.js +1 -1
  103. package/dist/features/auth/components/RegisterForm.js +2 -1
  104. package/dist/features/catalogue/actions/approve-catalogue-listing.d.ts +1 -1
  105. package/dist/features/catalogue/actions/approve-catalogue-listing.js +12 -1
  106. package/dist/features/catalogue/actions/list-from-catalogue.d.ts +1 -1
  107. package/dist/features/catalogue/actions/list-from-catalogue.js +12 -1
  108. package/dist/features/catalogue/actions/submit-for-approval.d.ts +1 -1
  109. package/dist/features/catalogue/actions/submit-for-approval.js +12 -1
  110. package/dist/features/catalogue/components/CatalogueItemEditorView.js +3 -3
  111. package/dist/features/categories/repository/price-observation.repository.d.ts +19 -0
  112. package/dist/features/categories/repository/price-observation.repository.js +21 -2
  113. package/dist/features/events/actions/event-actions.js +4 -1
  114. package/dist/features/events/components/AdminEventEditorView.js +79 -50
  115. package/dist/features/events/components/EventsListPageView.js +2 -1
  116. package/dist/features/events/schemas/firestore.d.ts +17 -0
  117. package/dist/features/events/schemas/firestore.js +1 -0
  118. package/dist/features/events/utils/sort-pinned.d.ts +33 -0
  119. package/dist/features/events/utils/sort-pinned.js +46 -0
  120. package/dist/features/gateway-events/repository/gateway-events.repository.js +3 -40
  121. package/dist/features/gateway-events/schemas/index.d.ts +2 -2
  122. package/dist/features/inventory/components/AdminStorageBoxesView.js +55 -39
  123. package/dist/features/inventory/components/ReceiveStationView.js +61 -17
  124. package/dist/features/inventory/repository/storage-boxes.repository.d.ts +3 -1
  125. package/dist/features/inventory/repository/storage-boxes.repository.js +36 -3
  126. package/dist/features/layout/hooks/useFormBottomActions.js +20 -1
  127. package/dist/features/obligations/repository/obligations.repository.js +10 -1
  128. package/dist/features/orders/components/EmiInstallmentsPanel.js +25 -7
  129. package/dist/features/orders/components/RefundRequestView.js +4 -4
  130. package/dist/features/orders/schemas/firestore.d.ts +19 -0
  131. package/dist/features/orders/schemas/firestore.js +19 -0
  132. package/dist/features/orders/schemas/index.d.ts +6 -6
  133. package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +1 -0
  134. package/dist/features/payment-cases/repository/payment-cases.repository.js +3 -14
  135. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +1 -1
  136. package/dist/features/products/components/GroupMemberPicker.js +4 -1
  137. package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
  138. package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
  139. package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
  140. package/dist/features/products/components/ProductDetailActions.js +2 -1
  141. package/dist/features/products/components/ProductForm.js +2 -2
  142. package/dist/features/products/components/ProductGrid.js +1 -1
  143. package/dist/features/promotions/repository/claimed-coupons.repository.js +31 -1
  144. package/dist/features/promotions/schemas/firestore.d.ts +22 -0
  145. package/dist/features/promotions/schemas/firestore.js +22 -0
  146. package/dist/features/promotions/schemas/index.d.ts +479 -6
  147. package/dist/features/promotions/schemas/index.js +153 -0
  148. package/dist/features/protection-claims/repository/protection-claims.repository.js +22 -15
  149. package/dist/features/seller/components/FulfillmentView.js +3 -2
  150. package/dist/features/seller/components/SellerAddressesView.js +32 -4
  151. package/dist/features/seller/components/SellerAnalyticsAlertsView.js +62 -3
  152. package/dist/features/seller/components/SellerBundlesView.js +53 -14
  153. package/dist/features/seller/components/SellerGroupedListingsView.js +23 -3
  154. package/dist/features/seller/components/SellerListingTypeView.js +56 -10
  155. package/dist/features/seller/components/SellerPayoutMethodsView.js +33 -1
  156. package/dist/features/seller/components/SellerPayoutSettingsView.js +48 -9
  157. package/dist/features/seller/components/SellerProductsView.js +5 -1
  158. package/dist/features/seller/components/SellerShippingConfigsView.js +33 -1
  159. package/dist/features/seller/components/SellerShippingView.js +2 -1
  160. package/dist/features/seller/components/SellerStoreCategoriesView.js +33 -1
  161. package/dist/features/seller/components/SellerSupportView.js +69 -2
  162. package/dist/features/seller/schemas/coupon-form.d.ts +5 -0
  163. package/dist/features/seller/schemas/coupon-form.js +18 -0
  164. package/dist/features/shell/SectionForm.js +35 -9
  165. package/dist/features/shell/build-sections.js +14 -1
  166. package/dist/features/shipments/components/AdminShipmentLotItemsView.js +54 -1
  167. package/dist/features/shipments/components/AdminShipmentProjectionsView.js +3 -2
  168. package/dist/features/sticker-trace/components/StickerCommitPanel.js +2 -1
  169. package/dist/features/sticker-trace/components/StickerPrintPanel.js +2 -1
  170. package/dist/features/sticker-trace/components/StickerRetryPanel.js +24 -4
  171. package/dist/features/sticker-trace/components/StickerTraceStudio.js +2 -1
  172. package/dist/features/sticker-trace/server.d.ts +2 -0
  173. package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +3 -2
  174. package/dist/http/api-handler.js +4 -1
  175. package/dist/index.d.ts +8 -4
  176. package/dist/index.js +6 -4
  177. package/dist/next/routing/route-map.d.ts +4 -2
  178. package/dist/next/routing/route-map.js +19 -1
  179. package/dist/schemas/registry.d.ts +15 -10
  180. package/dist/schemas/sieve.d.ts +3 -3
  181. package/dist/server.d.ts +1 -2
  182. package/dist/server.js +6 -4
  183. package/dist/styles.css +51 -0
  184. package/dist/ui/components/Checkbox.js +10 -2
  185. package/dist/ui/components/DateInput.js +8 -1
  186. package/dist/ui/components/Input.js +22 -2
  187. package/dist/ui/components/PaginatedSelect.d.ts +8 -19
  188. package/dist/ui/components/PaginatedSelect.js +0 -0
  189. package/dist/ui/components/Radio.js +8 -1
  190. package/dist/ui/components/Select.js +10 -2
  191. package/dist/ui/components/TagInput.d.ts +8 -1
  192. package/dist/ui/components/TagInput.js +4 -3
  193. package/dist/ui/components/Textarea.js +10 -2
  194. package/dist/ui/forms/FieldCheckbox.js +1 -1
  195. package/dist/ui/forms/FormErrorList.d.ts +0 -16
  196. package/dist/ui/forms/FormErrorList.js +34 -1
  197. package/dist/ui/forms/apply-zod-issues.d.ts +19 -1
  198. package/dist/ui/forms/apply-zod-issues.js +23 -1
  199. package/package.json +1 -1
  200. package/scripts/seed-cli.mjs +1822 -1812
  201. package/dist/features/tester/utils/phases.d.ts +0 -48
  202. package/dist/features/tester/utils/phases.js +0 -139
@@ -184,7 +184,7 @@ export function ProductCard({ product, href, onClick, onAddToWishlist, isWishlis
184
184
  * `justify-end` keeps it on the side the eye already uses for card actions;
185
185
  * `pt-0` because the card body's own bottom padding is the gap.
186
186
  */
187
- return (_jsxs(Div, { className: "flex h-full flex-col", children: [wrapped, _jsx(Div, { className: "flex justify-end px-[var(--appkit-space-3)] pb-[var(--appkit-space-3)] pt-0", children: ownerActions })] }));
187
+ return (_jsxs(Div, { layout: "flex-col", className: "h-full", children: [wrapped, _jsx(Div, { layout: "flex", justify: "end", className: "px-[var(--appkit-space-3)] pb-[var(--appkit-space-3)]", children: ownerActions })] }));
188
188
  }
189
189
  function ProductListRow({ product, onClick, onAddToWishlist, isWishlisted, }) {
190
190
  const discount = product.originalPrice && product.originalPrice > product.price
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { BaseRepository, prepareForFirestore, } from "../../../providers/db-firebase/index.js";
9
9
  import { normalizeError } from "../../../errors/normalize.js";
10
+ import { serverLogger } from "../../../monitoring/index.js";
10
11
  import { CLAIMED_COUPONS_COLLECTION, createClaimedCouponId } from "../schemas/index.js";
11
12
  import { DatabaseError } from "../../../errors/index.js";
12
13
  import { COUPON_USAGE_FIELDS } from "../../../constants/field-names.js";
@@ -128,10 +129,39 @@ export class ClaimedCouponsRepository extends BaseRepository {
128
129
  if (snap.empty)
129
130
  return 0;
130
131
  const writer = this.db.bulkWriter();
132
+ /*
133
+ * 🛑 `onWriteError` FIRST, before any write is queued.
134
+ *
135
+ * `BulkWriter.update()` returns a promise per write and the contract is
136
+ * not to await them individually — `close()` is what flushes. But an
137
+ * un-awaited promise that rejects is an unhandled rejection, which is
138
+ * what `@typescript-eslint/no-floating-promises` was reporting, and
139
+ * `void`-ing it would silence the lint while keeping the hazard.
140
+ *
141
+ * Registering the handler is the real fix: a failed row is RECORDED and
142
+ * the batch continues, which is the right behaviour for a denormalised
143
+ * snapshot refresh — one stale coupon card is not worth abandoning the
144
+ * other 499, and the method's docstring already says it must not throw.
145
+ */
146
+ let failed = 0;
147
+ writer.onWriteError((err) => {
148
+ failed++;
149
+ serverLogger.warn("claimedCoupons: snapshot refresh failed for one row", {
150
+ documentPath: err.documentRef.path,
151
+ error: err.message,
152
+ });
153
+ return false; // do not retry — the next refresh picks it up
154
+ });
131
155
  for (const doc of snap.docs) {
132
- writer.update(doc.ref, { couponSnapshot: snapshot, updatedAt: new Date() });
156
+ void writer.update(doc.ref, { couponSnapshot: snapshot, updatedAt: new Date() });
133
157
  }
134
158
  await writer.close();
159
+ if (failed > 0) {
160
+ serverLogger.warn("claimedCoupons: snapshot refresh partially failed", {
161
+ failed,
162
+ total: snap.size,
163
+ });
164
+ }
135
165
  return snap.size;
136
166
  }
137
167
  catch (error) {
@@ -12,6 +12,21 @@ export interface DiscountConfig {
12
12
  export interface BXGYConfig {
13
13
  buyQuantity: number;
14
14
  getQuantity: number;
15
+ /**
16
+ * Per-UNIT price ceiling, in decimal rupees. A unit priced above this does
17
+ * not qualify: it neither counts toward a block nor can be given free.
18
+ *
19
+ * 🛑 This is a UNIT price, not a line total and not the order total — the
20
+ * promotion it exists for is "buy 3 get 1 free on items under ₹2,000", and
21
+ * `discount.minPurchase` already covers the order-total reading. A line of
22
+ * quantity 3 at ₹1,500 contributes three qualifying units, not one ₹4,500
23
+ * item that fails the ceiling.
24
+ *
25
+ * Omitted means no ceiling, which is what every BOGO coupon written before
26
+ * 2026-10-22 means. Do not default it to a number — a ceiling nobody asked
27
+ * for would silently shrink an existing coupon's discount.
28
+ */
29
+ maxItemPrice?: number;
15
30
  applicableProducts?: string[];
16
31
  applicableCategories?: string[];
17
32
  }
@@ -194,6 +209,13 @@ export interface DiscountableLine {
194
209
  *
195
210
  * 🛑 An INCOMPLETE block earns nothing. "Buy 2 get 1" on 2 units is a block of
196
211
  * 2 against a required 3, so the discount is 0 — not a partial credit.
212
+ *
213
+ * 🛑 `bxgy.maxItemPrice` filters the UNIT POOL before blocks are formed, so an
214
+ * over-ceiling unit neither counts toward a block nor can be free. Filtering
215
+ * only the free-unit selection instead would let four ₹5,000 tops earn a free
216
+ * one under an "items under ₹2,000" promotion, because the cheapest of four
217
+ * dear units is still dear. The ceiling defines what the promotion is ABOUT,
218
+ * not merely what it pays out.
197
219
  */
198
220
  export declare function calculateBxgyDiscount(bxgy: BXGYConfig | undefined, lines: readonly DiscountableLine[]): number;
199
221
  export declare function calculateDiscount(coupon: CouponDocument, orderTotal: number,
@@ -159,6 +159,13 @@ export function canUserUseCoupon(coupon, userUsageCount) {
159
159
  *
160
160
  * 🛑 An INCOMPLETE block earns nothing. "Buy 2 get 1" on 2 units is a block of
161
161
  * 2 against a required 3, so the discount is 0 — not a partial credit.
162
+ *
163
+ * 🛑 `bxgy.maxItemPrice` filters the UNIT POOL before blocks are formed, so an
164
+ * over-ceiling unit neither counts toward a block nor can be free. Filtering
165
+ * only the free-unit selection instead would let four ₹5,000 tops earn a free
166
+ * one under an "items under ₹2,000" promotion, because the cheapest of four
167
+ * dear units is still dear. The ceiling defines what the promotion is ABOUT,
168
+ * not merely what it pays out.
162
169
  */
163
170
  export function calculateBxgyDiscount(bxgy, lines) {
164
171
  if (!bxgy)
@@ -169,6 +176,16 @@ export function calculateBxgyDiscount(bxgy, lines) {
169
176
  // unit free, which is a misconfiguration, not a promotion.
170
177
  if (!Number.isFinite(buy) || !Number.isFinite(get) || buy <= 0 || get <= 0)
171
178
  return 0;
179
+ /*
180
+ * A non-finite or non-positive ceiling is a misconfiguration, and treating
181
+ * it as "0" would disqualify every unit and silently zero the coupon. Treat
182
+ * it as absent — the same thing an omitted ceiling means.
183
+ */
184
+ const ceiling = typeof bxgy.maxItemPrice === "number" &&
185
+ Number.isFinite(bxgy.maxItemPrice) &&
186
+ bxgy.maxItemPrice > 0
187
+ ? bxgy.maxItemPrice
188
+ : undefined;
172
189
  // Expand to one entry per UNIT — a line of quantity 3 contributes 3 prices,
173
190
  // because the free units are counted in units, not in lines.
174
191
  const unitPrices = [];
@@ -178,6 +195,11 @@ export function calculateBxgyDiscount(bxgy, lines) {
178
195
  continue;
179
196
  if (!Number.isFinite(line.price) || line.price < 0)
180
197
  continue;
198
+ // Inclusive: "under ₹2,000" is authored as maxItemPrice 1999 when the
199
+ // boundary matters. An exclusive test here would make a ₹2,000 ceiling
200
+ // reject a ₹2,000 item, which is not how a price cap reads to an admin.
201
+ if (ceiling !== undefined && line.price > ceiling)
202
+ continue;
181
203
  for (let i = 0; i < qty; i++)
182
204
  unitPrices.push(line.price);
183
205
  }