@instockng/api-client 1.0.8 → 1.0.10

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 (193) hide show
  1. package/dist/fetchers/brands.d.ts +1 -1
  2. package/dist/fetchers/carts.d.ts +85 -47
  3. package/dist/fetchers/delivery-zones.d.ts +2 -0
  4. package/dist/fetchers/orders.d.ts +26 -14
  5. package/dist/fetchers/products.d.ts +14 -6
  6. package/dist/hooks/admin/abandoned-carts.d.ts +18 -10
  7. package/dist/hooks/admin/brands.d.ts +4 -4
  8. package/dist/hooks/admin/customers.d.ts +13 -7
  9. package/dist/hooks/admin/delivery-zones.d.ts +23 -15
  10. package/dist/hooks/admin/discount-codes.d.ts +10 -10
  11. package/dist/hooks/admin/inventory.d.ts +4 -0
  12. package/dist/hooks/admin/orders.d.ts +78 -42
  13. package/dist/hooks/admin/products.d.ts +14 -6
  14. package/dist/hooks/admin/stats.d.ts +13 -7
  15. package/dist/hooks/admin/variants.d.ts +5 -5
  16. package/dist/hooks/admin/warehouses.d.ts +11 -7
  17. package/dist/hooks/public/brands.d.ts +1 -1
  18. package/dist/hooks/public/carts.d.ts +85 -47
  19. package/dist/hooks/public/delivery-zones.d.ts +2 -0
  20. package/dist/hooks/public/orders.d.ts +26 -14
  21. package/dist/hooks/public/products.d.ts +14 -6
  22. package/dist/rpc-client.d.ts +335 -187
  23. package/package.json +1 -1
  24. package/dist/apps/backend/src/generated/zod/index.d.ts +0 -1114
  25. package/dist/apps/backend/src/generated/zod/index.js +0 -670
  26. package/dist/apps/backend/src/http-app.d.ts +0 -40
  27. package/dist/apps/backend/src/http-app.js +0 -134
  28. package/dist/apps/backend/src/lib/brand-response.d.ts +0 -14
  29. package/dist/apps/backend/src/lib/brand-response.js +0 -8
  30. package/dist/apps/backend/src/lib/cart-helpers.d.ts +0 -282
  31. package/dist/apps/backend/src/lib/cart-helpers.js +0 -121
  32. package/dist/apps/backend/src/lib/cart-recovery.d.ts +0 -30
  33. package/dist/apps/backend/src/lib/cart-recovery.js +0 -147
  34. package/dist/apps/backend/src/lib/cart-response.d.ts +0 -121
  35. package/dist/apps/backend/src/lib/cart-response.js +0 -150
  36. package/dist/apps/backend/src/lib/clerk.d.ts +0 -18
  37. package/dist/apps/backend/src/lib/clerk.js +0 -190
  38. package/dist/apps/backend/src/lib/delivery-zone-response.d.ts +0 -64
  39. package/dist/apps/backend/src/lib/delivery-zone-response.js +0 -24
  40. package/dist/apps/backend/src/lib/discount-code-response.d.ts +0 -42
  41. package/dist/apps/backend/src/lib/discount-code-response.js +0 -19
  42. package/dist/apps/backend/src/lib/discount.d.ts +0 -20
  43. package/dist/apps/backend/src/lib/discount.js +0 -35
  44. package/dist/apps/backend/src/lib/inventory.d.ts +0 -26
  45. package/dist/apps/backend/src/lib/inventory.js +0 -160
  46. package/dist/apps/backend/src/lib/meta-capi.d.ts +0 -53
  47. package/dist/apps/backend/src/lib/meta-capi.js +0 -151
  48. package/dist/apps/backend/src/lib/openapi.d.ts +0 -36
  49. package/dist/apps/backend/src/lib/openapi.js +0 -69
  50. package/dist/apps/backend/src/lib/order-recovery.d.ts +0 -459
  51. package/dist/apps/backend/src/lib/order-recovery.js +0 -378
  52. package/dist/apps/backend/src/lib/order-response.d.ts +0 -138
  53. package/dist/apps/backend/src/lib/order-response.js +0 -61
  54. package/dist/apps/backend/src/lib/pricing.d.ts +0 -39
  55. package/dist/apps/backend/src/lib/pricing.js +0 -62
  56. package/dist/apps/backend/src/lib/prisma.d.ts +0 -9
  57. package/dist/apps/backend/src/lib/prisma.js +0 -30
  58. package/dist/apps/backend/src/lib/product-response.d.ts +0 -82
  59. package/dist/apps/backend/src/lib/product-response.js +0 -29
  60. package/dist/apps/backend/src/lib/sentry.d.ts +0 -48
  61. package/dist/apps/backend/src/lib/sentry.js +0 -180
  62. package/dist/apps/backend/src/lib/utils.d.ts +0 -32
  63. package/dist/apps/backend/src/lib/utils.js +0 -63
  64. package/dist/apps/backend/src/middleware/clerk-auth.d.ts +0 -8
  65. package/dist/apps/backend/src/middleware/clerk-auth.js +0 -89
  66. package/dist/apps/backend/src/middleware/cors.d.ts +0 -8
  67. package/dist/apps/backend/src/middleware/cors.js +0 -11
  68. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.d.ts +0 -62
  69. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.js +0 -180
  70. package/dist/apps/backend/src/notifications/producers/order-notification.d.ts +0 -9
  71. package/dist/apps/backend/src/notifications/producers/order-notification.js +0 -18
  72. package/dist/apps/backend/src/notifications/producers/prospect-recovery-notification.d.ts +0 -10
  73. package/dist/apps/backend/src/notifications/producers/prospect-recovery-notification.js +0 -11
  74. package/dist/apps/backend/src/routes/admin/abandoned-carts.d.ts +0 -605
  75. package/dist/apps/backend/src/routes/admin/abandoned-carts.js +0 -194
  76. package/dist/apps/backend/src/routes/admin/brands.d.ts +0 -175
  77. package/dist/apps/backend/src/routes/admin/brands.js +0 -118
  78. package/dist/apps/backend/src/routes/admin/customers.d.ts +0 -308
  79. package/dist/apps/backend/src/routes/admin/customers.js +0 -39
  80. package/dist/apps/backend/src/routes/admin/delivery-zones.d.ts +0 -446
  81. package/dist/apps/backend/src/routes/admin/delivery-zones.js +0 -300
  82. package/dist/apps/backend/src/routes/admin/discount-codes.d.ts +0 -478
  83. package/dist/apps/backend/src/routes/admin/discount-codes.js +0 -418
  84. package/dist/apps/backend/src/routes/admin/inventory.d.ts +0 -273
  85. package/dist/apps/backend/src/routes/admin/inventory.js +0 -199
  86. package/dist/apps/backend/src/routes/admin/orders.d.ts +0 -1780
  87. package/dist/apps/backend/src/routes/admin/orders.js +0 -552
  88. package/dist/apps/backend/src/routes/admin/products.d.ts +0 -860
  89. package/dist/apps/backend/src/routes/admin/products.js +0 -126
  90. package/dist/apps/backend/src/routes/admin/stats.d.ts +0 -290
  91. package/dist/apps/backend/src/routes/admin/stats.js +0 -55
  92. package/dist/apps/backend/src/routes/admin/variants.d.ts +0 -239
  93. package/dist/apps/backend/src/routes/admin/variants.js +0 -197
  94. package/dist/apps/backend/src/routes/admin/warehouses.d.ts +0 -373
  95. package/dist/apps/backend/src/routes/admin/warehouses.js +0 -123
  96. package/dist/apps/backend/src/routes/public/brands.d.ts +0 -40
  97. package/dist/apps/backend/src/routes/public/brands.js +0 -38
  98. package/dist/apps/backend/src/routes/public/carts.d.ts +0 -2657
  99. package/dist/apps/backend/src/routes/public/carts.js +0 -778
  100. package/dist/apps/backend/src/routes/public/delivery-zones.d.ts +0 -37
  101. package/dist/apps/backend/src/routes/public/delivery-zones.js +0 -64
  102. package/dist/apps/backend/src/routes/public/orders.d.ts +0 -609
  103. package/dist/apps/backend/src/routes/public/orders.js +0 -184
  104. package/dist/apps/backend/src/routes/public/products.d.ts +0 -449
  105. package/dist/apps/backend/src/routes/public/products.js +0 -133
  106. package/dist/apps/backend/src/types/index.d.ts +0 -43
  107. package/dist/apps/backend/src/types/index.js +0 -2
  108. package/dist/apps/backend/src/validators/brand.d.ts +0 -17
  109. package/dist/apps/backend/src/validators/brand.js +0 -15
  110. package/dist/apps/backend/src/validators/delivery-zone.d.ts +0 -35
  111. package/dist/apps/backend/src/validators/delivery-zone.js +0 -55
  112. package/dist/apps/backend/src/validators/discount-code.d.ts +0 -74
  113. package/dist/apps/backend/src/validators/discount-code.js +0 -50
  114. package/dist/apps/backend/src/validators/inventory.d.ts +0 -20
  115. package/dist/apps/backend/src/validators/inventory.js +0 -15
  116. package/dist/apps/backend/src/validators/order.d.ts +0 -58
  117. package/dist/apps/backend/src/validators/order.js +0 -62
  118. package/dist/apps/backend/src/validators/product.d.ts +0 -18
  119. package/dist/apps/backend/src/validators/product.js +0 -19
  120. package/dist/apps/backend/src/validators/variant.d.ts +0 -19
  121. package/dist/apps/backend/src/validators/variant.js +0 -19
  122. package/dist/apps/backend/src/validators/warehouse.d.ts +0 -15
  123. package/dist/apps/backend/src/validators/warehouse.js +0 -15
  124. package/dist/packages/api-client/src/backend-types.d.ts +0 -10
  125. package/dist/packages/api-client/src/backend-types.js +0 -10
  126. package/dist/packages/api-client/src/client.d.ts +0 -20
  127. package/dist/packages/api-client/src/client.js +0 -40
  128. package/dist/packages/api-client/src/enum-types.d.ts +0 -8
  129. package/dist/packages/api-client/src/enum-types.js +0 -5
  130. package/dist/packages/api-client/src/fetchers/brands.d.ts +0 -25
  131. package/dist/packages/api-client/src/fetchers/brands.js +0 -26
  132. package/dist/packages/api-client/src/fetchers/carts.d.ts +0 -2337
  133. package/dist/packages/api-client/src/fetchers/carts.js +0 -174
  134. package/dist/packages/api-client/src/fetchers/delivery-zones.d.ts +0 -30
  135. package/dist/packages/api-client/src/fetchers/delivery-zones.js +0 -26
  136. package/dist/packages/api-client/src/fetchers/index.d.ts +0 -22
  137. package/dist/packages/api-client/src/fetchers/index.js +0 -22
  138. package/dist/packages/api-client/src/fetchers/orders.d.ts +0 -544
  139. package/dist/packages/api-client/src/fetchers/orders.js +0 -44
  140. package/dist/packages/api-client/src/fetchers/products.d.ts +0 -386
  141. package/dist/packages/api-client/src/fetchers/products.js +0 -42
  142. package/dist/packages/api-client/src/hooks/admin/abandoned-carts.d.ts +0 -535
  143. package/dist/packages/api-client/src/hooks/admin/abandoned-carts.js +0 -83
  144. package/dist/packages/api-client/src/hooks/admin/brands.d.ts +0 -79
  145. package/dist/packages/api-client/src/hooks/admin/brands.js +0 -108
  146. package/dist/packages/api-client/src/hooks/admin/customers.d.ts +0 -280
  147. package/dist/packages/api-client/src/hooks/admin/customers.js +0 -26
  148. package/dist/packages/api-client/src/hooks/admin/delivery-zones.d.ts +0 -278
  149. package/dist/packages/api-client/src/hooks/admin/delivery-zones.js +0 -176
  150. package/dist/packages/api-client/src/hooks/admin/discount-codes.d.ts +0 -299
  151. package/dist/packages/api-client/src/hooks/admin/discount-codes.js +0 -165
  152. package/dist/packages/api-client/src/hooks/admin/index.d.ts +0 -16
  153. package/dist/packages/api-client/src/hooks/admin/index.js +0 -16
  154. package/dist/packages/api-client/src/hooks/admin/inventory.d.ts +0 -224
  155. package/dist/packages/api-client/src/hooks/admin/inventory.js +0 -107
  156. package/dist/packages/api-client/src/hooks/admin/orders.d.ts +0 -1674
  157. package/dist/packages/api-client/src/hooks/admin/orders.js +0 -178
  158. package/dist/packages/api-client/src/hooks/admin/products.d.ts +0 -374
  159. package/dist/packages/api-client/src/hooks/admin/products.js +0 -89
  160. package/dist/packages/api-client/src/hooks/admin/stats.d.ts +0 -279
  161. package/dist/packages/api-client/src/hooks/admin/stats.js +0 -25
  162. package/dist/packages/api-client/src/hooks/admin/variants.d.ts +0 -115
  163. package/dist/packages/api-client/src/hooks/admin/variants.js +0 -127
  164. package/dist/packages/api-client/src/hooks/admin/warehouses.d.ts +0 -277
  165. package/dist/packages/api-client/src/hooks/admin/warehouses.js +0 -108
  166. package/dist/packages/api-client/src/hooks/public/brands.d.ts +0 -33
  167. package/dist/packages/api-client/src/hooks/public/brands.js +0 -30
  168. package/dist/packages/api-client/src/hooks/public/carts.d.ts +0 -2407
  169. package/dist/packages/api-client/src/hooks/public/carts.js +0 -213
  170. package/dist/packages/api-client/src/hooks/public/delivery-zones.d.ts +0 -36
  171. package/dist/packages/api-client/src/hooks/public/delivery-zones.js +0 -28
  172. package/dist/packages/api-client/src/hooks/public/index.d.ts +0 -10
  173. package/dist/packages/api-client/src/hooks/public/index.js +0 -10
  174. package/dist/packages/api-client/src/hooks/public/orders.d.ts +0 -563
  175. package/dist/packages/api-client/src/hooks/public/orders.js +0 -50
  176. package/dist/packages/api-client/src/hooks/public/products.d.ts +0 -398
  177. package/dist/packages/api-client/src/hooks/public/products.js +0 -47
  178. package/dist/packages/api-client/src/hooks/use-query-unwrapped.d.ts +0 -20
  179. package/dist/packages/api-client/src/hooks/use-query-unwrapped.js +0 -22
  180. package/dist/packages/api-client/src/hooks/useApiConfig.d.ts +0 -12
  181. package/dist/packages/api-client/src/hooks/useApiConfig.js +0 -14
  182. package/dist/packages/api-client/src/index.d.ts +0 -20
  183. package/dist/packages/api-client/src/index.js +0 -25
  184. package/dist/packages/api-client/src/provider.d.ts +0 -36
  185. package/dist/packages/api-client/src/provider.js +0 -54
  186. package/dist/packages/api-client/src/rpc-client.d.ts +0 -9639
  187. package/dist/packages/api-client/src/rpc-client.js +0 -78
  188. package/dist/packages/api-client/src/rpc-types.d.ts +0 -76
  189. package/dist/packages/api-client/src/rpc-types.js +0 -7
  190. package/dist/packages/api-client/src/types.d.ts +0 -34
  191. package/dist/packages/api-client/src/types.js +0 -16
  192. package/dist/packages/api-client/src/utils/query-keys.d.ts +0 -106
  193. package/dist/packages/api-client/src/utils/query-keys.js +0 -108
