@instockng/api-client 1.0.7 → 1.0.8

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 (66) hide show
  1. package/dist/apps/backend/src/http-app.js +28 -0
  2. package/dist/apps/backend/src/lib/brand-response.d.ts +1 -1
  3. package/dist/apps/backend/src/lib/cart-helpers.d.ts +13 -11
  4. package/dist/apps/backend/src/lib/cart-helpers.js +28 -0
  5. package/dist/apps/backend/src/lib/cart-response.d.ts +5 -5
  6. package/dist/apps/backend/src/lib/clerk.js +23 -0
  7. package/dist/apps/backend/src/lib/delivery-zone-response.d.ts +6 -4
  8. package/dist/apps/backend/src/lib/discount-code-response.d.ts +2 -2
  9. package/dist/apps/backend/src/lib/meta-capi.d.ts +5 -0
  10. package/dist/apps/backend/src/lib/meta-capi.js +33 -2
  11. package/dist/apps/backend/src/lib/order-recovery.d.ts +30 -24
  12. package/dist/apps/backend/src/lib/order-response.d.ts +9 -7
  13. package/dist/apps/backend/src/lib/product-response.d.ts +4 -4
  14. package/dist/apps/backend/src/lib/sentry.d.ts +48 -0
  15. package/dist/apps/backend/src/lib/sentry.js +180 -0
  16. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.js +18 -4
  17. package/dist/apps/backend/src/routes/admin/abandoned-carts.d.ts +10 -10
  18. package/dist/apps/backend/src/routes/admin/brands.d.ts +4 -4
  19. package/dist/apps/backend/src/routes/admin/customers.d.ts +9 -7
  20. package/dist/apps/backend/src/routes/admin/delivery-zones.d.ts +23 -15
  21. package/dist/apps/backend/src/routes/admin/discount-codes.d.ts +10 -10
  22. package/dist/apps/backend/src/routes/admin/inventory.js +10 -0
  23. package/dist/apps/backend/src/routes/admin/orders.d.ts +54 -42
  24. package/dist/apps/backend/src/routes/admin/orders.js +25 -0
  25. package/dist/apps/backend/src/routes/admin/products.d.ts +12 -12
  26. package/dist/apps/backend/src/routes/admin/products.js +34 -15
  27. package/dist/apps/backend/src/routes/admin/stats.d.ts +9 -7
  28. package/dist/apps/backend/src/routes/admin/variants.d.ts +5 -5
  29. package/dist/apps/backend/src/routes/admin/variants.js +42 -18
  30. package/dist/apps/backend/src/routes/admin/warehouses.d.ts +7 -7
  31. package/dist/apps/backend/src/routes/public/brands.d.ts +1 -1
  32. package/dist/apps/backend/src/routes/public/carts.d.ts +49 -47
  33. package/dist/apps/backend/src/routes/public/carts.js +148 -1
  34. package/dist/apps/backend/src/routes/public/delivery-zones.d.ts +2 -0
  35. package/dist/apps/backend/src/routes/public/delivery-zones.js +2 -0
  36. package/dist/apps/backend/src/routes/public/orders.d.ts +18 -14
  37. package/dist/apps/backend/src/routes/public/orders.js +24 -0
  38. package/dist/apps/backend/src/routes/public/products.d.ts +6 -6
  39. package/dist/apps/backend/src/types/index.d.ts +1 -0
  40. package/dist/apps/backend/src/validators/delivery-zone.d.ts +4 -0
  41. package/dist/apps/backend/src/validators/delivery-zone.js +4 -0
  42. package/dist/apps/backend/src/validators/discount-code.d.ts +3 -3
  43. package/dist/apps/backend/src/validators/order.d.ts +3 -1
  44. package/dist/apps/backend/src/validators/order.js +3 -1
  45. package/dist/packages/api-client/src/fetchers/brands.d.ts +1 -1
  46. package/dist/packages/api-client/src/fetchers/carts.d.ts +49 -47
  47. package/dist/packages/api-client/src/fetchers/delivery-zones.d.ts +2 -0
  48. package/dist/packages/api-client/src/fetchers/orders.d.ts +18 -14
  49. package/dist/packages/api-client/src/fetchers/products.d.ts +6 -6
  50. package/dist/packages/api-client/src/hooks/admin/abandoned-carts.d.ts +10 -10
  51. package/dist/packages/api-client/src/hooks/admin/brands.d.ts +4 -4
  52. package/dist/packages/api-client/src/hooks/admin/customers.d.ts +9 -7
  53. package/dist/packages/api-client/src/hooks/admin/delivery-zones.d.ts +23 -15
  54. package/dist/packages/api-client/src/hooks/admin/discount-codes.d.ts +10 -10
  55. package/dist/packages/api-client/src/hooks/admin/orders.d.ts +54 -42
  56. package/dist/packages/api-client/src/hooks/admin/products.d.ts +6 -6
  57. package/dist/packages/api-client/src/hooks/admin/stats.d.ts +9 -7
  58. package/dist/packages/api-client/src/hooks/admin/variants.d.ts +5 -5
  59. package/dist/packages/api-client/src/hooks/admin/warehouses.d.ts +7 -7
  60. package/dist/packages/api-client/src/hooks/public/brands.d.ts +1 -1
  61. package/dist/packages/api-client/src/hooks/public/carts.d.ts +49 -47
  62. package/dist/packages/api-client/src/hooks/public/delivery-zones.d.ts +2 -0
  63. package/dist/packages/api-client/src/hooks/public/orders.d.ts +18 -14
  64. package/dist/packages/api-client/src/hooks/public/products.d.ts +6 -6
  65. package/dist/packages/api-client/src/rpc-client.d.ts +219 -187
  66. package/package.json +1 -1
