@7365admin1/core 3.52.5 → 3.52.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.
- package/CHANGELOG.md +28 -0
- package/dist/index.d.ts +47 -4
- package/dist/index.js +113 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +112 -37
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/test/bulk-upsert-fail-closed.test.mjs +134 -0
- package/test/expired-vehicle-filter.test.mjs +114 -0
package/dist/index.mjs
CHANGED
|
@@ -20723,7 +20723,6 @@ function MVehicle(value) {
|
|
|
20723
20723
|
const expiredDate = new Date(createdAtDate);
|
|
20724
20724
|
expiredDate.setFullYear(expiredDate.getFullYear() + 10);
|
|
20725
20725
|
const createdAt = createdAtDate;
|
|
20726
|
-
const expiredAt = value.end ?? expiredDate;
|
|
20727
20726
|
return {
|
|
20728
20727
|
plateNumber: value.plateNumber ?? "",
|
|
20729
20728
|
type: value.type ?? "",
|
|
@@ -20740,7 +20739,12 @@ function MVehicle(value) {
|
|
|
20740
20739
|
remarks: value.remarks ?? "",
|
|
20741
20740
|
seasonPassType: value.seasonPassType ?? "",
|
|
20742
20741
|
start: value.start ? new Date(value.start) : createdAt,
|
|
20743
|
-
|
|
20742
|
+
// A blank expiry means "no expiry": it takes the createdAt + 10 years
|
|
20743
|
+
// sentinel, the same as a null or absent one. This read `value.end ??
|
|
20744
|
+
// expiredDate`, and `??` only falls through on null/undefined, so an empty
|
|
20745
|
+
// string was stored verbatim as `end: ""` - a String in a Date field. That
|
|
20746
|
+
// is what the expiry sweep then matched instead of the real expiries.
|
|
20747
|
+
end: value.end ? new Date(value.end) : expiredDate,
|
|
20744
20748
|
status: value.status ?? "active" /* ACTIVE */,
|
|
20745
20749
|
unitName: value.unitName ?? "",
|
|
20746
20750
|
peopleId: value.peopleId ?? "",
|
|
@@ -20792,6 +20796,12 @@ function MVehicleTransaction(value) {
|
|
|
20792
20796
|
category: value.category ?? ""
|
|
20793
20797
|
};
|
|
20794
20798
|
}
|
|
20799
|
+
function expiredVehicleSweepFilter(now = /* @__PURE__ */ new Date()) {
|
|
20800
|
+
return {
|
|
20801
|
+
end: { $type: "date", $lte: now },
|
|
20802
|
+
status: { $ne: "deleted" /* DELETED */ }
|
|
20803
|
+
};
|
|
20804
|
+
}
|
|
20795
20805
|
|
|
20796
20806
|
// src/repositories/vehicle.repo.ts
|
|
20797
20807
|
import { ObjectId as ObjectId42 } from "mongodb";
|
|
@@ -21504,18 +21514,22 @@ function useVehicleRepo() {
|
|
|
21504
21514
|
}
|
|
21505
21515
|
async function deleteExpiredVehicles(ids2, session) {
|
|
21506
21516
|
try {
|
|
21507
|
-
const now =
|
|
21517
|
+
const now = /* @__PURE__ */ new Date();
|
|
21508
21518
|
const _ids = (ids2 ?? []).map((id) => toObjectId7(id)).filter((id) => Boolean(id));
|
|
21509
21519
|
if (!_ids.length)
|
|
21510
21520
|
return 0;
|
|
21511
21521
|
const res = await collection.updateMany(
|
|
21512
21522
|
{
|
|
21513
21523
|
_id: { $in: _ids },
|
|
21514
|
-
|
|
21515
|
-
|
|
21516
|
-
|
|
21524
|
+
...expiredVehicleSweepFilter(now)
|
|
21525
|
+
},
|
|
21526
|
+
{
|
|
21527
|
+
$set: {
|
|
21528
|
+
status: "deleted",
|
|
21529
|
+
deletedAt: now.toISOString(),
|
|
21530
|
+
isDeletedInDahua: true
|
|
21531
|
+
}
|
|
21517
21532
|
},
|
|
21518
|
-
{ $set: { status: "deleted", deletedAt: now, isDeletedInDahua: true } },
|
|
21519
21533
|
{ session }
|
|
21520
21534
|
);
|
|
21521
21535
|
return res.modifiedCount;
|
|
@@ -21556,12 +21570,7 @@ function useVehicleRepo() {
|
|
|
21556
21570
|
}
|
|
21557
21571
|
async function getAllExpiredVehicles() {
|
|
21558
21572
|
try {
|
|
21559
|
-
const
|
|
21560
|
-
const query2 = {
|
|
21561
|
-
end: { $lte: now },
|
|
21562
|
-
status: { $ne: "deleted" }
|
|
21563
|
-
};
|
|
21564
|
-
const items = await collection.find(query2).toArray();
|
|
21573
|
+
const items = await collection.find(expiredVehicleSweepFilter()).toArray();
|
|
21565
21574
|
return items;
|
|
21566
21575
|
} catch (error) {
|
|
21567
21576
|
throw error;
|
|
@@ -35969,34 +35978,99 @@ function useVehicleService() {
|
|
|
35969
35978
|
if (!siteCameras.length) {
|
|
35970
35979
|
throw new Error("No site cameras found.");
|
|
35971
35980
|
}
|
|
35972
|
-
|
|
35973
|
-
|
|
35974
|
-
|
|
35975
|
-
|
|
35976
|
-
|
|
35977
|
-
|
|
35978
|
-
|
|
35979
|
-
|
|
35980
|
-
|
|
35981
|
-
|
|
35982
|
-
|
|
35983
|
-
|
|
35984
|
-
|
|
35985
|
-
|
|
35986
|
-
|
|
35987
|
-
|
|
35988
|
-
|
|
35989
|
-
|
|
35990
|
-
|
|
35981
|
+
const written = /* @__PURE__ */ new Map();
|
|
35982
|
+
const sweepRows = sanitizedValues.map((value, index) => ({
|
|
35983
|
+
_id: String(index),
|
|
35984
|
+
site,
|
|
35985
|
+
plateNumber: value.plateNumber
|
|
35986
|
+
}));
|
|
35987
|
+
const { deletableIds: savableIds, skipped } = await sweepExpiredVehicles(
|
|
35988
|
+
sweepRows,
|
|
35989
|
+
{
|
|
35990
|
+
camerasForSite: async () => siteCameras,
|
|
35991
|
+
cameraLabel,
|
|
35992
|
+
revoke: async (camera, row) => {
|
|
35993
|
+
const rowId = String(row._id);
|
|
35994
|
+
const vehicleValue = sanitizedValues[Number(rowId)];
|
|
35995
|
+
const plateNumber = vehicleValue.plateNumber;
|
|
35996
|
+
const { host, username, password } = camera;
|
|
35997
|
+
const dahuaPayload = {
|
|
35998
|
+
host,
|
|
35999
|
+
username,
|
|
36000
|
+
password,
|
|
36001
|
+
plateNumber,
|
|
36002
|
+
mode: vehicleValue.type === "whitelist" /* WHITELIST */ ? "TrafficRedList" /* TRAFFIC_REDLIST */ : "TrafficBlackList" /* TRAFFIC_BLACKLIST */,
|
|
36003
|
+
...vehicleValue.start ? { start: String(vehicleValue.start) } : {},
|
|
36004
|
+
...vehicleValue.end ? { end: String(vehicleValue.end) } : {},
|
|
36005
|
+
...vehicleValue.name ? { owner: vehicleValue.name } : {},
|
|
36006
|
+
...vehicleValue.vehicleModel ? { vehicleType: vehicleValue.vehicleModel } : {},
|
|
36007
|
+
...vehicleValue.vehicleColor ? { vehicleColor: vehicleValue.vehicleColor } : {}
|
|
36008
|
+
};
|
|
36009
|
+
try {
|
|
35991
36010
|
const dahuaResponse = await _bulkInsertPlateNumber(dahuaPayload);
|
|
36011
|
+
const responseStatus = dahuaResponse?.statusCode || dahuaResponse?.status || dahuaResponse?.res?.status || "unknown";
|
|
35992
36012
|
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
35993
|
-
|
|
35994
|
-
|
|
36013
|
+
if (responseStatus !== 200) {
|
|
36014
|
+
logCameraFailure(
|
|
36015
|
+
"bulk add",
|
|
36016
|
+
camera,
|
|
36017
|
+
`HTTP ${responseStatus}: ${responseData.slice(0, 500)}`
|
|
36018
|
+
);
|
|
36019
|
+
return {
|
|
36020
|
+
ok: false,
|
|
36021
|
+
reason: anprWriteReason(`HTTP ${responseStatus}`)
|
|
36022
|
+
};
|
|
36023
|
+
}
|
|
36024
|
+
const recNo = String(responseData.split("=")[1]?.trim() ?? "");
|
|
36025
|
+
if (recNo) {
|
|
36026
|
+
vehicleValue.recNo = vehicleValue.recNo || recNo;
|
|
36027
|
+
const entries = written.get(rowId) ?? [];
|
|
36028
|
+
entries.push({ camera, recno: recNo });
|
|
36029
|
+
written.set(rowId, entries);
|
|
36030
|
+
}
|
|
36031
|
+
return { ok: true, reason: "" };
|
|
36032
|
+
} catch (error) {
|
|
36033
|
+
logCameraFailure("bulk add", camera, error);
|
|
36034
|
+
return { ok: false, reason: anprWriteReason(error) };
|
|
36035
|
+
}
|
|
36036
|
+
}
|
|
36037
|
+
}
|
|
36038
|
+
);
|
|
36039
|
+
const failedRows = [];
|
|
36040
|
+
for (const entry of skipped) {
|
|
36041
|
+
const stranded = [];
|
|
36042
|
+
for (const write of written.get(entry.id) ?? []) {
|
|
36043
|
+
const outcome = await _removePlateNumber({
|
|
36044
|
+
host: write.camera.host,
|
|
36045
|
+
username: write.camera.username,
|
|
36046
|
+
password: write.camera.password,
|
|
36047
|
+
recno: write.recno,
|
|
36048
|
+
mode: sanitizedValues[Number(entry.id)]?.type === "whitelist" /* WHITELIST */ ? "TrafficRedList" /* TRAFFIC_REDLIST */ : "TrafficBlackList" /* TRAFFIC_BLACKLIST */
|
|
36049
|
+
}).catch((removeError) => anprRevokeThrew(removeError));
|
|
36050
|
+
if (!outcome?.ok)
|
|
36051
|
+
stranded.push(cameraLabel(write.camera));
|
|
36052
|
+
}
|
|
36053
|
+
let message = anprWriteFailureMessage(entry.failures);
|
|
36054
|
+
if (stranded.length) {
|
|
36055
|
+
logger63.error(
|
|
36056
|
+
`bulkUpsertVehicles could not take the plate back off: ${stranded.join(", ")} (plate ${JSON.stringify(entry.plateNumber)})`
|
|
35995
36057
|
);
|
|
35996
|
-
|
|
35997
|
-
}
|
|
36058
|
+
message += ` WARNING: the plate number was written to ${stranded.join(", ")} and could not be removed again - it WILL still open the barrier. Remove it on the camera by hand.`;
|
|
36059
|
+
}
|
|
36060
|
+
logger63.error(
|
|
36061
|
+
`bulkUpsertVehicles NOT saving plate ${JSON.stringify(entry.plateNumber)} (site ${entry.site}): ` + entry.failures.map((failure) => `${failure.camera} (${failure.reason})`).join(", ")
|
|
36062
|
+
);
|
|
36063
|
+
failedRows.push({
|
|
36064
|
+
plateNumber: String(entry.plateNumber ?? ""),
|
|
36065
|
+
message
|
|
36066
|
+
});
|
|
36067
|
+
}
|
|
36068
|
+
const savable = new Set(savableIds);
|
|
36069
|
+
const toSave = sanitizedValues.filter(
|
|
36070
|
+
(_, index) => savable.has(String(index))
|
|
35998
36071
|
);
|
|
35999
|
-
|
|
36072
|
+
const result = toSave.length ? await _bulkUpsertVehicles(toSave) : { matchedCount: 0, modifiedCount: 0, upsertedCount: 0 };
|
|
36073
|
+
return { ...result, savedCount: toSave.length, failedRows };
|
|
36000
36074
|
} catch (error) {
|
|
36001
36075
|
throw error;
|
|
36002
36076
|
}
|
|
@@ -91591,6 +91665,7 @@ export {
|
|
|
91591
91665
|
encodeHidPacsCard,
|
|
91592
91666
|
events_namespace_collection,
|
|
91593
91667
|
expiredBulletinSweepFilter,
|
|
91668
|
+
expiredVehicleSweepFilter,
|
|
91594
91669
|
facility_bookings_namespace_collection,
|
|
91595
91670
|
feedbackSchema,
|
|
91596
91671
|
feedbacks2_namespace_collection,
|