vr-commons 1.0.159 → 1.0.160
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Device, UserRole } from "vr-models";
|
|
2
2
|
import { Transaction } from "sequelize";
|
|
3
|
-
import {
|
|
3
|
+
import { DeviceResetOptions, DeviceResetResult, StockChangeResult } from "./types";
|
|
4
4
|
export declare const stockUtil: {
|
|
5
5
|
/**
|
|
6
6
|
* Increment stock when devices are added/created
|
|
@@ -121,9 +121,10 @@ export declare const stockUtil: {
|
|
|
121
121
|
devices: Device[];
|
|
122
122
|
}>;
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
125
|
-
* Locks both RIDER and PASSENGER devices in each pair together
|
|
126
|
-
*
|
|
124
|
+
* Reset device pairs status based on conditions
|
|
125
|
+
* - Locks/unlocks both RIDER and PASSENGER devices in each pair together
|
|
126
|
+
* - Flexible conditions and updates
|
|
127
|
+
* - Uses batch processing for large datasets
|
|
127
128
|
*/
|
|
128
|
-
|
|
129
|
+
resetAllDevicesStatus(options?: DeviceResetOptions): Promise<DeviceResetResult>;
|
|
129
130
|
};
|
|
@@ -17,6 +17,155 @@ const extractDedicationFromSerial = (serialNumber) => {
|
|
|
17
17
|
return "PASSENGER";
|
|
18
18
|
return "N/A";
|
|
19
19
|
};
|
|
20
|
+
// ==================== HELPER FUNCTIONS ====================
|
|
21
|
+
function buildWhereClause(condition) {
|
|
22
|
+
const parts = [];
|
|
23
|
+
if (condition.status) {
|
|
24
|
+
const statuses = Array.isArray(condition.status)
|
|
25
|
+
? condition.status
|
|
26
|
+
: [condition.status];
|
|
27
|
+
const quoted = statuses.map((s) => `'${s}'`).join(", ");
|
|
28
|
+
parts.push(`"status" IN (${quoted})`);
|
|
29
|
+
}
|
|
30
|
+
if (condition.excludeStatus) {
|
|
31
|
+
const statuses = Array.isArray(condition.excludeStatus)
|
|
32
|
+
? condition.excludeStatus
|
|
33
|
+
: [condition.excludeStatus];
|
|
34
|
+
const quoted = statuses.map((s) => `'${s}'`).join(", ");
|
|
35
|
+
parts.push(`"status" NOT IN (${quoted})`);
|
|
36
|
+
}
|
|
37
|
+
if (condition.isPermanentlyUnlocked !== undefined) {
|
|
38
|
+
parts.push(`"isPermanentlyUnlocked" = ${condition.isPermanentlyUnlocked}`);
|
|
39
|
+
}
|
|
40
|
+
if (condition.pairId) {
|
|
41
|
+
const pairIds = Array.isArray(condition.pairId)
|
|
42
|
+
? condition.pairId
|
|
43
|
+
: [condition.pairId];
|
|
44
|
+
const quoted = pairIds.map((p) => `'${p}'`).join(", ");
|
|
45
|
+
parts.push(`"pairId" IN (${quoted})`);
|
|
46
|
+
}
|
|
47
|
+
if (condition.excludePairIds) {
|
|
48
|
+
const pairIds = Array.isArray(condition.excludePairIds)
|
|
49
|
+
? condition.excludePairIds
|
|
50
|
+
: [condition.excludePairIds];
|
|
51
|
+
const quoted = pairIds.map((p) => `'${p}'`).join(", ");
|
|
52
|
+
parts.push(`"pairId" NOT IN (${quoted})`);
|
|
53
|
+
}
|
|
54
|
+
if (condition.productId) {
|
|
55
|
+
const productIds = Array.isArray(condition.productId)
|
|
56
|
+
? condition.productId
|
|
57
|
+
: [condition.productId];
|
|
58
|
+
const quoted = productIds.map((p) => `'${p}'`).join(", ");
|
|
59
|
+
parts.push(`"productId" IN (${quoted})`);
|
|
60
|
+
}
|
|
61
|
+
if (condition.dedicatedUser) {
|
|
62
|
+
const users = Array.isArray(condition.dedicatedUser)
|
|
63
|
+
? condition.dedicatedUser
|
|
64
|
+
: [condition.dedicatedUser];
|
|
65
|
+
const quoted = users.map((u) => `'${u}'`).join(", ");
|
|
66
|
+
parts.push(`"dedicatedUser" IN (${quoted})`);
|
|
67
|
+
}
|
|
68
|
+
if (condition.createdBefore) {
|
|
69
|
+
parts.push(`"createdAt" < '${condition.createdBefore.toISOString()}'`);
|
|
70
|
+
}
|
|
71
|
+
if (condition.createdAfter) {
|
|
72
|
+
parts.push(`"createdAt" > '${condition.createdAfter.toISOString()}'`);
|
|
73
|
+
}
|
|
74
|
+
return parts.length > 0 ? parts.join(" AND ") : "1=1";
|
|
75
|
+
}
|
|
76
|
+
function buildSequelizeWhere(condition) {
|
|
77
|
+
const where = {};
|
|
78
|
+
if (condition.status) {
|
|
79
|
+
where.status = {
|
|
80
|
+
[sequelize_1.Op.in]: Array.isArray(condition.status)
|
|
81
|
+
? condition.status
|
|
82
|
+
: [condition.status],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (condition.excludeStatus) {
|
|
86
|
+
where.status = {
|
|
87
|
+
...where.status,
|
|
88
|
+
[sequelize_1.Op.notIn]: Array.isArray(condition.excludeStatus)
|
|
89
|
+
? condition.excludeStatus
|
|
90
|
+
: [condition.excludeStatus],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (condition.isPermanentlyUnlocked !== undefined) {
|
|
94
|
+
where.isPermanentlyUnlocked = condition.isPermanentlyUnlocked;
|
|
95
|
+
}
|
|
96
|
+
if (condition.pairId) {
|
|
97
|
+
where.pairId = {
|
|
98
|
+
[sequelize_1.Op.in]: Array.isArray(condition.pairId)
|
|
99
|
+
? condition.pairId
|
|
100
|
+
: [condition.pairId],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (condition.excludePairIds) {
|
|
104
|
+
where.pairId = {
|
|
105
|
+
[sequelize_1.Op.notIn]: Array.isArray(condition.excludePairIds)
|
|
106
|
+
? condition.excludePairIds
|
|
107
|
+
: [condition.excludePairIds],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (condition.productId) {
|
|
111
|
+
where.productId = {
|
|
112
|
+
[sequelize_1.Op.in]: Array.isArray(condition.productId)
|
|
113
|
+
? condition.productId
|
|
114
|
+
: [condition.productId],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (condition.dedicatedUser) {
|
|
118
|
+
where.dedicatedUser = {
|
|
119
|
+
[sequelize_1.Op.in]: Array.isArray(condition.dedicatedUser)
|
|
120
|
+
? condition.dedicatedUser
|
|
121
|
+
: [condition.dedicatedUser],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (condition.createdBefore) {
|
|
125
|
+
where.createdAt = { [sequelize_1.Op.lt]: condition.createdBefore };
|
|
126
|
+
}
|
|
127
|
+
if (condition.createdAfter) {
|
|
128
|
+
where.createdAt = { ...where.createdAt, [sequelize_1.Op.gt]: condition.createdAfter };
|
|
129
|
+
}
|
|
130
|
+
return where;
|
|
131
|
+
}
|
|
132
|
+
function buildSetClause(update) {
|
|
133
|
+
const parts = [];
|
|
134
|
+
if (update.status !== undefined) {
|
|
135
|
+
parts.push(`"status" = '${update.status}'`);
|
|
136
|
+
}
|
|
137
|
+
if (update.isPermanentlyUnlocked !== undefined) {
|
|
138
|
+
parts.push(`"isPermanentlyUnlocked" = ${update.isPermanentlyUnlocked}`);
|
|
139
|
+
}
|
|
140
|
+
if (update.dedicatedUser !== undefined) {
|
|
141
|
+
parts.push(`"dedicatedUser" = '${update.dedicatedUser}'`);
|
|
142
|
+
}
|
|
143
|
+
if (update.devicePaymentPlanId !== undefined) {
|
|
144
|
+
parts.push(`"devicePaymentPlanId" = ${update.devicePaymentPlanId === null
|
|
145
|
+
? "NULL"
|
|
146
|
+
: `'${update.devicePaymentPlanId}'`}`);
|
|
147
|
+
}
|
|
148
|
+
if (update.activatedAt !== undefined) {
|
|
149
|
+
parts.push(`"activatedAt" = ${update.activatedAt === null
|
|
150
|
+
? "NULL"
|
|
151
|
+
: `'${update.activatedAt.toISOString()}'`}`);
|
|
152
|
+
}
|
|
153
|
+
return parts.length > 0 ? parts.join(", ") : "1=1";
|
|
154
|
+
}
|
|
155
|
+
function buildUpdateObject(update) {
|
|
156
|
+
const obj = {};
|
|
157
|
+
if (update.status !== undefined)
|
|
158
|
+
obj.status = update.status;
|
|
159
|
+
if (update.isPermanentlyUnlocked !== undefined)
|
|
160
|
+
obj.isPermanentlyUnlocked = update.isPermanentlyUnlocked;
|
|
161
|
+
if (update.dedicatedUser !== undefined)
|
|
162
|
+
obj.dedicatedUser = update.dedicatedUser;
|
|
163
|
+
if (update.devicePaymentPlanId !== undefined)
|
|
164
|
+
obj.devicePaymentPlanId = update.devicePaymentPlanId;
|
|
165
|
+
if (update.activatedAt !== undefined)
|
|
166
|
+
obj.activatedAt = update.activatedAt;
|
|
167
|
+
return obj;
|
|
168
|
+
}
|
|
20
169
|
exports.stockUtil = {
|
|
21
170
|
/**
|
|
22
171
|
* Increment stock when devices are added/created
|
|
@@ -453,41 +602,48 @@ exports.stockUtil = {
|
|
|
453
602
|
};
|
|
454
603
|
},
|
|
455
604
|
/**
|
|
456
|
-
*
|
|
457
|
-
* Locks both RIDER and PASSENGER devices in each pair together
|
|
458
|
-
*
|
|
605
|
+
* Reset device pairs status based on conditions
|
|
606
|
+
* - Locks/unlocks both RIDER and PASSENGER devices in each pair together
|
|
607
|
+
* - Flexible conditions and updates
|
|
608
|
+
* - Uses batch processing for large datasets
|
|
459
609
|
*/
|
|
460
|
-
async
|
|
461
|
-
const { actorId = "SYSTEM", actorRole = "SYSTEM", transaction, batchSize = 100, maxRetries = 3, triggeredBy = "manual", } = options;
|
|
610
|
+
async resetAllDevicesStatus(options = {}) {
|
|
611
|
+
const { actorId = "SYSTEM", actorRole = "SYSTEM", transaction, batchSize = 100, maxRetries = 3, triggeredBy = "manual", condition = {}, update = {}, } = options;
|
|
462
612
|
const isSystem = actorRole === "SYSTEM" || triggeredBy === "cronjob";
|
|
463
613
|
try {
|
|
464
|
-
const
|
|
614
|
+
const updatedPairIds = [];
|
|
465
615
|
const failedPairIds = [];
|
|
466
616
|
const errors = [];
|
|
467
|
-
|
|
617
|
+
const allDeviceIds = [];
|
|
618
|
+
let totalUpdatedDevices = 0;
|
|
468
619
|
let totalProcessedPairs = 0;
|
|
469
620
|
let batchNumber = 0;
|
|
470
621
|
let hasMore = true;
|
|
471
622
|
let offset = 0;
|
|
472
|
-
|
|
473
|
-
|
|
623
|
+
// Build WHERE clause for the query
|
|
624
|
+
const whereClause = buildWhereClause(condition);
|
|
625
|
+
// Build UPDATE SET clause
|
|
626
|
+
const setClause = buildSetClause(update);
|
|
627
|
+
console.log(`🔄 Resetting device pairs at ${new Date().toISOString()}`);
|
|
628
|
+
console.log(`📋 WHERE: ${whereClause}`);
|
|
629
|
+
console.log(`📝 SET: ${setClause}`);
|
|
630
|
+
// Log start
|
|
474
631
|
if (isSystem) {
|
|
475
|
-
await (0, systemLog_utils_1.logInfo)(`
|
|
632
|
+
await (0, systemLog_utils_1.logInfo)(`Reset device pairs job started`, {
|
|
476
633
|
category: "CRONJOB",
|
|
477
|
-
source: "device-
|
|
478
|
-
details: { triggeredBy, batchSize, maxRetries },
|
|
634
|
+
source: "device-reset.cronjob",
|
|
635
|
+
details: { triggeredBy, batchSize, maxRetries, condition, update },
|
|
479
636
|
});
|
|
480
637
|
}
|
|
481
638
|
else {
|
|
482
|
-
await (0, systemLog_utils_1.logInfo)(`
|
|
639
|
+
await (0, systemLog_utils_1.logInfo)(`Reset device pairs triggered by ${actorRole}`, {
|
|
483
640
|
category: "DEVICE",
|
|
484
641
|
userId: actorId || undefined,
|
|
485
642
|
userRole: actorRole,
|
|
486
|
-
source: "device-
|
|
487
|
-
details: { triggeredBy, batchSize, maxRetries },
|
|
643
|
+
source: "device-reset.manual",
|
|
644
|
+
details: { triggeredBy, batchSize, maxRetries, condition, update },
|
|
488
645
|
});
|
|
489
646
|
}
|
|
490
|
-
// ✅ Get the sequelize instance from the model
|
|
491
647
|
const sequelizeInstance = vr_models_1.Device.sequelize;
|
|
492
648
|
if (!sequelizeInstance) {
|
|
493
649
|
throw new Error("Sequelize instance not available");
|
|
@@ -496,12 +652,12 @@ exports.stockUtil = {
|
|
|
496
652
|
while (hasMore) {
|
|
497
653
|
batchNumber++;
|
|
498
654
|
offset = (batchNumber - 1) * batchSize;
|
|
499
|
-
//
|
|
655
|
+
// Get distinct pairIds that match the condition
|
|
500
656
|
const [pairIdsResult] = await sequelizeInstance.query(`
|
|
501
657
|
SELECT "pairId"
|
|
502
658
|
FROM "devices"
|
|
503
|
-
WHERE "
|
|
504
|
-
AND
|
|
659
|
+
WHERE "deletedAt" IS NULL
|
|
660
|
+
AND ${whereClause}
|
|
505
661
|
GROUP BY "pairId"
|
|
506
662
|
HAVING COUNT(*) = 2
|
|
507
663
|
ORDER BY "pairId" ASC
|
|
@@ -522,71 +678,48 @@ exports.stockUtil = {
|
|
|
522
678
|
}
|
|
523
679
|
totalProcessedPairs += pairIds.length;
|
|
524
680
|
console.log(`📦 Batch ${batchNumber}: Processing ${pairIds.length} pairs (Total: ${totalProcessedPairs})`);
|
|
525
|
-
// Process each pair
|
|
526
681
|
for (const pairId of pairIds) {
|
|
527
682
|
let retries = 0;
|
|
528
|
-
let
|
|
529
|
-
while (!
|
|
683
|
+
let pairUpdated = false;
|
|
684
|
+
while (!pairUpdated && retries < maxRetries) {
|
|
530
685
|
try {
|
|
531
|
-
// Get both devices in the pair
|
|
532
686
|
const devices = await vr_models_1.Device.findAll({
|
|
533
687
|
where: {
|
|
534
688
|
pairId: pairId,
|
|
535
|
-
status: { [sequelize_1.Op.ne]: "disabled" },
|
|
536
689
|
deletedAt: null,
|
|
690
|
+
...buildSequelizeWhere(condition),
|
|
537
691
|
},
|
|
538
692
|
transaction: transaction,
|
|
539
693
|
});
|
|
540
694
|
if (devices.length !== 2) {
|
|
541
695
|
throw new Error(`Incomplete pair ${pairId}: expected 2 devices, found ${devices.length}`);
|
|
542
696
|
}
|
|
543
|
-
// Check if
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
697
|
+
// Check if update would be a no-op
|
|
698
|
+
const shouldUpdate = devices.some((d) => {
|
|
699
|
+
const updateObj = buildUpdateObject(update);
|
|
700
|
+
return Object.keys(updateObj).some((key) => d[key] !== updateObj[key]);
|
|
701
|
+
});
|
|
702
|
+
if (!shouldUpdate) {
|
|
703
|
+
console.log(`⏭️ Pair ${pairId} already matches target state`);
|
|
704
|
+
pairUpdated = true;
|
|
548
705
|
break;
|
|
549
706
|
}
|
|
550
|
-
// Lock both devices
|
|
551
707
|
const deviceIds = devices.map((d) => d.id);
|
|
552
|
-
|
|
708
|
+
allDeviceIds.push(...deviceIds);
|
|
709
|
+
await vr_models_1.Device.update(buildUpdateObject(update), {
|
|
553
710
|
where: {
|
|
554
711
|
id: { [sequelize_1.Op.in]: deviceIds },
|
|
555
712
|
},
|
|
556
713
|
transaction: transaction,
|
|
557
714
|
});
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
console.log(
|
|
562
|
-
// Log event for each device in the pair
|
|
563
|
-
for (const device of devices) {
|
|
564
|
-
await (0, eventLog_utils_1.logEvent)({
|
|
565
|
-
actorId: isSystem ? null : actorId,
|
|
566
|
-
actorType: isSystem ? "ADMIN" : actorRole,
|
|
567
|
-
action: "DEVICES_LOCKED",
|
|
568
|
-
entity: "Device",
|
|
569
|
-
entityId: device.id,
|
|
570
|
-
metadata: {
|
|
571
|
-
serialNumber: device.serialNumber,
|
|
572
|
-
pairId: device.pairId,
|
|
573
|
-
dedicatedUser: device.dedicatedUser,
|
|
574
|
-
productId: device.productId,
|
|
575
|
-
lockedAt: new Date().toISOString(),
|
|
576
|
-
reason: "Scheduled lock all devices",
|
|
577
|
-
triggeredBy: triggeredBy,
|
|
578
|
-
batchNumber,
|
|
579
|
-
previousStatus: device.status,
|
|
580
|
-
isPartOfPair: true,
|
|
581
|
-
},
|
|
582
|
-
deviceSession: null,
|
|
583
|
-
transaction: transaction,
|
|
584
|
-
});
|
|
585
|
-
}
|
|
715
|
+
updatedPairIds.push(pairId);
|
|
716
|
+
totalUpdatedDevices += devices.length;
|
|
717
|
+
pairUpdated = true;
|
|
718
|
+
console.log(`✅ Updated pair ${pairId} (${devices.length} devices)`);
|
|
586
719
|
}
|
|
587
720
|
catch (err) {
|
|
588
721
|
retries++;
|
|
589
|
-
console.error(`❌ Failed to
|
|
722
|
+
console.error(`❌ Failed to update pair ${pairId} (attempt ${retries}/${maxRetries}):`, err instanceof Error ? err.message : "Unknown error");
|
|
590
723
|
if (retries >= maxRetries) {
|
|
591
724
|
failedPairIds.push(pairId);
|
|
592
725
|
errors.push(`Pair ${pairId}: ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
@@ -603,25 +736,56 @@ exports.stockUtil = {
|
|
|
603
736
|
}
|
|
604
737
|
const result = {
|
|
605
738
|
success: true,
|
|
606
|
-
|
|
739
|
+
updatedCount: totalUpdatedDevices,
|
|
607
740
|
failedCount: failedPairIds.length,
|
|
608
741
|
failedPairIds,
|
|
609
742
|
errors,
|
|
610
743
|
totalProcessed: totalProcessedPairs,
|
|
611
744
|
pairsProcessed: totalProcessedPairs,
|
|
612
|
-
message: `Successfully
|
|
745
|
+
message: `Successfully updated ${totalUpdatedDevices} devices (${updatedPairIds.length} pairs) out of ${totalProcessedPairs} pairs processed${failedPairIds.length > 0
|
|
613
746
|
? `, ${failedPairIds.length} pairs failed`
|
|
614
747
|
: ""}`,
|
|
615
748
|
};
|
|
616
|
-
console.log(`✅
|
|
617
|
-
// Log
|
|
749
|
+
console.log(`✅ Reset device pairs completed:`, result);
|
|
750
|
+
// Log single event with summary
|
|
751
|
+
await (0, eventLog_utils_1.logEvent)({
|
|
752
|
+
actorId: isSystem ? null : actorId,
|
|
753
|
+
actorType: isSystem ? "ADMIN" : actorRole,
|
|
754
|
+
action: "DEVICES_UPDATED",
|
|
755
|
+
entity: "Device",
|
|
756
|
+
entityId: null,
|
|
757
|
+
metadata: {
|
|
758
|
+
action: "RESET_DEVICES_STATUS",
|
|
759
|
+
triggeredBy: triggeredBy,
|
|
760
|
+
condition: condition,
|
|
761
|
+
update: update,
|
|
762
|
+
summary: {
|
|
763
|
+
totalPairsProcessed: result.pairsProcessed,
|
|
764
|
+
totalDevicesUpdated: result.updatedCount,
|
|
765
|
+
totalPairsUpdated: updatedPairIds.length,
|
|
766
|
+
failedPairs: result.failedCount,
|
|
767
|
+
failedPairIds: result.failedPairIds,
|
|
768
|
+
errors: result.errors,
|
|
769
|
+
deviceIds: allDeviceIds.slice(0, 100),
|
|
770
|
+
},
|
|
771
|
+
batchDetails: {
|
|
772
|
+
totalBatches: batchNumber,
|
|
773
|
+
batchSize: batchSize,
|
|
774
|
+
maxRetries: maxRetries,
|
|
775
|
+
},
|
|
776
|
+
timestamp: new Date().toISOString(),
|
|
777
|
+
},
|
|
778
|
+
deviceSession: null,
|
|
779
|
+
transaction: transaction,
|
|
780
|
+
});
|
|
781
|
+
// Log to system logs
|
|
618
782
|
if (isSystem) {
|
|
619
|
-
await (0, systemLog_utils_1.logInfo)(`
|
|
783
|
+
await (0, systemLog_utils_1.logInfo)(`Reset device pairs job completed`, {
|
|
620
784
|
category: "CRONJOB",
|
|
621
|
-
source: "device-
|
|
785
|
+
source: "device-reset.cronjob",
|
|
622
786
|
details: {
|
|
623
|
-
|
|
624
|
-
|
|
787
|
+
updatedDevices: result.updatedCount,
|
|
788
|
+
updatedPairs: updatedPairIds.length,
|
|
625
789
|
failedPairs: result.failedCount,
|
|
626
790
|
totalPairs: result.pairsProcessed,
|
|
627
791
|
hasErrors: result.errors.length > 0,
|
|
@@ -629,14 +793,14 @@ exports.stockUtil = {
|
|
|
629
793
|
});
|
|
630
794
|
}
|
|
631
795
|
else {
|
|
632
|
-
await (0, systemLog_utils_1.logInfo)(`
|
|
796
|
+
await (0, systemLog_utils_1.logInfo)(`Reset device pairs completed by ${actorRole}`, {
|
|
633
797
|
category: "DEVICE",
|
|
634
798
|
userId: actorId || undefined,
|
|
635
799
|
userRole: actorRole,
|
|
636
|
-
source: "device-
|
|
800
|
+
source: "device-reset.manual",
|
|
637
801
|
details: {
|
|
638
|
-
|
|
639
|
-
|
|
802
|
+
updatedDevices: result.updatedCount,
|
|
803
|
+
updatedPairs: updatedPairIds.length,
|
|
640
804
|
failedPairs: result.failedCount,
|
|
641
805
|
totalPairs: result.pairsProcessed,
|
|
642
806
|
hasErrors: result.errors.length > 0,
|
|
@@ -644,9 +808,9 @@ exports.stockUtil = {
|
|
|
644
808
|
});
|
|
645
809
|
}
|
|
646
810
|
if (result.errors.length > 0) {
|
|
647
|
-
await (0, systemLog_utils_1.logError)(`
|
|
811
|
+
await (0, systemLog_utils_1.logError)(`Reset device pairs had ${result.errors.length} failures`, {
|
|
648
812
|
category: isSystem ? "CRONJOB" : "DEVICE",
|
|
649
|
-
source: isSystem ? "device-
|
|
813
|
+
source: isSystem ? "device-reset.cronjob" : "device-reset.manual",
|
|
650
814
|
userId: isSystem ? null : actorId || undefined,
|
|
651
815
|
userRole: isSystem ? null : actorRole,
|
|
652
816
|
details: {
|
|
@@ -658,31 +822,31 @@ exports.stockUtil = {
|
|
|
658
822
|
return result;
|
|
659
823
|
}
|
|
660
824
|
catch (err) {
|
|
661
|
-
console.error("❌
|
|
825
|
+
console.error("❌ Reset device pairs failed:", err);
|
|
662
826
|
const errorMessage = err instanceof Error ? err.message : "Unknown error occurred";
|
|
663
827
|
const result = {
|
|
664
828
|
success: false,
|
|
665
|
-
|
|
829
|
+
updatedCount: 0,
|
|
666
830
|
failedCount: 0,
|
|
667
831
|
failedPairIds: [],
|
|
668
832
|
errors: [errorMessage],
|
|
669
833
|
totalProcessed: 0,
|
|
670
834
|
pairsProcessed: 0,
|
|
671
|
-
message: `
|
|
835
|
+
message: `Reset device pairs job failed: ${errorMessage}`,
|
|
672
836
|
};
|
|
673
837
|
if (isSystem) {
|
|
674
|
-
await (0, systemLog_utils_1.logError)(`
|
|
838
|
+
await (0, systemLog_utils_1.logError)(`Reset device pairs job failed`, {
|
|
675
839
|
category: "CRONJOB",
|
|
676
|
-
source: "device-
|
|
840
|
+
source: "device-reset.cronjob",
|
|
677
841
|
details: { error: errorMessage },
|
|
678
842
|
});
|
|
679
843
|
}
|
|
680
844
|
else {
|
|
681
|
-
await (0, systemLog_utils_1.logError)(`
|
|
845
|
+
await (0, systemLog_utils_1.logError)(`Reset device pairs failed`, {
|
|
682
846
|
category: "DEVICE",
|
|
683
847
|
userId: actorId || undefined,
|
|
684
848
|
userRole: actorRole,
|
|
685
|
-
source: "device-
|
|
849
|
+
source: "device-reset.manual",
|
|
686
850
|
details: { error: errorMessage },
|
|
687
851
|
});
|
|
688
852
|
}
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -35,9 +35,9 @@ export interface StockChangeResult {
|
|
|
35
35
|
productId: string;
|
|
36
36
|
productName: string;
|
|
37
37
|
}
|
|
38
|
-
export interface
|
|
38
|
+
export interface DeviceResetResult {
|
|
39
39
|
success: boolean;
|
|
40
|
-
|
|
40
|
+
updatedCount: number;
|
|
41
41
|
failedCount: number;
|
|
42
42
|
failedPairIds: string[];
|
|
43
43
|
errors: string[];
|
|
@@ -45,11 +45,29 @@ export interface LockAllDevicesResult {
|
|
|
45
45
|
totalProcessed: number;
|
|
46
46
|
pairsProcessed: number;
|
|
47
47
|
}
|
|
48
|
-
export interface
|
|
48
|
+
export interface DeviceResetOptions {
|
|
49
49
|
actorId?: string;
|
|
50
50
|
actorRole?: UserRole | string;
|
|
51
51
|
transaction?: any;
|
|
52
52
|
batchSize?: number;
|
|
53
53
|
maxRetries?: number;
|
|
54
54
|
triggeredBy?: "cronjob" | "manual";
|
|
55
|
+
condition?: {
|
|
56
|
+
status?: string | string[];
|
|
57
|
+
isPermanentlyUnlocked?: boolean;
|
|
58
|
+
pairId?: string | string[];
|
|
59
|
+
productId?: string | string[];
|
|
60
|
+
dedicatedUser?: string | string[];
|
|
61
|
+
createdBefore?: Date;
|
|
62
|
+
createdAfter?: Date;
|
|
63
|
+
excludeStatus?: string | string[];
|
|
64
|
+
excludePairIds?: string | string[];
|
|
65
|
+
};
|
|
66
|
+
update?: {
|
|
67
|
+
status?: string;
|
|
68
|
+
isPermanentlyUnlocked?: boolean;
|
|
69
|
+
dedicatedUser?: string;
|
|
70
|
+
devicePaymentPlanId?: string | null;
|
|
71
|
+
activatedAt?: Date | null;
|
|
72
|
+
};
|
|
55
73
|
}
|