@@ -19,8 +19,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
19
19
  createdAt: string;
20
20
  updatedAt: string;
21
21
  deletedAt: string;
22
- name: string;
23
22
  id: string;
23
+ name: string;
24
24
  slug: string;
25
25
  logoUrl: string | null;
26
26
  siteUrl: string;
@@ -40,14 +40,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
40
40
  lastRecoveryAttemptAt: string;
41
41
  recoveryDiscountCode: {
42
42
  id: string;
43
+ type: string;
44
+ value: string;
43
45
  createdAt: string;
44
46
  updatedAt: string;
45
47
  deletedAt: string;
46
48
  brandId: string | null;
47
49
  isActive: boolean;
48
50
  code: string;
49
- type: string;
50
- value: string;
51
51
  minPurchase: string;
52
52
  maxDiscount: string;
53
53
  usageLimit: number | null;
@@ -65,8 +65,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
65
65
  variant: {
66
66
  price: number;
67
67
  product: {
68
- name: string;
69
68
  id: string;
69
+ name: string;
70
70
  slug: string;
71
71
  createdAt: string;
72
72
  updatedAt: string;
@@ -221,8 +221,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
221
221
  };
222
222
  };
223
223
  };
224
- name: string | null;
225
224
  id: string;
225
+ name: string | null;
226
226
  createdAt: string;
227
227
  updatedAt: string;
228
228
  deletedAt: string;
@@ -300,8 +300,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
300
300
  createdAt: string;
301
301
  updatedAt: string;
302
302
  deletedAt: string;
303
- name: string;
304
303
  id: string;
304
+ name: string;
305
305
  slug: string;
306
306
  logoUrl: string | null;
307
307
  siteUrl: string;
@@ -321,14 +321,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
321
321
  lastRecoveryAttemptAt: string;
322
322
  recoveryDiscountCode: {
323
323
  id: string;
324
+ type: string;
325
+ value: string;
324
326
  createdAt: string;
325
327
  updatedAt: string;
326
328
  deletedAt: string;
327
329
  brandId: string | null;
328
330
  isActive: boolean;
329
331
  code: string;
330
- type: string;
331
- value: string;
332
332
  minPurchase: string;
333
333
  maxDiscount: string;
334
334
  usageLimit: number | null;
@@ -346,8 +346,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
346
346
  variant: {
347
347
  price: number;
348
348
  product: {
349
- name: string;
350
349
  id: string;
350
+ name: string;
351
351
  slug: string;
352
352
  createdAt: string;
353
353
  updatedAt: string;
@@ -502,8 +502,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
502
502
  };
503
503
  };
504
504
  };
505
- name: string | null;
506
505
  id: string;
506
+ name: string | null;
507
507
  createdAt: string;
508
508
  updatedAt: string;
509
509
  deletedAt: string;
@@ -571,8 +571,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
571
571
  createdAt: string;
572
572
  updatedAt: string;
573
573
  deletedAt: string;
