order-management 0.0.20 → 0.0.22
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.
- package/.medusa/server/src/admin/index.js +439 -413
- package/.medusa/server/src/admin/index.mjs +439 -413
- package/.medusa/server/src/api/admin/swaps/[id]/approve/route.js +69 -31
- package/.medusa/server/src/api/admin/swaps/health/route.js +150 -0
- package/.medusa/server/src/api/admin/swaps/route.js +6 -12
- package/.medusa/server/src/api/admin/swaps/validators.js +9 -13
- package/.medusa/server/src/api/store/orders/[order_id]/swaps/route.js +47 -2
- package/.medusa/server/src/api/store/swaps/[id]/cancel/route.js +8 -1
- package/.medusa/server/src/api/store/swaps/[id]/route.js +15 -4
- package/.medusa/server/src/api/store/swaps/route.js +53 -10
- package/.medusa/server/src/helpers/swaps.js +1 -1
- package/.medusa/server/src/modules/swap/migrations/Migration20260123144734.js +29 -0
- package/.medusa/server/src/modules/swap/migrations/Migration20260123162423.js +48 -0
- package/.medusa/server/src/modules/swap/migrations/Migration20260126114640.js +48 -0
- package/.medusa/server/src/modules/swap/models/swap.js +7 -2
- package/.medusa/server/src/modules/swap/service.js +259 -32
- package/.medusa/server/src/subscribers/exchange-created.js +171 -0
- package/.medusa/server/src/workflows/steps/swap/create-medusa-exchange-step.js +153 -19
- package/.medusa/server/src/workflows/steps/swap/create-medusa-return-step.js +62 -6
- package/.medusa/server/src/workflows/steps/swap/create-swap-step.js +7 -12
- package/.medusa/server/src/workflows/steps/swap/index.js +6 -4
- package/.medusa/server/src/workflows/steps/swap/rollback-return-step.js +70 -0
- package/.medusa/server/src/workflows/steps/swap/sync-medusa-status-step.js +49 -3
- package/.medusa/server/src/workflows/steps/swap/update-swap-exchange-details-step.js +27 -0
- package/.medusa/server/src/workflows/steps/swap/validate-eligibility-step.js +9 -4
- package/.medusa/server/src/workflows/steps/swap/validate-order-step.js +24 -1
- package/.medusa/server/src/workflows/swaps/approve-swap-workflow.js +19 -3
- package/.medusa/server/src/workflows/swaps/create-swap-workflow.js +3 -1
- package/.medusa/server/src/workflows/swaps/execute-swap-workflow.js +26 -4
- package/package.json +1 -1
- package/.medusa/server/src/api/admin/swaps/[id]/process-payment/route.js +0 -152
- package/.medusa/server/src/api/admin/swaps/[id]/status/route.js +0 -45
- package/.medusa/server/src/api/admin/swaps/[id]/sync/route.js +0 -148
- package/.medusa/server/src/workflows/steps/swap/handle-payment-difference-step.js +0 -102
|
@@ -8,28 +8,178 @@ class SwapService extends (0, utils_1.MedusaService)({ Swap: swap_1.Swap }) {
|
|
|
8
8
|
this.manager_ = container.manager;
|
|
9
9
|
this.logger_ = container.logger;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to parse and normalize swap items arrays
|
|
13
|
+
* Handles both array format and JSONB format from database
|
|
14
|
+
*/
|
|
15
|
+
parseSwapItems(items) {
|
|
16
|
+
if (!items)
|
|
17
|
+
return [];
|
|
18
|
+
if (Array.isArray(items)) {
|
|
19
|
+
return items.map((item) => ({
|
|
20
|
+
id: String(item.id || item.item_id || ""),
|
|
21
|
+
quantity: Number(item.quantity || 0),
|
|
22
|
+
reason: item.reason ? String(item.reason) : undefined,
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
// If it's a JSON string, parse it
|
|
26
|
+
if (typeof items === "string") {
|
|
27
|
+
try {
|
|
28
|
+
const parsed = JSON.parse(items);
|
|
29
|
+
return Array.isArray(parsed) ? this.parseSwapItems(parsed) : [];
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Helper function to parse and normalize new items arrays
|
|
39
|
+
*/
|
|
40
|
+
parseNewItems(items) {
|
|
41
|
+
if (!items)
|
|
42
|
+
return [];
|
|
43
|
+
if (Array.isArray(items)) {
|
|
44
|
+
return items.map((item) => ({
|
|
45
|
+
variant_id: String(item.variant_id || ""),
|
|
46
|
+
quantity: Number(item.quantity || 0),
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
// If it's a JSON string, parse it
|
|
50
|
+
if (typeof items === "string") {
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(items);
|
|
53
|
+
return Array.isArray(parsed) ? this.parseNewItems(parsed) : [];
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Helper function to normalize and compare swap items arrays
|
|
63
|
+
*/
|
|
64
|
+
normalizeSwapItems(items) {
|
|
65
|
+
return JSON.stringify(items
|
|
66
|
+
.map((item) => ({ id: item.id, quantity: item.quantity }))
|
|
67
|
+
.sort((a, b) => a.id.localeCompare(b.id)));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Helper function to normalize and compare new items arrays
|
|
71
|
+
*/
|
|
72
|
+
normalizeNewItems(items) {
|
|
73
|
+
return JSON.stringify(items
|
|
74
|
+
.map((item) => ({ variant_id: item.variant_id, quantity: item.quantity }))
|
|
75
|
+
.sort((a, b) => a.variant_id.localeCompare(b.variant_id)));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check for duplicate swaps with the same return_items and new_items
|
|
79
|
+
* This is called both in validateEligibility and createSwap to prevent race conditions
|
|
80
|
+
*
|
|
81
|
+
* Note: Uses pagination to handle orders with many swaps.
|
|
82
|
+
* If an order has more than 1000 swaps, we check in batches.
|
|
83
|
+
*/
|
|
84
|
+
async checkForDuplicateSwap(orderId, returnItems, newItems) {
|
|
85
|
+
// Check for ALL existing swaps for the same order (not just pending ones)
|
|
86
|
+
// This prevents creating duplicate swap requests regardless of status
|
|
87
|
+
// Use pagination to handle orders with many swaps
|
|
88
|
+
const batchSize = 1000;
|
|
89
|
+
let skip = 0;
|
|
90
|
+
let hasMore = true;
|
|
91
|
+
const allSwapsArray = [];
|
|
92
|
+
while (hasMore) {
|
|
93
|
+
const batch = await this.listSwaps({
|
|
94
|
+
order_id: orderId,
|
|
95
|
+
}, {
|
|
96
|
+
take: batchSize,
|
|
97
|
+
skip,
|
|
98
|
+
});
|
|
99
|
+
const batchArray = Array.isArray(batch) ? batch : batch ? [batch] : [];
|
|
100
|
+
allSwapsArray.push(...batchArray);
|
|
101
|
+
// If we got fewer results than batchSize, we've reached the end
|
|
102
|
+
hasMore = batchArray.length === batchSize;
|
|
103
|
+
skip += batchSize;
|
|
104
|
+
}
|
|
105
|
+
const swapsArray = allSwapsArray;
|
|
106
|
+
// Normalize current swap items for comparison
|
|
107
|
+
const currentReturnItemsNormalized = this.normalizeSwapItems(returnItems);
|
|
108
|
+
const currentNewItemsNormalized = this.normalizeNewItems(newItems);
|
|
109
|
+
this.logger_?.info(`Checking for duplicate swap: order_id=${orderId}, existing_swaps=${swapsArray.length}`);
|
|
110
|
+
// Check each existing swap for exact duplicates
|
|
111
|
+
for (const existingSwap of swapsArray) {
|
|
112
|
+
const swapData = existingSwap;
|
|
113
|
+
// Parse the stored data (might be JSONB format)
|
|
114
|
+
const existingReturnItems = this.parseSwapItems(swapData.return_items);
|
|
115
|
+
const existingNewItems = this.parseNewItems(swapData.new_items);
|
|
116
|
+
// Skip if no items found (shouldn't happen, but defensive)
|
|
117
|
+
if (existingReturnItems.length === 0 || existingNewItems.length === 0) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Normalize existing swap items for comparison
|
|
121
|
+
const existingReturnItemsNormalized = this.normalizeSwapItems(existingReturnItems);
|
|
122
|
+
const existingNewItemsNormalized = this.normalizeNewItems(existingNewItems);
|
|
123
|
+
// Check for exact match (both return_items AND new_items must match)
|
|
124
|
+
if (currentReturnItemsNormalized === existingReturnItemsNormalized &&
|
|
125
|
+
currentNewItemsNormalized === existingNewItemsNormalized) {
|
|
126
|
+
const status = swapData.status || "unknown";
|
|
127
|
+
this.logger_?.warn(`Duplicate swap detected: order_id=${orderId}, existing_swap_id=${swapData.id}, status=${status}`);
|
|
128
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `A swap request with the same return items and new items already exists for this order (ID: ${swapData.id}, status: ${status}). Please use the existing swap request instead.`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
11
132
|
async createSwap(input) {
|
|
12
|
-
const { order_id, return_items, new_items, reason, note } = input;
|
|
133
|
+
const { order_id, customer_id, return_items, new_items, difference_due, reason, note } = input;
|
|
134
|
+
if (!customer_id) {
|
|
135
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Customer ID is required");
|
|
136
|
+
}
|
|
13
137
|
if (!return_items || return_items.length === 0) {
|
|
14
138
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Return items are required");
|
|
15
139
|
}
|
|
16
140
|
if (!new_items || new_items.length === 0) {
|
|
17
141
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "New items are required");
|
|
18
142
|
}
|
|
143
|
+
// CRITICAL: Check for duplicates BEFORE creating to prevent race conditions
|
|
144
|
+
// This is called again here even though validateEligibility also checks,
|
|
145
|
+
// because there's a time window between validation and creation where
|
|
146
|
+
// another request could create a duplicate
|
|
147
|
+
//
|
|
148
|
+
// Note: This check reduces but doesn't eliminate race conditions.
|
|
149
|
+
// For complete protection, consider:
|
|
150
|
+
// 1. Database-level unique constraint on (order_id, return_items_hash, new_items_hash)
|
|
151
|
+
// 2. Application-level distributed locking (Redis, etc.)
|
|
152
|
+
// 3. Optimistic locking with version field
|
|
153
|
+
this.logger_?.info(`Creating swap: order_id=${order_id}, customer_id=${customer_id}, checking for duplicates before creation`);
|
|
154
|
+
try {
|
|
155
|
+
await this.checkForDuplicateSwap(order_id, return_items, new_items);
|
|
156
|
+
this.logger_?.info(`No duplicates found, proceeding with swap creation: order_id=${order_id}`);
|
|
157
|
+
}
|
|
158
|
+
catch (duplicateError) {
|
|
159
|
+
// Re-throw duplicate errors with more context
|
|
160
|
+
if (duplicateError instanceof utils_1.MedusaError && duplicateError.type === utils_1.MedusaError.Types.DUPLICATE_ERROR) {
|
|
161
|
+
throw duplicateError;
|
|
162
|
+
}
|
|
163
|
+
// If it's a different error, wrap it
|
|
164
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.DUPLICATE_ERROR, `Duplicate swap detected for order ${order_id}. This may be due to concurrent requests.`);
|
|
165
|
+
}
|
|
19
166
|
const swap = await this.createSwaps({
|
|
20
167
|
order_id,
|
|
168
|
+
customer_id,
|
|
21
169
|
status: "requested",
|
|
22
170
|
return_items: return_items,
|
|
23
171
|
new_items: new_items,
|
|
24
|
-
difference_due: 0, //
|
|
172
|
+
difference_due: difference_due ?? 0, // Use provided difference_due or default to 0
|
|
25
173
|
reason: reason || null,
|
|
26
174
|
note: note || null,
|
|
27
175
|
metadata: {
|
|
28
176
|
created_at: new Date().toISOString(),
|
|
177
|
+
customer_id, // Store in metadata for redundancy and audit trail
|
|
29
178
|
status_history: [
|
|
30
179
|
{
|
|
31
180
|
status: "requested",
|
|
32
181
|
timestamp: new Date().toISOString(),
|
|
182
|
+
customer_id,
|
|
33
183
|
},
|
|
34
184
|
],
|
|
35
185
|
},
|
|
@@ -113,15 +263,9 @@ class SwapService extends (0, utils_1.MedusaService)({ Swap: swap_1.Swap }) {
|
|
|
113
263
|
const currentStatus = swapData.status;
|
|
114
264
|
// Validate status transition
|
|
115
265
|
const validTransitions = {
|
|
116
|
-
requested: ["approved", "rejected"
|
|
117
|
-
approved: [
|
|
118
|
-
return_started: ["return_shipped", "cancelled"],
|
|
119
|
-
return_shipped: ["return_received", "cancelled"],
|
|
120
|
-
return_received: ["new_items_shipped", "cancelled"],
|
|
121
|
-
new_items_shipped: ["completed", "cancelled"],
|
|
266
|
+
requested: ["approved", "rejected"],
|
|
267
|
+
approved: [], // Terminal state (exchange created separately)
|
|
122
268
|
rejected: [], // Terminal state
|
|
123
|
-
completed: [], // Terminal state
|
|
124
|
-
cancelled: [], // Terminal state
|
|
125
269
|
};
|
|
126
270
|
const allowedTransitions = validTransitions[currentStatus] || [];
|
|
127
271
|
if (!allowedTransitions.includes(status)) {
|
|
@@ -159,33 +303,115 @@ class SwapService extends (0, utils_1.MedusaService)({ Swap: swap_1.Swap }) {
|
|
|
159
303
|
// For now, return stored value or 0 - this will be implemented in workflow step
|
|
160
304
|
return swapData.difference_due || 0;
|
|
161
305
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Rollback orphaned return - removes return_id from swap when exchange creation fails
|
|
308
|
+
* This is used when exchange creation fails after return creation
|
|
309
|
+
*/
|
|
310
|
+
async rollbackReturn(swapId, returnId, reason) {
|
|
311
|
+
const swap = await this.retrieveSwap(swapId);
|
|
312
|
+
const swapData = swap;
|
|
313
|
+
// Only rollback if return_id matches
|
|
314
|
+
if (swapData.return_id !== returnId) {
|
|
315
|
+
// Return already changed or doesn't match
|
|
316
|
+
return swap;
|
|
317
|
+
}
|
|
318
|
+
const swapMetadata = swapData.metadata || {};
|
|
319
|
+
const medusaIntegration = swapMetadata.medusa_integration || {};
|
|
320
|
+
const rollbackHistory = swapMetadata.rollback_history || [];
|
|
321
|
+
// Remove return_id from swap and log rollback
|
|
322
|
+
const updatedSwap = await this.updateSwaps({
|
|
323
|
+
selector: { id: swapId },
|
|
324
|
+
data: {
|
|
325
|
+
return_id: null,
|
|
326
|
+
metadata: {
|
|
327
|
+
...swapMetadata,
|
|
328
|
+
medusa_integration: {
|
|
329
|
+
...medusaIntegration,
|
|
330
|
+
return_id: null,
|
|
331
|
+
return_rollback_at: new Date().toISOString(),
|
|
332
|
+
return_rollback_reason: reason,
|
|
333
|
+
},
|
|
334
|
+
rollback_history: [
|
|
335
|
+
...rollbackHistory,
|
|
336
|
+
{
|
|
337
|
+
action: "rollback_return",
|
|
338
|
+
return_id: returnId,
|
|
339
|
+
reason,
|
|
340
|
+
timestamp: new Date().toISOString(),
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
},
|
|
344
|
+
},
|
|
169
345
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
346
|
+
return Array.isArray(updatedSwap) ? updatedSwap[0] : updatedSwap;
|
|
347
|
+
}
|
|
348
|
+
async validateEligibility(orderId, returnItems, newItems, orderItems) {
|
|
349
|
+
// 1. Check for exact duplicate swaps (same return_items + new_items)
|
|
350
|
+
// This uses the same logic as createSwap to ensure consistency
|
|
351
|
+
await this.checkForDuplicateSwap(orderId, returnItems, newItems);
|
|
352
|
+
// 2. Check quantity overlap for return items in PENDING swaps only
|
|
353
|
+
// Calculate total requested quantity per item across all pending swaps
|
|
354
|
+
// Use pagination to handle orders with many swaps
|
|
355
|
+
const batchSize = 1000;
|
|
356
|
+
let skip = 0;
|
|
357
|
+
let hasMore = true;
|
|
358
|
+
const allSwapsArray = [];
|
|
359
|
+
while (hasMore) {
|
|
360
|
+
const batch = await this.listSwaps({
|
|
361
|
+
order_id: orderId,
|
|
362
|
+
}, {
|
|
363
|
+
take: batchSize,
|
|
364
|
+
skip,
|
|
365
|
+
});
|
|
366
|
+
const batchArray = Array.isArray(batch) ? batch : batch ? [batch] : [];
|
|
367
|
+
allSwapsArray.push(...batchArray);
|
|
368
|
+
// If we got fewer results than batchSize, we've reached the end
|
|
369
|
+
hasMore = batchArray.length === batchSize;
|
|
370
|
+
skip += batchSize;
|
|
371
|
+
}
|
|
372
|
+
const swapsArray = allSwapsArray;
|
|
373
|
+
const pendingSwaps = swapsArray.filter((swap) => {
|
|
374
|
+
const swapData = swap;
|
|
375
|
+
const status = swapData.status || "";
|
|
376
|
+
return ["requested", "approved", "return_started"].includes(status);
|
|
377
|
+
});
|
|
378
|
+
const requestedQuantities = {};
|
|
379
|
+
// Sum quantities from existing pending swaps (parse the data first)
|
|
380
|
+
for (const existingSwap of pendingSwaps) {
|
|
173
381
|
const swapData = existingSwap;
|
|
174
|
-
const existingReturnItems = swapData.return_items;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Item ${returnItem.id} is already part of a pending swap for this order`);
|
|
180
|
-
}
|
|
382
|
+
const existingReturnItems = this.parseSwapItems(swapData.return_items);
|
|
383
|
+
for (const existingItem of existingReturnItems) {
|
|
384
|
+
if (existingItem.id && existingItem.quantity > 0) {
|
|
385
|
+
requestedQuantities[existingItem.id] =
|
|
386
|
+
(requestedQuantities[existingItem.id] || 0) + existingItem.quantity;
|
|
181
387
|
}
|
|
182
388
|
}
|
|
183
389
|
}
|
|
390
|
+
// Add current request quantities and validate against order quantities
|
|
391
|
+
for (const returnItem of returnItems) {
|
|
392
|
+
if (!returnItem.id || returnItem.quantity <= 0) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const orderItem = orderItems.find((item) => item.id === returnItem.id);
|
|
396
|
+
if (!orderItem) {
|
|
397
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Return item ${returnItem.id} not found in order`);
|
|
398
|
+
}
|
|
399
|
+
// STRICT CHECK: Prevent any item from being in multiple pending swaps
|
|
400
|
+
// This ensures no duplicate swap requests for the same item
|
|
401
|
+
if (requestedQuantities[returnItem.id] > 0) {
|
|
402
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Item ${returnItem.id} is already part of a pending swap for this order and cannot be included in another swap request`);
|
|
403
|
+
}
|
|
404
|
+
// Also validate quantity doesn't exceed available
|
|
405
|
+
if (returnItem.quantity > orderItem.quantity) {
|
|
406
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Item ${returnItem.id}: Requested quantity (${returnItem.quantity}) exceeds available quantity (${orderItem.quantity}) in order`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
184
409
|
}
|
|
185
410
|
async checkRateLimit(customerId, orderId) {
|
|
186
411
|
// Check for existing swaps by this customer for this order
|
|
187
412
|
const existingSwaps = await this.listSwaps({
|
|
188
413
|
order_id: orderId,
|
|
414
|
+
customer_id: customerId,
|
|
189
415
|
}, {
|
|
190
416
|
take: 100,
|
|
191
417
|
});
|
|
@@ -195,16 +421,17 @@ class SwapService extends (0, utils_1.MedusaService)({ Swap: swap_1.Swap }) {
|
|
|
195
421
|
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Maximum ${maxSwapsPerOrder} swaps allowed per order`);
|
|
196
422
|
}
|
|
197
423
|
// Check customer's total swap count (across all orders)
|
|
198
|
-
|
|
199
|
-
|
|
424
|
+
// Now we can filter directly by customer_id without joining with orders
|
|
425
|
+
const customerSwaps = await this.listSwaps({
|
|
426
|
+
customer_id: customerId,
|
|
427
|
+
}, {
|
|
428
|
+
take: 1000, // Reasonable limit for rate limiting check
|
|
200
429
|
});
|
|
201
430
|
const customerSwapsArray = Array.isArray(customerSwaps)
|
|
202
431
|
? customerSwaps
|
|
203
432
|
: customerSwaps
|
|
204
433
|
? [customerSwaps]
|
|
205
434
|
: [];
|
|
206
|
-
// Filter by customer (would need to join with order, simplified here)
|
|
207
|
-
// In a real implementation, you'd query orders with customer_id and then swaps
|
|
208
435
|
const maxSwapsPerCustomer = 20; // Configurable limit
|
|
209
436
|
const customerSwapCount = customerSwapsArray.length;
|
|
210
437
|
if (customerSwapCount >= maxSwapsPerCustomer) {
|
|
@@ -221,4 +448,4 @@ class SwapService extends (0, utils_1.MedusaService)({ Swap: swap_1.Swap }) {
|
|
|
221
448
|
}
|
|
222
449
|
}
|
|
223
450
|
exports.default = SwapService;
|
|
224
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3N3YXAvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFzRTtBQUN0RSx3Q0FBb0M7QUFrQ3BDLE1BQXFCLFdBQVksU0FBUSxJQUFBLHFCQUFhLEVBQUMsRUFBRSxJQUFJLEVBQUosV0FBSSxFQUFFLENBQUM7SUFJOUQsWUFBWSxTQUErQjtRQUN6QyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFBO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQTtJQUNqQyxDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFzQjtRQUNyQyxNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLEtBQUssQ0FBQTtRQUVqRSxJQUFJLENBQUMsWUFBWSxJQUFJLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDL0MsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsMkJBQTJCLENBQzVCLENBQUE7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHdCQUF3QixDQUN6QixDQUFBO1FBQ0gsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUNsQyxRQUFRO1lBQ1IsTUFBTSxFQUFFLFdBQVc7WUFDbkIsWUFBWSxFQUFFLFlBQWtEO1lBQ2hFLFNBQVMsRUFBRSxT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
|
|
451
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9tb2R1bGVzL3N3YXAvc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHFEQUFzRTtBQUN0RSx3Q0FBb0M7QUFvQ3BDLE1BQXFCLFdBQVksU0FBUSxJQUFBLHFCQUFhLEVBQUMsRUFBRSxJQUFJLEVBQUosV0FBSSxFQUFFLENBQUM7SUFJOUQsWUFBWSxTQUErQjtRQUN6QyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFBO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQTtJQUNqQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssY0FBYyxDQUFDLEtBQWM7UUFDbkMsSUFBSSxDQUFDLEtBQUs7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUNyQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzFCLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztnQkFDekMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDdEQsQ0FBQyxDQUFDLENBQUE7UUFDTCxDQUFDO1FBQ0Qsa0NBQWtDO1FBQ2xDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDO2dCQUNILE1B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
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.config = void 0;
|
|
4
|
+
exports.default = exchangeCreatedHandler;
|
|
5
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
|
+
const swap_1 = require("../modules/swap");
|
|
7
|
+
/**
|
|
8
|
+
* Subscriber handler for exchange created events
|
|
9
|
+
* Automatically links exchanges created by admin to approved swaps
|
|
10
|
+
*
|
|
11
|
+
* When an exchange is created, this subscriber:
|
|
12
|
+
* 1. Finds the swap with matching order_id and status "approved" without exchange_id
|
|
13
|
+
* 2. Links the exchange to the swap by updating exchange_id field
|
|
14
|
+
* 3. Stores linking timestamp in metadata
|
|
15
|
+
*/
|
|
16
|
+
async function exchangeCreatedHandler({ event: { data }, container, }) {
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
let retryCount = 0;
|
|
19
|
+
const maxRetries = 3;
|
|
20
|
+
const retryDelay = 1000; // 1 second base delay
|
|
21
|
+
// Log event received for verification
|
|
22
|
+
console.log("[Exchange Created Subscriber] Event received:", {
|
|
23
|
+
event_name: "exchange.created",
|
|
24
|
+
exchange_id: data.id,
|
|
25
|
+
order_id: data.order_id,
|
|
26
|
+
timestamp: new Date().toISOString(),
|
|
27
|
+
});
|
|
28
|
+
const executeWithRetry = async () => {
|
|
29
|
+
try {
|
|
30
|
+
const exchangeId = data.id;
|
|
31
|
+
const orderId = data.order_id;
|
|
32
|
+
if (!exchangeId) {
|
|
33
|
+
console.error("[Exchange Created Subscriber] No exchange ID found in event data");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!orderId) {
|
|
37
|
+
console.debug("[Exchange Created Subscriber] No order_id in exchange, skipping link");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const swapService = container.resolve(swap_1.SWAP_MODULE);
|
|
41
|
+
const remoteQuery = container.resolve(utils_1.ContainerRegistrationKeys.REMOTE_QUERY);
|
|
42
|
+
// Validate exchange exists in Medusa before processing
|
|
43
|
+
try {
|
|
44
|
+
const exchangeQuery = (0, utils_1.remoteQueryObjectFromString)({
|
|
45
|
+
entryPoint: "exchange",
|
|
46
|
+
fields: ["id", "order_id"],
|
|
47
|
+
filters: {
|
|
48
|
+
id: [exchangeId],
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const exchanges = await remoteQuery(exchangeQuery);
|
|
52
|
+
const exchangeArray = Array.isArray(exchanges) ? exchanges : exchanges ? [exchanges] : [];
|
|
53
|
+
const exchange = exchangeArray.find((e) => {
|
|
54
|
+
const eData = e;
|
|
55
|
+
return eData?.id === exchangeId;
|
|
56
|
+
});
|
|
57
|
+
if (!exchange) {
|
|
58
|
+
console.warn(`[Exchange Created Subscriber] Exchange ${exchangeId} not found in Medusa, skipping link`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (validationError) {
|
|
63
|
+
const validationErrorMessage = validationError instanceof Error ? validationError.message : String(validationError);
|
|
64
|
+
console.warn(`[Exchange Created Subscriber] Failed to validate exchange ${exchangeId}: ${validationErrorMessage}`);
|
|
65
|
+
// Continue processing even if validation fails (might be transient)
|
|
66
|
+
}
|
|
67
|
+
// Find swap by order_id where status is "approved" and exchange_id is null
|
|
68
|
+
let swaps;
|
|
69
|
+
let swap = null;
|
|
70
|
+
try {
|
|
71
|
+
swaps = await swapService.listSwaps({
|
|
72
|
+
order_id: orderId,
|
|
73
|
+
status: "approved",
|
|
74
|
+
}, { take: 10 });
|
|
75
|
+
const swapsArray = Array.isArray(swaps) ? swaps : swaps ? [swaps] : [];
|
|
76
|
+
// Find swap without exchange_id (not yet linked)
|
|
77
|
+
swap = swapsArray.find((s) => {
|
|
78
|
+
const swapData = s;
|
|
79
|
+
return !swapData.exchange_id;
|
|
80
|
+
}) || null;
|
|
81
|
+
}
|
|
82
|
+
catch (filterError) {
|
|
83
|
+
const errorMessage = filterError instanceof Error ? filterError.message : String(filterError);
|
|
84
|
+
console.warn(`[Exchange Created Subscriber] Failed to find swap: ${errorMessage}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!swap) {
|
|
88
|
+
// No unlinked approved swap found for this order
|
|
89
|
+
// This is expected if:
|
|
90
|
+
// - Exchange was created manually without a swap request
|
|
91
|
+
// - Swap is not approved yet
|
|
92
|
+
// - Swap already has an exchange_id
|
|
93
|
+
console.debug(`[Exchange Created Subscriber] No unlinked approved swap found for order ${orderId} and exchange ${exchangeId}`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const swapData = swap;
|
|
97
|
+
if (!swapData.id) {
|
|
98
|
+
console.error("[Exchange Created Subscriber] Swap found but missing ID");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Link exchange to swap
|
|
102
|
+
const swapMetadata = swapData.metadata || {};
|
|
103
|
+
const linkingHistory = swapMetadata.exchange_linking_history || [];
|
|
104
|
+
await swapService.updateSwaps({
|
|
105
|
+
selector: { id: swapData.id },
|
|
106
|
+
data: {
|
|
107
|
+
exchange_id: exchangeId,
|
|
108
|
+
metadata: {
|
|
109
|
+
...swapMetadata,
|
|
110
|
+
exchange_linking_history: [
|
|
111
|
+
...linkingHistory,
|
|
112
|
+
{
|
|
113
|
+
exchange_id: exchangeId,
|
|
114
|
+
linked_at: new Date().toISOString(),
|
|
115
|
+
linked_by: "exchange_created_subscriber",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
exchange_linked_at: new Date().toISOString(),
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
const duration = Date.now() - startTime;
|
|
123
|
+
console.log(`[Exchange Created Subscriber] Linked exchange ${exchangeId} to swap ${swapData.id}`, {
|
|
124
|
+
duration_ms: duration,
|
|
125
|
+
retry_count: retryCount,
|
|
126
|
+
order_id: orderId,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
131
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
132
|
+
// Retry logic with exponential backoff
|
|
133
|
+
if (retryCount < maxRetries) {
|
|
134
|
+
retryCount++;
|
|
135
|
+
const delay = retryDelay * Math.pow(2, retryCount - 1);
|
|
136
|
+
console.warn(`[Exchange Created Subscriber] Retry ${retryCount}/${maxRetries} after ${delay}ms:`, errorMessage);
|
|
137
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
138
|
+
return executeWithRetry();
|
|
139
|
+
}
|
|
140
|
+
console.error("[Exchange Created Subscriber] Error linking exchange to swap (max retries exceeded):", {
|
|
141
|
+
error: errorMessage,
|
|
142
|
+
stack: errorStack,
|
|
143
|
+
retry_count: retryCount,
|
|
144
|
+
exchange_id: data.id,
|
|
145
|
+
order_id: data.order_id,
|
|
146
|
+
});
|
|
147
|
+
// Don't throw - subscriber errors shouldn't break the exchange flow
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
await executeWithRetry();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Subscriber configuration
|
|
154
|
+
*
|
|
155
|
+
* Event Name: "exchange.created"
|
|
156
|
+
*
|
|
157
|
+
* This subscriber listens for exchange creation events in Medusa.
|
|
158
|
+
* When an exchange is created, it automatically links it to an approved swap
|
|
159
|
+
* if one exists for the same order.
|
|
160
|
+
*
|
|
161
|
+
* Event Data Structure Expected:
|
|
162
|
+
* {
|
|
163
|
+
* id: string (exchange ID)
|
|
164
|
+
* order_id?: string (order ID)
|
|
165
|
+
* [key: string]: unknown (other exchange fields)
|
|
166
|
+
* }
|
|
167
|
+
*/
|
|
168
|
+
exports.config = {
|
|
169
|
+
event: "exchange.created",
|
|
170
|
+
};
|
|
171
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhjaGFuZ2UtY3JlYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zdWJzY3JpYmVycy9leGNoYW5nZS1jcmVhdGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXFCQSx5Q0FxTEM7QUF6TUQscURBQWtHO0FBRWxHLDBDQUE2QztBQVM3Qzs7Ozs7Ozs7R0FRRztBQUNZLEtBQUssVUFBVSxzQkFBc0IsQ0FBQyxFQUNuRCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFDZixTQUFTLEdBQ2dDO0lBQ3pDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQTtJQUM1QixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUE7SUFDbEIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFBO0lBQ3BCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQSxDQUFDLHNCQUFzQjtJQUU5QyxzQ0FBc0M7SUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQ0FBK0MsRUFBRTtRQUMzRCxVQUFVLEVBQUUsa0JBQWtCO1FBQzlCLFdBQVcsRUFBRSxJQUFJLENBQUMsRUFBRTtRQUNwQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7UUFDdkIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO0tBQ3BDLENBQUMsQ0FBQTtJQUVGLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxJQUFtQixFQUFFO1FBQ2pELElBQUksQ0FBQztZQUNILE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUE7WUFDMUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQTtZQUU3QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQTtnQkFDakYsT0FBTTtZQUNSLENBQUM7WUFFRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxD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
|