@instockng/api-client 1.0.4 → 1.0.6

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 (186) hide show
  1. package/dist/enum-types.d.ts +8 -0
  2. package/dist/enum-types.js +5 -0
  3. package/dist/fetchers/carts.js +5 -0
  4. package/dist/hooks/admin/abandoned-carts.js +12 -8
  5. package/dist/hooks/admin/brands.js +15 -10
  6. package/dist/hooks/admin/customers.js +3 -2
  7. package/dist/hooks/admin/delivery-zones.js +24 -16
  8. package/dist/hooks/admin/discount-codes.js +24 -16
  9. package/dist/hooks/admin/inventory.js +15 -10
  10. package/dist/hooks/admin/orders.js +18 -12
  11. package/dist/hooks/admin/products.js +15 -10
  12. package/dist/hooks/admin/stats.js +3 -2
  13. package/dist/hooks/admin/variants.js +18 -12
  14. package/dist/hooks/admin/warehouses.js +15 -10
  15. package/dist/hooks/useApiConfig.d.ts +2 -1
  16. package/dist/hooks/useApiConfig.js +2 -2
  17. package/dist/provider.d.ts +7 -4
  18. package/dist/provider.js +5 -3
  19. package/dist/types.d.ts +1 -0
  20. package/package.json +1 -1
  21. package/dist/apps/backend/src/generated/zod/index.d.ts +0 -1114
  22. package/dist/apps/backend/src/generated/zod/index.js +0 -670
  23. package/dist/apps/backend/src/http-app.d.ts +0 -40
  24. package/dist/apps/backend/src/http-app.js +0 -106
  25. package/dist/apps/backend/src/lib/brand-response.d.ts +0 -14
  26. package/dist/apps/backend/src/lib/brand-response.js +0 -8
  27. package/dist/apps/backend/src/lib/cart-helpers.d.ts +0 -280
  28. package/dist/apps/backend/src/lib/cart-helpers.js +0 -93
  29. package/dist/apps/backend/src/lib/cart-recovery.d.ts +0 -30
  30. package/dist/apps/backend/src/lib/cart-recovery.js +0 -147
  31. package/dist/apps/backend/src/lib/cart-response.d.ts +0 -121
  32. package/dist/apps/backend/src/lib/cart-response.js +0 -150
  33. package/dist/apps/backend/src/lib/clerk.d.ts +0 -18
  34. package/dist/apps/backend/src/lib/clerk.js +0 -167
  35. package/dist/apps/backend/src/lib/delivery-zone-response.d.ts +0 -62
  36. package/dist/apps/backend/src/lib/delivery-zone-response.js +0 -24
  37. package/dist/apps/backend/src/lib/discount-code-response.d.ts +0 -42
  38. package/dist/apps/backend/src/lib/discount-code-response.js +0 -19
  39. package/dist/apps/backend/src/lib/discount.d.ts +0 -20
  40. package/dist/apps/backend/src/lib/discount.js +0 -35
  41. package/dist/apps/backend/src/lib/inventory.d.ts +0 -26
  42. package/dist/apps/backend/src/lib/inventory.js +0 -160
  43. package/dist/apps/backend/src/lib/meta-capi.d.ts +0 -48
  44. package/dist/apps/backend/src/lib/meta-capi.js +0 -120
  45. package/dist/apps/backend/src/lib/openapi.d.ts +0 -36
  46. package/dist/apps/backend/src/lib/openapi.js +0 -69
  47. package/dist/apps/backend/src/lib/order-recovery.d.ts +0 -367
  48. package/dist/apps/backend/src/lib/order-recovery.js +0 -373
  49. package/dist/apps/backend/src/lib/order-response.d.ts +0 -136
  50. package/dist/apps/backend/src/lib/order-response.js +0 -61
  51. package/dist/apps/backend/src/lib/pricing.d.ts +0 -39
  52. package/dist/apps/backend/src/lib/pricing.js +0 -62
  53. package/dist/apps/backend/src/lib/prisma.d.ts +0 -9
  54. package/dist/apps/backend/src/lib/prisma.js +0 -30
  55. package/dist/apps/backend/src/lib/product-response.d.ts +0 -82
  56. package/dist/apps/backend/src/lib/product-response.js +0 -29
  57. package/dist/apps/backend/src/lib/utils.d.ts +0 -32
  58. package/dist/apps/backend/src/lib/utils.js +0 -63
  59. package/dist/apps/backend/src/middleware/clerk-auth.d.ts +0 -8
  60. package/dist/apps/backend/src/middleware/clerk-auth.js +0 -89
  61. package/dist/apps/backend/src/middleware/cors.d.ts +0 -8
  62. package/dist/apps/backend/src/middleware/cors.js +0 -11
  63. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.d.ts +0 -55
  64. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.js +0 -125
  65. package/dist/apps/backend/src/notifications/producers/order-notification.d.ts +0 -9
  66. package/dist/apps/backend/src/notifications/producers/order-notification.js +0 -18
  67. package/dist/apps/backend/src/notifications/producers/prospect-recovery-notification.d.ts +0 -10
  68. package/dist/apps/backend/src/notifications/producers/prospect-recovery-notification.js +0 -11
  69. package/dist/apps/backend/src/routes/admin/abandoned-carts.d.ts +0 -605
  70. package/dist/apps/backend/src/routes/admin/abandoned-carts.js +0 -194
  71. package/dist/apps/backend/src/routes/admin/brands.d.ts +0 -175
  72. package/dist/apps/backend/src/routes/admin/brands.js +0 -118
  73. package/dist/apps/backend/src/routes/admin/customers.d.ts +0 -306
  74. package/dist/apps/backend/src/routes/admin/customers.js +0 -39
  75. package/dist/apps/backend/src/routes/admin/delivery-zones.d.ts +0 -438
  76. package/dist/apps/backend/src/routes/admin/delivery-zones.js +0 -300
  77. package/dist/apps/backend/src/routes/admin/discount-codes.d.ts +0 -478
  78. package/dist/apps/backend/src/routes/admin/discount-codes.js +0 -418
  79. package/dist/apps/backend/src/routes/admin/inventory.d.ts +0 -273
  80. package/dist/apps/backend/src/routes/admin/inventory.js +0 -189
  81. package/dist/apps/backend/src/routes/admin/orders.d.ts +0 -1478
  82. package/dist/apps/backend/src/routes/admin/orders.js +0 -503
  83. package/dist/apps/backend/src/routes/admin/products.d.ts +0 -860
  84. package/dist/apps/backend/src/routes/admin/products.js +0 -107
  85. package/dist/apps/backend/src/routes/admin/stats.d.ts +0 -288
  86. package/dist/apps/backend/src/routes/admin/stats.js +0 -55
  87. package/dist/apps/backend/src/routes/admin/variants.d.ts +0 -239
  88. package/dist/apps/backend/src/routes/admin/variants.js +0 -173
  89. package/dist/apps/backend/src/routes/admin/warehouses.d.ts +0 -373
  90. package/dist/apps/backend/src/routes/admin/warehouses.js +0 -123
  91. package/dist/apps/backend/src/routes/public/brands.d.ts +0 -40
  92. package/dist/apps/backend/src/routes/public/brands.js +0 -38
  93. package/dist/apps/backend/src/routes/public/carts.d.ts +0 -2655
  94. package/dist/apps/backend/src/routes/public/carts.js +0 -631
  95. package/dist/apps/backend/src/routes/public/delivery-zones.d.ts +0 -35
  96. package/dist/apps/backend/src/routes/public/delivery-zones.js +0 -62
  97. package/dist/apps/backend/src/routes/public/orders.d.ts +0 -323
  98. package/dist/apps/backend/src/routes/public/orders.js +0 -160
  99. package/dist/apps/backend/src/routes/public/products.d.ts +0 -449
  100. package/dist/apps/backend/src/routes/public/products.js +0 -133
  101. package/dist/apps/backend/src/types/index.d.ts +0 -42
  102. package/dist/apps/backend/src/types/index.js +0 -2
  103. package/dist/apps/backend/src/validators/brand.d.ts +0 -17
  104. package/dist/apps/backend/src/validators/brand.js +0 -15
  105. package/dist/apps/backend/src/validators/delivery-zone.d.ts +0 -31
  106. package/dist/apps/backend/src/validators/delivery-zone.js +0 -51
  107. package/dist/apps/backend/src/validators/discount-code.d.ts +0 -74
  108. package/dist/apps/backend/src/validators/discount-code.js +0 -50
  109. package/dist/apps/backend/src/validators/inventory.d.ts +0 -20
  110. package/dist/apps/backend/src/validators/inventory.js +0 -15
  111. package/dist/apps/backend/src/validators/order.d.ts +0 -87
  112. package/dist/apps/backend/src/validators/order.js +0 -61
  113. package/dist/apps/backend/src/validators/product.d.ts +0 -18
  114. package/dist/apps/backend/src/validators/product.js +0 -19
  115. package/dist/apps/backend/src/validators/variant.d.ts +0 -19
  116. package/dist/apps/backend/src/validators/variant.js +0 -19
  117. package/dist/apps/backend/src/validators/warehouse.d.ts +0 -15
  118. package/dist/apps/backend/src/validators/warehouse.js +0 -15
  119. package/dist/packages/api-client/src/backend-types.d.ts +0 -10
  120. package/dist/packages/api-client/src/backend-types.js +0 -10
  121. package/dist/packages/api-client/src/client.d.ts +0 -20
  122. package/dist/packages/api-client/src/client.js +0 -40
  123. package/dist/packages/api-client/src/fetchers/brands.d.ts +0 -25
  124. package/dist/packages/api-client/src/fetchers/brands.js +0 -26
  125. package/dist/packages/api-client/src/fetchers/carts.d.ts +0 -2335
  126. package/dist/packages/api-client/src/fetchers/carts.js +0 -169
  127. package/dist/packages/api-client/src/fetchers/delivery-zones.d.ts +0 -28
  128. package/dist/packages/api-client/src/fetchers/delivery-zones.js +0 -26
  129. package/dist/packages/api-client/src/fetchers/index.d.ts +0 -22
  130. package/dist/packages/api-client/src/fetchers/index.js +0 -22
  131. package/dist/packages/api-client/src/fetchers/orders.d.ts +0 -283
  132. package/dist/packages/api-client/src/fetchers/orders.js +0 -44
  133. package/dist/packages/api-client/src/fetchers/products.d.ts +0 -386
  134. package/dist/packages/api-client/src/fetchers/products.js +0 -42
  135. package/dist/packages/api-client/src/hooks/admin/abandoned-carts.d.ts +0 -535
  136. package/dist/packages/api-client/src/hooks/admin/abandoned-carts.js +0 -79
  137. package/dist/packages/api-client/src/hooks/admin/brands.d.ts +0 -79
  138. package/dist/packages/api-client/src/hooks/admin/brands.js +0 -103
  139. package/dist/packages/api-client/src/hooks/admin/customers.d.ts +0 -278
  140. package/dist/packages/api-client/src/hooks/admin/customers.js +0 -25
  141. package/dist/packages/api-client/src/hooks/admin/delivery-zones.d.ts +0 -270
  142. package/dist/packages/api-client/src/hooks/admin/delivery-zones.js +0 -168
  143. package/dist/packages/api-client/src/hooks/admin/discount-codes.d.ts +0 -299
  144. package/dist/packages/api-client/src/hooks/admin/discount-codes.js +0 -157
  145. package/dist/packages/api-client/src/hooks/admin/index.d.ts +0 -16
  146. package/dist/packages/api-client/src/hooks/admin/index.js +0 -16
  147. package/dist/packages/api-client/src/hooks/admin/inventory.d.ts +0 -224
  148. package/dist/packages/api-client/src/hooks/admin/inventory.js +0 -102
  149. package/dist/packages/api-client/src/hooks/admin/orders.d.ts +0 -1380
  150. package/dist/packages/api-client/src/hooks/admin/orders.js +0 -169
  151. package/dist/packages/api-client/src/hooks/admin/products.d.ts +0 -374
  152. package/dist/packages/api-client/src/hooks/admin/products.js +0 -84
  153. package/dist/packages/api-client/src/hooks/admin/stats.d.ts +0 -277
  154. package/dist/packages/api-client/src/hooks/admin/stats.js +0 -24
  155. package/dist/packages/api-client/src/hooks/admin/variants.d.ts +0 -115
  156. package/dist/packages/api-client/src/hooks/admin/variants.js +0 -121
  157. package/dist/packages/api-client/src/hooks/admin/warehouses.d.ts +0 -277
  158. package/dist/packages/api-client/src/hooks/admin/warehouses.js +0 -103
  159. package/dist/packages/api-client/src/hooks/public/brands.d.ts +0 -33
  160. package/dist/packages/api-client/src/hooks/public/brands.js +0 -30
  161. package/dist/packages/api-client/src/hooks/public/carts.d.ts +0 -2405
  162. package/dist/packages/api-client/src/hooks/public/carts.js +0 -213
  163. package/dist/packages/api-client/src/hooks/public/delivery-zones.d.ts +0 -34
  164. package/dist/packages/api-client/src/hooks/public/delivery-zones.js +0 -28
  165. package/dist/packages/api-client/src/hooks/public/index.d.ts +0 -10
  166. package/dist/packages/api-client/src/hooks/public/index.js +0 -10
  167. package/dist/packages/api-client/src/hooks/public/orders.d.ts +0 -302
  168. package/dist/packages/api-client/src/hooks/public/orders.js +0 -50
  169. package/dist/packages/api-client/src/hooks/public/products.d.ts +0 -398
  170. package/dist/packages/api-client/src/hooks/public/products.js +0 -47
  171. package/dist/packages/api-client/src/hooks/use-query-unwrapped.d.ts +0 -20
  172. package/dist/packages/api-client/src/hooks/use-query-unwrapped.js +0 -22
  173. package/dist/packages/api-client/src/hooks/useApiConfig.d.ts +0 -11
  174. package/dist/packages/api-client/src/hooks/useApiConfig.js +0 -14
  175. package/dist/packages/api-client/src/index.d.ts +0 -20
  176. package/dist/packages/api-client/src/index.js +0 -25
  177. package/dist/packages/api-client/src/provider.d.ts +0 -33
  178. package/dist/packages/api-client/src/provider.js +0 -52
  179. package/dist/packages/api-client/src/rpc-client.d.ts +0 -9035
  180. package/dist/packages/api-client/src/rpc-client.js +0 -78
  181. package/dist/packages/api-client/src/rpc-types.d.ts +0 -76
  182. package/dist/packages/api-client/src/rpc-types.js +0 -7
  183. package/dist/packages/api-client/src/types.d.ts +0 -33
  184. package/dist/packages/api-client/src/types.js +0 -16
  185. package/dist/packages/api-client/src/utils/query-keys.d.ts +0 -106
  186. package/dist/packages/api-client/src/utils/query-keys.js +0 -108