574
- name: string;
575
574
  id: string;
575
+ name: string;
576
576
  slug: string;
577
577
  logoUrl: string | null;
578
578
  siteUrl: string;
@@ -592,14 +592,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
592
592
  lastRecoveryAttemptAt: string;
593
593
  recoveryDiscountCode: {
594
594
  id: string;
595
+ type: string;
596
+ value: string;
595
597
  createdAt: string;
596
598
  updatedAt: string;
597
599
  deletedAt: string;
598
600
  brandId: string | null;
599
601
  isActive: boolean;
600
602
  code: string;
601
- type: string;
602
- value: string;
603
603
  minPurchase: string;
604
604
  maxDiscount: string;
605
605
  usageLimit: number | null;
@@ -617,8 +617,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
617
617
  variant: {
618
618
  price: number;
619
619
  product: {
620
- name: string;
621
620
  id: string;
621
+ name: string;
622
622
  slug: string;
623
623
  createdAt: string;
624
624
  updatedAt: string;
@@ -773,8 +773,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
773
773
  };
774
774
  };
775
775
  };
776
- name: string | null;
777
776
  id: string;
777
+ name: string | null;
778
778
  createdAt: string;
779
779
  updatedAt: string;
780
780
  deletedAt: string;
@@ -856,8 +856,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
856
856
  createdAt: string;
857
857
  updatedAt: string;
858
858
  deletedAt: string;
859
- name: string;
860
859
  id: string;
860
+ name: string;
861
861
  slug: string;
862
862
  logoUrl: string | null;
863
863
  siteUrl: string;
@@ -877,14 +877,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
877
877
  lastRecoveryAttemptAt: string;
878
878
  recoveryDiscountCode: {
879
879
  id: string;
880
+ type: string;
881
+ value: string;
880
882
  createdAt: string;
881
883
  updatedAt: string;
882
884
  deletedAt: string;
883
885
  brandId: string | null;
884
886
  isActive: boolean;
885
887
  code: string;
886
- type: string;
887
- value: string;
888
888
  minPurchase: string;
889
889
  maxDiscount: string;
890
890
  usageLimit: number | null;
@@ -902,8 +902,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
902
902
  variant: {
903
903
  price: number;
904
904
  product: {
905
- name: string;
906
905
  id: string;
906
+ name: string;
907
907
  slug: string;
908
908
  createdAt: string;
909
909
  updatedAt: string;
@@ -1058,8 +1058,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1058
1058
  };
1059
1059
  };
1060
1060
  };
1061
- name: string | null;
1062
1061
  id: string;
1062
+ name: string | null;
1063
1063
  createdAt: string;
1064
1064
  updatedAt: string;
1065
1065
  deletedAt: string;
@@ -1141,8 +1141,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1141
1141
  createdAt: string;
1142
1142
  updatedAt: string;
1143
1143
  deletedAt: string;
1144
- name: string;
1145
1144
  id: string;
1145
+ name: string;
1146
1146
  slug: string;
1147
1147
  logoUrl: string | null;
1148
1148
  siteUrl: string;
@@ -1162,14 +1162,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1162
1162
  lastRecoveryAttemptAt: string;
1163
1163
  recoveryDiscountCode: {
1164
1164
  id: string;
1165
+ type: string;
1166
+ value: string;
1165
1167
  createdAt: string;
1166
1168
  updatedAt: string;
1167
1169
  deletedAt: string;
1168
1170
  brandId: string | null;
1169
1171
  isActive: boolean;
1170
1172
  code: string;
1171
- type: string;
1172
- value: string;
1173
1173
  minPurchase: string;
1174
1174
  maxDiscount: string;
1175
1175
  usageLimit: number | null;
@@ -1187,8 +1187,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1187
1187
  variant: {
1188
1188
  price: number;
1189
1189
  product: {
1190
- name: string;
1191
1190
  id: string;
1191
+ name: string;
1192
1192
  slug: string;
1193
1193
  createdAt: string;
1194
1194
  updatedAt: string;
@@ -1343,8 +1343,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1343
1343
  };
1344
1344
  };
1345
1345
  };
1346
- name: string | null;
1347
1346
  id: string;
1347
+ name: string | null;
1348
1348
  createdAt: string;
1349
1349
  updatedAt: string;
1350
1350
  deletedAt: string;
