@instockng/api-client 1.0.5 → 1.0.7

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 (49) hide show
  1. package/dist/apps/backend/src/lib/meta-capi.d.ts +1 -1
  2. package/dist/apps/backend/src/lib/meta-capi.js +1 -1
  3. package/dist/apps/backend/src/lib/order-recovery.d.ts +86 -0
  4. package/dist/apps/backend/src/lib/order-recovery.js +7 -2
  5. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.d.ts +7 -0
  6. package/dist/apps/backend/src/notifications/producers/meta-capi-producer.js +41 -0
  7. package/dist/apps/backend/src/routes/admin/orders.d.ts +310 -20
  8. package/dist/apps/backend/src/routes/admin/orders.js +26 -2
  9. package/dist/apps/backend/src/routes/public/orders.d.ts +288 -6
  10. package/dist/apps/backend/src/routes/public/orders.js +1 -1
  11. package/dist/apps/backend/src/validators/order.d.ts +6 -37
  12. package/dist/apps/backend/src/validators/order.js +6 -7
  13. package/dist/enum-types.d.ts +8 -0
  14. package/dist/enum-types.js +5 -0
  15. package/dist/fetchers/carts.js +5 -0
  16. package/dist/fetchers/orders.d.ts +258 -1
  17. package/dist/hooks/admin/abandoned-carts.js +12 -8
  18. package/dist/hooks/admin/brands.js +15 -10
  19. package/dist/hooks/admin/customers.js +3 -2
  20. package/dist/hooks/admin/delivery-zones.js +24 -16
  21. package/dist/hooks/admin/discount-codes.js +24 -16
  22. package/dist/hooks/admin/inventory.js +15 -10
  23. package/dist/hooks/admin/orders.d.ts +285 -3
  24. package/dist/hooks/admin/orders.js +24 -15
  25. package/dist/hooks/admin/products.js +15 -10
  26. package/dist/hooks/admin/stats.js +3 -2
  27. package/dist/hooks/admin/variants.js +18 -12
  28. package/dist/hooks/admin/warehouses.js +15 -10
  29. package/dist/hooks/public/orders.d.ts +258 -1
  30. package/dist/hooks/useApiConfig.d.ts +2 -1
  31. package/dist/hooks/useApiConfig.js +2 -2
  32. package/dist/packages/api-client/src/enum-types.d.ts +8 -0
  33. package/dist/packages/api-client/src/enum-types.js +5 -0
  34. package/dist/packages/api-client/src/fetchers/carts.js +5 -0
  35. package/dist/packages/api-client/src/fetchers/orders.d.ts +258 -1
  36. package/dist/packages/api-client/src/hooks/admin/orders.d.ts +285 -3
  37. package/dist/packages/api-client/src/hooks/admin/orders.js +7 -4
  38. package/dist/packages/api-client/src/hooks/public/orders.d.ts +258 -1
  39. package/dist/packages/api-client/src/rpc-client.d.ts +891 -319
  40. package/dist/packages/api-client/src/types.d.ts +1 -4
  41. package/dist/packages/api-client/src/utils/query-keys.d.ts +1 -1
  42. package/dist/packages/api-client/src/utils/query-keys.js +1 -1
  43. package/dist/provider.d.ts +7 -4
  44. package/dist/provider.js +5 -3
  45. package/dist/rpc-client.d.ts +891 -319
  46. package/dist/types.d.ts +1 -0
  47. package/dist/utils/query-keys.d.ts +1 -1
  48. package/dist/utils/query-keys.js +1 -1
  49. package/package.json +1 -1
@@ -4,7 +4,7 @@
4
4
  * Sends server-side events to Meta for conversion tracking.
5
5
  * Used alongside browser pixel for maximum reliability and iOS 14+ compliance.
6
6
  */