@@ -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
- name: string;
19
- id: 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
- brandId: string | null;
30
- isActive: boolean;
31
- code: string;
32
- type: 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,48 +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';
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
- contentType?: string;
33
- numItems?: number;
34
- contentName?: string;
35
- };
36
- }
37
- /**
38
- * Send event to Meta Conversions API
39
- *
40
- * @param accessToken - Meta Access Token (from Cloudflare secrets)
41
- * @param message - Queue message with event data
42
- */
43
- export declare function sendMetaCapiEvent(accessToken: string, message: MetaCapiQueueMessage): Promise<void>;
44
- /**
45
- * Helper to generate event ID for deduplication
46
- * Uses existing DB IDs to ensure same event from browser and server have same ID
47
- */
48
- export declare function generateEventId(type: 'cart' | 'order', id: string, suffix?: string): string;
@@ -1,120 +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
- /**
9
- * Hash data with SHA256 for Meta CAPI
10
- * Meta requires PII to be hashed before sending
11
- */
12
- function hashData(data) {
13
- // Normalize: lowercase and trim whitespace
14
- const normalized = data.toLowerCase().trim();
15
- return crypto.createHash('sha256').update(normalized).digest('hex');
16
- }
17
- /**
18
- * Normalize phone number to E.164 format
19
- * Meta requires: country code + digits only (no spaces, dashes, etc.)
20
- */
21
- function normalizePhone(phone) {
22
- // Remove all non-digit characters
23
- let digits = phone.replace(/\D/g, '');
24
- // If starts with 0, assume Nigerian number and add +234
25
- if (digits.startsWith('0')) {
26
- digits = '234' + digits.slice(1);
27
- }
28
- // If doesn't start with country code, assume Nigerian
29
- if (!digits.startsWith('234')) {
30
- digits = '234' + digits;
31
- }
32
- return digits;
33
- }
34
- /**
35
- * Send event to Meta Conversions API
36
- *
37
- * @param accessToken - Meta Access Token (from Cloudflare secrets)
38
- * @param message - Queue message with event data
39
- */
40
- export async function sendMetaCapiEvent(accessToken, message) {
41
- const { pixelId, eventName, eventId, eventTime, eventSourceUrl, userData, customData } = message;
42
- // Build user_data with hashed PII
43
- const user_data = {
44
- client_ip_address: userData.clientIpAddress,
45
- client_user_agent: userData.clientUserAgent,
46
- fbc: userData.fbc,
47
- fbp: userData.fbp,
48
- };
49
- // Hash email if provided
50
- if (userData.email) {
51
- user_data.em = [hashData(userData.email)];
52
- }
53
- // Hash phone if provided
54
- if (userData.phone) {
55
- const normalized = normalizePhone(userData.phone);
56
- user_data.ph = [hashData(normalized)];
57
- }
58
- // Hash name if provided
59
- if (userData.firstName) {
60
- user_data.fn = [hashData(userData.firstName)];
61
- }
62
- if (userData.lastName) {
63
- user_data.ln = [hashData(userData.lastName)];
64
- }
65
- // Hash location if provided
66
- if (userData.city) {
67
- user_data.ct = [hashData(userData.city)];
68
- }
69
- if (userData.state) {
70
- user_data.st = [hashData(userData.state)];
71
- }
72
- if (userData.zipCode) {
73
- user_data.zp = [hashData(userData.zipCode)];
74
- }
75
- if (userData.country) {
76
- user_data.country = [hashData(userData.country)];
77
- }
78
- // Build event
79
- const event = {
80
- event_name: eventName,
81
- event_time: eventTime,
82
- event_id: eventId,
83
- event_source_url: eventSourceUrl,
84
- action_source: 'website',
85
- user_data,
86
- custom_data: customData,
87
- };
88
- // Send to Meta CAPI
89
- const url = `https://graph.facebook.com/v21.0/${pixelId}/events`;
90
- const response = await fetch(url, {
91
- method: 'POST',
92
- headers: {
93
- 'Content-Type': 'application/json',
94
- },
95
- body: JSON.stringify({
96
- data: [event],
97
- access_token: accessToken,
98
- }),
99
- });
100
- if (!response.ok) {
101
- const error = await response.text();
102
- throw new Error(`Meta CAPI error: ${response.status} ${error}`);
103
- }
104
- const result = await response.json();
105
- // Log if Meta returned any errors
106
- if (result.events_received !== 1) {
107
- console.error('[Meta CAPI] Event not received:', result);
108
- throw new Error('Meta CAPI did not receive event');
109
- }
110
- }
111
- /**
112
- * Helper to generate event ID for deduplication
113
- * Uses existing DB IDs to ensure same event from browser and server have same ID
114
- */
115
- export function generateEventId(type, id, suffix) {
116
- if (type === 'order') {
117
- return `order_${id}`;
118
- }
119
- return suffix ? `cart_${id}_${suffix}` : `cart_${id}`;
120
- }
@@ -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
- };