@@ -1426,8 +1426,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1426
1426
  createdAt: string;
1427
1427
  updatedAt: string;
1428
1428
  deletedAt: string;
1429
- name: string;
1430
1429
  id: string;
1430
+ name: string;
1431
1431
  slug: string;
1432
1432
  logoUrl: string | null;
1433
1433
  siteUrl: string;
@@ -1447,14 +1447,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1447
1447
  lastRecoveryAttemptAt: string;
1448
1448
  recoveryDiscountCode: {
1449
1449
  id: string;
1450
+ type: string;
1451
+ value: string;
1450
1452
  createdAt: string;
1451
1453
  updatedAt: string;
1452
1454
  deletedAt: string;
1453
1455
  brandId: string | null;
1454
1456
  isActive: boolean;
1455
1457
  code: string;
1456
- type: string;
1457
- value: string;
1458
1458
  minPurchase: string;
1459
1459
  maxDiscount: string;
1460
1460
  usageLimit: number | null;
@@ -1472,8 +1472,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1472
1472
  variant: {
1473
1473
  price: number;
1474
1474
  product: {
1475
- name: string;
1476
1475
  id: string;
1476
+ name: string;
1477
1477
  slug: string;
1478
1478
  createdAt: string;
1479
1479
  updatedAt: string;
@@ -1628,8 +1628,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1628
1628
  };
1629
1629
  };
1630
1630
  };
1631
- name: string | null;
1632
1631
  id: string;
1632
+ name: string | null;
1633
1633
  createdAt: string;
1634
1634
  updatedAt: string;
1635
1635
  deletedAt: string;
@@ -1713,8 +1713,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1713
1713
  createdAt: string;
1714
1714
  updatedAt: string;
1715
1715
  deletedAt: string;
1716
- name: string;
1717
1716
  id: string;
1717
+ name: string;
1718
1718
  slug: string;
1719
1719
  logoUrl: string | null;
1720
1720
  siteUrl: string;
@@ -1734,14 +1734,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1734
1734
  lastRecoveryAttemptAt: string;
1735
1735
  recoveryDiscountCode: {
1736
1736
  id: string;
1737
+ type: string;
1738
+ value: string;
1737
1739
  createdAt: string;
1738
1740
  updatedAt: string;
1739
1741
  deletedAt: string;
1740
1742
  brandId: string | null;
1741
1743
  isActive: boolean;
1742
1744
  code: string;
1743
- type: string;
1744
- value: string;
1745
1745
  minPurchase: string;
1746
1746
  maxDiscount: string;
1747
1747
  usageLimit: number | null;
@@ -1759,8 +1759,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1759
1759
  variant: {
1760
1760
  price: number;
1761
1761
  product: {
1762
- name: string;
1763
1762
  id: string;
1763
+ name: string;
1764
1764
  slug: string;
1765
1765
  createdAt: string;
1766
1766
  updatedAt: string;
@@ -1915,8 +1915,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1915
1915
  };
1916
1916
  };
1917
1917
  };
1918
- name: string | null;
1919
1918
  id: string;
1919
+ name: string | null;
1920
1920
  createdAt: string;
1921
1921
  updatedAt: string;
1922
1922
  deletedAt: string;
@@ -2020,8 +2020,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2020
2020
  createdAt: string;
2021
2021
  updatedAt: string;
2022
2022
  deletedAt: string;
2023
- name: string;
2024
2023
  id: string;
2024
+ name: string;
2025
2025
  slug: string;
2026
2026
  logoUrl: string | null;
2027
2027
  siteUrl: string;
@@ -2041,14 +2041,14 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2041
2041
  lastRecoveryAttemptAt: string;
2042
2042
  recoveryDiscountCode: {
2043
2043
  id: string;
2044
+ type: string;
2045
+ value: string;
2044
2046
  createdAt: string;
2045
2047
  updatedAt: string;
2046
2048
  deletedAt: string;
2047
2049
  brandId: string | null;
2048
2050
  isActive: boolean;
2049
2051
  code: string;
2050
- type: string;
2051
- value: string;
2052
2052
  minPurchase: string;
2053
2053
  maxDiscount: string;
2054
2054
  usageLimit: number | null;
@@ -2066,8 +2066,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2066
2066
  variant: {
2067
2067
  price: number;
2068
2068
  product: {
2069
- name: string;
2070
2069
  id: string;
2070
+ name: string;
2071
2071
  slug: string;
2072
2072
  createdAt: string;
2073
2073
  updatedAt: string;
@@ -2222,8 +2222,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2222
2222
  };
2223
2223
  };
2224
2224
  };