7
- export type MetaEventName = 'AddToCart' | 'InitiateCheckout' | 'Purchase' | 'ViewContent';
7
+ export type MetaEventName = 'AddToCart' | 'InitiateCheckout' | 'Purchase' | 'ViewContent' | 'ConfirmedPurchase';
8
8
  export interface MetaCapiQueueMessage {
9
9
  pixelId: string;
10
10
  eventName: MetaEventName;
@@ -114,7 +114,7 @@ export async function sendMetaCapiEvent(accessToken, message) {
114
114
  */
115
115
  export function generateEventId(type, id, suffix) {
116
116
  if (type === 'order') {
117
- return `order_${id}`;
117
+ return suffix ? `order_${id}_${suffix}` : `order_${id}`;
118
118
  }
119
119
  return suffix ? `cart_${id}_${suffix}` : `cart_${id}`;
120
120
  }
@@ -282,6 +282,92 @@ export declare function prepareOrderForRecoveryAttempt(prisma: PrismaClient, ord
282
282
  * Convert prospect order back to pending when customer confirms
283
283
  */
284
284
  export declare function confirmProspectOrder(prisma: PrismaClient, orderId: string, userActionToken: string): Promise<{
285
+ brand: {
286
+ name: string;
287
+ id: string;
288
+ slug: string;
289
+ logoUrl: string | null;
290
+ siteUrl: string;
291
+ domain: string;
292
+ metaPixelId: string | null;
293
+ createdAt: Date;
294
+ updatedAt: Date;
295
+ deletedAt: Date | null;
296
+ };
297
+ deliveryZone: {
298
+ state: {
299
+ name: string;
300
+ id: string;
301
+ createdAt: Date;
302
+ updatedAt: Date;
303
+ deletedAt: Date | null;
304
+ isActive: boolean;
305
+ };
306
+ } & {
307
+ name: string;
308
+ id: string;
309
+ createdAt: Date;
310
+ updatedAt: Date;
311
+ deletedAt: Date | null;
312
+ brandId: string | null;
313
+ stateId: string;
314
+ deliveryCost: import("@prisma/client/runtime/library").Decimal;
315
+ freeShippingThreshold: import("@prisma/client/runtime/library").Decimal | null;
316
+ allowCOD: boolean;
317
+ allowOnline: boolean;
318
+ waybillOnly: boolean;
319
+ estimatedDays: number | null;
320
+ isActive: boolean;
321
+ };
322
+ items: ({
323
+ warehouse: {
324
+ name: string;
325
+ id: string;
326
+ createdAt: Date;
327
+ updatedAt: Date;
328
+ deletedAt: Date | null;
329
+ isActive: boolean;
330
+ address: string | null;
331
+ city: string | null;
332
+ state: string | null;
333
+ };
334
+ variant: {
335
+ product: {
336
+ name: string;
337
+ id: string;
338
+ slug: string;
339
+ createdAt: Date;
340
+ updatedAt: Date;
341
+ deletedAt: Date | null;
342
+ brandId: string;
343
+ isActive: boolean;
344
+ description: string | null;
345
+ thumbnailUrl: string | null;
346
+ quantityDiscounts: import("@prisma/client/runtime/library").JsonValue | null;
347
+ };
348
+ } & {
349
+ name: string | null;
350
+ id: string;
351
+ createdAt: Date;
352
+ updatedAt: Date;
353
+ deletedAt: Date | null;
354
+ isActive: boolean;
355
+ thumbnailUrl: string | null;
356
+ productId: string;
357
+ sku: string;
358
+ price: import("@prisma/client/runtime/library").Decimal;
359
+ trackInventory: boolean;
360
+ lowStockThreshold: number | null;
361
+ };
362
+ } & {
363
+ id: string;
364
+ orderId: string;
365
+ variantId: string;
366
+ warehouseId: string | null;
367
+ quantity: number;
368
+ priceAtPurchase: import("@prisma/client/runtime/library").Decimal;
369
+ })[];
370
+ } & {
285
371
  id: string;
286
372
  email: string | null;
287
373
  createdAt: Date;
@@ -1,6 +1,7 @@
1
1
  import { OrderStatus, ProspectReason, NoteType } from '@prisma/client';
2
2
  import { subHours, addHours } from 'date-fns';
3
3
  import { generateDiscountCode } from './discount';
4
+ import { ORDER_INCLUDE_FULL } from './cart-helpers';
4
5
  // Recovery schedule configuration
5
6
  // Note: First email sent immediately after marking as prospect (since manual contact already attempted)
6
7
  export const PROSPECT_RECOVERY_SCHEDULE = [
@@ -200,7 +201,7 @@ export async function confirmProspectOrder(prisma, orderId, userActionToken) {
200
201
  updateData.discountAmount = discountAmount;
201
202
  }
202
203
  // Update order status
203
- const updatedOrder = await tx.order.update({
204
+ await tx.order.update({
204
205
  where: { id: orderId },
205
206
  data: updateData
206
207
  });
@@ -216,7 +217,11 @@ export async function confirmProspectOrder(prisma, orderId, userActionToken) {
216
217
  }
217
218
  }
218
219
  });
219
- return updatedOrder;
220
+ // Return the full order with all relations
221
+ return tx.order.findUnique({
222
+ where: { id: orderId },
223
+ include: ORDER_INCLUDE_FULL
224
+ });
220
225
  });
221
226
  }
222
227
  /**
@@ -53,3 +53,10 @@ export declare function enqueuePurchaseEvent(env: Env, order: OrderDBResponse, o
53
53
  fbc?: string;
54
54
  fbp?: string;
55
55
  }): Promise<void>;
56
+ /**
57
+ * Queue a ConfirmedPurchase event when order is delivered & paid
58
+ *
59
+ * This event tracks successful order completion (delivered + paid),
60
+ * which is a higher value conversion signal than initial purchase.
61
+ */
62
+ export declare function enqueueConfirmedPurchaseEvent(env: Env, order: OrderDBResponse): Promise<void>;
@@ -123,3 +123,44 @@ export async function enqueuePurchaseEvent(env, order, options) {
123
123
  await env.META_CAPI_QUEUE.send(message);
124
124
  console.log(`[Meta CAPI] Queued Purchase event: ${message.eventId}`);
125
125
  }
126
+ /**
127
+ * Queue a ConfirmedPurchase event when order is delivered & paid
128
+ *
129
+ * This event tracks successful order completion (delivered + paid),
130
+ * which is a higher value conversion signal than initial purchase.
131
+ */
132
+ export async function enqueueConfirmedPurchaseEvent(env, order) {
133
+ if (!env.META_CAPI_QUEUE) {
134
+ console.warn('[Meta CAPI] Queue not configured, skipping ConfirmedPurchase event');
135
+ return;
136
+ }
137
+ const pixelId = order.brand.metaPixelId;
138
+ if (!pixelId) {
139
+ console.log('[Meta CAPI] No pixel ID for brand, skipping ConfirmedPurchase event');
140
+ return;
141
+ }
142
+ const message = {
143
+ pixelId,
144
+ eventName: 'ConfirmedPurchase',
145
+ eventId: generateEventId('order', order.id, 'confirmed'),
146
+ eventTime: Math.floor(Date.now() / 1000),
147
+ eventSourceUrl: order.brand.siteUrl,
148
+ userData: {
149
+ email: order.email || undefined,
150
+ phone: order.phone,
151
+ firstName: order.firstName,
152
+ lastName: order.lastName,
153
+ city: order.city,
154
+ country: 'ng', // Nigeria
155
+ },
156
+ customData: {
157
+ value: Number(order.totalPrice),
158
+ currency: 'NGN',
159
+ contentIds: order.items.map((item) => item.variant.sku),
160
+ contentType: 'product',
161
+ numItems: order.items.reduce((sum, item) => sum + item.quantity, 0),
162
+ },
163
+ };
164
+ await env.META_CAPI_QUEUE.send(message);
165
+ console.log(`[Meta CAPI] Queued ConfirmedPurchase event: ${message.eventId}`);
166
+ }
@@ -572,20 +572,6 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
572
572
  } & {
573
573
  "/:id": {
574
574
  $get: {
575
- input: {
576
- param: {
577
- id: string;
578
- };
579
- };
580
- output: {
581
- error: {
582
- code: string;
583
- message: string;
584
- };
585
- };
586
- outputFormat: "json";
587
- status: 404;
588
- } | {
589
575
  input: {
590
576
  param: {
591
577
  id: string;
@@ -851,6 +837,20 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
851
837
  };
852
838
  outputFormat: "json";
853
839
  status: import("hono/utils/http-status").ContentfulStatusCode;
840
+ } | {
841
+ input: {
842
+ param: {
843
+ id: string;
844
+ };
845
+ };
846
+ output: {
847
+ error: {
848
+ code: string;
849
+ message: string;
850
+ };
851
+ };
852
+ outputFormat: "json";
853
+ status: 404;
854
854
  } | {
855
855
  input: {
856
856
  param: {
@@ -1438,18 +1438,308 @@ declare const app: import("hono/hono-base").HonoBase<AppContext, {
1438
1438
  id: string;
1439
1439
  };
1440
1440
  };
1441
- output: {};
1442
- outputFormat: string;
1443
- status: import("hono/utils/http-status").StatusCode;
1441
+ output: {
1442
+ subtotal: number;
1443
+ deliveryCharge: number;
1444
+ totalPrice: number;
1445
+ discountAmount: number;
1446
+ createdAt: string;
1447
+ updatedAt: string;
1448
+ deletedAt: string;
1449
+ prospectSince: string;
1450
+ lastRecoveryAttemptAt: string;
1451
+ brand: {
1452
+ createdAt: string;
1453
+ updatedAt: string;
1454
+ deletedAt: string;
1455
+ name: string;
1456
+ id: string;
1457
+ slug: string;
1458
+ logoUrl: string | null;
1459
+ siteUrl: string;
1460
+ domain: string;
1461
+ metaPixelId: string | null;
1462
+ };
1463
+ deliveryZone: {
1464
+ deliveryCost: number;
1465
+ freeShippingThreshold: number;
1466
+ createdAt: string;
1467
+ updatedAt: string;
1468
+ deletedAt: string;
1469
+ state: {
1470
+ createdAt: string;
1471
+ updatedAt: string;
1472
+ deletedAt: string;
1473
+ name: string;
1474
+ id: string;
1475
+ isActive: boolean;
1476
+ };
1477
+ name: string;
1478
+ id: string;
1479
+ brandId: string | null;
1480
+ stateId: string;
1481
+ allowCOD: boolean;
1482
+ allowOnline: boolean;
1483
+ waybillOnly: boolean;
1484
+ estimatedDays: number | null;
1485
+ isActive: boolean;
1486
+ };
1487
+ items: {
1488
+ priceAtPurchase: number;
1489
+ variant: {
1490
+ price: number;
1491
+ createdAt: string;
1492
+ updatedAt: string;
1493
+ deletedAt: string;
1494
+ product: {
1495
+ createdAt: string;
1496
+ updatedAt: string;
1497
+ deletedAt: string;
1498
+ name: string;
1499
+ id: string;
1500
+ slug: string;
1501
+ brandId: string;
1502
+ isActive: boolean;
1503
+ description: string | null;
1504
+ thumbnailUrl: string | null;
1505
+ quantityDiscounts: string | number | boolean | {
1506
+ [x: string]: string | number | boolean | /*elided*/ any | {
1507
+ [x: number]: string | number | boolean | /*elided*/ any | /*elided*/ any;
1508
+ length: number;
1509
+ toString: never;
1510
+ toLocaleString: never;
1511
+ pop: never;
1512
+ push: never;
1513
+ concat: never;
1514
+ join: never;
1515
+ reverse: never;
1516
+ shift: never;
1517
+ slice: never;
1518
+ sort: never;
1519
+ splice: never;
1520
+ unshift: never;
1521
+ indexOf: never;
1522
+ lastIndexOf: never;
1523
+ every: never;
1524
+ some: never;
1525
+ forEach: never;
1526
+ map: never;
1527
+ filter: never;
1528
+ reduce: never;
1529
+ reduceRight: never;
1530
+ find: never;
1531
+ findIndex: never;
1532
+ fill: never;
1533
+ copyWithin: never;
1534
+ entries: never;
1535
+ keys: never;
1536
+ values: never;
1537
+ includes: never;
1538
+ flatMap: never;
1539
+ flat: never;
1540
+ [Symbol.iterator]: never;
1541
+ readonly [Symbol.unscopables]: {
1542
+ [x: number]: boolean;
1543
+ length?: boolean;
1544
+ toString?: boolean;
1545
+ toLocaleString?: boolean;
1546
+ pop?: boolean;
1547
+ push?: boolean;
1548
+ concat?: boolean;
1549
+ join?: boolean;
1550
+ reverse?: boolean;
1551
+ shift?: boolean;
1552
+ slice?: boolean;
1553
+ sort?: boolean;
1554
+ splice?: boolean;
1555
+ unshift?: boolean;
1556
+ indexOf?: boolean;
1557
+ lastIndexOf?: boolean;
1558
+ every?: boolean;
1559
+ some?: boolean;
1560
+ forEach?: boolean;
1561
+ map?: boolean;
1562
+ filter?: boolean;
1563
+ reduce?: boolean;
1564
+ reduceRight?: boolean;
1565
+ find?: boolean;
1566
+ findIndex?: boolean;
1567
+ fill?: boolean;
1568
+ copyWithin?: boolean;
1569
+ entries?: boolean;
1570
+ keys?: boolean;
1571
+ values?: boolean;
1572
+ includes?: boolean;
1573
+ flatMap?: boolean;
1574
+ flat?: boolean;
1575
+ };
1576
+ };
1577
+ } | {
1578
+ [x: number]: string | number | boolean | {
1579
+ [x: string]: string | number | boolean | /*elided*/ any | /*elided*/ any;
1580
+ } | /*elided*/ any;
1581
+ length: number;
1582
+ toString: never;
1583
+ toLocaleString: never;
1584
+ pop: never;
1585
+ push: never;
1586
+ concat: never;
1587
+ join: never;
1588
+ reverse: never;
1589
+ shift: never;
1590
+ slice: never;
1591
+ sort: never;
1592
+ splice: never;
1593
+ unshift: never;
1594
+ indexOf: never;
1595
+ lastIndexOf: never;
1596
+ every: never;
1597
+ some: never;
1598
+ forEach: never;
1599
+ map: never;
1600
+ filter: never;
1601
+ reduce: never;
1602
+ reduceRight: never;
1603
+ find: never;
1604
+ findIndex: never;
1605
+ fill: never;
1606
+ copyWithin: never;
1607
+ entries: never;
1608
+ keys: never;
1609
+ values: never;
1610
+ includes: never;
1611
+ flatMap: never;
1612
+ flat: never;
1613
+ [Symbol.iterator]: never;
1614
+ readonly [Symbol.unscopables]: {
1615
+ [x: number]: boolean;
1616
+ length?: boolean;
1617
+ toString?: boolean;
1618
+ toLocaleString?: boolean;
1619
+ pop?: boolean;
1620
+ push?: boolean;
1621
+ concat?: boolean;
1622
+ join?: boolean;
1623
+ reverse?: boolean;
1624
+ shift?: boolean;
1625
+ slice?: boolean;
1626
+ sort?: boolean;
1627
+ splice?: boolean;
1628
+ unshift?: boolean;
1629
+ indexOf?: boolean;
1630
+ lastIndexOf?: boolean;
1631
+ every?: boolean;
1632
+ some?: boolean;
1633
+ forEach?: boolean;
1634
+ map?: boolean;
1635
+ filter?: boolean;
1636
+ reduce?: boolean;
1637
+ reduceRight?: boolean;
1638
+ find?: boolean;
1639
+ findIndex?: boolean;
1640
+ fill?: boolean;
1641
+ copyWithin?: boolean;
1642
+ entries?: boolean;
1643
+ keys?: boolean;
1644
+ values?: boolean;
1645
+ includes?: boolean;
1646
+ flatMap?: boolean;
1647
+ flat?: boolean;
1648
+ };
1649
+ };
1650
+ };
1651
+ name: string | null;
1652
+ id: string;
1653
+ isActive: boolean;
1654
+ thumbnailUrl: string | null;
1655
+ productId: string;
1656
+ sku: string;
1657
+ trackInventory: boolean;
1658
+ lowStockThreshold: number | null;
1659
+ };
1660
+ warehouse: {
1661
+ createdAt: string;
1662
+ updatedAt: string;
1663
+ deletedAt: string;
1664
+ name: string;
1665
+ id: string;
1666
+ isActive: boolean;
1667
+ address: string | null;
1668
+ city: string | null;
1669
+ state: string | null;
1670
+ };
1671
+ id: string;
1672
+ orderId: string;
1673
+ variantId: string;
1674
+ warehouseId: string | null;
1675
+ quantity: number;
1676
+ }[];
1677
+ id: string;
1678
+ email: string | null;
1679
+ brandId: string;
1680
+ deliveryZoneId: string;
1681
+ recoveryAttempts: number;
1682
+ recoveryDiscountCodeId: string | null;
1683
+ wasRecovered: boolean;
1684
+ estimatedDays: number | null;
1685
+ orderNumber: number;
1686
+ firstName: string;
1687
+ lastName: string;
1688
+ phone: string;
1689
+ address: string;
1690
+ city: string;
1691
+ discountCodeId: string | null;
1692
+ paymentMethod: import("@prisma/client").$Enums.PaymentMethod;
1693
+ paystackReference: string | null;
1694
+ status: import("@prisma/client").$Enums.OrderStatus;
1695
+ cancellationReason: string | null;
1696
+ prospectReason: import("@prisma/client").$Enums.ProspectReason | null;
1697
+ userActionToken: string;
1698
+ };
1699
+ outputFormat: "json";
1700
+ status: import("hono/utils/http-status").ContentfulStatusCode;
1444
1701
  } | {
1445
1702
  input: {
1446
1703
  param: {
1447
1704
  id: string;
1448
1705
  };
1449
1706
  };
1450
- output: {};
1451
- outputFormat: string;
1452
- status: import("hono/utils/http-status").StatusCode;
1707
+ output: {
1708
+ error: {
1709
+ code: string;
1710
+ message: string;
1711
+ };
1712
+ };
1713
+ outputFormat: "json";
1714
+ status: 404;
1715
+ } | {
1716
+ input: {
1717
+ param: {
1718
+ id: string;
1719
+ };
1720
+ };
1721
+ output: {
1722
+ error: {
1723
+ code: string;
1724
+ message: string;
1725
+ };
1726
+ };
1727
+ outputFormat: "json";
1728
+ status: 400;
1729
+ } | {
1730
+ input: {
1731
+ param: {
1732
+ id: string;
1733
+ };
1734
+ };
1735
+ output: {
1736
+ error: {
1737
+ code: string;
1738
+ message: string;
1739
+ };
1740
+ };
1741
+ outputFormat: "json";
1742
+ status: 500;
1453
1743
  };
1454
1744
  };
1455
1745
  } & {
@@ -139,6 +139,7 @@ const app = new Hono()
139
139
  { phone: { contains: query.search } },
140
140
  { firstName: { contains: query.search, mode: 'insensitive' } },
141
141
  { lastName: { contains: query.search, mode: 'insensitive' } },
142
+ { address: { contains: query.search, mode: 'insensitive' } },
142
143
  ].filter((item) => Object.values(item).some((v) => v !== undefined));
143
144
  }
144
145
  if (query.startDate)
@@ -267,7 +268,7 @@ const app = new Hono()
267
268
  address: input.address ?? order.address,
268
269
  city: input.city ?? order.city,
269
270
  deliveryCharge,
270
- paymentMethod: input.paymentMethod ?? order.paymentMethod,
271
+ paymentMethod: (input.paymentMethod ?? order.paymentMethod),
271
272
  paystackReference: input.paystackReference ?? order.paystackReference,
272
273
  totalPrice,
273
274
  },