@@ -1,24 +0,0 @@
1
- import { formatBrandResponse } from "./brand-response";
2
- import { toNumber } from "./utils";
3
- export function formatStateResponse(state) {
4
- return {
5
- ...state,
6
- zonesCount: state.deliveryZones?.length || 0,
7
- createdAt: state.createdAt.toISOString(),
8
- updatedAt: state.updatedAt.toISOString(),
9
- deletedAt: state.deletedAt ? state.deletedAt.toISOString() : null,
10
- };
11
- }
12
- export function formatDeliveryZoneResponse(deliveryZone) {
13
- return {
14
- ...deliveryZone,
15
- deliveryCost: toNumber(deliveryZone.deliveryCost),
16
- freeShippingThreshold: deliveryZone.freeShippingThreshold ? toNumber(deliveryZone.freeShippingThreshold) : null,
17
- createdAt: deliveryZone.createdAt.toISOString(),
18
- updatedAt: deliveryZone.updatedAt.toISOString(),
19
- deletedAt: deliveryZone.deletedAt ? deliveryZone.deletedAt.toISOString() : null,
20
- brand: deliveryZone.brand ? formatBrandResponse(deliveryZone.brand) : null,
21
- stateName: deliveryZone.state?.name || '',
22
- brandName: deliveryZone.brand?.name || null,
23
- };
24
- }
@@ -1,42 +0,0 @@
1
- import type { Prisma } from "@prisma/client";
2
- export type DiscountCodeDBResponse = Prisma.DiscountCodeGetPayload<{
3
- include: {
4
- brand: true;
5
- };
6
- }>;
7
- export declare function formatDiscountCodeResponse(discountCode: DiscountCodeDBResponse): {
8
- value: number;
9
- minPurchase: number;
10
- maxDiscount: number;
11
- createdAt: string;
12
- updatedAt: string;
13
- deletedAt: string;
14
- brand: {
15
- createdAt: string;
16
- updatedAt: string;
17
- deletedAt: string;
18
- id: string;
19
- name: string;
20
- slug: string;
21
- logoUrl: string | null;
22
- siteUrl: string;
23
- domain: string;
24
- metaPixelId: string | null;
25
- };
26
- isExpired: boolean;
27
- usagePercentage: number;
28
- id: string;
29
- type: string;
30
- brandId: string | null;
31
- isActive: boolean;
32
- code: string;
33
- usageLimit: number | null;
34
- usageCount: number;
35
- perCustomerLimit: number | null;
36
- validFrom: Date;
37
- validUntil: Date | null;
38
- isAutoApply: boolean;
39
- description: string | null;
40
- category: string;
41
- createdBy: string | null;
42
- };
@@ -1,19 +0,0 @@
1
- import { formatBrandResponse } from "./brand-response";
2
- import { toNumber } from "./utils";
3
- export function formatDiscountCodeResponse(discountCode) {
4
- const now = new Date();
5
- return {
6
- ...discountCode,
7
- value: toNumber(discountCode.value),
8
- minPurchase: discountCode.minPurchase ? toNumber(discountCode.minPurchase) : null,
9
- maxDiscount: discountCode.maxDiscount ? toNumber(discountCode.maxDiscount) : null,
10
- createdAt: discountCode.createdAt.toISOString(),
11
- updatedAt: discountCode.updatedAt.toISOString(),
12
- deletedAt: discountCode.deletedAt ? discountCode.deletedAt.toISOString() : null,
13
- brand: discountCode.brand ? formatBrandResponse(discountCode.brand) : null,
14
- isExpired: discountCode.validUntil ? discountCode.validUntil < now : false,
15
- usagePercentage: discountCode.usageLimit
16
- ? (discountCode.usageCount / discountCode.usageLimit) * 100
17
- : null,
18
- };
19
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Discount code generation and validation utilities
3
- */
4
- /**
5
- * Generate a unique discount code for abandoned cart recovery
6
- * Format: CART{RANDOM8} (e.g., CART5A9F3B2E)
7
- */
8
- export declare function generateDiscountCode(): string;
9
- /**
10
- * Calculate discount amount based on cart recovery attempt
11
- */
12
- export declare function getRecoveryDiscountPercentage(attemptNumber: number): number;
13
- /**
14
- * Calculate discount amount in currency
15
- */
16
- export declare function calculateDiscountAmount(subtotal: number, discountPercent: number): number;
17
- /**
18
- * Validate discount code format
19
- */
20
- export declare function isValidDiscountCodeFormat(code: string): boolean;
@@ -1,35 +0,0 @@
1
- /**
2
- * Discount code generation and validation utilities
3
- */
4
- import { RECOVERY_SCHEDULE } from './cart-recovery';
5
- /**
6
- * Generate a unique discount code for abandoned cart recovery
7
- * Format: CART{RANDOM8} (e.g., CART5A9F3B2E)
8
- */
9
- export function generateDiscountCode() {
10
- const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // Excluding similar characters
11
- let code = 'CART';
12
- for (let i = 0; i < 8; i++) {
13
- code += chars.charAt(Math.floor(Math.random() * chars.length));
14
- }
15
- return code;
16
- }
17
- /**
18
- * Calculate discount amount based on cart recovery attempt
19
- */
20
- export function getRecoveryDiscountPercentage(attemptNumber) {
21
- const schedule = RECOVERY_SCHEDULE.find((s) => s.attemptNumber === attemptNumber);
22
- return schedule ? schedule.discountPercent : 0;
23
- }
24
- /**
25
- * Calculate discount amount in currency
26
- */
27
- export function calculateDiscountAmount(subtotal, discountPercent) {
28
- return Math.round(subtotal * (discountPercent / 100));
29
- }
30
- /**
31
- * Validate discount code format
32
- */
33
- export function isValidDiscountCodeFormat(code) {
34
- return /^CART[A-Z2-9]{8}$/.test(code);
35
- }
@@ -1,26 +0,0 @@
1
- import { PrismaClient, InventoryTransactionType } from '@prisma/client';
2
- export interface InventoryAdjustment {
3
- variantId: string;
4
- warehouseId: string;
5
- quantity: number;
6
- type: InventoryTransactionType;
7
- reason?: string;
8
- userId?: string;
9
- metadata?: any;
10
- orderId?: string;
11
- }
12
- export declare function adjustInventory(prisma: PrismaClient, adjustment: InventoryAdjustment): Promise<void>;
13
- export declare function transferInventory(prisma: PrismaClient, params: {
14
- variantId: string;
15
- fromWarehouseId: string;
16
- toWarehouseId: string;
17
- quantity: number;
18
- userId?: string;
19
- reason?: string;
20
- }): Promise<void>;
21
- export declare function getTotalInventoryForVariant(prisma: PrismaClient, variantId: string): Promise<number>;
22
- export declare function checkInventoryAvailability(prisma: PrismaClient, variantId: string, requiredQuantity: number, warehouseId?: string): Promise<{
23
- available: boolean;
24
- totalInventory: number;
25
- }>;
26
- export declare function getLowStockVariants(prisma: PrismaClient, brandId?: string): Promise<any[]>;
@@ -1,160 +0,0 @@
1
- export async function adjustInventory(prisma, adjustment) {
2
- const { variantId, warehouseId, quantity, type, reason, userId, metadata, orderId } = adjustment;
3
- // Get current inventory
4
- let inventory = await prisma.warehouseInventory.findUnique({
5
- where: {
6
- variantId_warehouseId: {
7
- variantId,
8
- warehouseId,
9
- },
10
- },
11
- });
12
- // Create inventory record if it doesn't exist
13
- if (!inventory) {
14
- inventory = await prisma.warehouseInventory.create({
15
- data: {
16
- variantId,
17
- warehouseId,
18
- inventoryCount: 0,
19
- },
20
- });
21
- }
22
- // Calculate new balance
23
- const balanceAfter = inventory.inventoryCount + quantity;
24
- // TODO:Prevent negative inventory (optional - can be configured per variant)
25
- if (balanceAfter < 0) {
26
- // throw new Error('Insufficient inventory');
27
- }
28
- // Update inventory count
29
- await prisma.warehouseInventory.update({
30
- where: {
31
- variantId_warehouseId: {
32
- variantId,
33
- warehouseId,
34
- },
35
- },
36
- data: {
37
- inventoryCount: balanceAfter,
38
- },
39
- });
40
- // Create transaction record
41
- await prisma.inventoryTransaction.create({
42
- data: {
43
- variantId,
44
- warehouseId,
45
- type,
46
- quantity,
47
- balanceAfter,
48
- reason,
49
- userId,
50
- metadata,
51
- orderId,
52
- },
53
- });
54
- }
55
- export async function transferInventory(prisma, params) {
56
- const { variantId, fromWarehouseId, toWarehouseId, quantity, userId, reason } = params;
57
- if (quantity <= 0) {
58
- throw new Error('Transfer quantity must be positive');
59
- }
60
- const metadata = {
61
- transferFrom: fromWarehouseId,
62
- transferTo: toWarehouseId,
63
- transferQuantity: quantity,
64
- };
65
- // Use transaction to ensure atomicity
66
- await prisma.$transaction(async (tx) => {
67
- // Decrement from source warehouse
68
- await adjustInventory(tx, {
69
- variantId,
70
- warehouseId: fromWarehouseId,
71
- quantity: -quantity,
72
- type: 'transfer_out',
73
- reason: reason || `Transfer to ${toWarehouseId}`,
74
- userId,
75
- metadata,
76
- });
77
- // Increment to destination warehouse
78
- await adjustInventory(tx, {
79
- variantId,
80
- warehouseId: toWarehouseId,
81
- quantity: quantity,
82
- type: 'transfer_in',
83
- reason: reason || `Transfer from ${fromWarehouseId}`,
84
- userId,
85
- metadata,
86
- });
87
- });
88
- }
89
- export async function getTotalInventoryForVariant(prisma, variantId) {
90
- const inventories = await prisma.warehouseInventory.findMany({
91
- where: { variantId },
92
- });
93
- return inventories.reduce((sum, inv) => sum + inv.inventoryCount, 0);
94
- }
95
- export async function checkInventoryAvailability(prisma, variantId, requiredQuantity, warehouseId) {
96
- let totalInventory = 0;
97
- if (warehouseId) {
98
- // Check specific warehouse
99
- const inventory = await prisma.warehouseInventory.findUnique({
100
- where: {
101
- variantId_warehouseId: {
102
- variantId,
103
- warehouseId,
104
- },
105
- },
106
- });
107
- totalInventory = inventory?.inventoryCount || 0;
108
- }
109
- else {
110
- // Check total across all warehouses
111
- totalInventory = await getTotalInventoryForVariant(prisma, variantId);
112
- }
113
- return {
114
- available: totalInventory >= requiredQuantity,
115
- totalInventory,
116
- };
117
- }
118
- export async function getLowStockVariants(prisma, brandId) {
119
- const where = {
120
- trackInventory: true,
121
- lowStockThreshold: { not: null },
122
- deletedAt: null,
123
- };
124
- if (brandId) {
125
- where.product = { brandId };
126
- }
127
- const variants = await prisma.productVariant.findMany({
128
- where,
129
- include: {
130
- product: {
131
- include: { brand: true },
132
- },
133
- warehouseInventories: {
134
- include: { warehouse: true },
135
- },
136
- },
137
- });
138
- // Filter variants where total inventory is below threshold
139
- const lowStockVariants = variants.filter((variant) => {
140
- const totalInventory = variant.warehouseInventories.reduce((sum, inv) => sum + inv.inventoryCount, 0);
141
- return totalInventory < (variant.lowStockThreshold || 0);
142
- });
143
- return lowStockVariants.map((variant) => {
144
- const totalInventory = variant.warehouseInventories.reduce((sum, inv) => sum + inv.inventoryCount, 0);
145
- return {
146
- id: variant.id,
147
- sku: variant.sku,
148
- productName: variant.product.name,
149
- name: variant.name,
150
- brandName: variant.product.brand.name,
151
- totalInventory,
152
- threshold: variant.lowStockThreshold,
153
- warehouses: variant.warehouseInventories.map((inv) => ({
154
- warehouseId: inv.warehouseId,
155
- warehouseName: inv.warehouse.name,
156
- inventory: inv.inventoryCount,
157
- })),
158
- };
159
- });
160
- }
@@ -1,53 +0,0 @@
1
- /**
2
- * Meta Conversions API (CAPI) Service
3
- *
4
- * Sends server-side events to Meta for conversion tracking.
5
- * Used alongside browser pixel for maximum reliability and iOS 14+ compliance.
6
- */
7
- export type MetaEventName = 'AddToCart' | 'InitiateCheckout' | 'Purchase' | 'ViewContent' | 'ConfirmedPurchase';
8
- export interface MetaCapiQueueMessage {
9
- pixelId: string;
10
- eventName: MetaEventName;
11
- eventId: string;
12
- eventTime: number;
13
- eventSourceUrl: string;
14
- userData: {
15
- email?: string;
16
- phone?: string;
17
- firstName?: string;
18
- lastName?: string;
19
- city?: string;
20
- state?: string;
21
- country?: string;
22
- zipCode?: string;
23
- clientIpAddress?: string;
24
- clientUserAgent?: string;
25
- fbc?: string;
26
- fbp?: string;
27
- };
28
- customData: {
29
- value?: number;
30
- currency?: string;
31
- contentIds?: string[];
32
- contents?: Array<{
33
- id: string;
34
- quantity: number;
35
- item_price: number;
36
- }>;
37
- contentType?: string;
38
- numItems?: number;
39
- contentName?: string;
40
- };
41
- }
42
- /**
43
- * Send event to Meta Conversions API
44
- *
45
- * @param accessToken - Meta Access Token (from Cloudflare secrets)
46
- * @param message - Queue message with event data
47
- */
48
- export declare function sendMetaCapiEvent(accessToken: string, message: MetaCapiQueueMessage): Promise<void>;
49
- /**
50
- * Helper to generate event ID for deduplication
51
- * Uses existing DB IDs to ensure same event from browser and server have same ID
52
- */
53
- export declare function generateEventId(type: 'cart' | 'order', id: string, suffix?: string): string;
@@ -1,151 +0,0 @@
1
- /**
2
- * Meta Conversions API (CAPI) Service
3
- *
4
- * Sends server-side events to Meta for conversion tracking.
5
- * Used alongside browser pixel for maximum reliability and iOS 14+ compliance.
6
- */
7
- import crypto from 'crypto';
8
- import { captureException } from './sentry';
9
- /**
10
- * Hash data with SHA256 for Meta CAPI
11
- * Meta requires PII to be hashed before sending
12
- */
13
- function hashData(data) {
14
- // Normalize: lowercase and trim whitespace
15
- const normalized = data.toLowerCase().trim();
16
- return crypto.createHash('sha256').update(normalized).digest('hex');
17
- }
18
- /**
19
- * Normalize phone number to E.164 format
20
- * Meta requires: country code + digits only (no spaces, dashes, etc.)
21
- */
22
- function normalizePhone(phone) {
23
- // Remove all non-digit characters
24
- let digits = phone.replace(/\D/g, '');
25
- // If starts with 0, assume Nigerian number and add +234
26
- if (digits.startsWith('0')) {
27
- digits = '234' + digits.slice(1);
28
- }
29
- // If doesn't start with country code, assume Nigerian
30
- if (!digits.startsWith('234')) {
31
- digits = '234' + digits;
32
- }
33
- return digits;
34
- }
35
- /**
36
- * Send event to Meta Conversions API
37
- *
38
- * @param accessToken - Meta Access Token (from Cloudflare secrets)
39
- * @param message - Queue message with event data
40
- */
41
- export async function sendMetaCapiEvent(accessToken, message) {
42
- const { pixelId, eventName, eventId, eventTime, eventSourceUrl, userData, customData } = message;
43
- // Build user_data with hashed PII
44
- const user_data = {
45
- client_ip_address: userData.clientIpAddress,
46
- client_user_agent: userData.clientUserAgent,
47
- fbc: userData.fbc,
48
- fbp: userData.fbp,
49
- };
50
- // Hash email if provided
51
- if (userData.email) {
52
- user_data.em = [hashData(userData.email)];
53
- }
54
- // Hash phone if provided
55
- if (userData.phone) {
56
- const normalized = normalizePhone(userData.phone);
57
- user_data.ph = [hashData(normalized)];
58
- }
59
- // Hash name if provided
60
- if (userData.firstName) {
61
- user_data.fn = [hashData(userData.firstName)];
62
- }
63
- if (userData.lastName) {
64
- user_data.ln = [hashData(userData.lastName)];
65
- }
66
- // Hash location if provided
67
- if (userData.city) {
68
- user_data.ct = [hashData(userData.city)];
69
- }
70
- if (userData.state) {
71
- user_data.st = [hashData(userData.state)];
72
- }
73
- if (userData.zipCode) {
74
- user_data.zp = [hashData(userData.zipCode)];
75
- }
76
- if (userData.country) {
77
- user_data.country = [hashData(userData.country)];
78
- }
79
- // Build event
80
- const event = {
81
- event_name: eventName,
82
- event_time: eventTime,
83
- event_id: eventId,
84
- event_source_url: eventSourceUrl,
85
- action_source: 'website',
86
- user_data,
87
- custom_data: customData,
88
- };
89
- // Send to Meta CAPI
90
- const url = `https://graph.facebook.com/v21.0/${pixelId}/events`;
91
- const response = await fetch(url, {
92
- method: 'POST',
93
- headers: {
94
- 'Content-Type': 'application/json',
95
- },
96
- body: JSON.stringify({
97
- data: [event],
98
- access_token: accessToken,
99
- }),
100
- });
101
- if (!response.ok) {
102
- const error = await response.text();
103
- const metaError = new Error(`Meta CAPI error: ${response.status} ${error}`);
104
- // Capture Meta CAPI HTTP errors
105
- captureException(metaError, {
106
- level: 'warning', // Non-blocking for users
107
- tags: {
108
- error_type: 'meta_capi_http_error',
109
- event_name: message.eventName,
110
- pixel_id: message.pixelId,
111
- http_status: response.status.toString(),
112
- },
113
- extra: {
114
- eventId: message.eventId,
115
- responseBody: error,
116
- },
117
- });
118
- throw metaError;
119
- }
120
- const result = await response.json();
121
- // Log if Meta returned any errors
122
- if (result.events_received !== 1) {
123
- console.error('[Meta CAPI] Event not received:', result);
124
- const receiveError = new Error('Meta CAPI did not receive event');
125
- // Capture event not received errors
126
- captureException(receiveError, {
127
- level: 'warning',
128
- tags: {
129
- error_type: 'meta_capi_event_not_received',
130
- event_name: message.eventName,
131
- pixel_id: message.pixelId,
132
- },
133
- extra: {
134
- eventId: message.eventId,
135
- eventsReceived: result.events_received,
136
- response: result,
137
- },
138
- });
139
- throw receiveError;
140
- }
141
- }
142
- /**
143
- * Helper to generate event ID for deduplication
144
- * Uses existing DB IDs to ensure same event from browser and server have same ID
145
- */
146
- export function generateEventId(type, id, suffix) {
147
- if (type === 'order') {
148
- return suffix ? `order_${id}_${suffix}` : `order_${id}`;
149
- }
150
- return suffix ? `cart_${id}_${suffix}` : `cart_${id}`;
151
- }
@@ -1,36 +0,0 @@
1
- import { OpenAPIHono } from '@hono/zod-openapi';
2
- import { AppContext } from '../types';
3
- /**
4
- * Create a new OpenAPI-enabled Hono app instance
5
- * This extends the standard Hono with OpenAPI documentation capabilities
6
- */
7
- export declare function createOpenAPIApp(): OpenAPIHono<AppContext, {}, "/">;
8
- /**
9
- * OpenAPI documentation configuration
10
- */
11
- export declare const openapiConfig: {
12
- openapi: string;
13
- info: {
14
- title: string;
15
- version: string;
16
- description: string;
17
- };
18
- servers: {
19
- url: string;
20
- description: string;
21
- }[];
22
- tags: {
23
- name: string;
24
- description: string;
25
- }[];
26
- components: {
27
- securitySchemes: {
28
- clerkAuth: {
29
- type: string;
30
- scheme: string;
31
- bearerFormat: string;
32
- description: string;
33
- };
34
- };
35
- };
36
- };
@@ -1,69 +0,0 @@
1
- import { OpenAPIHono } from '@hono/zod-openapi';
2
- /**
3
- * Create a new OpenAPI-enabled Hono app instance
4
- * This extends the standard Hono with OpenAPI documentation capabilities
5
- */
6
- export function createOpenAPIApp() {
7
- return new OpenAPIHono({
8
- defaultHook: (result, c) => {
9
- if (!result.success) {
10
- return c.json({
11
- success: false,
12
- error: {
13
- code: 'VALIDATION_ERROR',
14
- message: 'Request validation failed',
15
- details: 'error' in result ? result.error.flatten() : undefined,
16
- },
17
- }, 400);
18
- }
19
- },
20
- });
21
- }
22
- /**
23
- * OpenAPI documentation configuration
24
- */
25
- export const openapiConfig = {
26
- openapi: '3.1.0',
27
- info: {
28
- title: 'OMS API',
29
- version: '1.0.0',
30
- description: 'Order Management System API - A comprehensive e-commerce backend',
31
- },
32
- servers: [
33
- {
34
- url: 'https://api.example.com',
35
- description: 'Production server',
36
- },
37
- {
38
- url: 'http://localhost:8787',
39
- description: 'Local development server',
40
- },
41
- ],
42
- tags: [
43
- { name: 'Public - Orders', description: 'Public order tracking endpoints' },
44
- { name: 'Public - Products', description: 'Public product catalog endpoints' },
45
- { name: 'Public - Carts', description: 'Public shopping cart endpoints' },
46
- { name: 'Public - Delivery Zones', description: 'Public delivery zone endpoints' },
47
- { name: 'Admin - Orders', description: 'Admin order management endpoints' },
48
- { name: 'Admin - Products', description: 'Admin product management endpoints' },
49
- { name: 'Admin - Brands', description: 'Admin brand management endpoints' },
50
- { name: 'Admin - Variants', description: 'Admin variant management endpoints' },
51
- { name: 'Admin - Warehouses', description: 'Admin warehouse management endpoints' },
52
- { name: 'Admin - Inventory', description: 'Admin inventory management endpoints' },
53
- { name: 'Admin - Customers', description: 'Admin customer management endpoints' },
54
- { name: 'Admin - Stats', description: 'Admin statistics endpoints' },
55
- { name: 'Admin - Abandoned Carts', description: 'Admin abandoned cart management endpoints' },
56
- { name: 'Admin - Discount Codes', description: 'Admin discount code management endpoints' },
57
- { name: 'Admin - Delivery Zones', description: 'Admin delivery zone management endpoints' },
58
- ],
59
- components: {
60
- securitySchemes: {
61
- clerkAuth: {
62
- type: 'http',
63
- scheme: 'bearer',
64
- bearerFormat: 'JWT',
65
- description: 'Clerk JWT token for admin authentication',
66
- },
67
- },
68
- },
69
- };