2225
- name: string | null;
2226
2225
  id: string;
2226
+ name: string | null;
2227
2227
  createdAt: string;
2228
2228
  updatedAt: string;
2229
2229
  deletedAt: string;
@@ -2389,8 +2389,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2389
2389
  createdAt: string;
2390
2390
  updatedAt: string;
2391
2391
  deletedAt: string;
2392
- name: string;
2393
2392
  id: string;
2393
+ name: string;
2394
2394
  slug: string;
2395
2395
  logoUrl: string | null;
2396
2396
  siteUrl: string;
@@ -2407,18 +2407,20 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2407
2407
  createdAt: string;
2408
2408
  updatedAt: string;
2409
2409
  deletedAt: string;
2410
- name: string;
2411
2410
  id: string;
2411
+ name: string;
2412
2412
  isActive: boolean;
2413
2413
  };
2414
- name: string;
2415
2414
  id: string;
2415
+ name: string;
2416
2416
  brandId: string | null;
2417
2417
  stateId: string;
2418
2418
  allowCOD: boolean;
2419
2419
  allowOnline: boolean;
2420
2420
  waybillOnly: boolean;
2421
2421
  estimatedDays: number | null;
2422
+ noteTitle: string | null;
2423
+ noteContent: string | null;
2422
2424
  isActive: boolean;
2423
2425
  };
2424
2426
  items: {
@@ -2432,8 +2434,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2432
2434
  createdAt: string;
2433
2435
  updatedAt: string;
2434
2436
  deletedAt: string;
2435
- name: string;
2436
2437
  id: string;
2438
+ name: string;
2437
2439
  slug: string;
2438
2440
  brandId: string;
2439
2441
  isActive: boolean;
@@ -2585,8 +2587,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2585
2587
  };
2586
2588
  };
2587
2589
  };
2588
- name: string | null;
2589
2590
  id: string;
2591
+ name: string | null;
2590
2592
  isActive: boolean;
2591
2593
  thumbnailUrl: string | null;
2592
2594
  productId: string;
@@ -2598,8 +2600,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2598
2600
  createdAt: string;
2599
2601
  updatedAt: string;
2600
2602
  deletedAt: string;
2601
- name: string;
2602
2603
  id: string;
2604
+ name: string;
2603
2605
  isActive: boolean;
2604
2606
  address: string | null;
2605
2607
  city: string | null;
@@ -2611,8 +2613,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
2611
2613
  warehouseId: string | null;
2612
2614
  quantity: number;
2613
2615
  }[];
2614
- id: string;
2615
2616
  email: string | null;
2617
+ id: string;
2616
2618
  brandId: string;
2617
2619
  deliveryZoneId: string;
2618
2620
  recoveryAttempts: number;
@@ -8,19 +8,32 @@ import { toPricingItems } from '../../lib/cart-response';
8
8
  import { validateCart, buildCartResponse, etagFrom, paymentFromZone, CART_INCLUDE_FULL, CART_ITEM_WITH_CART_INCLUDE, ORDER_INCLUDE_FULL, } from '../../lib/cart-helpers';
9
9
  import { round, toNumber } from '../../lib/utils';
10
10
  import { formatOrderResponse } from '../../lib/order-response';
11
+ import { captureMessage, captureException, getSampleRate } from '../../lib/sentry';
11
12
  const app = new Hono()
12
13
  // CREATE CART
