@mohasinac/appkit 3.2.11 → 3.2.12

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.
@@ -1,4 +1,5 @@
1
1
  import { normalizeError } from "../../../../errors/normalize";
2
+ import { safeFireAndForget } from "../../../../utils/safe-fire-forget";
2
3
  /**
3
4
  * Checkout server actions (appkit).
4
5
  *
@@ -29,6 +30,7 @@ import { formatShippingAddress } from "./data";
29
30
  import { enforceMaxPerUserForCart, computePrizeRevealDeadline, } from "./prize-bundle-gates";
30
31
  import { getListingRule, runSyncPreflight, } from "../../../shared/checkout/rules";
31
32
  import { cartIsDigitalOnly } from "../../../shared/listing-types/cart-shipping";
33
+ const AUDIT_LOG_FAIL_MSG = "checkout: audit log failed (non-critical)";
32
34
  /**
33
35
  * SB-UNI-N — Atomically claim the next available digital code for a confirmed
34
36
  * order. Pre-fetches a candidate code outside the transaction then locks and
@@ -264,7 +266,7 @@ export async function createCheckoutOrderAction(input) {
264
266
  if (!addressId) {
265
267
  failedCheckoutRepository
266
268
  .logCheckout(uid, "address_not_found", "Address required for physical cart", { addressId: "", paymentMethod })
267
- .catch(console.error);
269
+ .catch((err) => { void normalizeError(err); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: err instanceof Error ? err.message : String(err) }); });
268
270
  throw new NotFoundError(ERROR_MESSAGES.CHECKOUT.ADDRESS_REQUIRED);
269
271
  }
270
272
  const addressDoc = await unitOfWork.addresses.findById(addressId);
@@ -275,7 +277,7 @@ export async function createCheckoutOrderAction(input) {
275
277
  if (!resolvedAddress) {
276
278
  failedCheckoutRepository
277
279
  .logCheckout(uid, "address_not_found", "Address not found", { addressId, paymentMethod })
278
- .catch(console.error);
280
+ .catch((err) => { void normalizeError(err); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: err instanceof Error ? err.message : String(err) }); });
279
281
  throw new NotFoundError(ERROR_MESSAGES.CHECKOUT.ADDRESS_REQUIRED);
280
282
  }
281
283
  shippingAddress = formatShippingAddress(resolvedAddress);
@@ -414,7 +416,7 @@ export async function createCheckoutOrderAction(input) {
414
416
  addressId,
415
417
  paymentMethod,
416
418
  })
417
- .catch(console.error);
419
+ .catch((logErr) => { void normalizeError(logErr); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: logErr instanceof Error ? logErr.message : String(logErr) }); });
418
420
  throw err;
419
421
  }
420
422
  const { available, unavailable, emailOtpUsed } = stockResult;
@@ -425,7 +427,7 @@ export async function createCheckoutOrderAction(input) {
425
427
  paymentMethod,
426
428
  cartItemCount: cartItems.length,
427
429
  })
428
- .catch(console.error);
430
+ .catch((logErr) => { void normalizeError(logErr); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: logErr instanceof Error ? logErr.message : String(logErr) }); });
429
431
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.INSUFFICIENT_STOCK);
430
432
  }
431
433
  const appliedCoupons = cart.appliedCoupons ?? [];
@@ -669,7 +671,7 @@ export async function verifyAndPlaceRazorpayOrderAction(input) {
669
671
  gatewayPaymentId: razorpay_payment_id,
670
672
  addressId,
671
673
  })
672
- .catch(console.error);
674
+ .catch((logErr) => { void normalizeError(logErr); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: logErr instanceof Error ? logErr.message : String(logErr) }); });
673
675
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.PAYMENT_FAILED);
674
676
  }
675
677
  const cart = await unitOfWork.carts.getOrCreate(uid);
@@ -711,7 +713,7 @@ export async function verifyAndPlaceRazorpayOrderAction(input) {
711
713
  gatewayPaymentId: razorpay_payment_id,
712
714
  addressId,
713
715
  })
714
- .catch(console.error);
716
+ .catch((err) => { void normalizeError(err); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: err instanceof Error ? err.message : String(err) }); });
715
717
  throw new ApiError(403, "Order verification required. Please complete OTP verification and retry.");
716
718
  }
717
719
  }
@@ -762,7 +764,7 @@ export async function verifyAndPlaceRazorpayOrderAction(input) {
762
764
  gatewayPaymentId: razorpay_payment_id,
763
765
  addressId,
764
766
  })
765
- .catch(console.error);
767
+ .catch((err) => { void normalizeError(err); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: err instanceof Error ? err.message : String(err) }); });
766
768
  throw new ValidationError(exists
767
769
  ? ERROR_MESSAGES.CHECKOUT.INSUFFICIENT_STOCK
768
770
  : ERROR_MESSAGES.CHECKOUT.PRODUCT_UNAVAILABLE);
@@ -790,7 +792,7 @@ export async function verifyAndPlaceRazorpayOrderAction(input) {
790
792
  amountRs: paidAmountRs,
791
793
  addressId,
792
794
  })
793
- .catch(console.error);
795
+ .catch((err) => { void normalizeError(err); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: err instanceof Error ? err.message : String(err) }); });
794
796
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.PAYMENT_FAILED);
795
797
  }
796
798
  }
@@ -996,7 +998,7 @@ export async function verifyAndPlaceRazorpayOrderAction(input) {
996
998
  });
997
999
  if (!isDigitalCartRazorpay && addressId) {
998
1000
  const otpRefForDelete = consentOtpRef(db, uid, addressId);
999
- otpRefForDelete.delete().catch(console.error);
1001
+ safeFireAndForget(otpRefForDelete.delete(), "checkout: delete OTP consent ref after Razorpay payment");
1000
1002
  }
1001
1003
  if (emailsToSend.length > 0) {
1002
1004
  Promise.all(emailsToSend.map((e) => sendOrderConfirmationEmail(e))).catch((err) => serverLogger.error("Order confirmation email error:", err));
@@ -1,5 +1,7 @@
1
1
  import { cache } from "react";
2
2
  import { getAdminDb } from "../../../../providers/db-firebase";
3
+ import { normalizeError } from "../../../../errors/normalize";
4
+ import { serverLogger } from "../../../../monitoring/server-logger";
3
5
  import { GROUPED_LISTINGS_COLLECTION, } from "../../../../features/grouped/schemas/firestore";
4
6
  import { productRepository } from "../../../../repositories";
5
7
  import { PRODUCT_FIELDS, CATEGORY_FIELDS } from "../../../../constants/field-names";
@@ -55,7 +57,9 @@ export const getGroupedListingForDetail = cache(async (slug) => {
55
57
  }
56
58
  return mapDoc(snap.docs[0]);
57
59
  }
58
- catch {
60
+ catch (err) {
61
+ void normalizeError(err);
62
+ serverLogger.warn("grouped-data: getGroupedListingForDetail failed — returning null", { slug, error: err instanceof Error ? err.message : String(err) });
59
63
  return null;
60
64
  }
61
65
  });
@@ -93,7 +97,9 @@ export async function listGroupedListings(params = {}) {
93
97
  .get();
94
98
  return snap.docs.map(mapDoc);
95
99
  }
96
- catch {
100
+ catch (err) {
101
+ void normalizeError(err);
102
+ serverLogger.warn("grouped-data: listGroupedListings failed — returning empty", { params, error: err instanceof Error ? err.message : String(err) });
97
103
  return [];
98
104
  }
99
105
  }
@@ -118,7 +124,9 @@ export async function listSitemapGroupedListings() {
118
124
  };
119
125
  });
120
126
  }
121
- catch {
127
+ catch (err) {
128
+ void normalizeError(err);
129
+ serverLogger.warn("grouped-data: listSitemapGroupedListings failed — returning empty", { error: err instanceof Error ? err.message : String(err) });
122
130
  return [];
123
131
  }
124
132
  }
@@ -1,6 +1,7 @@
1
1
  import { DatabaseError } from "../../../errors";
2
2
  import { BaseRepository, prepareForFirestore, } from "../../../providers/db-firebase";
3
3
  import { normalizeError } from "../../../errors/normalize";
4
+ import { serverLogger } from "../../../monitoring/server-logger";
4
5
  import { increment } from "../../../contracts/field-ops";
5
6
  import { SCAMMER_COLLECTION, SCAMMER_FIELDS, SCAMMER_INCIDENTS_SUBCOLLECTION, SCAMMER_COMMENTS_SUBCOLLECTION, DEFAULT_SCAMMER_DATA, } from "../schemas/firestore";
6
7
  class ScammerRepository extends BaseRepository {
@@ -116,7 +117,9 @@ class ScammerRepository extends BaseRepository {
116
117
  .get();
117
118
  return snap.docs.map((d) => this.mapDoc(d));
118
119
  }
119
- catch {
120
+ catch (err) {
121
+ void normalizeError(err);
122
+ serverLogger.warn("scammer-repo: listPublicIncidents failed — returning empty", { scammerId, error: err instanceof Error ? err.message : String(err) });
120
123
  return [];
121
124
  }
122
125
  }
@@ -132,7 +135,9 @@ class ScammerRepository extends BaseRepository {
132
135
  .get();
133
136
  return snap.docs.map((d) => this.mapDoc(d));
134
137
  }
135
- catch {
138
+ catch (err) {
139
+ void normalizeError(err);
140
+ serverLogger.warn("scammer-repo: listPublicComments failed — returning empty", { scammerId, error: err instanceof Error ? err.message : String(err) });
136
141
  return [];
137
142
  }
138
143
  }
@@ -143,7 +148,9 @@ class ScammerRepository extends BaseRepository {
143
148
  const results = await Promise.all(ids.slice(0, 5).map((id) => this.findById(id).catch(() => null)));
144
149
  return results.filter((d) => d !== null && d.status === "verified");
145
150
  }
146
- catch {
151
+ catch (err) {
152
+ void normalizeError(err);
153
+ serverLogger.warn("scammer-repo: findManyById failed — returning empty", { ids, error: err instanceof Error ? err.message : String(err) });
147
154
  return [];
148
155
  }
149
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "3.2.11",
3
+ "version": "3.2.12",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"