@@ -477,8 +478,31 @@ const app = new Hono()
477
478
  catch (error) {
478
479
  console.error('Failed to queue order status update notification:', error);
479
480
  }
481
+ // Queue Meta CAPI ConfirmedPurchase event when order is delivered & paid
482
+ if (newStatus === 'delivered' && previousStatus !== 'delivered') {
483
+ try {
484
+ const { enqueueConfirmedPurchaseEvent } = await import('../../notifications/producers/meta-capi-producer');
485
+ // Fetch full order details with items for the CAPI event
486
+ const fullOrder = await prisma.order.findFirst({
487
+ where: { id, deletedAt: null },
488
+ include: ORDER_INCLUDE_FULL,
489
+ });
490
+ if (fullOrder) {
491
+ await enqueueConfirmedPurchaseEvent(c.env, fullOrder);
492
+ }
493
+ }
494
+ catch (error) {
495
+ console.error('Failed to queue Meta CAPI ConfirmedPurchase event:', error);
496
+ // Don't fail the status update if CAPI queuing fails
497
+ }
498
+ }
480
499
  }
481
- return c.status(200);
500
+ // Fetch updated order to return
501
+ const updatedOrder = await prisma.order.findFirst({
502
+ where: { id, deletedAt: null },
503
+ include: ORDER_INCLUDE_FULL,
504
+ });
505
+ return c.json(formatOrderResponse(updatedOrder));
482
506
  }
483
507
  catch (error) {
484
508
  return c.json({