13
14
  .post('/', zValidator('json', z.object({
14
15
  brandSlug: z.string(),
15
16
  })), async (c) => {
17
+ const input = c.req.valid('json');
16
18
  try {
17
- const input = c.req.valid('json');
18
19
  const prisma = getPrismaClient(c.env.DATABASE_URL);
19
20
  // Look up brand by slug
20
21
  const brand = await prisma.brand.findFirst({
21
22
  where: { slug: input.brandSlug, deletedAt: null },
22
23
  });
23
24
  if (!brand) {
25
+ // Track brand not found with sampling - could indicate broken links
26
+ captureMessage('Brand not found during cart creation', {
27
+ level: 'info',
28
+ tags: {
29
+ error_code: 'BRAND_NOT_FOUND',
30
+ endpoint: 'POST /carts',
31
+ },
32
+ extra: {
33
+ brandSlug: input.brandSlug,
34
+ },
35
+ sampleRate: 0.1, // 10% sampling
36
+ });
24
37
  return c.json({ error: { code: 'BRAND_NOT_FOUND', message: 'Brand not found' } }, 404);
25
38
  }
26
39
  // Create cart that expires in 7 days
@@ -37,6 +50,19 @@ const app = new Hono()
37
50
  }
38
51
  catch (error) {
39
52
  console.error('Error creating cart:', error);
53
+ // Capture cart creation errors - could be database issues
54
+ captureException(error instanceof Error ? error : new Error(String(error)), {
55
+ level: 'error',
56
+ tags: {
57
+ error_code: 'CART_CREATE_ERROR',
58
+ endpoint: 'POST /carts',
59
+ },
60
+ extra: {
61
+ brandSlug: input.brandSlug,
62
+ errorMessage: error?.message,
63
+ },
64
+ honoContext: c,
65
+ });
40
66
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
41
67
  }
42
68
  })
@@ -56,6 +82,17 @@ const app = new Hono()
56
82
  }
57
83
  catch (error) {
58
84
  console.error('Error fetching cart:', error);
85
+ captureException(error instanceof Error ? error : new Error(String(error)), {
86
+ level: 'error',
87
+ tags: {
88
+ error_code: 'CART_FETCH_ERROR',
89
+ endpoint: 'GET /carts/:id',
90
+ },
91
+ extra: {
92
+ cartId: c.req.param('id'),
93
+ },
94
+ honoContext: c,
95
+ });
59
96
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
60
97
  }
61
98
  })
@@ -125,6 +162,17 @@ const app = new Hono()
125
162
  }
126
163
  catch (error) {
127
164
  console.error('Error updating cart:', error);
165
+ captureException(error instanceof Error ? error : new Error(String(error)), {
166
+ level: 'error',
167
+ tags: {
168
+ error_code: 'CART_UPDATE_ERROR',
169
+ endpoint: 'PATCH /carts/:id',
170
+ },
171
+ extra: {
172
+ cartId: c.req.param('id'),
173
+ },
174
+ honoContext: c,
175
+ });
128
176
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
129
177
  }
130
178
  })
@@ -153,6 +201,20 @@ const app = new Hono()
153
201
  },
154
202
  });
155
203
  if (!discount) {
204
+ // Track invalid discount code attempts
205
+ captureMessage('Invalid or expired discount code', {
206
+ level: 'info',
207
+ tags: {
208
+ error_code: 'INVALID_DISCOUNT_CODE',
209
+ brand: cart.brand?.slug || 'unknown',
210
+ },
211
+ extra: {
212
+ code,
213
+ cartId,
214
+ brandId: cart.brandId,
215
+ },
216
+ sampleRate: getSampleRate('INVALID_DISCOUNT_CODE'), // 20% sampling
217
+ });
156
218
  return c.json({ error: { code: 'INVALID_DISCOUNT_CODE', message: 'Invalid or expired discount code' } }, 400);
157
219
  }
158
220
  // Check minimum purchase
@@ -160,6 +222,22 @@ const app = new Hono()
160
222
  if (discount.minPurchase) {
161
223
  const minPurchase = toNumber(discount.minPurchase);
162
224
  if (pricing.subtotal < minPurchase) {
225
+ // Track minimum purchase not met
226
+ captureMessage('Minimum purchase not met for discount code', {
227
+ level: 'info',
228
+ tags: {
229
+ error_code: 'MIN_PURCHASE_NOT_MET',
230
+ brand: cart.brand?.slug || 'unknown',
231
+ },
232
+ extra: {
233
+ code,
234
+ cartId,
235
+ minPurchase,
236
+ currentSubtotal: pricing.subtotal,
237
+ shortfall: minPurchase - pricing.subtotal,
238
+ },
239
+ sampleRate: getSampleRate('MIN_PURCHASE_NOT_MET'), // 15% sampling
240
+ });
163
241
  return c.json({ error: { code: 'MIN_PURCHASE_NOT_MET', message: `Minimum purchase of ₦${minPurchase.toLocaleString('en-NG', { minimumFractionDigits: 2 })} required` } }, 400);
164
242
  }
165
243
  }
@@ -174,6 +252,17 @@ const app = new Hono()
174
252
  }
175
253
  catch (error) {
176
254
  console.error('Error applying discount to cart:', error);
255
+ captureException(error instanceof Error ? error : new Error(String(error)), {
256
+ level: 'error',
257
+ tags: {
258
+ error_code: 'DISCOUNT_APPLY_ERROR',
259
+ endpoint: 'POST /carts/:id/apply-discount',
260
+ },
261
+ extra: {
262
+ cartId: c.req.param('id'),
263
+ },
264
+ honoContext: c,
265
+ });
177
266
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
178
267
  }
179
268
  })
@@ -197,6 +286,17 @@ const app = new Hono()
197
286
  }
198
287
  catch (error) {
199
288
  console.error('Error removing discount from cart:', error);
289
+ captureException(error instanceof Error ? error : new Error(String(error)), {
290
+ level: 'error',
291
+ tags: {
292
+ error_code: 'DISCOUNT_REMOVE_ERROR',
293
+ endpoint: 'POST /carts/:id/remove-discount',
294
+ },
295
+ extra: {
296
+ cartId: c.req.param('id'),
297
+ },
298
+ honoContext: c,
299
+ });
200
300
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
201
301
  }
202
302
  })
@@ -307,6 +407,17 @@ const app = new Hono()
307
407
  }
308
408
  catch (error) {
309
409
  console.error('Error adding cart item:', error);
410
+ captureException(error instanceof Error ? error : new Error(String(error)), {
411
+ level: 'error',
412
+ tags: {
413
+ error_code: 'CART_ITEM_ADD_ERROR',
414
+ endpoint: 'POST /carts/:id/items',
415
+ },
416
+ extra: {
417
+ cartId: c.req.param('id'),
418
+ },
419
+ honoContext: c,
420
+ });
310
421
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
311
422
  }
312
423
  })
@@ -346,6 +457,18 @@ const app = new Hono()
346
457
  }
347
458
  catch (error) {
348
459
  console.error('Error updating cart item:', error);
460
+ captureException(error instanceof Error ? error : new Error(String(error)), {
461
+ level: 'error',
462
+ tags: {
463
+ error_code: 'CART_ITEM_UPDATE_ERROR',
464
+ endpoint: 'PATCH /carts/:id/items/:itemId',
465
+ },
466
+ extra: {
467
+ cartId: c.req.param('id'),
468
+ itemId: c.req.param('itemId'),
469
+ },
470
+ honoContext: c,
471
+ });
349
472
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
350
473
  }
351
474
  })
@@ -384,6 +507,18 @@ const app = new Hono()
384
507
  }
385
508
  catch (error) {
386
509
  console.error('Error removing cart item:', error);
510
+ captureException(error instanceof Error ? error : new Error(String(error)), {
511
+ level: 'error',
512
+ tags: {
513
+ error_code: 'CART_ITEM_DELETE_ERROR',
514
+ endpoint: 'DELETE /carts/:id/items/:itemId',
515
+ },
516
+ extra: {
517
+ cartId: c.req.param('id'),
518
+ itemId: c.req.param('itemId'),
519
+ },
520
+ honoContext: c,
521
+ });
387
522
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
388
523
  }
389
524
  })
@@ -625,6 +760,18 @@ const app = new Hono()
625
760
  }
626
761
  catch (error) {
627
762
  console.error('Error checking out cart:', error);
763
+ // CRITICAL: Checkout failures directly impact revenue
764
+ captureException(error instanceof Error ? error : new Error(String(error)), {
765
+ level: 'fatal', // Highest severity - revenue impacting
766
+ tags: {
767
+ error_code: 'CHECKOUT_ERROR',
768
+ endpoint: 'POST /carts/:id/checkout',
769
+ },
770
+ extra: {
771
+ cartId: c.req.param('id'),
772
+ },
773
+ honoContext: c,
774
+ });
628
775
  return c.json({ error: { code: 'INTERNAL_ERROR', message: error.message } }, 500);
629
776
  }
630
777
  });
@@ -15,6 +15,8 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
15
15
  allowOnline: boolean;
16
16
  waybillOnly: boolean;
17
17
  estimatedDays: number;
18
+ noteTitle: string;
19
+ noteContent: string;
18
20
  }[];
19
21
  }[];
20
22
  outputFormat: "json";