@7365admin1/core 3.7.1 → 3.9.0
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 +12 -0
- package/dist/index.d.ts +395 -19
- package/dist/index.js +2453 -565
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2431 -563
- package/dist/index.mjs.map +1 -1
- package/docs/hid-amico-diagram.md +201 -0
- package/docs/hid-amico-integration.md +491 -0
- package/docs/hid-amico-postman-api.md +614 -0
- package/docs/hid-amico-ui-design-scope.md +441 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -537,13 +537,13 @@ var require_logger = __commonJS({
|
|
|
537
537
|
"use strict";
|
|
538
538
|
exports.__esModule = true;
|
|
539
539
|
var _utils = require_utils();
|
|
540
|
-
var
|
|
540
|
+
var logger200 = {
|
|
541
541
|
methodMap: ["debug", "info", "warn", "error"],
|
|
542
542
|
level: "info",
|
|
543
543
|
// Maps a given level value to the `methodMap` indexes above.
|
|
544
544
|
lookupLevel: function lookupLevel(level) {
|
|
545
545
|
if (typeof level === "string") {
|
|
546
|
-
var levelMap = _utils.indexOf(
|
|
546
|
+
var levelMap = _utils.indexOf(logger200.methodMap, level.toLowerCase());
|
|
547
547
|
if (levelMap >= 0) {
|
|
548
548
|
level = levelMap;
|
|
549
549
|
} else {
|
|
@@ -554,9 +554,9 @@ var require_logger = __commonJS({
|
|
|
554
554
|
},
|
|
555
555
|
// Can be overridden in the host environment
|
|
556
556
|
log: function log(level) {
|
|
557
|
-
level =
|
|
558
|
-
if (typeof console !== "undefined" &&
|
|
559
|
-
var method =
|
|
557
|
+
level = logger200.lookupLevel(level);
|
|
558
|
+
if (typeof console !== "undefined" && logger200.lookupLevel(logger200.level) <= level) {
|
|
559
|
+
var method = logger200.methodMap[level];
|
|
560
560
|
if (!console[method]) {
|
|
561
561
|
method = "log";
|
|
562
562
|
}
|
|
@@ -567,7 +567,7 @@ var require_logger = __commonJS({
|
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
};
|
|
570
|
-
exports["default"] =
|
|
570
|
+
exports["default"] = logger200;
|
|
571
571
|
module.exports = exports["default"];
|
|
572
572
|
}
|
|
573
573
|
});
|
|
@@ -10822,7 +10822,8 @@ var metadataSchema3 = Joi9.object({
|
|
|
10822
10822
|
guardPosts: Joi9.number().optional(),
|
|
10823
10823
|
gracePeriod: Joi9.number().optional(),
|
|
10824
10824
|
incidentCounter: Joi9.number().optional(),
|
|
10825
|
-
incidentLogo: Joi9.string().optional().allow("", null)
|
|
10825
|
+
incidentLogo: Joi9.string().optional().allow("", null),
|
|
10826
|
+
services: Joi9.array().items(Joi9.object().unknown(true)).optional()
|
|
10826
10827
|
});
|
|
10827
10828
|
var updateAddressSchema = Joi9.object({
|
|
10828
10829
|
line1: Joi9.string().min(3).allow("", null),
|
|
@@ -10852,7 +10853,8 @@ var allowedFieldsSite = [
|
|
|
10852
10853
|
"metadata.guardPosts",
|
|
10853
10854
|
"metadata.gracePeriod",
|
|
10854
10855
|
"metadata.incidentCounter",
|
|
10855
|
-
"metadata.incidentLogo"
|
|
10856
|
+
"metadata.incidentLogo",
|
|
10857
|
+
"metadata.services"
|
|
10856
10858
|
];
|
|
10857
10859
|
var siteSchema = Joi9.object({
|
|
10858
10860
|
name: Joi9.string().required(),
|
|
@@ -11746,9 +11748,7 @@ function useVerificationRepoV2() {
|
|
|
11746
11748
|
}
|
|
11747
11749
|
);
|
|
11748
11750
|
} catch (error) {
|
|
11749
|
-
throw new InternalServerError11(
|
|
11750
|
-
"Failed to retrieve verification."
|
|
11751
|
-
);
|
|
11751
|
+
throw new InternalServerError11("Failed to retrieve verification.");
|
|
11752
11752
|
}
|
|
11753
11753
|
}
|
|
11754
11754
|
async function updateVerificationCodeById(_id, verificationCode, expireAt, session) {
|
|
@@ -11766,9 +11766,7 @@ function useVerificationRepoV2() {
|
|
|
11766
11766
|
{ session }
|
|
11767
11767
|
);
|
|
11768
11768
|
} catch (error) {
|
|
11769
|
-
throw new InternalServerError11(
|
|
11770
|
-
"Failed to update verification code."
|
|
11771
|
-
);
|
|
11769
|
+
throw new InternalServerError11("Failed to update verification code.");
|
|
11772
11770
|
}
|
|
11773
11771
|
}
|
|
11774
11772
|
return {
|
|
@@ -20787,12 +20785,20 @@ var schemaVisitorTransaction = Joi37.object({
|
|
|
20787
20785
|
nric: Joi37.string().optional().allow(null, ""),
|
|
20788
20786
|
visitorPass: Joi37.array().items(
|
|
20789
20787
|
Joi37.object({
|
|
20790
|
-
keyId: Joi37.string().hex().length(24).required()
|
|
20788
|
+
keyId: Joi37.string().hex().length(24).required(),
|
|
20789
|
+
receivedDate: Joi37.date().optional().allow(null),
|
|
20790
|
+
status: Joi37.string().optional().allow(null, ""),
|
|
20791
|
+
lastUpdate: Joi37.date().optional().allow(null),
|
|
20792
|
+
remarks: Joi37.string().optional().allow(null, "")
|
|
20791
20793
|
})
|
|
20792
20794
|
).optional().allow(null),
|
|
20793
20795
|
passKeys: Joi37.array().items(
|
|
20794
20796
|
Joi37.object({
|
|
20795
|
-
keyId: Joi37.string().hex().length(24).required()
|
|
20797
|
+
keyId: Joi37.string().hex().length(24).required(),
|
|
20798
|
+
receivedDate: Joi37.date().optional().allow(null),
|
|
20799
|
+
status: Joi37.string().optional().allow(null, ""),
|
|
20800
|
+
lastUpdate: Joi37.date().optional().allow(null),
|
|
20801
|
+
remarks: Joi37.string().optional().allow(null, "")
|
|
20796
20802
|
})
|
|
20797
20803
|
).optional().allow(null),
|
|
20798
20804
|
contact: Joi37.string().optional().allow(null, "")
|
|
@@ -20809,19 +20815,28 @@ var schemaVisitorTransaction = Joi37.object({
|
|
|
20809
20815
|
numberOfPassengers: Joi37.number().integer().optional().allow(null, ""),
|
|
20810
20816
|
visitorPass: Joi37.array().items(
|
|
20811
20817
|
Joi37.object({
|
|
20812
|
-
keyId: Joi37.string().hex().length(24).allow(null, "")
|
|
20818
|
+
keyId: Joi37.string().hex().length(24).allow(null, ""),
|
|
20819
|
+
receivedDate: Joi37.date().optional().allow(null),
|
|
20820
|
+
status: Joi37.string().optional().allow(null, ""),
|
|
20821
|
+
lastUpdate: Joi37.date().optional().allow(null),
|
|
20822
|
+
remarks: Joi37.string().optional().allow(null, "")
|
|
20813
20823
|
})
|
|
20814
20824
|
).optional().allow(null),
|
|
20815
20825
|
passKeys: Joi37.array().items(
|
|
20816
20826
|
Joi37.object({
|
|
20817
|
-
keyId: Joi37.string().hex().length(24).allow(null, "")
|
|
20827
|
+
keyId: Joi37.string().hex().length(24).allow(null, ""),
|
|
20828
|
+
receivedDate: Joi37.date().optional().allow(null),
|
|
20829
|
+
status: Joi37.string().optional().allow(null, ""),
|
|
20830
|
+
lastUpdate: Joi37.date().optional().allow(null),
|
|
20831
|
+
remarks: Joi37.string().optional().allow(null, "")
|
|
20818
20832
|
})
|
|
20819
20833
|
).optional().allow(null),
|
|
20820
20834
|
checkInRemarks: Joi37.string().optional().allow("", null),
|
|
20821
20835
|
checkOutRemarks: Joi37.string().optional().allow("", null),
|
|
20822
20836
|
expectedCheckIn: Joi37.string().isoDate().optional(),
|
|
20823
20837
|
purpose: Joi37.string().optional().allow(null, ""),
|
|
20824
|
-
inviterId: Joi37.any().optional().allow(null, "")
|
|
20838
|
+
inviterId: Joi37.any().optional().allow(null, ""),
|
|
20839
|
+
createdBy: Joi37.string().hex().length(24).optional().allow(null, "")
|
|
20825
20840
|
});
|
|
20826
20841
|
var schemaUpdateVisTrans = Joi37.object({
|
|
20827
20842
|
_id: Joi37.string().hex().length(24).required(),
|
|
@@ -20941,22 +20956,22 @@ function MVisitorTransaction(value) {
|
|
|
20941
20956
|
throw new Error("Invalid type for manualCheckout key.");
|
|
20942
20957
|
}
|
|
20943
20958
|
}
|
|
20944
|
-
if (
|
|
20959
|
+
if (Array.isArray(value.visitorPass)) {
|
|
20945
20960
|
value.visitorPass = value.visitorPass.map((v) => {
|
|
20946
|
-
|
|
20947
|
-
|
|
20948
|
-
|
|
20949
|
-
|
|
20961
|
+
try {
|
|
20962
|
+
v.keyId = new ObjectId39(v.keyId);
|
|
20963
|
+
} catch (error2) {
|
|
20964
|
+
throw new Error("Invalid VisitorPass ID.");
|
|
20950
20965
|
}
|
|
20951
20966
|
return v;
|
|
20952
20967
|
});
|
|
20953
20968
|
}
|
|
20954
|
-
if (
|
|
20969
|
+
if (Array.isArray(value.passKeys)) {
|
|
20955
20970
|
value.passKeys = value.passKeys.map((p) => {
|
|
20956
|
-
|
|
20957
|
-
|
|
20958
|
-
|
|
20959
|
-
|
|
20971
|
+
try {
|
|
20972
|
+
p.keyId = new ObjectId39(p.keyId);
|
|
20973
|
+
} catch (error2) {
|
|
20974
|
+
throw new Error("Invalid PassKey ID.");
|
|
20960
20975
|
}
|
|
20961
20976
|
return p;
|
|
20962
20977
|
});
|
|
@@ -21651,9 +21666,57 @@ function useVisitorTransactionRepo() {
|
|
|
21651
21666
|
}
|
|
21652
21667
|
}
|
|
21653
21668
|
async function resendEmailInvitedResident(visitorId, updatedBy) {
|
|
21654
|
-
const
|
|
21655
|
-
_id: await convertObjectIdUtil(visitorId)
|
|
21656
|
-
|
|
21669
|
+
const pipeline = [
|
|
21670
|
+
{ $match: { _id: await convertObjectIdUtil(visitorId) } },
|
|
21671
|
+
{
|
|
21672
|
+
$lookup: {
|
|
21673
|
+
from: "buildings",
|
|
21674
|
+
localField: "block",
|
|
21675
|
+
foreignField: "_id",
|
|
21676
|
+
as: "blockDetails"
|
|
21677
|
+
}
|
|
21678
|
+
},
|
|
21679
|
+
{
|
|
21680
|
+
$addFields: {
|
|
21681
|
+
blockName: {
|
|
21682
|
+
$ifNull: [
|
|
21683
|
+
{ $arrayElemAt: ["$blockDetails.name", 0] },
|
|
21684
|
+
"Unknown"
|
|
21685
|
+
]
|
|
21686
|
+
}
|
|
21687
|
+
}
|
|
21688
|
+
},
|
|
21689
|
+
{
|
|
21690
|
+
$project: {
|
|
21691
|
+
blockDetails: 0
|
|
21692
|
+
}
|
|
21693
|
+
},
|
|
21694
|
+
{
|
|
21695
|
+
$lookup: {
|
|
21696
|
+
from: "building-levels",
|
|
21697
|
+
localField: "level",
|
|
21698
|
+
foreignField: "_id",
|
|
21699
|
+
as: "levelDetails"
|
|
21700
|
+
}
|
|
21701
|
+
},
|
|
21702
|
+
{
|
|
21703
|
+
$addFields: {
|
|
21704
|
+
levelName: {
|
|
21705
|
+
$ifNull: [
|
|
21706
|
+
{ $arrayElemAt: ["$levelDetails.name", 0] },
|
|
21707
|
+
"Unknown"
|
|
21708
|
+
]
|
|
21709
|
+
}
|
|
21710
|
+
}
|
|
21711
|
+
},
|
|
21712
|
+
{
|
|
21713
|
+
$project: {
|
|
21714
|
+
levelDetails: 0
|
|
21715
|
+
}
|
|
21716
|
+
}
|
|
21717
|
+
];
|
|
21718
|
+
const results = await collection.aggregate(pipeline).toArray();
|
|
21719
|
+
const updatedDocument = results[0] || null;
|
|
21657
21720
|
if (!updatedDocument?.email)
|
|
21658
21721
|
return;
|
|
21659
21722
|
if (!updatedDocument?._id)
|
|
@@ -21668,7 +21731,7 @@ function useVisitorTransactionRepo() {
|
|
|
21668
21731
|
name: `${updatedDocument?.name}`,
|
|
21669
21732
|
plateNumber: updatedDocument?.plateNumber,
|
|
21670
21733
|
nric: updatedDocument?.nric,
|
|
21671
|
-
address: `${updatedDocument?.
|
|
21734
|
+
address: `${updatedDocument?.blockName} ${updatedDocument?.levelName} ${updatedDocument?.unitName}`,
|
|
21672
21735
|
contactNumber: updatedDocument?.contact ? updatedDocument?.contact : "N/A",
|
|
21673
21736
|
email: updatedDocument?.email ? updatedDocument?.email : "N/A",
|
|
21674
21737
|
duration: updatedDocument?.duration ? updatedDocument?.duration : "N/A",
|
|
@@ -27615,7 +27678,7 @@ function useBuildingRepo() {
|
|
|
27615
27678
|
try {
|
|
27616
27679
|
await collection.createIndexes([
|
|
27617
27680
|
{ key: { name: "text" }, name: "text-index" },
|
|
27618
|
-
{ key: { name: 1 }, unique: true, name: "unique-name-index" },
|
|
27681
|
+
// { key: { name: 1 }, unique: true, name: "unique-name-index" },
|
|
27619
27682
|
{ key: { site: 1 } },
|
|
27620
27683
|
{ key: { createdAt: 1 } },
|
|
27621
27684
|
{
|
|
@@ -28307,11 +28370,6 @@ function useBuildingLevelRepo() {
|
|
|
28307
28370
|
try {
|
|
28308
28371
|
await collection.createIndexes([
|
|
28309
28372
|
// Ensure name is unique per blockId
|
|
28310
|
-
{
|
|
28311
|
-
key: { blockId: 1, name: 1 },
|
|
28312
|
-
unique: true,
|
|
28313
|
-
name: "unique_name_per_blockId"
|
|
28314
|
-
},
|
|
28315
28373
|
// Other useful indexes
|
|
28316
28374
|
{ key: { site: 1 }, name: "idx_site" },
|
|
28317
28375
|
{ key: { blockId: 1 }, name: "idx_blockId" },
|
|
@@ -28572,7 +28630,11 @@ function useBuildingLevelRepo() {
|
|
|
28572
28630
|
const res = await collection.bulkWrite(operations, { session });
|
|
28573
28631
|
delCachedData();
|
|
28574
28632
|
return {
|
|
28575
|
-
insertedIds: res.insertedIds
|
|
28633
|
+
insertedIds: res.insertedIds,
|
|
28634
|
+
levels: levels.map((l, i) => ({
|
|
28635
|
+
_id: res.insertedIds[i],
|
|
28636
|
+
name: l.name
|
|
28637
|
+
}))
|
|
28576
28638
|
};
|
|
28577
28639
|
} catch (error) {
|
|
28578
28640
|
logger63.log({
|
|
@@ -28856,8 +28918,8 @@ function useBuildingService() {
|
|
|
28856
28918
|
const name = row.name;
|
|
28857
28919
|
const rawLevel = row.level?.toString().trim();
|
|
28858
28920
|
const rawUnit = row.unit?.toString().trim();
|
|
28859
|
-
const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null :
|
|
28860
|
-
const normalizedUnit = /^(na|n\/a)$/i.test(rawUnit) ? null :
|
|
28921
|
+
const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null : rawLevel;
|
|
28922
|
+
const normalizedUnit = /^(na|n\/a)$/i.test(rawUnit) ? null : rawUnit;
|
|
28861
28923
|
if (!blockMap.has(block)) {
|
|
28862
28924
|
blockMap.set(block, { name, levels: [], unitsByLevel: /* @__PURE__ */ new Map() });
|
|
28863
28925
|
}
|
|
@@ -28878,57 +28940,76 @@ function useBuildingService() {
|
|
|
28878
28940
|
}
|
|
28879
28941
|
}
|
|
28880
28942
|
}
|
|
28881
|
-
const buildingPayloads =
|
|
28882
|
-
|
|
28943
|
+
const buildingPayloads = [];
|
|
28944
|
+
const buildingUnitPayloads = [];
|
|
28945
|
+
for (const [
|
|
28946
|
+
block,
|
|
28947
|
+
{ name, levels, unitsByLevel }
|
|
28948
|
+
] of blockMap.entries()) {
|
|
28949
|
+
const buildingId = new ObjectId53();
|
|
28950
|
+
const levelsPayload = (levels ?? []).map((levelName) => ({
|
|
28951
|
+
blockId: buildingId.toString(),
|
|
28952
|
+
site: site.toString(),
|
|
28953
|
+
name: levelName,
|
|
28954
|
+
status: "active" /* ACTIVE */,
|
|
28955
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
28956
|
+
updatedAt: null,
|
|
28957
|
+
deletedAt: null
|
|
28958
|
+
}));
|
|
28959
|
+
let insertedLevels;
|
|
28960
|
+
if (levelsPayload.length > 0) {
|
|
28961
|
+
insertedLevels = await _bulkWriteLevels(levelsPayload, session);
|
|
28962
|
+
}
|
|
28963
|
+
const levelNameToId = /* @__PURE__ */ new Map();
|
|
28964
|
+
if (insertedLevels) {
|
|
28965
|
+
insertedLevels.levels.forEach((lvl) => {
|
|
28966
|
+
levelNameToId.set(lvl.name, lvl._id);
|
|
28967
|
+
});
|
|
28968
|
+
}
|
|
28969
|
+
const buildingPayload = {
|
|
28970
|
+
_id: buildingId,
|
|
28883
28971
|
site,
|
|
28884
28972
|
block,
|
|
28885
28973
|
name,
|
|
28886
|
-
levels
|
|
28887
|
-
}
|
|
28888
|
-
|
|
28889
|
-
|
|
28890
|
-
|
|
28891
|
-
|
|
28892
|
-
|
|
28893
|
-
|
|
28894
|
-
|
|
28895
|
-
|
|
28896
|
-
|
|
28897
|
-
|
|
28898
|
-
|
|
28899
|
-
|
|
28900
|
-
|
|
28901
|
-
|
|
28902
|
-
|
|
28903
|
-
|
|
28904
|
-
|
|
28905
|
-
|
|
28906
|
-
|
|
28907
|
-
|
|
28908
|
-
|
|
28909
|
-
|
|
28910
|
-
|
|
28911
|
-
|
|
28912
|
-
|
|
28913
|
-
companyRegistrationNumber: "",
|
|
28914
|
-
billing: [],
|
|
28915
|
-
unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null,
|
|
28916
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
28917
|
-
updatedAt: "",
|
|
28918
|
-
deletedAt: ""
|
|
28919
|
-
});
|
|
28974
|
+
levels: insertedLevels ? Object.values(insertedLevels.insertedIds) : []
|
|
28975
|
+
};
|
|
28976
|
+
const buildingResult = await _add(buildingPayload, session);
|
|
28977
|
+
Array.from(unitsByLevel.entries()).forEach(([levelName, units]) => {
|
|
28978
|
+
const levelId = levelNameToId.get(levelName);
|
|
28979
|
+
units.forEach((unit) => {
|
|
28980
|
+
buildingUnitPayloads.push({
|
|
28981
|
+
site: new ObjectId53(site),
|
|
28982
|
+
name: unit,
|
|
28983
|
+
building: buildingId,
|
|
28984
|
+
// already an ObjectId
|
|
28985
|
+
buildingName: name,
|
|
28986
|
+
block,
|
|
28987
|
+
level: levelId,
|
|
28988
|
+
// ✅ use ObjectId instead of string
|
|
28989
|
+
category: "",
|
|
28990
|
+
status: "active" /* ACTIVE */,
|
|
28991
|
+
buildingUnitFiles: [],
|
|
28992
|
+
owner: "",
|
|
28993
|
+
ownerName: "",
|
|
28994
|
+
companyName: "",
|
|
28995
|
+
companyRegistrationNumber: "",
|
|
28996
|
+
billing: [],
|
|
28997
|
+
unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null,
|
|
28998
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
28999
|
+
updatedAt: "",
|
|
29000
|
+
deletedAt: ""
|
|
28920
29001
|
});
|
|
28921
29002
|
});
|
|
28922
|
-
}
|
|
28923
|
-
|
|
29003
|
+
});
|
|
29004
|
+
}
|
|
28924
29005
|
await _bulkAddBuildingUnits(buildingUnitPayloads);
|
|
28925
|
-
await session
|
|
29006
|
+
await session.commitTransaction();
|
|
28926
29007
|
return { buildingPayloads, buildingUnitPayloads };
|
|
28927
29008
|
} catch (error) {
|
|
28928
|
-
await session
|
|
29009
|
+
await session.abortTransaction();
|
|
28929
29010
|
throw error;
|
|
28930
29011
|
} finally {
|
|
28931
|
-
session
|
|
29012
|
+
session.endSession();
|
|
28932
29013
|
}
|
|
28933
29014
|
}
|
|
28934
29015
|
return {
|
|
@@ -29199,9 +29280,9 @@ function useBuildingController() {
|
|
|
29199
29280
|
const lowerName = originalname.toLowerCase();
|
|
29200
29281
|
const rowSchema = Joi46.object({
|
|
29201
29282
|
block: Joi46.number().integer().min(0).required(),
|
|
29202
|
-
level: Joi46.string().optional().allow(null, ""),
|
|
29203
|
-
unit: Joi46.string().optional().allow(null, ""),
|
|
29204
|
-
category: Joi46.string().trim().
|
|
29283
|
+
level: Joi46.alternatives().try(Joi46.string(), Joi46.number()).custom((value) => String(value)).optional().allow(null, ""),
|
|
29284
|
+
unit: Joi46.alternatives().try(Joi46.string(), Joi46.number()).custom((value) => String(value)).optional().allow(null, ""),
|
|
29285
|
+
category: Joi46.string().trim().optional().allow(null, ""),
|
|
29205
29286
|
name: Joi46.string().trim().optional().allow(null, ""),
|
|
29206
29287
|
email: Joi46.string().email().lowercase().optional().allow(null, ""),
|
|
29207
29288
|
phoneNumber: Joi46.string().trim().optional().allow(null, "")
|
|
@@ -29215,11 +29296,9 @@ function useBuildingController() {
|
|
|
29215
29296
|
{ abortEarly: false, convert: true }
|
|
29216
29297
|
);
|
|
29217
29298
|
if (queryError) {
|
|
29218
|
-
|
|
29219
|
-
|
|
29220
|
-
|
|
29221
|
-
)
|
|
29222
|
-
);
|
|
29299
|
+
const messages = queryError.details.map((d) => d.message).join(", ");
|
|
29300
|
+
logger65.log({ level: "error", message: messages });
|
|
29301
|
+
next(new BadRequestError84(messages));
|
|
29223
29302
|
return;
|
|
29224
29303
|
}
|
|
29225
29304
|
const { site, org } = queryValue;
|
|
@@ -29254,11 +29333,11 @@ function useBuildingController() {
|
|
|
29254
29333
|
} else if (lowerName.endsWith(".csv")) {
|
|
29255
29334
|
rows = await new Promise((resolve, reject) => {
|
|
29256
29335
|
const parsed = [];
|
|
29257
|
-
fs2.createReadStream(path5).pipe(
|
|
29258
|
-
|
|
29259
|
-
(
|
|
29260
|
-
)
|
|
29261
|
-
|
|
29336
|
+
fs2.createReadStream(path5).pipe(
|
|
29337
|
+
csv({
|
|
29338
|
+
mapHeaders: ({ header }) => header.trim().replace(/\(.*\)/, "").trim()
|
|
29339
|
+
})
|
|
29340
|
+
).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
|
|
29262
29341
|
});
|
|
29263
29342
|
} else {
|
|
29264
29343
|
next(
|
|
@@ -29276,6 +29355,7 @@ function useBuildingController() {
|
|
|
29276
29355
|
if (error) {
|
|
29277
29356
|
invalidRows.push({
|
|
29278
29357
|
row: index + 2,
|
|
29358
|
+
// +2 because header is row 1
|
|
29279
29359
|
data: row,
|
|
29280
29360
|
errors: error.details.map((d) => d.message)
|
|
29281
29361
|
});
|
|
@@ -29297,6 +29377,7 @@ function useBuildingController() {
|
|
|
29297
29377
|
fs2.unlink(path5, () => {
|
|
29298
29378
|
});
|
|
29299
29379
|
} catch (error) {
|
|
29380
|
+
console.log(error);
|
|
29300
29381
|
logger65.log({ level: "error", message: error.message });
|
|
29301
29382
|
next(error);
|
|
29302
29383
|
}
|
|
@@ -33271,17 +33352,13 @@ var KeyRepo = class {
|
|
|
33271
33352
|
}
|
|
33272
33353
|
}
|
|
33273
33354
|
static async updateKeyById(keyId, key, site, session, isChild) {
|
|
33274
|
-
|
|
33275
|
-
|
|
33276
|
-
|
|
33277
|
-
|
|
33278
|
-
|
|
33279
|
-
|
|
33280
|
-
|
|
33281
|
-
delete key.status;
|
|
33282
|
-
} catch (error) {
|
|
33283
|
-
return Promise.reject("Invalid key id");
|
|
33284
|
-
}
|
|
33355
|
+
keyId = await convertObjectIdUtil2(keyId, "keyId");
|
|
33356
|
+
if (site)
|
|
33357
|
+
site = await convertObjectIdUtil2(site, "Site");
|
|
33358
|
+
if (key.updatedBy)
|
|
33359
|
+
key.updatedBy = await convertObjectIdUtil2(key.updatedBy, "Updated By");
|
|
33360
|
+
if (!key.status)
|
|
33361
|
+
delete key.status;
|
|
33285
33362
|
try {
|
|
33286
33363
|
key.updatedAt = /* @__PURE__ */ new Date();
|
|
33287
33364
|
const query = { _id: keyId, ...site && { site } };
|
|
@@ -33294,6 +33371,7 @@ var KeyRepo = class {
|
|
|
33294
33371
|
{ session }
|
|
33295
33372
|
);
|
|
33296
33373
|
let setKeys = [];
|
|
33374
|
+
console.log("updateKeyById result", result);
|
|
33297
33375
|
if (result.modifiedCount > 0) {
|
|
33298
33376
|
const updatedDocs = await this.collection().find(find).toArray();
|
|
33299
33377
|
if (Array.isArray(updatedDocs) && updatedDocs.length > 0) {
|
|
@@ -33308,10 +33386,12 @@ var KeyRepo = class {
|
|
|
33308
33386
|
await this.collectionDynamic("keys-histories").insertMany(setKeys, {
|
|
33309
33387
|
session
|
|
33310
33388
|
});
|
|
33389
|
+
} else {
|
|
33390
|
+
throw new Error("Failed Updating Keys");
|
|
33311
33391
|
}
|
|
33312
33392
|
return result;
|
|
33313
33393
|
} catch (error) {
|
|
33314
|
-
|
|
33394
|
+
throw new Error(error);
|
|
33315
33395
|
}
|
|
33316
33396
|
}
|
|
33317
33397
|
static async deleteKeyById(_id, session) {
|
|
@@ -33394,6 +33474,176 @@ var KeyRepo = class {
|
|
|
33394
33474
|
}
|
|
33395
33475
|
};
|
|
33396
33476
|
|
|
33477
|
+
// src/services/notification.service.ts
|
|
33478
|
+
import { sendExpoPushNotifications } from "iservice365-expo-notifications";
|
|
33479
|
+
|
|
33480
|
+
// src/repositories/push-token.repository.ts
|
|
33481
|
+
var PushTokenRepo = class {
|
|
33482
|
+
static collection() {
|
|
33483
|
+
return getDB().collection("push_tokens");
|
|
33484
|
+
}
|
|
33485
|
+
static async createIndexes() {
|
|
33486
|
+
await Promise.all([
|
|
33487
|
+
this.collection().createIndex({ token: 1 }, { unique: true }),
|
|
33488
|
+
this.collection().createIndex({ userId: 1, platform: 1 }),
|
|
33489
|
+
this.collection().createIndex({ siteId: 1 })
|
|
33490
|
+
]);
|
|
33491
|
+
}
|
|
33492
|
+
static async upsert(userId, token, platform, siteId, projectId, appSlug) {
|
|
33493
|
+
const now = /* @__PURE__ */ new Date();
|
|
33494
|
+
const p = platform;
|
|
33495
|
+
const existing = await this.collection().findOne({ token });
|
|
33496
|
+
if (existing) {
|
|
33497
|
+
await this.collection().updateOne(
|
|
33498
|
+
{ token },
|
|
33499
|
+
{
|
|
33500
|
+
$set: {
|
|
33501
|
+
userId,
|
|
33502
|
+
platform: p,
|
|
33503
|
+
siteId,
|
|
33504
|
+
projectId,
|
|
33505
|
+
appSlug,
|
|
33506
|
+
updatedAt: now
|
|
33507
|
+
}
|
|
33508
|
+
}
|
|
33509
|
+
);
|
|
33510
|
+
return;
|
|
33511
|
+
}
|
|
33512
|
+
await this.collection().deleteMany({ userId, platform: p });
|
|
33513
|
+
await this.collection().insertOne({
|
|
33514
|
+
userId,
|
|
33515
|
+
siteId,
|
|
33516
|
+
token,
|
|
33517
|
+
platform: p,
|
|
33518
|
+
projectId,
|
|
33519
|
+
appSlug,
|
|
33520
|
+
createdAt: now,
|
|
33521
|
+
updatedAt: now
|
|
33522
|
+
});
|
|
33523
|
+
}
|
|
33524
|
+
static async remove(token) {
|
|
33525
|
+
await this.collection().deleteMany({ token });
|
|
33526
|
+
}
|
|
33527
|
+
static async findTokensByUserIds(userIds, appSlug) {
|
|
33528
|
+
const docs = await this.collection().find({ userId: { $in: userIds }, appSlug: { $eq: appSlug } }).toArray();
|
|
33529
|
+
return docs.map((d) => d.token);
|
|
33530
|
+
}
|
|
33531
|
+
};
|
|
33532
|
+
|
|
33533
|
+
// src/services/notification.service.ts
|
|
33534
|
+
function toStringArray(recipient) {
|
|
33535
|
+
const arr = Array.isArray(recipient) ? recipient : [recipient];
|
|
33536
|
+
return arr.map((r) => r.toString());
|
|
33537
|
+
}
|
|
33538
|
+
async function send(userIds, title, body, data, isForMAMobileApp = false, appSlug) {
|
|
33539
|
+
try {
|
|
33540
|
+
let tokens = [];
|
|
33541
|
+
if (isForMAMobileApp) {
|
|
33542
|
+
tokens = await PushTokenRepo.findTokensByUserIds(userIds, appSlug);
|
|
33543
|
+
} else {
|
|
33544
|
+
tokens = await PushTokenRepo.findTokensByUserIds(userIds);
|
|
33545
|
+
}
|
|
33546
|
+
if (!tokens.length)
|
|
33547
|
+
return;
|
|
33548
|
+
for (const token of tokens) {
|
|
33549
|
+
await sendExpoPushNotifications([token], { title, body, data });
|
|
33550
|
+
}
|
|
33551
|
+
} catch (error) {
|
|
33552
|
+
console.warn("[NotificationService]", error);
|
|
33553
|
+
}
|
|
33554
|
+
}
|
|
33555
|
+
var NotificationService = class {
|
|
33556
|
+
static async bulletinBoardCreated(payload) {
|
|
33557
|
+
await send(
|
|
33558
|
+
toStringArray(payload.to),
|
|
33559
|
+
"Bulletin Board",
|
|
33560
|
+
`There is new ${payload.status} bulletin board.`,
|
|
33561
|
+
{
|
|
33562
|
+
bulletinId: payload.bulletinId.toString(),
|
|
33563
|
+
status: payload.status,
|
|
33564
|
+
module: "feedback",
|
|
33565
|
+
screen: "/(user)/bulletinInfo",
|
|
33566
|
+
params: {
|
|
33567
|
+
id: payload.bulletinId.toString()
|
|
33568
|
+
}
|
|
33569
|
+
},
|
|
33570
|
+
false,
|
|
33571
|
+
"iservice365-resident-mobile-app"
|
|
33572
|
+
);
|
|
33573
|
+
}
|
|
33574
|
+
static async prelovedMarketplacePostCreation(payload) {
|
|
33575
|
+
await send(
|
|
33576
|
+
toStringArray(payload.to),
|
|
33577
|
+
"Preloved Marketplace",
|
|
33578
|
+
`New preloved marketplace post added.`,
|
|
33579
|
+
{
|
|
33580
|
+
prelovedId: payload.prelovedId.toString(),
|
|
33581
|
+
status: payload.status,
|
|
33582
|
+
module: "prelovedMarketplace",
|
|
33583
|
+
screen: "/(user)/(marketplace)/prelovedPostInfo",
|
|
33584
|
+
params: {
|
|
33585
|
+
id: payload.prelovedId.toString()
|
|
33586
|
+
}
|
|
33587
|
+
},
|
|
33588
|
+
false,
|
|
33589
|
+
"iservice365-resident-mobile-app"
|
|
33590
|
+
);
|
|
33591
|
+
}
|
|
33592
|
+
static async bulletinBoardCreatedForMA(payload) {
|
|
33593
|
+
await send(
|
|
33594
|
+
toStringArray(payload.to),
|
|
33595
|
+
"Bulletin Board",
|
|
33596
|
+
`There is new ${payload.status} bulletin board.`,
|
|
33597
|
+
{
|
|
33598
|
+
bulletinId: payload.bulletinId.toString(),
|
|
33599
|
+
status: payload.status,
|
|
33600
|
+
module: "feedback",
|
|
33601
|
+
screen: "/(user)/(bulletin-board)",
|
|
33602
|
+
params: {
|
|
33603
|
+
id: payload.bulletinId.toString()
|
|
33604
|
+
}
|
|
33605
|
+
},
|
|
33606
|
+
true,
|
|
33607
|
+
"iservice365-ma-mobile-app"
|
|
33608
|
+
);
|
|
33609
|
+
}
|
|
33610
|
+
static async eventCreatedForMA(payload) {
|
|
33611
|
+
await send(
|
|
33612
|
+
toStringArray(payload.to),
|
|
33613
|
+
"Event",
|
|
33614
|
+
`There is new ${payload.status} event.`,
|
|
33615
|
+
{
|
|
33616
|
+
eventId: payload.eventId.toString(),
|
|
33617
|
+
status: payload.status,
|
|
33618
|
+
module: "event",
|
|
33619
|
+
screen: "/(user)/(events)",
|
|
33620
|
+
params: {
|
|
33621
|
+
id: payload.eventId.toString()
|
|
33622
|
+
}
|
|
33623
|
+
},
|
|
33624
|
+
true,
|
|
33625
|
+
"iservice365-ma-mobile-app"
|
|
33626
|
+
);
|
|
33627
|
+
}
|
|
33628
|
+
static async invitedVisitorCheckOutForMa(payload) {
|
|
33629
|
+
await send(
|
|
33630
|
+
toStringArray(payload.to),
|
|
33631
|
+
"Invited Visitor Check Out",
|
|
33632
|
+
`The invited visitor ${payload.name}, has been checked out.`,
|
|
33633
|
+
{
|
|
33634
|
+
visitorTransactionId: payload._id.toString(),
|
|
33635
|
+
module: "visitors",
|
|
33636
|
+
screen: "/(user)/visitor-management",
|
|
33637
|
+
params: {
|
|
33638
|
+
id: payload._id.toString()
|
|
33639
|
+
}
|
|
33640
|
+
},
|
|
33641
|
+
true,
|
|
33642
|
+
"iservice365-ma-mobile-app"
|
|
33643
|
+
);
|
|
33644
|
+
}
|
|
33645
|
+
};
|
|
33646
|
+
|
|
33397
33647
|
// src/services/visitor-transaction.service.ts
|
|
33398
33648
|
function useVisitorTransactionService() {
|
|
33399
33649
|
const MailerConfig = {
|
|
@@ -33432,6 +33682,7 @@ function useVisitorTransactionService() {
|
|
|
33432
33682
|
getBlocklistedVehicleByPlateNumber: _getBlocklistedVehicleByPlateNumber
|
|
33433
33683
|
} = useVehicleRepo();
|
|
33434
33684
|
const { getById: _getUnitById } = useBuildingUnitRepo();
|
|
33685
|
+
const { getUsersBySiteId } = useMemberRepo();
|
|
33435
33686
|
function extractKeyId(item) {
|
|
33436
33687
|
if (!item)
|
|
33437
33688
|
return null;
|
|
@@ -33581,47 +33832,50 @@ function useVisitorTransactionService() {
|
|
|
33581
33832
|
const chunk = value.members.slice(i, i + chunkSize);
|
|
33582
33833
|
for (const member of chunk) {
|
|
33583
33834
|
await KeyRepo.checkPassKeyAvailability(member.visitorPass, member.passKeys);
|
|
33584
|
-
if (
|
|
33585
|
-
for (const
|
|
33586
|
-
|
|
33587
|
-
|
|
33588
|
-
|
|
33589
|
-
|
|
33590
|
-
|
|
33591
|
-
|
|
33592
|
-
|
|
33593
|
-
|
|
33594
|
-
|
|
33595
|
-
|
|
33596
|
-
|
|
33597
|
-
|
|
33598
|
-
|
|
33835
|
+
if (Array.isArray(member.visitorPass)) {
|
|
33836
|
+
for (const item of member.visitorPass) {
|
|
33837
|
+
console.log("Type of keyId:", typeof item.keyId);
|
|
33838
|
+
console.log("item visitorPass", item);
|
|
33839
|
+
await KeyRepo.updateKeyById(
|
|
33840
|
+
item.keyId,
|
|
33841
|
+
{
|
|
33842
|
+
status: "In Use" /* IN_USE */,
|
|
33843
|
+
updatedBy: value.createdBy
|
|
33844
|
+
},
|
|
33845
|
+
value.site,
|
|
33846
|
+
session
|
|
33847
|
+
);
|
|
33848
|
+
item.receivedDate = /* @__PURE__ */ new Date();
|
|
33849
|
+
item.status = "Not Returned" /* NOT_RETURNED */;
|
|
33850
|
+
item.lastUpdate = null;
|
|
33851
|
+
item.remarks = "";
|
|
33599
33852
|
}
|
|
33600
33853
|
}
|
|
33601
|
-
if (
|
|
33602
|
-
for (const
|
|
33603
|
-
|
|
33604
|
-
|
|
33605
|
-
|
|
33606
|
-
|
|
33607
|
-
value.
|
|
33608
|
-
|
|
33609
|
-
|
|
33610
|
-
|
|
33611
|
-
|
|
33612
|
-
|
|
33613
|
-
|
|
33614
|
-
|
|
33615
|
-
|
|
33854
|
+
if (Array.isArray(member.passKeys)) {
|
|
33855
|
+
for (const item of member.passKeys) {
|
|
33856
|
+
await KeyRepo.updateKeyById(
|
|
33857
|
+
item.keyId,
|
|
33858
|
+
{
|
|
33859
|
+
status: "In Use" /* IN_USE */,
|
|
33860
|
+
updatedBy: value.createdBy
|
|
33861
|
+
},
|
|
33862
|
+
value.site,
|
|
33863
|
+
session
|
|
33864
|
+
);
|
|
33865
|
+
item.receivedDate = /* @__PURE__ */ new Date();
|
|
33866
|
+
item.status = "Not Returned" /* NOT_RETURNED */;
|
|
33867
|
+
item.lastUpdate = null;
|
|
33868
|
+
item.remarks = "";
|
|
33616
33869
|
}
|
|
33617
33870
|
}
|
|
33618
33871
|
}
|
|
33619
33872
|
await Promise.all(
|
|
33620
33873
|
chunk.map((member) => {
|
|
33621
|
-
const
|
|
33874
|
+
const clonedMember = structuredClone(member);
|
|
33875
|
+
const { visitorPass, passKeys } = clonedMember;
|
|
33622
33876
|
return _add(
|
|
33623
33877
|
{
|
|
33624
|
-
...
|
|
33878
|
+
...clonedMember,
|
|
33625
33879
|
block,
|
|
33626
33880
|
level,
|
|
33627
33881
|
unit,
|
|
@@ -33668,38 +33922,38 @@ function useVisitorTransactionService() {
|
|
|
33668
33922
|
throw new BadRequestError100("This plate number is blocklisted");
|
|
33669
33923
|
}
|
|
33670
33924
|
await KeyRepo.checkPassKeyAvailability(value.visitorPass, value.passKeys);
|
|
33671
|
-
if (
|
|
33672
|
-
for (const
|
|
33673
|
-
|
|
33674
|
-
|
|
33675
|
-
|
|
33676
|
-
|
|
33677
|
-
value.
|
|
33678
|
-
|
|
33679
|
-
|
|
33680
|
-
|
|
33681
|
-
|
|
33682
|
-
|
|
33683
|
-
|
|
33684
|
-
|
|
33685
|
-
|
|
33925
|
+
if (Array.isArray(value.visitorPass)) {
|
|
33926
|
+
for (const item of value.visitorPass) {
|
|
33927
|
+
await KeyRepo.updateKeyById(
|
|
33928
|
+
item.keyId,
|
|
33929
|
+
{
|
|
33930
|
+
status: "In Use" /* IN_USE */,
|
|
33931
|
+
updatedBy: value.createdBy
|
|
33932
|
+
},
|
|
33933
|
+
value.site,
|
|
33934
|
+
session
|
|
33935
|
+
);
|
|
33936
|
+
item.receivedDate = /* @__PURE__ */ new Date();
|
|
33937
|
+
item.status = "Not Returned" /* NOT_RETURNED */;
|
|
33938
|
+
item.lastUpdate = null;
|
|
33939
|
+
item.remarks = "";
|
|
33686
33940
|
}
|
|
33687
33941
|
}
|
|
33688
|
-
if (
|
|
33689
|
-
for (const
|
|
33690
|
-
|
|
33691
|
-
|
|
33692
|
-
|
|
33693
|
-
|
|
33694
|
-
value.
|
|
33695
|
-
|
|
33696
|
-
|
|
33697
|
-
|
|
33698
|
-
|
|
33699
|
-
|
|
33700
|
-
|
|
33701
|
-
|
|
33702
|
-
|
|
33942
|
+
if (Array.isArray(value.passKeys)) {
|
|
33943
|
+
for (const item of value.passKeys) {
|
|
33944
|
+
await KeyRepo.updateKeyById(
|
|
33945
|
+
item.keyId,
|
|
33946
|
+
{
|
|
33947
|
+
status: "In Use" /* IN_USE */,
|
|
33948
|
+
updatedBy: value.createdBy
|
|
33949
|
+
},
|
|
33950
|
+
value.site,
|
|
33951
|
+
session
|
|
33952
|
+
);
|
|
33953
|
+
item.receivedDate = /* @__PURE__ */ new Date();
|
|
33954
|
+
item.status = "Not Returned" /* NOT_RETURNED */;
|
|
33955
|
+
item.lastUpdate = null;
|
|
33956
|
+
item.remarks = "";
|
|
33703
33957
|
}
|
|
33704
33958
|
}
|
|
33705
33959
|
const result = await _add(value, session);
|
|
@@ -33869,6 +34123,28 @@ function useVisitorTransactionService() {
|
|
|
33869
34123
|
}
|
|
33870
34124
|
}
|
|
33871
34125
|
console.log("Open barrier response:", openBarrier);
|
|
34126
|
+
const visitorTransaction = await _getVisitorTransactionById(
|
|
34127
|
+
id.toString()
|
|
34128
|
+
);
|
|
34129
|
+
if (!visitorTransaction) {
|
|
34130
|
+
throw new Error("Visitor transaction not found.");
|
|
34131
|
+
}
|
|
34132
|
+
if (value.checkOut && visitorTransaction.type === "guest" /* GUEST */) {
|
|
34133
|
+
const users = await getUsersBySiteId({
|
|
34134
|
+
status: "active",
|
|
34135
|
+
siteId: visitorTransaction.site.toString()
|
|
34136
|
+
});
|
|
34137
|
+
if (users?.length > 0) {
|
|
34138
|
+
const userIds = Array.from(
|
|
34139
|
+
new Set(users.map((item) => item.user.toString()))
|
|
34140
|
+
);
|
|
34141
|
+
NotificationService.invitedVisitorCheckOutForMa({
|
|
34142
|
+
to: userIds,
|
|
34143
|
+
name: visitorTransaction.name,
|
|
34144
|
+
_id: id.toString()
|
|
34145
|
+
});
|
|
34146
|
+
}
|
|
34147
|
+
}
|
|
33872
34148
|
await session?.commitTransaction();
|
|
33873
34149
|
return "Successfully updated visitor transaction.";
|
|
33874
34150
|
} catch (error) {
|
|
@@ -33960,9 +34236,9 @@ function useVisitorTransactionService() {
|
|
|
33960
34236
|
value.checkIn = null;
|
|
33961
34237
|
const payload = {
|
|
33962
34238
|
...value,
|
|
33963
|
-
block: inviter?.block,
|
|
33964
|
-
level: inviter?.level,
|
|
33965
|
-
unit: inviter?.unit,
|
|
34239
|
+
block: inviter?.block?.toString(),
|
|
34240
|
+
level: inviter?.level?.toString(),
|
|
34241
|
+
unit: inviter?.unit?.toString(),
|
|
33966
34242
|
unitName: unit?.name,
|
|
33967
34243
|
org: inviter?.org.toString(),
|
|
33968
34244
|
site: inviter?.site.toString(),
|
|
@@ -34058,7 +34334,8 @@ function useVisitorTransactionController() {
|
|
|
34058
34334
|
} = useVisitorTransactionRepo();
|
|
34059
34335
|
async function add(req, res, next) {
|
|
34060
34336
|
try {
|
|
34061
|
-
const {
|
|
34337
|
+
const { companyName, firstName, lastName, ...restData } = req.body;
|
|
34338
|
+
const { error, value } = schemaVisitorTransaction.validate(restData, {
|
|
34062
34339
|
abortEarly: false
|
|
34063
34340
|
});
|
|
34064
34341
|
if (error) {
|
|
@@ -34290,8 +34567,11 @@ function useVisitorTransactionController() {
|
|
|
34290
34567
|
return;
|
|
34291
34568
|
} catch (error2) {
|
|
34292
34569
|
logger81.log({ level: "error", message: error2.message });
|
|
34293
|
-
|
|
34294
|
-
|
|
34570
|
+
if (error2?.message) {
|
|
34571
|
+
next(new BadRequestError101(error2?.message));
|
|
34572
|
+
} else {
|
|
34573
|
+
next(error2);
|
|
34574
|
+
}
|
|
34295
34575
|
}
|
|
34296
34576
|
}
|
|
34297
34577
|
async function changeVisitorTransactionKeysById(req, res, next) {
|
|
@@ -41032,120 +41312,6 @@ function useBulletinBoardRepo() {
|
|
|
41032
41312
|
// src/services/bulletin-board.service.ts
|
|
41033
41313
|
import { useAtlas as useAtlas68, NotFoundError as NotFoundError30 } from "@7365admin1/node-server-utils";
|
|
41034
41314
|
import { ObjectId as ObjectId85 } from "mongodb";
|
|
41035
|
-
|
|
41036
|
-
// src/services/notification.service.ts
|
|
41037
|
-
import { sendExpoPushNotifications } from "iservice365-expo-notifications";
|
|
41038
|
-
|
|
41039
|
-
// src/repositories/push-token.repository.ts
|
|
41040
|
-
var PushTokenRepo = class {
|
|
41041
|
-
static collection() {
|
|
41042
|
-
return getDB().collection("push_tokens");
|
|
41043
|
-
}
|
|
41044
|
-
static async createIndexes() {
|
|
41045
|
-
await Promise.all([
|
|
41046
|
-
this.collection().createIndex({ token: 1 }, { unique: true }),
|
|
41047
|
-
this.collection().createIndex({ userId: 1, platform: 1 }),
|
|
41048
|
-
this.collection().createIndex({ siteId: 1 })
|
|
41049
|
-
]);
|
|
41050
|
-
}
|
|
41051
|
-
static async upsert(userId, token, platform, siteId, projectId, appSlug) {
|
|
41052
|
-
const now = /* @__PURE__ */ new Date();
|
|
41053
|
-
const p = platform;
|
|
41054
|
-
const existing = await this.collection().findOne({ token });
|
|
41055
|
-
if (existing) {
|
|
41056
|
-
await this.collection().updateOne(
|
|
41057
|
-
{ token },
|
|
41058
|
-
{
|
|
41059
|
-
$set: {
|
|
41060
|
-
userId,
|
|
41061
|
-
platform: p,
|
|
41062
|
-
siteId,
|
|
41063
|
-
projectId,
|
|
41064
|
-
appSlug,
|
|
41065
|
-
updatedAt: now
|
|
41066
|
-
}
|
|
41067
|
-
}
|
|
41068
|
-
);
|
|
41069
|
-
return;
|
|
41070
|
-
}
|
|
41071
|
-
await this.collection().deleteMany({ userId, platform: p });
|
|
41072
|
-
await this.collection().insertOne({
|
|
41073
|
-
userId,
|
|
41074
|
-
siteId,
|
|
41075
|
-
token,
|
|
41076
|
-
platform: p,
|
|
41077
|
-
projectId,
|
|
41078
|
-
appSlug,
|
|
41079
|
-
createdAt: now,
|
|
41080
|
-
updatedAt: now
|
|
41081
|
-
});
|
|
41082
|
-
}
|
|
41083
|
-
static async remove(token) {
|
|
41084
|
-
await this.collection().deleteMany({ token });
|
|
41085
|
-
}
|
|
41086
|
-
static async findTokensByUserIds(userIds, appSlug) {
|
|
41087
|
-
const docs = await this.collection().find({ userId: { $in: userIds }, appSlug: { $eq: appSlug } }).toArray();
|
|
41088
|
-
return docs.map((d) => d.token);
|
|
41089
|
-
}
|
|
41090
|
-
};
|
|
41091
|
-
|
|
41092
|
-
// src/services/notification.service.ts
|
|
41093
|
-
function toStringArray(recipient) {
|
|
41094
|
-
const arr = Array.isArray(recipient) ? recipient : [recipient];
|
|
41095
|
-
return arr.map((r) => r.toString());
|
|
41096
|
-
}
|
|
41097
|
-
async function send(userIds, title, body, data, appSlug) {
|
|
41098
|
-
try {
|
|
41099
|
-
const tokens = Array.from(
|
|
41100
|
-
new Set(await PushTokenRepo.findTokensByUserIds(userIds, appSlug))
|
|
41101
|
-
);
|
|
41102
|
-
if (!tokens.length)
|
|
41103
|
-
return;
|
|
41104
|
-
for (const token of tokens) {
|
|
41105
|
-
await sendExpoPushNotifications([token], { title, body, data });
|
|
41106
|
-
}
|
|
41107
|
-
} catch (error) {
|
|
41108
|
-
console.warn("[NotificationService]", error);
|
|
41109
|
-
}
|
|
41110
|
-
}
|
|
41111
|
-
var NotificationService = class {
|
|
41112
|
-
static async bulletinBoardCreated(payload) {
|
|
41113
|
-
await send(
|
|
41114
|
-
toStringArray(payload.to),
|
|
41115
|
-
"Bulletin Board",
|
|
41116
|
-
`There is new ${payload.status} bulletin board.`,
|
|
41117
|
-
{
|
|
41118
|
-
bulletinId: payload.bulletinId.toString(),
|
|
41119
|
-
status: payload.status,
|
|
41120
|
-
module: "feedback",
|
|
41121
|
-
screen: "/(user)/bulletinInfo",
|
|
41122
|
-
params: {
|
|
41123
|
-
id: payload.bulletinId.toString()
|
|
41124
|
-
}
|
|
41125
|
-
},
|
|
41126
|
-
"iservice365-resident-mobile-app"
|
|
41127
|
-
);
|
|
41128
|
-
}
|
|
41129
|
-
static async prelovedMarketplacePostCreation(payload) {
|
|
41130
|
-
await send(
|
|
41131
|
-
toStringArray(payload.to),
|
|
41132
|
-
"Preloved Marketplace",
|
|
41133
|
-
`New preloved marketplace post added.`,
|
|
41134
|
-
{
|
|
41135
|
-
prelovedId: payload.prelovedId.toString(),
|
|
41136
|
-
status: payload.status,
|
|
41137
|
-
module: "prelovedMarketplace",
|
|
41138
|
-
screen: "/(user)/(marketplace)/prelovedPostInfo",
|
|
41139
|
-
params: {
|
|
41140
|
-
id: payload.prelovedId.toString()
|
|
41141
|
-
}
|
|
41142
|
-
},
|
|
41143
|
-
"iservice365-resident-mobile-app"
|
|
41144
|
-
);
|
|
41145
|
-
}
|
|
41146
|
-
};
|
|
41147
|
-
|
|
41148
|
-
// src/services/bulletin-board.service.ts
|
|
41149
41315
|
function useBulletinBoardService() {
|
|
41150
41316
|
const {
|
|
41151
41317
|
add: _add,
|
|
@@ -41212,6 +41378,12 @@ function useBulletinBoardService() {
|
|
|
41212
41378
|
status: bulletinBoardStatus
|
|
41213
41379
|
});
|
|
41214
41380
|
}
|
|
41381
|
+
NotificationService.bulletinBoardCreatedForMA({
|
|
41382
|
+
to: userIds,
|
|
41383
|
+
bulletinId: bulletinBoardId,
|
|
41384
|
+
subject: "Bulletin Board",
|
|
41385
|
+
status: bulletinBoardStatus
|
|
41386
|
+
});
|
|
41215
41387
|
}
|
|
41216
41388
|
await session?.commitTransaction();
|
|
41217
41389
|
return "Successfully added bulletin board.";
|
|
@@ -43174,11 +43346,27 @@ function useEventManagementService() {
|
|
|
43174
43346
|
updateEventManagementById: _updateEventManagementById,
|
|
43175
43347
|
processCompletedEvents: _processCompletedEvents
|
|
43176
43348
|
} = useEventManagementRepo();
|
|
43349
|
+
const { getUsersBySiteId } = useMemberRepo();
|
|
43177
43350
|
async function add(value) {
|
|
43178
43351
|
const session = useAtlas74.getClient()?.startSession();
|
|
43179
43352
|
try {
|
|
43180
43353
|
session?.startTransaction();
|
|
43181
|
-
await _add(value, session);
|
|
43354
|
+
const response = await _add(value, session);
|
|
43355
|
+
console.log("response", response);
|
|
43356
|
+
const users = await getUsersBySiteId({
|
|
43357
|
+
status: "active",
|
|
43358
|
+
siteId: value.site
|
|
43359
|
+
});
|
|
43360
|
+
if (users?.length > 0) {
|
|
43361
|
+
const userIds = Array.from(
|
|
43362
|
+
new Set(users.map((item) => item.user.toString()))
|
|
43363
|
+
);
|
|
43364
|
+
NotificationService.eventCreatedForMA({
|
|
43365
|
+
to: userIds,
|
|
43366
|
+
eventId: response,
|
|
43367
|
+
status: value.status
|
|
43368
|
+
});
|
|
43369
|
+
}
|
|
43182
43370
|
await session?.commitTransaction();
|
|
43183
43371
|
return "Successfully added event.";
|
|
43184
43372
|
} catch (error) {
|
|
@@ -56685,73 +56873,6 @@ var Period = /* @__PURE__ */ ((Period2) => {
|
|
|
56685
56873
|
Period2["THIS_MONTH"] = "thisMonth";
|
|
56686
56874
|
return Period2;
|
|
56687
56875
|
})(Period || {});
|
|
56688
|
-
function getPeriodRangeWithPrevious(period) {
|
|
56689
|
-
const now = /* @__PURE__ */ new Date();
|
|
56690
|
-
let currentStart = /* @__PURE__ */ new Date();
|
|
56691
|
-
let currentEnd = /* @__PURE__ */ new Date();
|
|
56692
|
-
let previousStart = /* @__PURE__ */ new Date();
|
|
56693
|
-
let previousEnd = /* @__PURE__ */ new Date();
|
|
56694
|
-
if (period === "today" /* TODAY */) {
|
|
56695
|
-
currentStart.setHours(0, 0, 0, 0);
|
|
56696
|
-
currentEnd.setHours(23, 59, 59, 999);
|
|
56697
|
-
previousStart = new Date(currentStart);
|
|
56698
|
-
previousStart.setDate(previousStart.getDate() - 1);
|
|
56699
|
-
previousEnd = new Date(currentEnd);
|
|
56700
|
-
previousEnd.setDate(previousEnd.getDate() - 1);
|
|
56701
|
-
} else if (period === "thisWeek" /* THIS_WEEK */) {
|
|
56702
|
-
const day = now.getDay();
|
|
56703
|
-
const diffToMonday = day === 0 ? -6 : 1 - day;
|
|
56704
|
-
currentStart = new Date(now);
|
|
56705
|
-
currentStart.setDate(now.getDate() + diffToMonday);
|
|
56706
|
-
currentStart.setHours(0, 0, 0, 0);
|
|
56707
|
-
currentEnd = new Date(currentStart);
|
|
56708
|
-
currentEnd.setDate(currentStart.getDate() + 6);
|
|
56709
|
-
currentEnd.setHours(23, 59, 59, 999);
|
|
56710
|
-
previousStart = new Date(currentStart);
|
|
56711
|
-
previousStart.setDate(previousStart.getDate() - 7);
|
|
56712
|
-
previousEnd = new Date(currentEnd);
|
|
56713
|
-
previousEnd.setDate(previousEnd.getDate() - 7);
|
|
56714
|
-
} else if (period === "thisMonth" /* THIS_MONTH */) {
|
|
56715
|
-
currentStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
56716
|
-
currentEnd = new Date(
|
|
56717
|
-
now.getFullYear(),
|
|
56718
|
-
now.getMonth() + 1,
|
|
56719
|
-
0,
|
|
56720
|
-
23,
|
|
56721
|
-
59,
|
|
56722
|
-
59,
|
|
56723
|
-
999
|
|
56724
|
-
);
|
|
56725
|
-
previousStart = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
|
56726
|
-
previousEnd = new Date(
|
|
56727
|
-
now.getFullYear(),
|
|
56728
|
-
now.getMonth(),
|
|
56729
|
-
0,
|
|
56730
|
-
23,
|
|
56731
|
-
59,
|
|
56732
|
-
59,
|
|
56733
|
-
999
|
|
56734
|
-
);
|
|
56735
|
-
} else {
|
|
56736
|
-
throw new BadRequestError182("Invalid period.");
|
|
56737
|
-
}
|
|
56738
|
-
return {
|
|
56739
|
-
current: {
|
|
56740
|
-
start: currentStart.toISOString(),
|
|
56741
|
-
end: currentEnd.toISOString()
|
|
56742
|
-
},
|
|
56743
|
-
previous: {
|
|
56744
|
-
start: previousStart.toISOString(),
|
|
56745
|
-
end: previousEnd.toISOString()
|
|
56746
|
-
}
|
|
56747
|
-
};
|
|
56748
|
-
}
|
|
56749
|
-
function calculatePercentage(current, previous) {
|
|
56750
|
-
if (previous === 0) {
|
|
56751
|
-
return current === 0 ? 0 : 100;
|
|
56752
|
-
}
|
|
56753
|
-
return Number(((current - previous) / previous * 100).toFixed(2));
|
|
56754
|
-
}
|
|
56755
56876
|
function useNewDashboardRepo() {
|
|
56756
56877
|
const db = useAtlas100.getDb();
|
|
56757
56878
|
if (!db) {
|
|
@@ -57260,7 +57381,8 @@ function useNewDashboardRepo() {
|
|
|
57260
57381
|
currentlyOnSiteCount,
|
|
57261
57382
|
facilityReport,
|
|
57262
57383
|
yesterdayFacilityReport,
|
|
57263
|
-
todayFacilityReport
|
|
57384
|
+
todayFacilityReport,
|
|
57385
|
+
workOrderStatusReport
|
|
57264
57386
|
] = await Promise.all([
|
|
57265
57387
|
workOrderCollection.aggregate([
|
|
57266
57388
|
{
|
|
@@ -57450,6 +57572,20 @@ function useNewDashboardRepo() {
|
|
|
57450
57572
|
}
|
|
57451
57573
|
},
|
|
57452
57574
|
{ $count: "count" }
|
|
57575
|
+
]).toArray(),
|
|
57576
|
+
workOrderCollection.aggregate([
|
|
57577
|
+
{
|
|
57578
|
+
$match: {
|
|
57579
|
+
site: { $in: [siteIdObj, siteId] },
|
|
57580
|
+
createdAt: periodRange
|
|
57581
|
+
}
|
|
57582
|
+
},
|
|
57583
|
+
{
|
|
57584
|
+
$group: {
|
|
57585
|
+
_id: "$status",
|
|
57586
|
+
count: { $sum: 1 }
|
|
57587
|
+
}
|
|
57588
|
+
}
|
|
57453
57589
|
]).toArray()
|
|
57454
57590
|
]);
|
|
57455
57591
|
const wFacet = workOrderReport[0] ?? { total: [], inProgress: [] };
|
|
@@ -57458,6 +57594,23 @@ function useNewDashboardRepo() {
|
|
|
57458
57594
|
ongoing: [],
|
|
57459
57595
|
waitingApproval: []
|
|
57460
57596
|
};
|
|
57597
|
+
const workOrderStatus = {
|
|
57598
|
+
pending: 0,
|
|
57599
|
+
inProgress: 0,
|
|
57600
|
+
completed: 0
|
|
57601
|
+
};
|
|
57602
|
+
for (const item of workOrderStatusReport || []) {
|
|
57603
|
+
const rawStatus = String(item._id || "").toLowerCase().trim();
|
|
57604
|
+
if (rawStatus === "to-do" || rawStatus === "for-review") {
|
|
57605
|
+
workOrderStatus.pending += item.count || 0;
|
|
57606
|
+
} else if (rawStatus === "in-progress") {
|
|
57607
|
+
workOrderStatus.inProgress += item.count || 0;
|
|
57608
|
+
} else if (rawStatus === "completed") {
|
|
57609
|
+
workOrderStatus.completed += item.count || 0;
|
|
57610
|
+
} else {
|
|
57611
|
+
workOrderStatus.pending += item.count || 0;
|
|
57612
|
+
}
|
|
57613
|
+
}
|
|
57461
57614
|
const data = {
|
|
57462
57615
|
openWorkOrder: {
|
|
57463
57616
|
count: wFacet.total[0]?.count ?? 0,
|
|
@@ -57492,6 +57645,7 @@ function useNewDashboardRepo() {
|
|
|
57492
57645
|
yesterdayFacilityReport[0]?.count ?? 0
|
|
57493
57646
|
)
|
|
57494
57647
|
},
|
|
57648
|
+
workOrderStatus,
|
|
57495
57649
|
upcomingEvents,
|
|
57496
57650
|
todayReminders,
|
|
57497
57651
|
todayAttentions
|
|
@@ -66191,7 +66345,8 @@ var schemaUpdateChatPreloved = Joi141.object({
|
|
|
66191
66345
|
reactions: Joi141.string().optional().allow("", null)
|
|
66192
66346
|
});
|
|
66193
66347
|
var schemaChatPreloved = Joi141.object({
|
|
66194
|
-
channelId: Joi141.string().hex().length(24).
|
|
66348
|
+
channelId: Joi141.string().hex().length(24).optional().allow("", null),
|
|
66349
|
+
receiverId: Joi141.string().hex().length(24).optional().allow("", null),
|
|
66195
66350
|
senderId: Joi141.string().hex().length(24).required(),
|
|
66196
66351
|
postId: Joi141.string().hex().length(24).optional().allow("", null),
|
|
66197
66352
|
message: schemaMessage.required(),
|
|
@@ -66238,7 +66393,7 @@ function MChatPreloved(value) {
|
|
|
66238
66393
|
}
|
|
66239
66394
|
return {
|
|
66240
66395
|
_id: new ObjectId145(),
|
|
66241
|
-
channelId: value.channelId ??
|
|
66396
|
+
channelId: value.channelId ?? null,
|
|
66242
66397
|
senderId: value.senderId ?? "",
|
|
66243
66398
|
postId: value.postId ?? null,
|
|
66244
66399
|
message: {
|
|
@@ -66320,10 +66475,6 @@ function useChatPrelovedRepo() {
|
|
|
66320
66475
|
return { add, updateById, deleteById };
|
|
66321
66476
|
}
|
|
66322
66477
|
|
|
66323
|
-
// src/controllers/chat-preloved.controller.ts
|
|
66324
|
-
import { BadRequestError as BadRequestError222, logger as logger192 } from "@7365admin1/node-server-utils";
|
|
66325
|
-
import Joi143 from "joi";
|
|
66326
|
-
|
|
66327
66478
|
// src/services/chat-preloved.service.ts
|
|
66328
66479
|
import { BadRequestError as BadRequestError221, InternalServerError as InternalServerError81, useAtlas as useAtlas126 } from "@7365admin1/node-server-utils";
|
|
66329
66480
|
|
|
@@ -66477,7 +66628,130 @@ function useChannelPrelovedRepo() {
|
|
|
66477
66628
|
throw error;
|
|
66478
66629
|
}
|
|
66479
66630
|
}
|
|
66480
|
-
|
|
66631
|
+
async function getChatLists(currentUserId, page = 1, limit = 10, search) {
|
|
66632
|
+
const normalizedPage = page > 0 ? page - 1 : 0;
|
|
66633
|
+
const normalizedLimit = limit || 10;
|
|
66634
|
+
const _currentUserId = new ObjectId148(currentUserId);
|
|
66635
|
+
const escapedSearch = search ? search.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") : null;
|
|
66636
|
+
const pipeline = [
|
|
66637
|
+
{
|
|
66638
|
+
$match: {
|
|
66639
|
+
$or: [{ receiverId: _currentUserId }, { senderId: _currentUserId }]
|
|
66640
|
+
}
|
|
66641
|
+
},
|
|
66642
|
+
{
|
|
66643
|
+
$lookup: {
|
|
66644
|
+
from: "users",
|
|
66645
|
+
localField: "senderId",
|
|
66646
|
+
foreignField: "_id",
|
|
66647
|
+
pipeline: [
|
|
66648
|
+
{
|
|
66649
|
+
$project: {
|
|
66650
|
+
name: 1,
|
|
66651
|
+
profile: 1,
|
|
66652
|
+
type: 1
|
|
66653
|
+
}
|
|
66654
|
+
}
|
|
66655
|
+
],
|
|
66656
|
+
as: "senderId"
|
|
66657
|
+
}
|
|
66658
|
+
},
|
|
66659
|
+
{ $unwind: { path: "$senderId", preserveNullAndEmptyArrays: true } },
|
|
66660
|
+
{
|
|
66661
|
+
$lookup: {
|
|
66662
|
+
from: "post-preloved",
|
|
66663
|
+
localField: "postId",
|
|
66664
|
+
foreignField: "_id",
|
|
66665
|
+
pipeline: [
|
|
66666
|
+
{
|
|
66667
|
+
$project: {
|
|
66668
|
+
title: 1,
|
|
66669
|
+
description: 1,
|
|
66670
|
+
attachments: 1,
|
|
66671
|
+
price: 1,
|
|
66672
|
+
status: 1,
|
|
66673
|
+
createdBy: 1,
|
|
66674
|
+
reserverId: 1
|
|
66675
|
+
}
|
|
66676
|
+
}
|
|
66677
|
+
],
|
|
66678
|
+
as: "postDetails"
|
|
66679
|
+
}
|
|
66680
|
+
},
|
|
66681
|
+
{ $unwind: { path: "$postDetails", preserveNullAndEmptyArrays: true } },
|
|
66682
|
+
...escapedSearch ? [
|
|
66683
|
+
{
|
|
66684
|
+
$match: {
|
|
66685
|
+
$or: [
|
|
66686
|
+
{
|
|
66687
|
+
"senderId.name": {
|
|
66688
|
+
$regex: new RegExp(escapedSearch, "i")
|
|
66689
|
+
}
|
|
66690
|
+
},
|
|
66691
|
+
{
|
|
66692
|
+
"postDetails.title": {
|
|
66693
|
+
$regex: new RegExp(escapedSearch, "i")
|
|
66694
|
+
}
|
|
66695
|
+
}
|
|
66696
|
+
]
|
|
66697
|
+
}
|
|
66698
|
+
}
|
|
66699
|
+
] : [],
|
|
66700
|
+
{
|
|
66701
|
+
$lookup: {
|
|
66702
|
+
from: "chat-preloved",
|
|
66703
|
+
localField: "_id",
|
|
66704
|
+
foreignField: "channelId",
|
|
66705
|
+
pipeline: [
|
|
66706
|
+
{ $match: { deletedAt: null } },
|
|
66707
|
+
{ $sort: { createdAt: -1 } },
|
|
66708
|
+
{ $limit: 1 }
|
|
66709
|
+
],
|
|
66710
|
+
as: "latestChat"
|
|
66711
|
+
}
|
|
66712
|
+
},
|
|
66713
|
+
{ $unwind: { path: "$latestChat", preserveNullAndEmptyArrays: true } },
|
|
66714
|
+
{ $addFields: { lastMessageDate: "$latestChat.createdAt" } },
|
|
66715
|
+
{
|
|
66716
|
+
$lookup: {
|
|
66717
|
+
from: "bid-preloved",
|
|
66718
|
+
localField: "postId",
|
|
66719
|
+
foreignField: "postId",
|
|
66720
|
+
pipeline: [
|
|
66721
|
+
{ $sort: { createdAt: -1 } },
|
|
66722
|
+
{ $limit: 1 },
|
|
66723
|
+
{ $project: { price: 1, message: 1, status: 1, type: 1 } }
|
|
66724
|
+
],
|
|
66725
|
+
as: "latestBidDetails"
|
|
66726
|
+
}
|
|
66727
|
+
},
|
|
66728
|
+
{
|
|
66729
|
+
$unwind: {
|
|
66730
|
+
path: "$latestBidDetails",
|
|
66731
|
+
preserveNullAndEmptyArrays: true
|
|
66732
|
+
}
|
|
66733
|
+
},
|
|
66734
|
+
{ $sort: { lastMessageDate: -1 } },
|
|
66735
|
+
{
|
|
66736
|
+
$facet: {
|
|
66737
|
+
totalCount: [{ $count: "count" }],
|
|
66738
|
+
items: [
|
|
66739
|
+
{ $skip: normalizedPage * normalizedLimit },
|
|
66740
|
+
{ $limit: normalizedLimit }
|
|
66741
|
+
]
|
|
66742
|
+
}
|
|
66743
|
+
}
|
|
66744
|
+
];
|
|
66745
|
+
try {
|
|
66746
|
+
const result = await collection.aggregate(pipeline).toArray();
|
|
66747
|
+
const totalCount = result[0].totalCount[0]?.count ?? 0;
|
|
66748
|
+
const items = result[0].items;
|
|
66749
|
+
return paginate63(items, normalizedPage, normalizedLimit, totalCount);
|
|
66750
|
+
} catch (error) {
|
|
66751
|
+
throw error;
|
|
66752
|
+
}
|
|
66753
|
+
}
|
|
66754
|
+
return { add, getByParticipants, getChatLists, getChannelMessages };
|
|
66481
66755
|
}
|
|
66482
66756
|
|
|
66483
66757
|
// src/services/chat-preloved.service.ts
|
|
@@ -66531,6 +66805,8 @@ function useChatPrelovedService() {
|
|
|
66531
66805
|
}
|
|
66532
66806
|
|
|
66533
66807
|
// src/controllers/chat-preloved.controller.ts
|
|
66808
|
+
import { BadRequestError as BadRequestError222, logger as logger192 } from "@7365admin1/node-server-utils";
|
|
66809
|
+
import Joi143 from "joi";
|
|
66534
66810
|
function useChatPrelovedController() {
|
|
66535
66811
|
const { add: _add } = useChatPrelovedService();
|
|
66536
66812
|
const { updateById: _updateById, deleteById: _deleteById } = useChatPrelovedRepo();
|
|
@@ -66595,7 +66871,12 @@ function useChatPrelovedController() {
|
|
|
66595
66871
|
import { BadRequestError as BadRequestError223, logger as logger193 } from "@7365admin1/node-server-utils";
|
|
66596
66872
|
import Joi144 from "joi";
|
|
66597
66873
|
function useChannelPrelovedController() {
|
|
66598
|
-
const {
|
|
66874
|
+
const {
|
|
66875
|
+
add: _add,
|
|
66876
|
+
getByParticipants: _getByParticipants,
|
|
66877
|
+
getChatLists: _getChatLists,
|
|
66878
|
+
getChannelMessages: _getChannelMessages
|
|
66879
|
+
} = useChannelPrelovedRepo();
|
|
66599
66880
|
async function add(req, res, next) {
|
|
66600
66881
|
const { error, value } = schemaChannelPreloved.validate(req.body, {
|
|
66601
66882
|
abortEarly: false
|
|
@@ -66632,9 +66913,7 @@ function useChannelPrelovedController() {
|
|
|
66632
66913
|
next(new BadRequestError223(paramError.message));
|
|
66633
66914
|
return;
|
|
66634
66915
|
}
|
|
66635
|
-
const { error: queryError, value: query } = querySchema.validate(
|
|
66636
|
-
req.query
|
|
66637
|
-
);
|
|
66916
|
+
const { error: queryError, value: query } = querySchema.validate(req.query);
|
|
66638
66917
|
if (queryError) {
|
|
66639
66918
|
logger193.log({ level: "error", message: queryError.message });
|
|
66640
66919
|
next(new BadRequestError223(queryError.message));
|
|
@@ -66654,61 +66933,253 @@ function useChannelPrelovedController() {
|
|
|
66654
66933
|
next(error);
|
|
66655
66934
|
}
|
|
66656
66935
|
}
|
|
66657
|
-
|
|
66936
|
+
async function getChannel(req, res, next) {
|
|
66937
|
+
const querySchema = Joi144.object({
|
|
66938
|
+
postId: Joi144.string().hex().length(24).required(),
|
|
66939
|
+
receiverId: Joi144.string().hex().length(24).required(),
|
|
66940
|
+
senderId: Joi144.string().hex().length(24).required()
|
|
66941
|
+
});
|
|
66942
|
+
const { error, value } = querySchema.validate(req.query);
|
|
66943
|
+
if (error) {
|
|
66944
|
+
logger193.log({ level: "error", message: error.message });
|
|
66945
|
+
next(new BadRequestError223(error.message));
|
|
66946
|
+
return;
|
|
66947
|
+
}
|
|
66948
|
+
try {
|
|
66949
|
+
const data = await _getByParticipants(
|
|
66950
|
+
value.senderId,
|
|
66951
|
+
value.receiverId,
|
|
66952
|
+
value.postId
|
|
66953
|
+
);
|
|
66954
|
+
res.status(200).json(data);
|
|
66955
|
+
} catch (error2) {
|
|
66956
|
+
logger193.log({ level: "error", message: error2.message });
|
|
66957
|
+
next(error2);
|
|
66958
|
+
}
|
|
66959
|
+
}
|
|
66960
|
+
async function getChatLists(req, res, next) {
|
|
66961
|
+
const querySchema = Joi144.object({
|
|
66962
|
+
currentUserId: Joi144.string().hex().length(24).required(),
|
|
66963
|
+
page: Joi144.number().integer().min(1).default(1),
|
|
66964
|
+
limit: Joi144.number().integer().min(1).max(100).default(10),
|
|
66965
|
+
search: Joi144.string().optional().allow("", null)
|
|
66966
|
+
});
|
|
66967
|
+
const { error, value } = querySchema.validate(req.query);
|
|
66968
|
+
if (error) {
|
|
66969
|
+
logger193.log({ level: "error", message: error.message });
|
|
66970
|
+
next(new BadRequestError223(error.message));
|
|
66971
|
+
return;
|
|
66972
|
+
}
|
|
66973
|
+
try {
|
|
66974
|
+
const data = await _getChatLists(
|
|
66975
|
+
value.currentUserId,
|
|
66976
|
+
value.page,
|
|
66977
|
+
value.limit,
|
|
66978
|
+
value.search || void 0
|
|
66979
|
+
);
|
|
66980
|
+
res.status(200).json(data);
|
|
66981
|
+
} catch (error2) {
|
|
66982
|
+
logger193.log({ level: "error", message: error2.message });
|
|
66983
|
+
next(error2);
|
|
66984
|
+
}
|
|
66985
|
+
}
|
|
66986
|
+
return { add, getChannel, getChatLists, getChannelMessages };
|
|
66658
66987
|
}
|
|
66659
66988
|
|
|
66660
|
-
// src/models/
|
|
66989
|
+
// src/models/bid-preloved.model.ts
|
|
66661
66990
|
import Joi145 from "joi";
|
|
66662
66991
|
import { ObjectId as ObjectId149 } from "mongodb";
|
|
66992
|
+
var BidType = /* @__PURE__ */ ((BidType2) => {
|
|
66993
|
+
BidType2["BID"] = "bid";
|
|
66994
|
+
BidType2["RESERVE"] = "reserve";
|
|
66995
|
+
return BidType2;
|
|
66996
|
+
})(BidType || {});
|
|
66997
|
+
var BidStatus = /* @__PURE__ */ ((BidStatus3) => {
|
|
66998
|
+
BidStatus3["PENDING"] = "pending";
|
|
66999
|
+
BidStatus3["ACCEPTED"] = "accepted";
|
|
67000
|
+
BidStatus3["RESERVED"] = "reserved";
|
|
67001
|
+
BidStatus3["CANCELLED"] = "cancelled";
|
|
67002
|
+
return BidStatus3;
|
|
67003
|
+
})(BidStatus || {});
|
|
67004
|
+
var schemaBidPreloved = Joi145.object({
|
|
67005
|
+
type: Joi145.string().valid(...Object.values(BidType)).required(),
|
|
67006
|
+
postId: Joi145.string().hex().length(24).required(),
|
|
67007
|
+
price: Joi145.when("type", {
|
|
67008
|
+
is: "bid" /* BID */,
|
|
67009
|
+
then: Joi145.number().required(),
|
|
67010
|
+
otherwise: Joi145.number().optional().allow(null)
|
|
67011
|
+
}),
|
|
67012
|
+
message: Joi145.string().optional().allow("", null),
|
|
67013
|
+
buyerId: Joi145.string().hex().length(24).optional().allow("", null),
|
|
67014
|
+
status: Joi145.string().valid(...Object.values(BidStatus)).optional().default("pending" /* PENDING */)
|
|
67015
|
+
});
|
|
67016
|
+
var schemaUpdateBidPreloved = Joi145.object({
|
|
67017
|
+
status: Joi145.string().valid(...Object.values(BidStatus)).required()
|
|
67018
|
+
});
|
|
67019
|
+
function MBidPreloved(value) {
|
|
67020
|
+
const { error } = schemaBidPreloved.validate(value);
|
|
67021
|
+
if (error)
|
|
67022
|
+
throw new Error(error.details[0].message);
|
|
67023
|
+
if (value.postId && typeof value.postId === "string")
|
|
67024
|
+
value.postId = new ObjectId149(value.postId);
|
|
67025
|
+
if (value.buyerId && typeof value.buyerId === "string")
|
|
67026
|
+
value.buyerId = new ObjectId149(value.buyerId);
|
|
67027
|
+
return {
|
|
67028
|
+
_id: new ObjectId149(),
|
|
67029
|
+
price: value.price ?? null,
|
|
67030
|
+
message: value.message ?? "",
|
|
67031
|
+
status: value.status ?? "pending" /* PENDING */,
|
|
67032
|
+
type: value.type,
|
|
67033
|
+
postId: value.postId,
|
|
67034
|
+
buyerId: value.buyerId ?? null,
|
|
67035
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
67036
|
+
updatedAt: null
|
|
67037
|
+
};
|
|
67038
|
+
}
|
|
67039
|
+
|
|
67040
|
+
// src/repositories/bid-preloved.repo.ts
|
|
67041
|
+
import {
|
|
67042
|
+
InternalServerError as InternalServerError82,
|
|
67043
|
+
NotFoundError as NotFoundError61,
|
|
67044
|
+
useAtlas as useAtlas127
|
|
67045
|
+
} from "@7365admin1/node-server-utils";
|
|
67046
|
+
import { ObjectId as ObjectId150 } from "mongodb";
|
|
67047
|
+
function useBidPrelovedRepo() {
|
|
67048
|
+
const db = useAtlas127.getDb();
|
|
67049
|
+
if (!db)
|
|
67050
|
+
throw new InternalServerError82("Unable to connect to server.");
|
|
67051
|
+
const collection = db.collection("bid-preloved");
|
|
67052
|
+
async function add(value, session) {
|
|
67053
|
+
try {
|
|
67054
|
+
const doc = MBidPreloved(value);
|
|
67055
|
+
const res = await collection.insertOne(doc, { session });
|
|
67056
|
+
return res.insertedId;
|
|
67057
|
+
} catch (error) {
|
|
67058
|
+
throw error;
|
|
67059
|
+
}
|
|
67060
|
+
}
|
|
67061
|
+
async function updateStatus(_id, status) {
|
|
67062
|
+
const objectId2 = typeof _id === "string" ? new ObjectId150(_id) : _id;
|
|
67063
|
+
const existing = await collection.findOne({ _id: objectId2 });
|
|
67064
|
+
if (!existing)
|
|
67065
|
+
throw new NotFoundError61("Bid not found.");
|
|
67066
|
+
const res = await collection.updateOne(
|
|
67067
|
+
{ _id: objectId2 },
|
|
67068
|
+
{ $set: { status, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } }
|
|
67069
|
+
);
|
|
67070
|
+
if (res.modifiedCount === 0)
|
|
67071
|
+
throw new InternalServerError82("Unable to update bid.");
|
|
67072
|
+
return "Bid updated successfully.";
|
|
67073
|
+
}
|
|
67074
|
+
return { add, updateStatus };
|
|
67075
|
+
}
|
|
67076
|
+
|
|
67077
|
+
// src/controllers/bid-preloved.controller.ts
|
|
67078
|
+
import { BadRequestError as BadRequestError224, logger as logger194 } from "@7365admin1/node-server-utils";
|
|
67079
|
+
import Joi146 from "joi";
|
|
67080
|
+
function useBidPrelovedController() {
|
|
67081
|
+
const { add: _add, updateStatus: _updateStatus } = useBidPrelovedRepo();
|
|
67082
|
+
async function add(req, res, next) {
|
|
67083
|
+
const { error, value } = schemaBidPreloved.validate(req.body, {
|
|
67084
|
+
abortEarly: false
|
|
67085
|
+
});
|
|
67086
|
+
if (error) {
|
|
67087
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
67088
|
+
logger194.log({ level: "error", message: messages });
|
|
67089
|
+
next(new BadRequestError224(messages));
|
|
67090
|
+
return;
|
|
67091
|
+
}
|
|
67092
|
+
try {
|
|
67093
|
+
const data = await _add(value);
|
|
67094
|
+
res.status(201).json(data);
|
|
67095
|
+
} catch (error2) {
|
|
67096
|
+
logger194.log({ level: "error", message: error2.message });
|
|
67097
|
+
next(error2);
|
|
67098
|
+
}
|
|
67099
|
+
}
|
|
67100
|
+
async function updateStatus(req, res, next) {
|
|
67101
|
+
const paramsSchema = Joi146.object({
|
|
67102
|
+
id: Joi146.string().hex().length(24).required()
|
|
67103
|
+
});
|
|
67104
|
+
const { error: paramError, value: params } = paramsSchema.validate(
|
|
67105
|
+
req.params
|
|
67106
|
+
);
|
|
67107
|
+
if (paramError) {
|
|
67108
|
+
logger194.log({ level: "error", message: paramError.message });
|
|
67109
|
+
next(new BadRequestError224(paramError.message));
|
|
67110
|
+
return;
|
|
67111
|
+
}
|
|
67112
|
+
const { error: bodyError, value: body } = schemaUpdateBidPreloved.validate(
|
|
67113
|
+
req.body
|
|
67114
|
+
);
|
|
67115
|
+
if (bodyError) {
|
|
67116
|
+
logger194.log({ level: "error", message: bodyError.message });
|
|
67117
|
+
next(new BadRequestError224(bodyError.message));
|
|
67118
|
+
return;
|
|
67119
|
+
}
|
|
67120
|
+
try {
|
|
67121
|
+
const data = await _updateStatus(params.id, body.status);
|
|
67122
|
+
res.status(200).json(data);
|
|
67123
|
+
} catch (error) {
|
|
67124
|
+
logger194.log({ level: "error", message: error.message });
|
|
67125
|
+
next(error);
|
|
67126
|
+
}
|
|
67127
|
+
}
|
|
67128
|
+
return { add, updateStatus };
|
|
67129
|
+
}
|
|
67130
|
+
|
|
67131
|
+
// src/models/online-forms-v2.model.ts
|
|
67132
|
+
import Joi147 from "joi";
|
|
67133
|
+
import { ObjectId as ObjectId151 } from "mongodb";
|
|
66663
67134
|
var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
|
|
66664
67135
|
FormEntryStatus2["ACTIVE"] = "active";
|
|
66665
67136
|
FormEntryStatus2["INACTIVE"] = "inactive";
|
|
66666
67137
|
FormEntryStatus2["DELETED"] = "deleted";
|
|
66667
67138
|
return FormEntryStatus2;
|
|
66668
67139
|
})(FormEntryStatus || {});
|
|
66669
|
-
var schemaFormEntry =
|
|
66670
|
-
_id:
|
|
66671
|
-
formType:
|
|
66672
|
-
block:
|
|
66673
|
-
level:
|
|
66674
|
-
unit:
|
|
66675
|
-
name:
|
|
66676
|
-
phoneNumber:
|
|
66677
|
-
createdBy:
|
|
66678
|
-
fields:
|
|
66679
|
-
|
|
66680
|
-
|
|
66681
|
-
|
|
66682
|
-
|
|
66683
|
-
|
|
66684
|
-
|
|
67140
|
+
var schemaFormEntry = Joi147.object({
|
|
67141
|
+
_id: Joi147.string().hex().optional().allow("", null),
|
|
67142
|
+
formType: Joi147.string().required(),
|
|
67143
|
+
block: Joi147.string().optional().allow(null, ""),
|
|
67144
|
+
level: Joi147.string().optional().allow(null, ""),
|
|
67145
|
+
unit: Joi147.string().optional().allow(null, ""),
|
|
67146
|
+
name: Joi147.string().optional().allow(null, ""),
|
|
67147
|
+
phoneNumber: Joi147.string().optional().allow(null, ""),
|
|
67148
|
+
createdBy: Joi147.string().required(),
|
|
67149
|
+
fields: Joi147.object().pattern(
|
|
67150
|
+
Joi147.string(),
|
|
67151
|
+
Joi147.alternatives().try(
|
|
67152
|
+
Joi147.string(),
|
|
67153
|
+
Joi147.number(),
|
|
67154
|
+
Joi147.boolean(),
|
|
67155
|
+
Joi147.valid(null)
|
|
66685
67156
|
)
|
|
66686
67157
|
).required(),
|
|
66687
|
-
status:
|
|
66688
|
-
org:
|
|
66689
|
-
site:
|
|
66690
|
-
createdAt:
|
|
66691
|
-
updatedAt:
|
|
66692
|
-
deletedAt:
|
|
67158
|
+
status: Joi147.string().optional().allow("", null),
|
|
67159
|
+
org: Joi147.string().hex().optional().allow("", null),
|
|
67160
|
+
site: Joi147.string().hex().optional().allow("", null),
|
|
67161
|
+
createdAt: Joi147.date().optional().allow("", null),
|
|
67162
|
+
updatedAt: Joi147.date().optional().allow("", null),
|
|
67163
|
+
deletedAt: Joi147.date().optional().allow("", null)
|
|
66693
67164
|
});
|
|
66694
|
-
var schemaUpdateFormEntry =
|
|
66695
|
-
_id:
|
|
66696
|
-
formType:
|
|
66697
|
-
block:
|
|
66698
|
-
level:
|
|
66699
|
-
unit:
|
|
66700
|
-
fields:
|
|
66701
|
-
|
|
66702
|
-
|
|
66703
|
-
|
|
66704
|
-
|
|
66705
|
-
|
|
66706
|
-
|
|
67165
|
+
var schemaUpdateFormEntry = Joi147.object({
|
|
67166
|
+
_id: Joi147.string().hex().required(),
|
|
67167
|
+
formType: Joi147.string().optional().allow("", null),
|
|
67168
|
+
block: Joi147.string().optional().allow(null, ""),
|
|
67169
|
+
level: Joi147.string().optional().allow(null, ""),
|
|
67170
|
+
unit: Joi147.string().optional().allow(null, ""),
|
|
67171
|
+
fields: Joi147.object().pattern(
|
|
67172
|
+
Joi147.string(),
|
|
67173
|
+
Joi147.alternatives().try(
|
|
67174
|
+
Joi147.string(),
|
|
67175
|
+
Joi147.number(),
|
|
67176
|
+
Joi147.boolean(),
|
|
67177
|
+
Joi147.valid(null)
|
|
66707
67178
|
)
|
|
66708
67179
|
).optional(),
|
|
66709
|
-
status:
|
|
66710
|
-
updatedAt:
|
|
66711
|
-
deletedAt:
|
|
67180
|
+
status: Joi147.string().optional().allow("", null),
|
|
67181
|
+
updatedAt: Joi147.date().optional().allow("", null),
|
|
67182
|
+
deletedAt: Joi147.date().optional().allow("", null)
|
|
66712
67183
|
});
|
|
66713
67184
|
function MFormEntry(value) {
|
|
66714
67185
|
const { error } = schemaFormEntry.validate(value);
|
|
@@ -66717,21 +67188,21 @@ function MFormEntry(value) {
|
|
|
66717
67188
|
}
|
|
66718
67189
|
if (value._id && typeof value._id === "string") {
|
|
66719
67190
|
try {
|
|
66720
|
-
value._id = new
|
|
67191
|
+
value._id = new ObjectId151(value._id);
|
|
66721
67192
|
} catch {
|
|
66722
67193
|
throw new Error("Invalid ID.");
|
|
66723
67194
|
}
|
|
66724
67195
|
}
|
|
66725
67196
|
if (value.org && typeof value.org === "string") {
|
|
66726
67197
|
try {
|
|
66727
|
-
value.org = new
|
|
67198
|
+
value.org = new ObjectId151(value.org);
|
|
66728
67199
|
} catch {
|
|
66729
67200
|
throw new Error("Invalid org ID.");
|
|
66730
67201
|
}
|
|
66731
67202
|
}
|
|
66732
67203
|
if (value.site && typeof value.site === "string") {
|
|
66733
67204
|
try {
|
|
66734
|
-
value.site = new
|
|
67205
|
+
value.site = new ObjectId151(value.site);
|
|
66735
67206
|
} catch {
|
|
66736
67207
|
throw new Error("Invalid site ID.");
|
|
66737
67208
|
}
|
|
@@ -66753,55 +67224,55 @@ function MFormEntry(value) {
|
|
|
66753
67224
|
deletedAt: value.deletedAt ?? null
|
|
66754
67225
|
};
|
|
66755
67226
|
}
|
|
66756
|
-
var residentFormEntry =
|
|
66757
|
-
_id:
|
|
66758
|
-
typeOfForm:
|
|
66759
|
-
unitNumber:
|
|
66760
|
-
fields:
|
|
66761
|
-
|
|
66762
|
-
|
|
66763
|
-
|
|
66764
|
-
|
|
66765
|
-
|
|
66766
|
-
|
|
67227
|
+
var residentFormEntry = Joi147.object({
|
|
67228
|
+
_id: Joi147.string().hex().optional().allow("", null),
|
|
67229
|
+
typeOfForm: Joi147.string().optional().allow("", null),
|
|
67230
|
+
unitNumber: Joi147.string().optional().allow(null, ""),
|
|
67231
|
+
fields: Joi147.object().pattern(
|
|
67232
|
+
Joi147.string(),
|
|
67233
|
+
Joi147.alternatives().try(
|
|
67234
|
+
Joi147.string(),
|
|
67235
|
+
Joi147.number(),
|
|
67236
|
+
Joi147.boolean(),
|
|
67237
|
+
Joi147.valid(null)
|
|
66767
67238
|
)
|
|
66768
67239
|
).optional().allow(null, ""),
|
|
66769
|
-
status:
|
|
66770
|
-
org:
|
|
66771
|
-
site:
|
|
66772
|
-
userId:
|
|
66773
|
-
createdAt:
|
|
66774
|
-
updatedAt:
|
|
66775
|
-
deletedAt:
|
|
66776
|
-
remarks:
|
|
66777
|
-
managementValues:
|
|
66778
|
-
|
|
66779
|
-
|
|
66780
|
-
|
|
66781
|
-
|
|
66782
|
-
|
|
66783
|
-
|
|
67240
|
+
status: Joi147.string().optional().allow("", null),
|
|
67241
|
+
org: Joi147.string().hex().optional().allow("", null),
|
|
67242
|
+
site: Joi147.string().hex().optional().allow("", null),
|
|
67243
|
+
userId: Joi147.string().hex().optional().allow("", null),
|
|
67244
|
+
createdAt: Joi147.date().optional().allow("", null),
|
|
67245
|
+
updatedAt: Joi147.date().optional().allow("", null),
|
|
67246
|
+
deletedAt: Joi147.date().optional().allow("", null),
|
|
67247
|
+
remarks: Joi147.string().optional().allow("", null),
|
|
67248
|
+
managementValues: Joi147.object().pattern(
|
|
67249
|
+
Joi147.string(),
|
|
67250
|
+
Joi147.alternatives().try(
|
|
67251
|
+
Joi147.string(),
|
|
67252
|
+
Joi147.number(),
|
|
67253
|
+
Joi147.boolean(),
|
|
67254
|
+
Joi147.valid(null)
|
|
66784
67255
|
)
|
|
66785
67256
|
).optional().allow(null, "")
|
|
66786
67257
|
});
|
|
66787
67258
|
|
|
66788
67259
|
// src/repositories/online-forms-v2.repository.ts
|
|
66789
67260
|
import {
|
|
66790
|
-
BadRequestError as
|
|
66791
|
-
InternalServerError as
|
|
66792
|
-
logger as
|
|
67261
|
+
BadRequestError as BadRequestError225,
|
|
67262
|
+
InternalServerError as InternalServerError83,
|
|
67263
|
+
logger as logger195,
|
|
66793
67264
|
makeCacheKey as makeCacheKey65,
|
|
66794
|
-
NotFoundError as
|
|
67265
|
+
NotFoundError as NotFoundError62,
|
|
66795
67266
|
paginate as paginate64,
|
|
66796
|
-
useAtlas as
|
|
67267
|
+
useAtlas as useAtlas128,
|
|
66797
67268
|
useCache as useCache69
|
|
66798
67269
|
} from "@7365admin1/node-server-utils";
|
|
66799
|
-
import { ObjectId as
|
|
67270
|
+
import { ObjectId as ObjectId152 } from "mongodb";
|
|
66800
67271
|
var online_forms_namespace_collection = "online-forms";
|
|
66801
67272
|
function useFormEntryRepo() {
|
|
66802
|
-
const db =
|
|
67273
|
+
const db = useAtlas128.getDb();
|
|
66803
67274
|
if (!db) {
|
|
66804
|
-
throw new
|
|
67275
|
+
throw new InternalServerError83("Unable to connect to server.");
|
|
66805
67276
|
}
|
|
66806
67277
|
const collection = db.collection(online_forms_namespace_collection);
|
|
66807
67278
|
const { delNamespace, getCache, setCache } = useCache69(
|
|
@@ -66813,7 +67284,7 @@ function useFormEntryRepo() {
|
|
|
66813
67284
|
name: "text"
|
|
66814
67285
|
});
|
|
66815
67286
|
} catch (error) {
|
|
66816
|
-
throw new
|
|
67287
|
+
throw new InternalServerError83(
|
|
66817
67288
|
"Failed to create text index on online form."
|
|
66818
67289
|
);
|
|
66819
67290
|
}
|
|
@@ -66823,11 +67294,11 @@ function useFormEntryRepo() {
|
|
|
66823
67294
|
value = MFormEntry(value);
|
|
66824
67295
|
const res = await collection.insertOne(value, { session });
|
|
66825
67296
|
delNamespace().then(() => {
|
|
66826
|
-
|
|
67297
|
+
logger195.info(
|
|
66827
67298
|
`Cache cleared for namespace: ${online_forms_namespace_collection}`
|
|
66828
67299
|
);
|
|
66829
67300
|
}).catch((err) => {
|
|
66830
|
-
|
|
67301
|
+
logger195.error(
|
|
66831
67302
|
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
66832
67303
|
err
|
|
66833
67304
|
);
|
|
@@ -66836,7 +67307,7 @@ function useFormEntryRepo() {
|
|
|
66836
67307
|
} catch (error) {
|
|
66837
67308
|
const isDuplicated = error.message.includes("duplicate");
|
|
66838
67309
|
if (isDuplicated) {
|
|
66839
|
-
throw new
|
|
67310
|
+
throw new BadRequestError225("Online Form already exists.");
|
|
66840
67311
|
}
|
|
66841
67312
|
throw error;
|
|
66842
67313
|
}
|
|
@@ -66852,8 +67323,8 @@ function useFormEntryRepo() {
|
|
|
66852
67323
|
}) {
|
|
66853
67324
|
page = page > 0 ? page - 1 : 0;
|
|
66854
67325
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
66855
|
-
site = new
|
|
66856
|
-
org = new
|
|
67326
|
+
site = new ObjectId152(site);
|
|
67327
|
+
org = new ObjectId152(org);
|
|
66857
67328
|
const cacheOptions = {
|
|
66858
67329
|
page,
|
|
66859
67330
|
limit,
|
|
@@ -66879,7 +67350,7 @@ function useFormEntryRepo() {
|
|
|
66879
67350
|
);
|
|
66880
67351
|
const cachedData = await getCache(cacheKey);
|
|
66881
67352
|
if (cachedData) {
|
|
66882
|
-
|
|
67353
|
+
logger195.info(`Cache hit for key: ${cacheKey}`);
|
|
66883
67354
|
return cachedData;
|
|
66884
67355
|
}
|
|
66885
67356
|
try {
|
|
@@ -66887,14 +67358,30 @@ function useFormEntryRepo() {
|
|
|
66887
67358
|
{ $match: query },
|
|
66888
67359
|
{ $sort: sort },
|
|
66889
67360
|
{ $skip: page * limit },
|
|
66890
|
-
{ $limit: limit }
|
|
67361
|
+
{ $limit: limit },
|
|
67362
|
+
{
|
|
67363
|
+
$lookup: {
|
|
67364
|
+
from: "users",
|
|
67365
|
+
localField: "userId",
|
|
67366
|
+
foreignField: "_id",
|
|
67367
|
+
as: "user",
|
|
67368
|
+
pipeline: [{ $project: { name: 1 } }]
|
|
67369
|
+
}
|
|
67370
|
+
},
|
|
67371
|
+
{ $unwind: { path: "$user", preserveNullAndEmptyArrays: true } },
|
|
67372
|
+
{
|
|
67373
|
+
$addFields: {
|
|
67374
|
+
name: { $ifNull: ["$user.name", "$name"] }
|
|
67375
|
+
}
|
|
67376
|
+
},
|
|
67377
|
+
{ $project: { user: 0 } }
|
|
66891
67378
|
]).toArray();
|
|
66892
67379
|
const length = await collection.countDocuments(query);
|
|
66893
67380
|
const data = paginate64(items, page, limit, length);
|
|
66894
67381
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
66895
|
-
|
|
67382
|
+
logger195.info(`Cache set for key: ${cacheKey}`);
|
|
66896
67383
|
}).catch((err) => {
|
|
66897
|
-
|
|
67384
|
+
logger195.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
66898
67385
|
});
|
|
66899
67386
|
return data;
|
|
66900
67387
|
} catch (error) {
|
|
@@ -66905,24 +67392,24 @@ function useFormEntryRepo() {
|
|
|
66905
67392
|
const cacheKey = makeCacheKey65(online_forms_namespace_collection, { _id });
|
|
66906
67393
|
const cachedData = await getCache(cacheKey);
|
|
66907
67394
|
if (cachedData) {
|
|
66908
|
-
|
|
67395
|
+
logger195.info(`Cache hit for key: ${cacheKey}`);
|
|
66909
67396
|
return cachedData;
|
|
66910
67397
|
}
|
|
66911
67398
|
try {
|
|
66912
|
-
_id = new
|
|
67399
|
+
_id = new ObjectId152(_id);
|
|
66913
67400
|
} catch (error) {
|
|
66914
|
-
throw new
|
|
67401
|
+
throw new BadRequestError225("Invalid online form ID format.");
|
|
66915
67402
|
}
|
|
66916
67403
|
const query = { _id, status: { $ne: "deleted" } };
|
|
66917
67404
|
try {
|
|
66918
67405
|
const [data] = await collection.aggregate([{ $match: query }]).toArray();
|
|
66919
67406
|
if (!data) {
|
|
66920
|
-
throw new
|
|
67407
|
+
throw new NotFoundError62("Document not found.");
|
|
66921
67408
|
}
|
|
66922
67409
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
66923
|
-
|
|
67410
|
+
logger195.info(`Cache set for key: ${cacheKey}`);
|
|
66924
67411
|
}).catch((err) => {
|
|
66925
|
-
|
|
67412
|
+
logger195.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
66926
67413
|
});
|
|
66927
67414
|
return data;
|
|
66928
67415
|
} catch (error) {
|
|
@@ -66931,9 +67418,9 @@ function useFormEntryRepo() {
|
|
|
66931
67418
|
}
|
|
66932
67419
|
async function updateFormEntryById(_id, value) {
|
|
66933
67420
|
try {
|
|
66934
|
-
_id = new
|
|
67421
|
+
_id = new ObjectId152(_id);
|
|
66935
67422
|
} catch (error) {
|
|
66936
|
-
throw new
|
|
67423
|
+
throw new BadRequestError225("Invalid online form ID format.");
|
|
66937
67424
|
}
|
|
66938
67425
|
try {
|
|
66939
67426
|
const updateValue = {
|
|
@@ -66942,14 +67429,14 @@ function useFormEntryRepo() {
|
|
|
66942
67429
|
};
|
|
66943
67430
|
const res = await collection.updateOne({ _id }, { $set: updateValue });
|
|
66944
67431
|
if (res.modifiedCount === 0) {
|
|
66945
|
-
throw new
|
|
67432
|
+
throw new InternalServerError83("Unable to update online form.");
|
|
66946
67433
|
}
|
|
66947
67434
|
delNamespace().then(() => {
|
|
66948
|
-
|
|
67435
|
+
logger195.info(
|
|
66949
67436
|
`Cache cleared for namespace: ${online_forms_namespace_collection}`
|
|
66950
67437
|
);
|
|
66951
67438
|
}).catch((err) => {
|
|
66952
|
-
|
|
67439
|
+
logger195.error(
|
|
66953
67440
|
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
66954
67441
|
err
|
|
66955
67442
|
);
|
|
@@ -66961,9 +67448,9 @@ function useFormEntryRepo() {
|
|
|
66961
67448
|
}
|
|
66962
67449
|
async function deleteOnlineFormById(_id, session) {
|
|
66963
67450
|
try {
|
|
66964
|
-
_id = new
|
|
67451
|
+
_id = new ObjectId152(_id);
|
|
66965
67452
|
} catch (error) {
|
|
66966
|
-
throw new
|
|
67453
|
+
throw new BadRequestError225("Invalid online form ID format.");
|
|
66967
67454
|
}
|
|
66968
67455
|
try {
|
|
66969
67456
|
const updateValue = {
|
|
@@ -66977,12 +67464,12 @@ function useFormEntryRepo() {
|
|
|
66977
67464
|
{ session }
|
|
66978
67465
|
);
|
|
66979
67466
|
if (res.modifiedCount === 0) {
|
|
66980
|
-
throw new
|
|
67467
|
+
throw new InternalServerError83("Unable to delete online form.");
|
|
66981
67468
|
}
|
|
66982
67469
|
delNamespace().then(() => {
|
|
66983
|
-
|
|
67470
|
+
logger195.info(`Cache cleared for namespace: ${online_forms_namespace_collection}`);
|
|
66984
67471
|
}).catch((err) => {
|
|
66985
|
-
|
|
67472
|
+
logger195.error(
|
|
66986
67473
|
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
66987
67474
|
err
|
|
66988
67475
|
);
|
|
@@ -66994,16 +67481,16 @@ function useFormEntryRepo() {
|
|
|
66994
67481
|
}
|
|
66995
67482
|
async function addResidentForm(value, session) {
|
|
66996
67483
|
try {
|
|
66997
|
-
value.site = new
|
|
66998
|
-
value.org = new
|
|
66999
|
-
value.userId = new
|
|
67484
|
+
value.site = new ObjectId152(value.site);
|
|
67485
|
+
value.org = new ObjectId152(value.org);
|
|
67486
|
+
value.userId = new ObjectId152(value.userId);
|
|
67000
67487
|
const res = await collection.insertOne(value, { session });
|
|
67001
67488
|
delNamespace().then(() => {
|
|
67002
|
-
|
|
67489
|
+
logger195.info(
|
|
67003
67490
|
`Cache cleared for namespace: ${online_forms_namespace_collection}`
|
|
67004
67491
|
);
|
|
67005
67492
|
}).catch((err) => {
|
|
67006
|
-
|
|
67493
|
+
logger195.error(
|
|
67007
67494
|
`Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
|
|
67008
67495
|
err
|
|
67009
67496
|
);
|
|
@@ -67012,16 +67499,16 @@ function useFormEntryRepo() {
|
|
|
67012
67499
|
} catch (error) {
|
|
67013
67500
|
const isDuplicated = error.message.includes("duplicate");
|
|
67014
67501
|
if (isDuplicated) {
|
|
67015
|
-
throw new
|
|
67502
|
+
throw new BadRequestError225("Online Form already exists.");
|
|
67016
67503
|
}
|
|
67017
67504
|
throw error;
|
|
67018
67505
|
}
|
|
67019
67506
|
}
|
|
67020
67507
|
async function residentForm({ userId, site, org }) {
|
|
67021
67508
|
try {
|
|
67022
|
-
const user = new
|
|
67023
|
-
const siteId = new
|
|
67024
|
-
const orgId = new
|
|
67509
|
+
const user = new ObjectId152(userId);
|
|
67510
|
+
const siteId = new ObjectId152(site);
|
|
67511
|
+
const orgId = new ObjectId152(org);
|
|
67025
67512
|
const res = await collection.aggregate([
|
|
67026
67513
|
{
|
|
67027
67514
|
$match: {
|
|
@@ -67049,8 +67536,8 @@ function useFormEntryRepo() {
|
|
|
67049
67536
|
}
|
|
67050
67537
|
|
|
67051
67538
|
// src/controllers/online-forms-v2.controller.ts
|
|
67052
|
-
import { BadRequestError as
|
|
67053
|
-
import
|
|
67539
|
+
import { BadRequestError as BadRequestError226, logger as logger196 } from "@7365admin1/node-server-utils";
|
|
67540
|
+
import Joi148 from "joi";
|
|
67054
67541
|
import ExcelJS3 from "exceljs";
|
|
67055
67542
|
import fs6 from "fs";
|
|
67056
67543
|
function useFormEntryController() {
|
|
@@ -67076,14 +67563,14 @@ function useFormEntryController() {
|
|
|
67076
67563
|
async function uploadFormEntrys(req, res, next) {
|
|
67077
67564
|
try {
|
|
67078
67565
|
if (!req.file) {
|
|
67079
|
-
next(new
|
|
67566
|
+
next(new BadRequestError226("Excel file is required."));
|
|
67080
67567
|
return;
|
|
67081
67568
|
}
|
|
67082
67569
|
const workbook = new ExcelJS3.Workbook();
|
|
67083
67570
|
await workbook.xlsx.readFile(req.file.path);
|
|
67084
67571
|
const worksheet = workbook.worksheets[0];
|
|
67085
67572
|
if (!worksheet) {
|
|
67086
|
-
next(new
|
|
67573
|
+
next(new BadRequestError226("No worksheet found in uploaded Excel file."));
|
|
67087
67574
|
return;
|
|
67088
67575
|
}
|
|
67089
67576
|
const headerRow = worksheet.getRow(1);
|
|
@@ -67111,8 +67598,8 @@ function useFormEntryController() {
|
|
|
67111
67598
|
});
|
|
67112
67599
|
if (error) {
|
|
67113
67600
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67114
|
-
|
|
67115
|
-
next(new
|
|
67601
|
+
logger196.log({ level: "error", message: messages });
|
|
67602
|
+
next(new BadRequestError226(messages));
|
|
67116
67603
|
return;
|
|
67117
67604
|
}
|
|
67118
67605
|
const result = await _add(value);
|
|
@@ -67120,25 +67607,25 @@ function useFormEntryController() {
|
|
|
67120
67607
|
fs6.unlink(req.file.path, () => {
|
|
67121
67608
|
});
|
|
67122
67609
|
} catch (error) {
|
|
67123
|
-
|
|
67610
|
+
logger196.log({ level: "error", message: error.message });
|
|
67124
67611
|
next(error);
|
|
67125
67612
|
}
|
|
67126
67613
|
}
|
|
67127
67614
|
async function getAll(req, res, next) {
|
|
67128
67615
|
try {
|
|
67129
|
-
const schema2 =
|
|
67130
|
-
search:
|
|
67131
|
-
page:
|
|
67132
|
-
limit:
|
|
67133
|
-
status:
|
|
67134
|
-
org:
|
|
67135
|
-
site:
|
|
67616
|
+
const schema2 = Joi148.object({
|
|
67617
|
+
search: Joi148.string().optional().allow("", null),
|
|
67618
|
+
page: Joi148.number().integer().min(1).allow("", null).default(1),
|
|
67619
|
+
limit: Joi148.number().integer().min(1).max(100).allow("", null).default(10),
|
|
67620
|
+
status: Joi148.string().optional().allow(null, ""),
|
|
67621
|
+
org: Joi148.string().hex().optional().allow("", null),
|
|
67622
|
+
site: Joi148.string().hex().optional().allow("", null)
|
|
67136
67623
|
});
|
|
67137
67624
|
const { error, value } = schema2.validate(req.query);
|
|
67138
67625
|
if (error) {
|
|
67139
67626
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67140
|
-
|
|
67141
|
-
next(new
|
|
67627
|
+
logger196.log({ level: "error", message: messages });
|
|
67628
|
+
next(new BadRequestError226(messages));
|
|
67142
67629
|
return;
|
|
67143
67630
|
}
|
|
67144
67631
|
const { search, page, limit, status, org, site } = value;
|
|
@@ -67146,21 +67633,21 @@ function useFormEntryController() {
|
|
|
67146
67633
|
res.json(data);
|
|
67147
67634
|
return;
|
|
67148
67635
|
} catch (error) {
|
|
67149
|
-
|
|
67636
|
+
logger196.log({ level: "error", message: error.message });
|
|
67150
67637
|
next(error);
|
|
67151
67638
|
return;
|
|
67152
67639
|
}
|
|
67153
67640
|
}
|
|
67154
67641
|
async function getFormEntryById(req, res, next) {
|
|
67155
67642
|
try {
|
|
67156
|
-
const schema2 =
|
|
67157
|
-
_id:
|
|
67643
|
+
const schema2 = Joi148.object({
|
|
67644
|
+
_id: Joi148.string().hex().length(24).required()
|
|
67158
67645
|
});
|
|
67159
67646
|
const { error, value } = schema2.validate({ _id: req.params.id });
|
|
67160
67647
|
if (error) {
|
|
67161
67648
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67162
|
-
|
|
67163
|
-
next(new
|
|
67649
|
+
logger196.log({ level: "error", message: messages });
|
|
67650
|
+
next(new BadRequestError226(messages));
|
|
67164
67651
|
return;
|
|
67165
67652
|
}
|
|
67166
67653
|
const { _id } = value;
|
|
@@ -67168,7 +67655,7 @@ function useFormEntryController() {
|
|
|
67168
67655
|
res.json(data);
|
|
67169
67656
|
return;
|
|
67170
67657
|
} catch (error) {
|
|
67171
|
-
|
|
67658
|
+
logger196.log({ level: "error", message: error.message });
|
|
67172
67659
|
next(error);
|
|
67173
67660
|
return;
|
|
67174
67661
|
}
|
|
@@ -67181,8 +67668,8 @@ function useFormEntryController() {
|
|
|
67181
67668
|
});
|
|
67182
67669
|
if (error) {
|
|
67183
67670
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67184
|
-
|
|
67185
|
-
next(new
|
|
67671
|
+
logger196.log({ level: "error", message: messages });
|
|
67672
|
+
next(new BadRequestError226(messages));
|
|
67186
67673
|
return;
|
|
67187
67674
|
}
|
|
67188
67675
|
const { _id, ...rest } = value;
|
|
@@ -67190,26 +67677,26 @@ function useFormEntryController() {
|
|
|
67190
67677
|
res.json({ message: "Successfully updated online form." });
|
|
67191
67678
|
return;
|
|
67192
67679
|
} catch (error) {
|
|
67193
|
-
|
|
67680
|
+
logger196.log({ level: "error", message: error.message });
|
|
67194
67681
|
next(error);
|
|
67195
67682
|
return;
|
|
67196
67683
|
}
|
|
67197
67684
|
}
|
|
67198
67685
|
async function deleteFormEntryById(req, res, next) {
|
|
67199
67686
|
try {
|
|
67200
|
-
const validation =
|
|
67687
|
+
const validation = Joi148.string().hex().required();
|
|
67201
67688
|
const _id = req.params.id;
|
|
67202
67689
|
const { error } = validation.validate(_id);
|
|
67203
67690
|
if (error) {
|
|
67204
|
-
|
|
67205
|
-
next(new
|
|
67691
|
+
logger196.log({ level: "error", message: error.message });
|
|
67692
|
+
next(new BadRequestError226(error.message));
|
|
67206
67693
|
return;
|
|
67207
67694
|
}
|
|
67208
67695
|
await _deleteOnlineFormById(_id);
|
|
67209
67696
|
res.json({ message: "Successfully deleted online form." });
|
|
67210
67697
|
return;
|
|
67211
67698
|
} catch (error) {
|
|
67212
|
-
|
|
67699
|
+
logger196.log({ level: "error", message: error.message });
|
|
67213
67700
|
next(error);
|
|
67214
67701
|
return;
|
|
67215
67702
|
}
|
|
@@ -67226,8 +67713,8 @@ function useFormEntryController() {
|
|
|
67226
67713
|
});
|
|
67227
67714
|
if (error) {
|
|
67228
67715
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67229
|
-
|
|
67230
|
-
next(new
|
|
67716
|
+
logger196.log({ level: "error", message: messages });
|
|
67717
|
+
next(new BadRequestError226(messages));
|
|
67231
67718
|
return;
|
|
67232
67719
|
}
|
|
67233
67720
|
try {
|
|
@@ -67235,7 +67722,7 @@ function useFormEntryController() {
|
|
|
67235
67722
|
res.status(201).json({ message: data });
|
|
67236
67723
|
return;
|
|
67237
67724
|
} catch (error2) {
|
|
67238
|
-
|
|
67725
|
+
logger196.log({ level: "error", message: error2.message });
|
|
67239
67726
|
next(error2);
|
|
67240
67727
|
return;
|
|
67241
67728
|
}
|
|
@@ -67247,8 +67734,8 @@ function useFormEntryController() {
|
|
|
67247
67734
|
});
|
|
67248
67735
|
if (error) {
|
|
67249
67736
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67250
|
-
|
|
67251
|
-
next(new
|
|
67737
|
+
logger196.log({ level: "error", message: messages });
|
|
67738
|
+
next(new BadRequestError226(messages));
|
|
67252
67739
|
return;
|
|
67253
67740
|
}
|
|
67254
67741
|
try {
|
|
@@ -67256,7 +67743,7 @@ function useFormEntryController() {
|
|
|
67256
67743
|
res.status(201).json({ message: data });
|
|
67257
67744
|
return;
|
|
67258
67745
|
} catch (error2) {
|
|
67259
|
-
|
|
67746
|
+
logger196.log({ level: "error", message: error2.message });
|
|
67260
67747
|
next(error2);
|
|
67261
67748
|
return;
|
|
67262
67749
|
}
|
|
@@ -67264,22 +67751,22 @@ function useFormEntryController() {
|
|
|
67264
67751
|
async function residentForm(req, res, next) {
|
|
67265
67752
|
try {
|
|
67266
67753
|
const { site, userId, org } = req.query;
|
|
67267
|
-
const residentFormPayload =
|
|
67268
|
-
org:
|
|
67269
|
-
site:
|
|
67270
|
-
userId:
|
|
67754
|
+
const residentFormPayload = Joi148.object({
|
|
67755
|
+
org: Joi148.string().hex().required(),
|
|
67756
|
+
site: Joi148.string().hex().required(),
|
|
67757
|
+
userId: Joi148.string().hex().required()
|
|
67271
67758
|
});
|
|
67272
67759
|
const { error } = residentFormPayload.validate({ site, userId, org }, { abortEarly: true });
|
|
67273
67760
|
if (error) {
|
|
67274
67761
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67275
|
-
|
|
67276
|
-
next(new
|
|
67762
|
+
logger196.log({ level: "error", message: messages });
|
|
67763
|
+
next(new BadRequestError226(messages));
|
|
67277
67764
|
return;
|
|
67278
67765
|
}
|
|
67279
67766
|
const result = await _residentForm({ userId, site, org });
|
|
67280
67767
|
res.json(result);
|
|
67281
67768
|
} catch (error) {
|
|
67282
|
-
|
|
67769
|
+
logger196.log({ level: "error", message: error.message });
|
|
67283
67770
|
next(error);
|
|
67284
67771
|
return;
|
|
67285
67772
|
}
|
|
@@ -67297,11 +67784,11 @@ function useFormEntryController() {
|
|
|
67297
67784
|
}
|
|
67298
67785
|
|
|
67299
67786
|
// src/services/building-level.service.ts
|
|
67300
|
-
import { useAtlas as
|
|
67787
|
+
import { useAtlas as useAtlas129 } from "@7365admin1/node-server-utils";
|
|
67301
67788
|
function useBuildingLevelService() {
|
|
67302
67789
|
const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelRepo();
|
|
67303
67790
|
async function add(value) {
|
|
67304
|
-
const session =
|
|
67791
|
+
const session = useAtlas129.getClient()?.startSession();
|
|
67305
67792
|
try {
|
|
67306
67793
|
session?.startTransaction();
|
|
67307
67794
|
await _add(value, session);
|
|
@@ -67315,7 +67802,7 @@ function useBuildingLevelService() {
|
|
|
67315
67802
|
}
|
|
67316
67803
|
}
|
|
67317
67804
|
async function updateLevelById(_id, value) {
|
|
67318
|
-
const session =
|
|
67805
|
+
const session = useAtlas129.getClient()?.startSession();
|
|
67319
67806
|
try {
|
|
67320
67807
|
session?.startTransaction();
|
|
67321
67808
|
await _updateLevelById(_id, value, session);
|
|
@@ -67335,8 +67822,8 @@ function useBuildingLevelService() {
|
|
|
67335
67822
|
}
|
|
67336
67823
|
|
|
67337
67824
|
// src/controllers/building-level.controller.ts
|
|
67338
|
-
import { BadRequestError as
|
|
67339
|
-
import
|
|
67825
|
+
import { BadRequestError as BadRequestError227, logger as logger197 } from "@7365admin1/node-server-utils";
|
|
67826
|
+
import Joi149 from "joi";
|
|
67340
67827
|
function useBuildingLevelController() {
|
|
67341
67828
|
const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelService();
|
|
67342
67829
|
const {
|
|
@@ -67353,8 +67840,8 @@ function useBuildingLevelController() {
|
|
|
67353
67840
|
});
|
|
67354
67841
|
if (error) {
|
|
67355
67842
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67356
|
-
|
|
67357
|
-
next(new
|
|
67843
|
+
logger197.log({ level: "error", message: messages });
|
|
67844
|
+
next(new BadRequestError227(messages));
|
|
67358
67845
|
return;
|
|
67359
67846
|
}
|
|
67360
67847
|
const result = await _add(value);
|
|
@@ -67365,20 +67852,20 @@ function useBuildingLevelController() {
|
|
|
67365
67852
|
}
|
|
67366
67853
|
async function getAll(req, res, next) {
|
|
67367
67854
|
try {
|
|
67368
|
-
const validation =
|
|
67369
|
-
page:
|
|
67370
|
-
limit:
|
|
67371
|
-
search:
|
|
67372
|
-
site:
|
|
67373
|
-
status:
|
|
67855
|
+
const validation = Joi149.object({
|
|
67856
|
+
page: Joi149.number().min(1).optional().default(1),
|
|
67857
|
+
limit: Joi149.number().min(1).optional().default(20),
|
|
67858
|
+
search: Joi149.string().optional().allow("", null),
|
|
67859
|
+
site: Joi149.string().hex().length(24).optional().allow("", null),
|
|
67860
|
+
status: Joi149.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
|
|
67374
67861
|
});
|
|
67375
67862
|
const { error, value } = validation.validate(req.query, {
|
|
67376
67863
|
abortEarly: false
|
|
67377
67864
|
});
|
|
67378
67865
|
if (error) {
|
|
67379
67866
|
const messages = error.details.map((d) => d.message);
|
|
67380
|
-
|
|
67381
|
-
next(new
|
|
67867
|
+
logger197.log({ level: "error", message: messages.join(", ") });
|
|
67868
|
+
next(new BadRequestError227(messages.join(", ")));
|
|
67382
67869
|
return;
|
|
67383
67870
|
}
|
|
67384
67871
|
const { page, limit, status, site, search } = value;
|
|
@@ -67397,14 +67884,14 @@ function useBuildingLevelController() {
|
|
|
67397
67884
|
}
|
|
67398
67885
|
async function getById(req, res, next) {
|
|
67399
67886
|
try {
|
|
67400
|
-
const schema2 =
|
|
67401
|
-
id:
|
|
67887
|
+
const schema2 = Joi149.object({
|
|
67888
|
+
id: Joi149.string().hex().length(24).required()
|
|
67402
67889
|
});
|
|
67403
67890
|
const { error, value } = schema2.validate({ id: req.params.id });
|
|
67404
67891
|
if (error) {
|
|
67405
67892
|
const messages = error.details.map((d) => d.message);
|
|
67406
|
-
|
|
67407
|
-
next(new
|
|
67893
|
+
logger197.log({ level: "error", message: messages.join(", ") });
|
|
67894
|
+
next(new BadRequestError227(messages.join(", ")));
|
|
67408
67895
|
return;
|
|
67409
67896
|
}
|
|
67410
67897
|
const { id } = value;
|
|
@@ -67423,8 +67910,8 @@ function useBuildingLevelController() {
|
|
|
67423
67910
|
});
|
|
67424
67911
|
if (error) {
|
|
67425
67912
|
const messages = error.details.map((d) => d.message);
|
|
67426
|
-
|
|
67427
|
-
next(new
|
|
67913
|
+
logger197.log({ level: "error", message: messages.join(", ") });
|
|
67914
|
+
next(new BadRequestError227(messages.join(", ")));
|
|
67428
67915
|
return;
|
|
67429
67916
|
}
|
|
67430
67917
|
const { _id, ...rest } = value;
|
|
@@ -67436,14 +67923,14 @@ function useBuildingLevelController() {
|
|
|
67436
67923
|
}
|
|
67437
67924
|
async function deleteById(req, res, next) {
|
|
67438
67925
|
try {
|
|
67439
|
-
const schema2 =
|
|
67440
|
-
id:
|
|
67926
|
+
const schema2 = Joi149.object({
|
|
67927
|
+
id: Joi149.string().hex().required()
|
|
67441
67928
|
});
|
|
67442
67929
|
const { error, value } = schema2.validate({ id: req.params.id });
|
|
67443
67930
|
if (error) {
|
|
67444
67931
|
const messages = error.details.map((d) => d.message);
|
|
67445
|
-
|
|
67446
|
-
next(new
|
|
67932
|
+
logger197.log({ level: "error", message: messages.join(", ") });
|
|
67933
|
+
next(new BadRequestError227(messages.join(", ")));
|
|
67447
67934
|
return;
|
|
67448
67935
|
}
|
|
67449
67936
|
const { id } = value;
|
|
@@ -67456,19 +67943,19 @@ function useBuildingLevelController() {
|
|
|
67456
67943
|
}
|
|
67457
67944
|
async function batchUpdateByIds(req, res, next) {
|
|
67458
67945
|
try {
|
|
67459
|
-
const schema2 =
|
|
67460
|
-
|
|
67461
|
-
_id:
|
|
67462
|
-
value:
|
|
67463
|
-
name:
|
|
67946
|
+
const schema2 = Joi149.array().items(
|
|
67947
|
+
Joi149.object({
|
|
67948
|
+
_id: Joi149.string().hex().length(24).required(),
|
|
67949
|
+
value: Joi149.object({
|
|
67950
|
+
name: Joi149.string().optional().allow("", null)
|
|
67464
67951
|
}).required()
|
|
67465
67952
|
})
|
|
67466
67953
|
);
|
|
67467
67954
|
const { error, value } = schema2.validate(req.body);
|
|
67468
67955
|
if (error) {
|
|
67469
67956
|
const messages = error.details.map((d) => d.message);
|
|
67470
|
-
|
|
67471
|
-
next(new
|
|
67957
|
+
logger197.log({ level: "error", message: messages.join(", ") });
|
|
67958
|
+
next(new BadRequestError227(messages.join(", ")));
|
|
67472
67959
|
return;
|
|
67473
67960
|
}
|
|
67474
67961
|
const updates = value.map((item) => ({
|
|
@@ -67483,9 +67970,9 @@ function useBuildingLevelController() {
|
|
|
67483
67970
|
}
|
|
67484
67971
|
async function getBuildingLevelList(req, res, next) {
|
|
67485
67972
|
try {
|
|
67486
|
-
const schema2 =
|
|
67487
|
-
site:
|
|
67488
|
-
block:
|
|
67973
|
+
const schema2 = Joi149.object({
|
|
67974
|
+
site: Joi149.string().hex().length(24).required(),
|
|
67975
|
+
block: Joi149.string().hex().length(24).required()
|
|
67489
67976
|
});
|
|
67490
67977
|
const { error, value } = schema2.validate({
|
|
67491
67978
|
site: req.params.siteId,
|
|
@@ -67493,8 +67980,8 @@ function useBuildingLevelController() {
|
|
|
67493
67980
|
});
|
|
67494
67981
|
if (error) {
|
|
67495
67982
|
const messages = error.details.map((d) => d.message).join(", ");
|
|
67496
|
-
|
|
67497
|
-
next(new
|
|
67983
|
+
logger197.log({ level: "error", message: messages });
|
|
67984
|
+
next(new BadRequestError227(messages));
|
|
67498
67985
|
return;
|
|
67499
67986
|
}
|
|
67500
67987
|
const { site, block } = value;
|
|
@@ -67515,10 +68002,1363 @@ function useBuildingLevelController() {
|
|
|
67515
68002
|
getBuildingLevelList
|
|
67516
68003
|
};
|
|
67517
68004
|
}
|
|
68005
|
+
|
|
68006
|
+
// src/models/hid-amico.model.ts
|
|
68007
|
+
import { BadRequestError as BadRequestError228, logger as logger198 } from "@7365admin1/node-server-utils";
|
|
68008
|
+
import { ObjectId as ObjectId153 } from "mongodb";
|
|
68009
|
+
import Joi150 from "joi";
|
|
68010
|
+
function canReadObjectId(value) {
|
|
68011
|
+
if (value instanceof ObjectId153)
|
|
68012
|
+
return true;
|
|
68013
|
+
if (typeof value === "string")
|
|
68014
|
+
return ObjectId153.isValid(value);
|
|
68015
|
+
if (value && typeof value === "object") {
|
|
68016
|
+
const candidate = value;
|
|
68017
|
+
if (canReadObjectId(candidate._id) || canReadObjectId(candidate.$oid))
|
|
68018
|
+
return true;
|
|
68019
|
+
if (typeof candidate.toHexString === "function" && ObjectId153.isValid(candidate.toHexString()))
|
|
68020
|
+
return true;
|
|
68021
|
+
if (typeof candidate.toString === "function") {
|
|
68022
|
+
const text = candidate.toString();
|
|
68023
|
+
return text !== "[object Object]" && ObjectId153.isValid(text);
|
|
68024
|
+
}
|
|
68025
|
+
}
|
|
68026
|
+
return false;
|
|
68027
|
+
}
|
|
68028
|
+
function toObjectId23(value, label = "ID") {
|
|
68029
|
+
if (value instanceof ObjectId153)
|
|
68030
|
+
return value;
|
|
68031
|
+
if (typeof value === "string" && ObjectId153.isValid(value))
|
|
68032
|
+
return new ObjectId153(value);
|
|
68033
|
+
if (value && typeof value === "object") {
|
|
68034
|
+
const candidate = value;
|
|
68035
|
+
if (candidate._id)
|
|
68036
|
+
return toObjectId23(candidate._id, label);
|
|
68037
|
+
if (candidate.$oid)
|
|
68038
|
+
return toObjectId23(candidate.$oid, label);
|
|
68039
|
+
if (typeof candidate.toHexString === "function")
|
|
68040
|
+
return toObjectId23(candidate.toHexString(), label);
|
|
68041
|
+
if (typeof candidate.toString === "function") {
|
|
68042
|
+
const text = candidate.toString();
|
|
68043
|
+
if (text !== "[object Object]")
|
|
68044
|
+
return toObjectId23(text, label);
|
|
68045
|
+
}
|
|
68046
|
+
}
|
|
68047
|
+
throw new BadRequestError228(`Invalid ${label} format`);
|
|
68048
|
+
}
|
|
68049
|
+
var objectIdSchema2 = Joi150.custom((value, helpers) => canReadObjectId(value) ? value : helpers.error("any.invalid"), "ObjectId").messages({
|
|
68050
|
+
"any.invalid": "{{#label}} must be a valid ObjectId"
|
|
68051
|
+
});
|
|
68052
|
+
var schemaHidAmicoReader = Joi150.object({
|
|
68053
|
+
_id: objectIdSchema2.optional(),
|
|
68054
|
+
site: objectIdSchema2.required(),
|
|
68055
|
+
name: Joi150.string().trim().required(),
|
|
68056
|
+
baseUrl: Joi150.string().uri({ scheme: ["http", "https"] }).required(),
|
|
68057
|
+
username: Joi150.string().trim().required(),
|
|
68058
|
+
password: Joi150.string().required(),
|
|
68059
|
+
location: Joi150.string().allow(null, "").optional(),
|
|
68060
|
+
deviceId: Joi150.string().allow(null, "").optional(),
|
|
68061
|
+
monitorPath: Joi150.string().allow(null, "").optional(),
|
|
68062
|
+
enabled: Joi150.boolean().optional(),
|
|
68063
|
+
status: Joi150.string().valid("active", "inactive", "deleted", "offline").optional(),
|
|
68064
|
+
lastSeenAt: Joi150.date().optional(),
|
|
68065
|
+
lastSyncAt: Joi150.date().optional(),
|
|
68066
|
+
lastSyncStatus: Joi150.string().valid("idle", "running", "completed", "failed").optional(),
|
|
68067
|
+
lastSyncMessage: Joi150.string().allow(null, "").optional(),
|
|
68068
|
+
createdAt: Joi150.date().optional(),
|
|
68069
|
+
updatedAt: Joi150.date().optional(),
|
|
68070
|
+
deletedAt: Joi150.date().optional()
|
|
68071
|
+
});
|
|
68072
|
+
var schemaUpdateHidAmicoReader = Joi150.object({
|
|
68073
|
+
site: objectIdSchema2.optional(),
|
|
68074
|
+
name: Joi150.string().trim().optional(),
|
|
68075
|
+
baseUrl: Joi150.string().uri({ scheme: ["http", "https"] }).optional(),
|
|
68076
|
+
username: Joi150.string().trim().optional(),
|
|
68077
|
+
password: Joi150.string().allow(null, "").optional(),
|
|
68078
|
+
location: Joi150.string().allow(null, "").optional(),
|
|
68079
|
+
deviceId: Joi150.string().allow(null, "").optional(),
|
|
68080
|
+
monitorPath: Joi150.string().allow(null, "").optional(),
|
|
68081
|
+
enabled: Joi150.boolean().optional(),
|
|
68082
|
+
status: Joi150.string().valid("active", "inactive", "deleted", "offline").optional(),
|
|
68083
|
+
lastSeenAt: Joi150.date().optional(),
|
|
68084
|
+
lastSyncAt: Joi150.date().optional(),
|
|
68085
|
+
lastSyncStatus: Joi150.string().valid("idle", "running", "completed", "failed").optional(),
|
|
68086
|
+
lastSyncMessage: Joi150.string().allow(null, "").optional(),
|
|
68087
|
+
deletedAt: Joi150.date().optional()
|
|
68088
|
+
});
|
|
68089
|
+
var schemaHidAmicoEvent = Joi150.object({
|
|
68090
|
+
_id: objectIdSchema2.optional(),
|
|
68091
|
+
reader: objectIdSchema2.required(),
|
|
68092
|
+
site: objectIdSchema2.optional(),
|
|
68093
|
+
type: Joi150.string().required(),
|
|
68094
|
+
payload: Joi150.object().unknown(true).required(),
|
|
68095
|
+
status: Joi150.string().valid("received", "processed", "failed").optional(),
|
|
68096
|
+
createdAt: Joi150.date().optional()
|
|
68097
|
+
});
|
|
68098
|
+
var schemaHidAmicoIdentity = Joi150.object({
|
|
68099
|
+
_id: objectIdSchema2.optional(),
|
|
68100
|
+
reader: objectIdSchema2.required(),
|
|
68101
|
+
site: objectIdSchema2.required(),
|
|
68102
|
+
hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
|
|
68103
|
+
registration: Joi150.string().optional().allow(null, ""),
|
|
68104
|
+
cardNo: Joi150.string().optional().allow(null, ""),
|
|
68105
|
+
person: objectIdSchema2.optional().allow(null, ""),
|
|
68106
|
+
user: objectIdSchema2.optional().allow(null, ""),
|
|
68107
|
+
member: objectIdSchema2.optional().allow(null, ""),
|
|
68108
|
+
visitor: objectIdSchema2.optional().allow(null, ""),
|
|
68109
|
+
type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").required(),
|
|
68110
|
+
status: Joi150.string().valid("active", "inactive", "deleted").optional(),
|
|
68111
|
+
metadata: Joi150.object().unknown(true).optional(),
|
|
68112
|
+
createdAt: Joi150.date().optional(),
|
|
68113
|
+
updatedAt: Joi150.date().optional(),
|
|
68114
|
+
deletedAt: Joi150.date().optional()
|
|
68115
|
+
}).or("hidUserId", "registration", "cardNo");
|
|
68116
|
+
var schemaCreateHidAmicoIdentity = Joi150.object({
|
|
68117
|
+
site: objectIdSchema2.optional(),
|
|
68118
|
+
hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
|
|
68119
|
+
registration: Joi150.string().optional().allow(null, ""),
|
|
68120
|
+
cardNo: Joi150.string().optional().allow(null, ""),
|
|
68121
|
+
person: objectIdSchema2.optional().allow(null, ""),
|
|
68122
|
+
user: objectIdSchema2.optional().allow(null, ""),
|
|
68123
|
+
member: objectIdSchema2.optional().allow(null, ""),
|
|
68124
|
+
visitor: objectIdSchema2.optional().allow(null, ""),
|
|
68125
|
+
type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").required(),
|
|
68126
|
+
status: Joi150.string().valid("active", "inactive", "deleted").optional(),
|
|
68127
|
+
metadata: Joi150.object().unknown(true).optional()
|
|
68128
|
+
}).or("hidUserId", "registration", "cardNo");
|
|
68129
|
+
var schemaUpdateHidAmicoIdentity = Joi150.object({
|
|
68130
|
+
hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
|
|
68131
|
+
registration: Joi150.string().optional().allow(null, ""),
|
|
68132
|
+
cardNo: Joi150.string().optional().allow(null, ""),
|
|
68133
|
+
person: objectIdSchema2.optional().allow(null, ""),
|
|
68134
|
+
user: objectIdSchema2.optional().allow(null, ""),
|
|
68135
|
+
member: objectIdSchema2.optional().allow(null, ""),
|
|
68136
|
+
visitor: objectIdSchema2.optional().allow(null, ""),
|
|
68137
|
+
type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").optional(),
|
|
68138
|
+
status: Joi150.string().valid("active", "inactive", "deleted").optional(),
|
|
68139
|
+
metadata: Joi150.object().unknown(true).optional(),
|
|
68140
|
+
deletedAt: Joi150.date().optional()
|
|
68141
|
+
});
|
|
68142
|
+
var schemaHidAmicoReaderIdParams = Joi150.object({
|
|
68143
|
+
readerId: Joi150.string().hex().length(24).required()
|
|
68144
|
+
});
|
|
68145
|
+
var schemaHidAmicoUserImageParams = Joi150.object({
|
|
68146
|
+
readerId: Joi150.string().hex().length(24).required(),
|
|
68147
|
+
hidUserId: Joi150.alternatives().try(Joi150.string(), Joi150.number()).required()
|
|
68148
|
+
});
|
|
68149
|
+
var schemaHidAmicoIdentityIdParams = Joi150.object({
|
|
68150
|
+
identityId: Joi150.string().hex().length(24).required()
|
|
68151
|
+
});
|
|
68152
|
+
var schemaHidAmicoReaderListQuery = Joi150.object({
|
|
68153
|
+
site: Joi150.string().hex().length(24).optional(),
|
|
68154
|
+
page: Joi150.number().min(1).optional(),
|
|
68155
|
+
limit: Joi150.number().min(1).optional()
|
|
68156
|
+
});
|
|
68157
|
+
var schemaHidAmicoLogQuery = Joi150.object({
|
|
68158
|
+
page: Joi150.number().min(1).optional(),
|
|
68159
|
+
limit: Joi150.number().min(1).optional(),
|
|
68160
|
+
type: Joi150.string().optional()
|
|
68161
|
+
});
|
|
68162
|
+
var schemaHidAmicoIdentityQuery = Joi150.object({
|
|
68163
|
+
page: Joi150.number().min(1).optional(),
|
|
68164
|
+
limit: Joi150.number().min(1).optional(),
|
|
68165
|
+
type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").optional(),
|
|
68166
|
+
status: Joi150.string().valid("active", "inactive", "deleted").optional(),
|
|
68167
|
+
search: Joi150.string().allow("").optional()
|
|
68168
|
+
});
|
|
68169
|
+
var schemaHidAmicoSync = Joi150.object({
|
|
68170
|
+
objects: Joi150.array().items(
|
|
68171
|
+
Joi150.object({
|
|
68172
|
+
object: Joi150.string().required(),
|
|
68173
|
+
values: Joi150.array().items(Joi150.object().unknown(true)).required()
|
|
68174
|
+
}).unknown(true)
|
|
68175
|
+
).optional(),
|
|
68176
|
+
users: Joi150.array().items(Joi150.object().unknown(true)).optional(),
|
|
68177
|
+
cards: Joi150.array().items(Joi150.object().unknown(true)).optional(),
|
|
68178
|
+
qrcodes: Joi150.array().items(Joi150.object().unknown(true)).optional(),
|
|
68179
|
+
pins: Joi150.array().items(Joi150.object().unknown(true)).optional()
|
|
68180
|
+
}).unknown(true);
|
|
68181
|
+
var schemaHidAmicoExecuteActions = Joi150.object({
|
|
68182
|
+
actions: Joi150.array().items(Joi150.object().unknown(true)).min(1).required()
|
|
68183
|
+
}).unknown(true);
|
|
68184
|
+
var schemaHidAmicoConfiguration = Joi150.object().pattern(Joi150.string(), Joi150.array().items(Joi150.string())).min(1).unknown(true);
|
|
68185
|
+
var schemaHidAmicoSetConfiguration = Joi150.object().unknown(true);
|
|
68186
|
+
var schemaHidAmicoObjectOperation = Joi150.object({
|
|
68187
|
+
operation: Joi150.string().valid("load", "create", "modify", "destroy").required(),
|
|
68188
|
+
object: Joi150.string().required(),
|
|
68189
|
+
values: Joi150.alternatives().try(
|
|
68190
|
+
Joi150.array().items(Joi150.object().unknown(true)),
|
|
68191
|
+
Joi150.object().unknown(true)
|
|
68192
|
+
).optional(),
|
|
68193
|
+
where: Joi150.object().unknown(true).optional(),
|
|
68194
|
+
fields: Joi150.array().items(Joi150.string()).optional(),
|
|
68195
|
+
order: Joi150.array().items(Joi150.string()).optional(),
|
|
68196
|
+
limit: Joi150.number().integer().min(1).optional(),
|
|
68197
|
+
offset: Joi150.number().integer().min(0).optional()
|
|
68198
|
+
}).unknown(true);
|
|
68199
|
+
var schemaHidAmicoNotificationParams = Joi150.object({
|
|
68200
|
+
readerId: Joi150.string().hex().length(24).required(),
|
|
68201
|
+
type: Joi150.string().valid(
|
|
68202
|
+
"dao",
|
|
68203
|
+
"template",
|
|
68204
|
+
"user_image",
|
|
68205
|
+
"card",
|
|
68206
|
+
"pin",
|
|
68207
|
+
"password",
|
|
68208
|
+
"operation_mode",
|
|
68209
|
+
"door",
|
|
68210
|
+
"secbox",
|
|
68211
|
+
"access_photo",
|
|
68212
|
+
"new_user_identified",
|
|
68213
|
+
"push_result"
|
|
68214
|
+
).required()
|
|
68215
|
+
});
|
|
68216
|
+
function MHidAmicoReader(value) {
|
|
68217
|
+
const { error } = schemaHidAmicoReader.validate(value);
|
|
68218
|
+
if (error) {
|
|
68219
|
+
logger198.info(`HID Amico reader: ${error.message}`);
|
|
68220
|
+
throw new BadRequestError228(error.message);
|
|
68221
|
+
}
|
|
68222
|
+
return {
|
|
68223
|
+
_id: value._id ? toObjectId23(value._id, "reader ID") : new ObjectId153(),
|
|
68224
|
+
site: toObjectId23(value.site, "site ID"),
|
|
68225
|
+
name: value.name,
|
|
68226
|
+
baseUrl: value.baseUrl.replace(/\/+$/, ""),
|
|
68227
|
+
username: value.username,
|
|
68228
|
+
password: value.password,
|
|
68229
|
+
location: value.location ?? "",
|
|
68230
|
+
deviceId: value.deviceId ?? "",
|
|
68231
|
+
monitorPath: value.monitorPath ?? "api/notifications",
|
|
68232
|
+
enabled: value.enabled ?? true,
|
|
68233
|
+
status: value.status ?? "active",
|
|
68234
|
+
lastSeenAt: value.lastSeenAt ?? "",
|
|
68235
|
+
lastSyncAt: value.lastSyncAt ?? "",
|
|
68236
|
+
lastSyncStatus: value.lastSyncStatus ?? "idle",
|
|
68237
|
+
lastSyncMessage: value.lastSyncMessage ?? "",
|
|
68238
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
68239
|
+
updatedAt: value.updatedAt ?? /* @__PURE__ */ new Date(),
|
|
68240
|
+
deletedAt: value.deletedAt ?? ""
|
|
68241
|
+
};
|
|
68242
|
+
}
|
|
68243
|
+
function MHidAmicoEvent(value) {
|
|
68244
|
+
const { error } = schemaHidAmicoEvent.validate(value);
|
|
68245
|
+
if (error) {
|
|
68246
|
+
logger198.info(`HID Amico event: ${error.message}`);
|
|
68247
|
+
throw new BadRequestError228(error.message);
|
|
68248
|
+
}
|
|
68249
|
+
return {
|
|
68250
|
+
_id: value._id ? toObjectId23(value._id, "event ID") : new ObjectId153(),
|
|
68251
|
+
reader: toObjectId23(value.reader, "reader ID"),
|
|
68252
|
+
site: value.site ? toObjectId23(value.site, "site ID") : void 0,
|
|
68253
|
+
type: value.type,
|
|
68254
|
+
payload: value.payload,
|
|
68255
|
+
status: value.status ?? "received",
|
|
68256
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
|
|
68257
|
+
};
|
|
68258
|
+
}
|
|
68259
|
+
function optionalObjectId(value) {
|
|
68260
|
+
return value ? toObjectId23(value) : void 0;
|
|
68261
|
+
}
|
|
68262
|
+
function MHidAmicoIdentity(value) {
|
|
68263
|
+
const { error } = schemaHidAmicoIdentity.validate(value);
|
|
68264
|
+
if (error) {
|
|
68265
|
+
logger198.info(`HID Amico identity: ${error.message}`);
|
|
68266
|
+
throw new BadRequestError228(error.message);
|
|
68267
|
+
}
|
|
68268
|
+
return {
|
|
68269
|
+
_id: value._id ? toObjectId23(value._id, "identity ID") : new ObjectId153(),
|
|
68270
|
+
reader: toObjectId23(value.reader, "reader ID"),
|
|
68271
|
+
site: toObjectId23(value.site, "site ID"),
|
|
68272
|
+
hidUserId: value.hidUserId === void 0 || value.hidUserId === null ? "" : String(value.hidUserId),
|
|
68273
|
+
registration: value.registration ?? "",
|
|
68274
|
+
cardNo: value.cardNo ?? "",
|
|
68275
|
+
person: optionalObjectId(value.person),
|
|
68276
|
+
user: optionalObjectId(value.user),
|
|
68277
|
+
member: optionalObjectId(value.member),
|
|
68278
|
+
visitor: optionalObjectId(value.visitor),
|
|
68279
|
+
type: value.type,
|
|
68280
|
+
status: value.status ?? "active",
|
|
68281
|
+
metadata: value.metadata ?? {},
|
|
68282
|
+
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
68283
|
+
updatedAt: value.updatedAt ?? /* @__PURE__ */ new Date(),
|
|
68284
|
+
deletedAt: value.deletedAt ?? ""
|
|
68285
|
+
};
|
|
68286
|
+
}
|
|
68287
|
+
|
|
68288
|
+
// src/repositories/hid-amico.repo.ts
|
|
68289
|
+
import {
|
|
68290
|
+
BadRequestError as BadRequestError229,
|
|
68291
|
+
InternalServerError as InternalServerError84,
|
|
68292
|
+
logger as logger199,
|
|
68293
|
+
paginate as paginate65,
|
|
68294
|
+
useAtlas as useAtlas130
|
|
68295
|
+
} from "@7365admin1/node-server-utils";
|
|
68296
|
+
import { ObjectId as ObjectId154 } from "mongodb";
|
|
68297
|
+
function useHidAmicoRepo() {
|
|
68298
|
+
function db() {
|
|
68299
|
+
const instance = useAtlas130.getDb();
|
|
68300
|
+
if (!instance) {
|
|
68301
|
+
throw new InternalServerError84("Unable to connect to server.");
|
|
68302
|
+
}
|
|
68303
|
+
return instance;
|
|
68304
|
+
}
|
|
68305
|
+
function readers() {
|
|
68306
|
+
return db().collection("hid-amico-readers");
|
|
68307
|
+
}
|
|
68308
|
+
function events() {
|
|
68309
|
+
return db().collection("hid-amico-events");
|
|
68310
|
+
}
|
|
68311
|
+
function identities() {
|
|
68312
|
+
return db().collection("hid-amico-identities");
|
|
68313
|
+
}
|
|
68314
|
+
function toId(id, label = "ID") {
|
|
68315
|
+
try {
|
|
68316
|
+
return new ObjectId154(id);
|
|
68317
|
+
} catch {
|
|
68318
|
+
throw new BadRequestError229(`Invalid ${label} format`);
|
|
68319
|
+
}
|
|
68320
|
+
}
|
|
68321
|
+
function hideSecret(reader) {
|
|
68322
|
+
if (!reader) {
|
|
68323
|
+
return reader;
|
|
68324
|
+
}
|
|
68325
|
+
const { password, ...safeReader } = reader;
|
|
68326
|
+
const status = safeReader.lastSyncStatus === "failed" && safeReader.status === "active" ? "offline" : safeReader.status;
|
|
68327
|
+
return {
|
|
68328
|
+
...safeReader,
|
|
68329
|
+
status,
|
|
68330
|
+
passwordSet: Boolean(password)
|
|
68331
|
+
};
|
|
68332
|
+
}
|
|
68333
|
+
function escapeRegex(value) {
|
|
68334
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
68335
|
+
}
|
|
68336
|
+
function buildIdentityKeyQuery(value) {
|
|
68337
|
+
const or = [];
|
|
68338
|
+
if (value.hidUserId !== void 0 && value.hidUserId !== null && String(value.hidUserId) !== "") {
|
|
68339
|
+
or.push({ hidUserId: String(value.hidUserId) });
|
|
68340
|
+
}
|
|
68341
|
+
if (value.registration) {
|
|
68342
|
+
or.push({ registration: value.registration });
|
|
68343
|
+
}
|
|
68344
|
+
if (value.cardNo) {
|
|
68345
|
+
or.push({ cardNo: value.cardNo });
|
|
68346
|
+
}
|
|
68347
|
+
return or;
|
|
68348
|
+
}
|
|
68349
|
+
async function createIndexes() {
|
|
68350
|
+
try {
|
|
68351
|
+
await Promise.all([
|
|
68352
|
+
readers().createIndex({ site: 1, status: 1 }),
|
|
68353
|
+
readers().createIndex(
|
|
68354
|
+
{ site: 1, baseUrl: 1 },
|
|
68355
|
+
{ unique: true, partialFilterExpression: { status: "active" } }
|
|
68356
|
+
),
|
|
68357
|
+
readers().createIndex({ deviceId: 1 }),
|
|
68358
|
+
events().createIndex({ reader: 1, createdAt: -1 }),
|
|
68359
|
+
events().createIndex({ site: 1, createdAt: -1 }),
|
|
68360
|
+
events().createIndex({ type: 1, createdAt: -1 }),
|
|
68361
|
+
identities().createIndex({ reader: 1, status: 1 }),
|
|
68362
|
+
identities().createIndex({ site: 1, status: 1 }),
|
|
68363
|
+
identities().createIndex({ reader: 1, hidUserId: 1 }),
|
|
68364
|
+
identities().createIndex({ reader: 1, registration: 1 }),
|
|
68365
|
+
identities().createIndex({ reader: 1, cardNo: 1 })
|
|
68366
|
+
]);
|
|
68367
|
+
return "HID Amico indexes created.";
|
|
68368
|
+
} catch (error) {
|
|
68369
|
+
logger199.error(error.message);
|
|
68370
|
+
throw new Error("Failed to create HID Amico indexes.");
|
|
68371
|
+
}
|
|
68372
|
+
}
|
|
68373
|
+
async function add(value, session) {
|
|
68374
|
+
try {
|
|
68375
|
+
const doc = MHidAmicoReader(value);
|
|
68376
|
+
await readers().insertOne(doc, { session });
|
|
68377
|
+
return hideSecret(doc);
|
|
68378
|
+
} catch (error) {
|
|
68379
|
+
if (error.message?.includes("duplicate")) {
|
|
68380
|
+
throw new BadRequestError229("HID Amico reader already exists for this site and URL.");
|
|
68381
|
+
}
|
|
68382
|
+
throw error;
|
|
68383
|
+
}
|
|
68384
|
+
}
|
|
68385
|
+
async function list(value) {
|
|
68386
|
+
const page = value.page ? value.page - 1 : 0;
|
|
68387
|
+
const limit = value.limit || 10;
|
|
68388
|
+
const query = { status: { $ne: "deleted" } };
|
|
68389
|
+
if (value.site) {
|
|
68390
|
+
query.site = toId(value.site, "site ID");
|
|
68391
|
+
}
|
|
68392
|
+
const items = await readers().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
|
|
68393
|
+
const total = await readers().countDocuments(query);
|
|
68394
|
+
return paginate65(items.map(hideSecret), page, limit, total);
|
|
68395
|
+
}
|
|
68396
|
+
async function getById(id, options = {}) {
|
|
68397
|
+
const _id = toId(id, "reader ID");
|
|
68398
|
+
const reader = await readers().findOne(
|
|
68399
|
+
{ _id, status: { $ne: "deleted" } }
|
|
68400
|
+
);
|
|
68401
|
+
if (!reader) {
|
|
68402
|
+
throw new BadRequestError229("HID Amico reader not found.");
|
|
68403
|
+
}
|
|
68404
|
+
return options.includePassword ? reader : hideSecret(reader);
|
|
68405
|
+
}
|
|
68406
|
+
async function updateById(id, value, session) {
|
|
68407
|
+
const { error } = schemaUpdateHidAmicoReader.validate(value);
|
|
68408
|
+
if (error) {
|
|
68409
|
+
throw new BadRequestError229(error.message);
|
|
68410
|
+
}
|
|
68411
|
+
const _id = toId(id, "reader ID");
|
|
68412
|
+
const payload = {
|
|
68413
|
+
...value,
|
|
68414
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
68415
|
+
};
|
|
68416
|
+
if (payload.site) {
|
|
68417
|
+
payload.site = toId(payload.site, "site ID");
|
|
68418
|
+
}
|
|
68419
|
+
if (payload.baseUrl) {
|
|
68420
|
+
payload.baseUrl = payload.baseUrl.replace(/\/+$/, "");
|
|
68421
|
+
}
|
|
68422
|
+
const updated = await readers().findOneAndUpdate(
|
|
68423
|
+
{ _id, status: { $ne: "deleted" } },
|
|
68424
|
+
{ $set: payload },
|
|
68425
|
+
{ returnDocument: "after", session }
|
|
68426
|
+
);
|
|
68427
|
+
if (!updated) {
|
|
68428
|
+
throw new BadRequestError229("HID Amico reader not found.");
|
|
68429
|
+
}
|
|
68430
|
+
return hideSecret(updated);
|
|
68431
|
+
}
|
|
68432
|
+
async function markDeleted(id, session) {
|
|
68433
|
+
return updateById(
|
|
68434
|
+
id,
|
|
68435
|
+
{
|
|
68436
|
+
status: "deleted",
|
|
68437
|
+
enabled: false,
|
|
68438
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
68439
|
+
},
|
|
68440
|
+
session
|
|
68441
|
+
);
|
|
68442
|
+
}
|
|
68443
|
+
async function addEvent(value, session) {
|
|
68444
|
+
const event = MHidAmicoEvent(value);
|
|
68445
|
+
await events().insertOne(event, { session });
|
|
68446
|
+
return event;
|
|
68447
|
+
}
|
|
68448
|
+
async function listEvents(value) {
|
|
68449
|
+
const page = value.page ? value.page - 1 : 0;
|
|
68450
|
+
const limit = value.limit || 20;
|
|
68451
|
+
const query = { reader: toId(value.reader, "reader ID") };
|
|
68452
|
+
if (value.type) {
|
|
68453
|
+
query.type = value.type;
|
|
68454
|
+
}
|
|
68455
|
+
const items = await events().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
|
|
68456
|
+
const total = await events().countDocuments(query);
|
|
68457
|
+
return paginate65(items, page, limit, total);
|
|
68458
|
+
}
|
|
68459
|
+
async function addIdentity(value, session) {
|
|
68460
|
+
try {
|
|
68461
|
+
const identity = MHidAmicoIdentity(value);
|
|
68462
|
+
const existing = await findExistingIdentity({
|
|
68463
|
+
reader: identity.reader,
|
|
68464
|
+
hidUserId: identity.hidUserId,
|
|
68465
|
+
registration: identity.registration,
|
|
68466
|
+
cardNo: identity.cardNo
|
|
68467
|
+
});
|
|
68468
|
+
if (existing) {
|
|
68469
|
+
throw new BadRequestError229("HID Amico identity already exists for this reader.");
|
|
68470
|
+
}
|
|
68471
|
+
await identities().insertOne(identity, { session });
|
|
68472
|
+
return identity;
|
|
68473
|
+
} catch (error) {
|
|
68474
|
+
if (error instanceof BadRequestError229) {
|
|
68475
|
+
throw error;
|
|
68476
|
+
}
|
|
68477
|
+
if (error.message?.includes("duplicate")) {
|
|
68478
|
+
throw new BadRequestError229("HID Amico identity already exists for this reader.");
|
|
68479
|
+
}
|
|
68480
|
+
throw error;
|
|
68481
|
+
}
|
|
68482
|
+
}
|
|
68483
|
+
async function listIdentities(value) {
|
|
68484
|
+
const page = value.page ? value.page - 1 : 0;
|
|
68485
|
+
const limit = value.limit || 20;
|
|
68486
|
+
const query = {
|
|
68487
|
+
reader: toId(value.reader, "reader ID"),
|
|
68488
|
+
status: value.status || { $ne: "deleted" }
|
|
68489
|
+
};
|
|
68490
|
+
if (value.type) {
|
|
68491
|
+
query.type = value.type;
|
|
68492
|
+
}
|
|
68493
|
+
if (value.search) {
|
|
68494
|
+
const search = escapeRegex(value.search);
|
|
68495
|
+
query.$or = [
|
|
68496
|
+
{ hidUserId: { $regex: search, $options: "i" } },
|
|
68497
|
+
{ registration: { $regex: search, $options: "i" } },
|
|
68498
|
+
{ cardNo: { $regex: search, $options: "i" } }
|
|
68499
|
+
];
|
|
68500
|
+
}
|
|
68501
|
+
const items = await identities().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
|
|
68502
|
+
const total = await identities().countDocuments(query);
|
|
68503
|
+
return paginate65(items, page, limit, total);
|
|
68504
|
+
}
|
|
68505
|
+
async function updateIdentity(id, value, session) {
|
|
68506
|
+
const { error } = schemaUpdateHidAmicoIdentity.validate(value);
|
|
68507
|
+
if (error) {
|
|
68508
|
+
throw new BadRequestError229(error.message);
|
|
68509
|
+
}
|
|
68510
|
+
const payload = {
|
|
68511
|
+
...value,
|
|
68512
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
68513
|
+
};
|
|
68514
|
+
const unsetPayload = {};
|
|
68515
|
+
["person", "user", "member", "visitor"].forEach((field) => {
|
|
68516
|
+
if (payload[field]) {
|
|
68517
|
+
payload[field] = toId(payload[field], `${field} ID`);
|
|
68518
|
+
}
|
|
68519
|
+
if (payload[field] === "" || payload[field] === null) {
|
|
68520
|
+
delete payload[field];
|
|
68521
|
+
unsetPayload[field] = "";
|
|
68522
|
+
}
|
|
68523
|
+
});
|
|
68524
|
+
if (payload.hidUserId !== void 0 && payload.hidUserId !== null) {
|
|
68525
|
+
payload.hidUserId = String(payload.hidUserId);
|
|
68526
|
+
}
|
|
68527
|
+
const updated = await identities().findOneAndUpdate(
|
|
68528
|
+
{ _id: toId(id, "identity ID"), status: { $ne: "deleted" } },
|
|
68529
|
+
{
|
|
68530
|
+
$set: payload,
|
|
68531
|
+
...Object.keys(unsetPayload).length ? { $unset: unsetPayload } : {}
|
|
68532
|
+
},
|
|
68533
|
+
{ returnDocument: "after", session }
|
|
68534
|
+
);
|
|
68535
|
+
if (!updated) {
|
|
68536
|
+
throw new BadRequestError229("HID Amico identity not found.");
|
|
68537
|
+
}
|
|
68538
|
+
return updated;
|
|
68539
|
+
}
|
|
68540
|
+
async function deleteIdentity(id, session) {
|
|
68541
|
+
return updateIdentity(
|
|
68542
|
+
id,
|
|
68543
|
+
{
|
|
68544
|
+
status: "deleted",
|
|
68545
|
+
deletedAt: /* @__PURE__ */ new Date()
|
|
68546
|
+
},
|
|
68547
|
+
session
|
|
68548
|
+
);
|
|
68549
|
+
}
|
|
68550
|
+
async function findIdentity(value) {
|
|
68551
|
+
const or = buildIdentityKeyQuery(value);
|
|
68552
|
+
if (!or.length) {
|
|
68553
|
+
return null;
|
|
68554
|
+
}
|
|
68555
|
+
return identities().findOne({
|
|
68556
|
+
reader: toId(value.reader, "reader ID"),
|
|
68557
|
+
status: "active",
|
|
68558
|
+
$or: or
|
|
68559
|
+
});
|
|
68560
|
+
}
|
|
68561
|
+
async function findExistingIdentity(value) {
|
|
68562
|
+
const or = buildIdentityKeyQuery(value);
|
|
68563
|
+
if (!or.length) {
|
|
68564
|
+
return null;
|
|
68565
|
+
}
|
|
68566
|
+
return identities().findOne({
|
|
68567
|
+
reader: toId(value.reader, "reader ID"),
|
|
68568
|
+
status: { $ne: "deleted" },
|
|
68569
|
+
$or: or
|
|
68570
|
+
});
|
|
68571
|
+
}
|
|
68572
|
+
return {
|
|
68573
|
+
createIndexes,
|
|
68574
|
+
add,
|
|
68575
|
+
list,
|
|
68576
|
+
getById,
|
|
68577
|
+
updateById,
|
|
68578
|
+
markDeleted,
|
|
68579
|
+
addEvent,
|
|
68580
|
+
listEvents,
|
|
68581
|
+
addIdentity,
|
|
68582
|
+
listIdentities,
|
|
68583
|
+
updateIdentity,
|
|
68584
|
+
deleteIdentity,
|
|
68585
|
+
findIdentity,
|
|
68586
|
+
findExistingIdentity
|
|
68587
|
+
};
|
|
68588
|
+
}
|
|
68589
|
+
|
|
68590
|
+
// src/services/hid-amico.service.ts
|
|
68591
|
+
import crypto5 from "crypto";
|
|
68592
|
+
import axios4 from "axios";
|
|
68593
|
+
import { BadRequestError as BadRequestError230 } from "@7365admin1/node-server-utils";
|
|
68594
|
+
var PASSWORD_PREFIX = "v1";
|
|
68595
|
+
function getSecretKey() {
|
|
68596
|
+
const secret = process.env.HID_AMICO_SECRET || process.env.ACCESS_TOKEN_SECRET || "iservice365-hid-amico";
|
|
68597
|
+
return crypto5.createHash("sha256").update(secret).digest();
|
|
68598
|
+
}
|
|
68599
|
+
function encryptSecret(value) {
|
|
68600
|
+
const iv = crypto5.randomBytes(12);
|
|
68601
|
+
const cipher = crypto5.createCipheriv("aes-256-gcm", getSecretKey(), iv);
|
|
68602
|
+
const encrypted = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
|
|
68603
|
+
const tag = cipher.getAuthTag();
|
|
68604
|
+
return [PASSWORD_PREFIX, iv.toString("hex"), tag.toString("hex"), encrypted.toString("hex")].join(":");
|
|
68605
|
+
}
|
|
68606
|
+
function decryptSecret(value) {
|
|
68607
|
+
if (!value?.startsWith(`${PASSWORD_PREFIX}:`)) {
|
|
68608
|
+
return value;
|
|
68609
|
+
}
|
|
68610
|
+
const [, ivHex, tagHex, encryptedHex] = value.split(":");
|
|
68611
|
+
const decipher = crypto5.createDecipheriv("aes-256-gcm", getSecretKey(), Buffer.from(ivHex, "hex"));
|
|
68612
|
+
decipher.setAuthTag(Buffer.from(tagHex, "hex"));
|
|
68613
|
+
return Buffer.concat([
|
|
68614
|
+
decipher.update(Buffer.from(encryptedHex, "hex")),
|
|
68615
|
+
decipher.final()
|
|
68616
|
+
]).toString("utf8");
|
|
68617
|
+
}
|
|
68618
|
+
function formatHidResponse(data) {
|
|
68619
|
+
if (data === void 0 || data === null) {
|
|
68620
|
+
return "";
|
|
68621
|
+
}
|
|
68622
|
+
const text = typeof data === "string" ? data : JSON.stringify(data);
|
|
68623
|
+
return text.length > 300 ? `${text.slice(0, 300)}...` : text;
|
|
68624
|
+
}
|
|
68625
|
+
function sanitizeHidPath(path5) {
|
|
68626
|
+
return path5.replace(/([?&]session=)[^&]+/i, "$1<redacted>");
|
|
68627
|
+
}
|
|
68628
|
+
function toHidRequestError(error, path5) {
|
|
68629
|
+
if (axios4.isAxiosError(error)) {
|
|
68630
|
+
const status = error.response?.status;
|
|
68631
|
+
const payload = formatHidResponse(error.response?.data);
|
|
68632
|
+
const detail = [
|
|
68633
|
+
`HID Amico request failed: ${sanitizeHidPath(path5)}`,
|
|
68634
|
+
status ? `status ${status}` : "",
|
|
68635
|
+
payload ? `response ${payload}` : error.message
|
|
68636
|
+
].filter(Boolean).join(" - ");
|
|
68637
|
+
return new BadRequestError230(detail);
|
|
68638
|
+
}
|
|
68639
|
+
return error;
|
|
68640
|
+
}
|
|
68641
|
+
var HidAmicoClient = class {
|
|
68642
|
+
constructor(reader) {
|
|
68643
|
+
this.reader = reader;
|
|
68644
|
+
this.session = "";
|
|
68645
|
+
this.http = axios4.create({
|
|
68646
|
+
baseURL: reader.baseUrl.replace(/\/+$/, ""),
|
|
68647
|
+
timeout: 15e3,
|
|
68648
|
+
headers: { "Content-Type": "application/json" }
|
|
68649
|
+
});
|
|
68650
|
+
}
|
|
68651
|
+
async post(path5, body) {
|
|
68652
|
+
try {
|
|
68653
|
+
return await this.http.post(path5, body);
|
|
68654
|
+
} catch (error) {
|
|
68655
|
+
throw toHidRequestError(error, path5);
|
|
68656
|
+
}
|
|
68657
|
+
}
|
|
68658
|
+
async get(path5, responseType = "json") {
|
|
68659
|
+
try {
|
|
68660
|
+
return await this.http.get(path5, { responseType });
|
|
68661
|
+
} catch (error) {
|
|
68662
|
+
throw toHidRequestError(error, path5);
|
|
68663
|
+
}
|
|
68664
|
+
}
|
|
68665
|
+
url(path5) {
|
|
68666
|
+
const normalizedPath = path5.startsWith("/") ? path5 : `/${path5}`;
|
|
68667
|
+
if (!this.session) {
|
|
68668
|
+
return normalizedPath;
|
|
68669
|
+
}
|
|
68670
|
+
const separator = normalizedPath.includes("?") ? "&" : "?";
|
|
68671
|
+
return `${normalizedPath}${separator}session=${encodeURIComponent(this.session)}`;
|
|
68672
|
+
}
|
|
68673
|
+
async login() {
|
|
68674
|
+
const res = await this.post("/hidlogin.fcgi", {
|
|
68675
|
+
login: this.reader.username,
|
|
68676
|
+
password: decryptSecret(this.reader.password)
|
|
68677
|
+
});
|
|
68678
|
+
if (!res.data?.session) {
|
|
68679
|
+
throw new BadRequestError230("HID Amico login failed: missing session.");
|
|
68680
|
+
}
|
|
68681
|
+
this.session = res.data.session;
|
|
68682
|
+
return this.session;
|
|
68683
|
+
}
|
|
68684
|
+
async sessionIsValid() {
|
|
68685
|
+
if (!this.session) {
|
|
68686
|
+
await this.login();
|
|
68687
|
+
}
|
|
68688
|
+
const res = await this.post(this.url("/session_is_valid.fcgi"), {});
|
|
68689
|
+
return Boolean(res.data?.session_is_valid ?? res.data?.valid ?? true);
|
|
68690
|
+
}
|
|
68691
|
+
async getUserImage(hidUserId) {
|
|
68692
|
+
if (!this.session) {
|
|
68693
|
+
await this.login();
|
|
68694
|
+
}
|
|
68695
|
+
const path5 = this.url(`/user_get_image.fcgi?user_id=${encodeURIComponent(String(hidUserId))}`);
|
|
68696
|
+
const res = await this.get(path5, "arraybuffer");
|
|
68697
|
+
const contentType = String(res.headers?.["content-type"] || "");
|
|
68698
|
+
const buffer = Buffer.from(res.data);
|
|
68699
|
+
if (contentType.includes("application/json")) {
|
|
68700
|
+
const payload = JSON.parse(buffer.toString("utf8"));
|
|
68701
|
+
const image = payload.image || payload.photo || payload.data?.image || payload.data?.photo;
|
|
68702
|
+
if (!image) {
|
|
68703
|
+
throw new BadRequestError230("HID Amico user image response did not include an image.");
|
|
68704
|
+
}
|
|
68705
|
+
return {
|
|
68706
|
+
contentType: payload.contentType || payload.mimeType || "image/jpeg",
|
|
68707
|
+
base64: String(image).replace(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, "")
|
|
68708
|
+
};
|
|
68709
|
+
}
|
|
68710
|
+
return {
|
|
68711
|
+
contentType: contentType || "image/jpeg",
|
|
68712
|
+
base64: buffer.toString("base64")
|
|
68713
|
+
};
|
|
68714
|
+
}
|
|
68715
|
+
async logout() {
|
|
68716
|
+
if (!this.session) {
|
|
68717
|
+
return;
|
|
68718
|
+
}
|
|
68719
|
+
const logoutUrl = this.url("/logout.fcgi");
|
|
68720
|
+
try {
|
|
68721
|
+
this.session = "";
|
|
68722
|
+
await this.post(logoutUrl, {});
|
|
68723
|
+
} catch {
|
|
68724
|
+
this.session = "";
|
|
68725
|
+
}
|
|
68726
|
+
}
|
|
68727
|
+
async createObjects(batch) {
|
|
68728
|
+
if (!this.session) {
|
|
68729
|
+
await this.login();
|
|
68730
|
+
}
|
|
68731
|
+
const res = await this.post(this.url("/create_objects.fcgi"), {
|
|
68732
|
+
object: batch.object,
|
|
68733
|
+
values: batch.values
|
|
68734
|
+
});
|
|
68735
|
+
return res.data;
|
|
68736
|
+
}
|
|
68737
|
+
async loadObjects(query) {
|
|
68738
|
+
if (!this.session) {
|
|
68739
|
+
await this.login();
|
|
68740
|
+
}
|
|
68741
|
+
const res = await this.post(this.url("/load_objects.fcgi"), query);
|
|
68742
|
+
return res.data;
|
|
68743
|
+
}
|
|
68744
|
+
async modifyObjects(payload) {
|
|
68745
|
+
if (!this.session) {
|
|
68746
|
+
await this.login();
|
|
68747
|
+
}
|
|
68748
|
+
const res = await this.post(this.url("/modify_objects.fcgi"), payload);
|
|
68749
|
+
return res.data;
|
|
68750
|
+
}
|
|
68751
|
+
async destroyObjects(payload) {
|
|
68752
|
+
if (!this.session) {
|
|
68753
|
+
await this.login();
|
|
68754
|
+
}
|
|
68755
|
+
const res = await this.post(this.url("/destroy_objects.fcgi"), payload);
|
|
68756
|
+
return res.data;
|
|
68757
|
+
}
|
|
68758
|
+
async doorState() {
|
|
68759
|
+
if (!this.session) {
|
|
68760
|
+
await this.login();
|
|
68761
|
+
}
|
|
68762
|
+
const res = await this.post(this.url("/door_state.fcgi"), {});
|
|
68763
|
+
return res.data;
|
|
68764
|
+
}
|
|
68765
|
+
async executeActions(actions) {
|
|
68766
|
+
if (!this.session) {
|
|
68767
|
+
await this.login();
|
|
68768
|
+
}
|
|
68769
|
+
const res = await this.post(this.url("/execute_actions.fcgi"), { actions });
|
|
68770
|
+
return res.data;
|
|
68771
|
+
}
|
|
68772
|
+
async getConfiguration(payload) {
|
|
68773
|
+
if (!this.session) {
|
|
68774
|
+
await this.login();
|
|
68775
|
+
}
|
|
68776
|
+
const res = await this.post(this.url("/get_configuration.fcgi"), payload);
|
|
68777
|
+
return res.data;
|
|
68778
|
+
}
|
|
68779
|
+
async setConfiguration(payload) {
|
|
68780
|
+
if (!this.session) {
|
|
68781
|
+
await this.login();
|
|
68782
|
+
}
|
|
68783
|
+
const res = await this.post(this.url("/set_configuration.fcgi"), payload);
|
|
68784
|
+
return res.data;
|
|
68785
|
+
}
|
|
68786
|
+
};
|
|
68787
|
+
function normalizeBatches(payload) {
|
|
68788
|
+
if (Array.isArray(payload?.objects)) {
|
|
68789
|
+
return payload.objects.filter((batch) => batch?.object && Array.isArray(batch?.values));
|
|
68790
|
+
}
|
|
68791
|
+
const batches = [];
|
|
68792
|
+
const mappings = [
|
|
68793
|
+
["users", "users"],
|
|
68794
|
+
["cards", "cards"],
|
|
68795
|
+
["qrcodes", "qrcodes"],
|
|
68796
|
+
["pins", "pins"]
|
|
68797
|
+
];
|
|
68798
|
+
mappings.forEach(([key, object]) => {
|
|
68799
|
+
if (Array.isArray(payload?.[key]) && payload[key].length) {
|
|
68800
|
+
batches.push({ object, values: payload[key] });
|
|
68801
|
+
}
|
|
68802
|
+
});
|
|
68803
|
+
return batches;
|
|
68804
|
+
}
|
|
68805
|
+
function firstValue(payload, keys) {
|
|
68806
|
+
for (const key of keys) {
|
|
68807
|
+
const value = payload?.[key];
|
|
68808
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
68809
|
+
return value;
|
|
68810
|
+
}
|
|
68811
|
+
}
|
|
68812
|
+
return void 0;
|
|
68813
|
+
}
|
|
68814
|
+
function extractIdentityKeys(payload) {
|
|
68815
|
+
const nested = payload?.user || payload?.person || payload?.data || {};
|
|
68816
|
+
const merged = { ...payload, ...nested };
|
|
68817
|
+
return {
|
|
68818
|
+
hidUserId: firstValue(merged, ["hidUserId", "hid_user_id", "user_id", "userId", "id", "user"]),
|
|
68819
|
+
registration: firstValue(merged, ["registration", "register", "employeeNo", "staffNo", "memberNo"]),
|
|
68820
|
+
cardNo: firstValue(merged, ["cardNo", "card_no", "card", "cardNumber", "value"])
|
|
68821
|
+
};
|
|
68822
|
+
}
|
|
68823
|
+
function useHidAmicoService() {
|
|
68824
|
+
const repo = useHidAmicoRepo();
|
|
68825
|
+
async function getActiveReader(id) {
|
|
68826
|
+
const reader = await repo.getById(id, { includePassword: true });
|
|
68827
|
+
if (reader.enabled === false || reader.status === "inactive" || reader.status === "deleted") {
|
|
68828
|
+
throw new BadRequestError230("HID Amico reader is not active.");
|
|
68829
|
+
}
|
|
68830
|
+
return reader;
|
|
68831
|
+
}
|
|
68832
|
+
async function createReader(value) {
|
|
68833
|
+
return repo.add({
|
|
68834
|
+
...value,
|
|
68835
|
+
baseUrl: value.baseUrl.replace(/\/+$/, ""),
|
|
68836
|
+
password: encryptSecret(value.password)
|
|
68837
|
+
});
|
|
68838
|
+
}
|
|
68839
|
+
async function updateReader(id, value) {
|
|
68840
|
+
const payload = { ...value };
|
|
68841
|
+
if (payload.password) {
|
|
68842
|
+
payload.password = encryptSecret(payload.password);
|
|
68843
|
+
} else {
|
|
68844
|
+
delete payload.password;
|
|
68845
|
+
}
|
|
68846
|
+
return repo.updateById(id, payload);
|
|
68847
|
+
}
|
|
68848
|
+
async function listReaders(value) {
|
|
68849
|
+
return repo.list(value);
|
|
68850
|
+
}
|
|
68851
|
+
async function deleteReader(id) {
|
|
68852
|
+
return repo.markDeleted(id);
|
|
68853
|
+
}
|
|
68854
|
+
async function testReader(id) {
|
|
68855
|
+
const reader = await repo.getById(id, { includePassword: true });
|
|
68856
|
+
const client = new HidAmicoClient(reader);
|
|
68857
|
+
try {
|
|
68858
|
+
await client.login();
|
|
68859
|
+
const valid = await client.sessionIsValid();
|
|
68860
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date(), lastSyncMessage: "Connection test succeeded." });
|
|
68861
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "test", payload: { valid } });
|
|
68862
|
+
return { valid, message: "HID Amico connection test succeeded." };
|
|
68863
|
+
} catch (error) {
|
|
68864
|
+
await repo.updateById(id, {
|
|
68865
|
+
status: "offline",
|
|
68866
|
+
lastSyncAt: /* @__PURE__ */ new Date(),
|
|
68867
|
+
lastSyncStatus: "failed",
|
|
68868
|
+
lastSyncMessage: error.message
|
|
68869
|
+
});
|
|
68870
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "test_failed", payload: { message: error.message } });
|
|
68871
|
+
throw error;
|
|
68872
|
+
} finally {
|
|
68873
|
+
await client.logout();
|
|
68874
|
+
}
|
|
68875
|
+
}
|
|
68876
|
+
async function syncReader(id, payload) {
|
|
68877
|
+
const reader = await getActiveReader(id);
|
|
68878
|
+
const batches = normalizeBatches(payload);
|
|
68879
|
+
const client = new HidAmicoClient(reader);
|
|
68880
|
+
const results = [];
|
|
68881
|
+
await repo.updateById(id, { lastSyncStatus: "running", lastSyncMessage: "Sync started." });
|
|
68882
|
+
try {
|
|
68883
|
+
await client.login();
|
|
68884
|
+
for (const batch of batches) {
|
|
68885
|
+
const result = await client.createObjects(batch);
|
|
68886
|
+
results.push({ object: batch.object, count: batch.values.length, result });
|
|
68887
|
+
}
|
|
68888
|
+
const message = batches.length ? `Synced ${batches.length} HID object batch(es).` : "HID reader session verified. No sync payload was supplied.";
|
|
68889
|
+
await repo.updateById(id, {
|
|
68890
|
+
lastSeenAt: /* @__PURE__ */ new Date(),
|
|
68891
|
+
lastSyncAt: /* @__PURE__ */ new Date(),
|
|
68892
|
+
lastSyncStatus: "completed",
|
|
68893
|
+
lastSyncMessage: message
|
|
68894
|
+
});
|
|
68895
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "sync", payload: { message, results } });
|
|
68896
|
+
return { message, results };
|
|
68897
|
+
} catch (error) {
|
|
68898
|
+
await repo.updateById(id, {
|
|
68899
|
+
status: "offline",
|
|
68900
|
+
lastSyncAt: /* @__PURE__ */ new Date(),
|
|
68901
|
+
lastSyncStatus: "failed",
|
|
68902
|
+
lastSyncMessage: error.message
|
|
68903
|
+
});
|
|
68904
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "sync_failed", payload: { message: error.message } });
|
|
68905
|
+
throw error;
|
|
68906
|
+
} finally {
|
|
68907
|
+
await client.logout();
|
|
68908
|
+
}
|
|
68909
|
+
}
|
|
68910
|
+
async function receiveNotification(readerId, type, payload) {
|
|
68911
|
+
const reader = await repo.getById(readerId);
|
|
68912
|
+
const identityKeys = extractIdentityKeys(payload);
|
|
68913
|
+
const identity = await repo.findIdentity({
|
|
68914
|
+
reader: readerId,
|
|
68915
|
+
...identityKeys
|
|
68916
|
+
});
|
|
68917
|
+
const enrichedPayload = identity ? {
|
|
68918
|
+
...payload,
|
|
68919
|
+
identity: {
|
|
68920
|
+
_id: identity._id,
|
|
68921
|
+
type: identity.type,
|
|
68922
|
+
hidUserId: identity.hidUserId,
|
|
68923
|
+
registration: identity.registration,
|
|
68924
|
+
cardNo: identity.cardNo,
|
|
68925
|
+
person: identity.person,
|
|
68926
|
+
user: identity.user,
|
|
68927
|
+
member: identity.member,
|
|
68928
|
+
visitor: identity.visitor
|
|
68929
|
+
}
|
|
68930
|
+
} : {
|
|
68931
|
+
...payload,
|
|
68932
|
+
identity: null,
|
|
68933
|
+
identityLookup: identityKeys
|
|
68934
|
+
};
|
|
68935
|
+
await repo.updateById(readerId, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
68936
|
+
return repo.addEvent({
|
|
68937
|
+
reader: readerId,
|
|
68938
|
+
site: reader.site,
|
|
68939
|
+
type,
|
|
68940
|
+
payload: enrichedPayload,
|
|
68941
|
+
status: identity ? "processed" : "received"
|
|
68942
|
+
});
|
|
68943
|
+
}
|
|
68944
|
+
async function listLogs(value) {
|
|
68945
|
+
return repo.listEvents(value);
|
|
68946
|
+
}
|
|
68947
|
+
async function listIdentities(value) {
|
|
68948
|
+
return repo.listIdentities(value);
|
|
68949
|
+
}
|
|
68950
|
+
async function createIdentity(readerId, value) {
|
|
68951
|
+
const reader = await repo.getById(readerId);
|
|
68952
|
+
return repo.addIdentity({
|
|
68953
|
+
...value,
|
|
68954
|
+
reader: readerId,
|
|
68955
|
+
site: value.site || reader?.site?.toString()
|
|
68956
|
+
});
|
|
68957
|
+
}
|
|
68958
|
+
async function updateIdentity(identityId, value) {
|
|
68959
|
+
return repo.updateIdentity(identityId, value);
|
|
68960
|
+
}
|
|
68961
|
+
async function deleteIdentity(identityId) {
|
|
68962
|
+
return repo.deleteIdentity(identityId);
|
|
68963
|
+
}
|
|
68964
|
+
async function runObjectOperation(id, operation, payload) {
|
|
68965
|
+
const reader = await getActiveReader(id);
|
|
68966
|
+
const client = new HidAmicoClient(reader);
|
|
68967
|
+
try {
|
|
68968
|
+
await client.login();
|
|
68969
|
+
let result;
|
|
68970
|
+
if (operation === "load") {
|
|
68971
|
+
result = await client.loadObjects(payload);
|
|
68972
|
+
} else if (operation === "create") {
|
|
68973
|
+
result = await client.createObjects(payload);
|
|
68974
|
+
} else if (operation === "modify") {
|
|
68975
|
+
result = await client.modifyObjects(payload);
|
|
68976
|
+
} else {
|
|
68977
|
+
result = await client.destroyObjects(payload);
|
|
68978
|
+
}
|
|
68979
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
68980
|
+
await repo.addEvent({ reader: id, site: reader.site, type: `objects_${operation}`, payload: { request: payload, result } });
|
|
68981
|
+
return result;
|
|
68982
|
+
} catch (error) {
|
|
68983
|
+
await repo.addEvent({ reader: id, site: reader.site, type: `objects_${operation}_failed`, payload: { request: payload, message: error.message } });
|
|
68984
|
+
throw error;
|
|
68985
|
+
} finally {
|
|
68986
|
+
await client.logout();
|
|
68987
|
+
}
|
|
68988
|
+
}
|
|
68989
|
+
async function getUserImage(readerId, hidUserId) {
|
|
68990
|
+
const reader = await getActiveReader(readerId);
|
|
68991
|
+
const client = new HidAmicoClient(reader);
|
|
68992
|
+
try {
|
|
68993
|
+
await client.login();
|
|
68994
|
+
return await client.getUserImage(hidUserId);
|
|
68995
|
+
} finally {
|
|
68996
|
+
await client.logout();
|
|
68997
|
+
}
|
|
68998
|
+
}
|
|
68999
|
+
async function getDoorState(id) {
|
|
69000
|
+
const reader = await getActiveReader(id);
|
|
69001
|
+
const client = new HidAmicoClient(reader);
|
|
69002
|
+
try {
|
|
69003
|
+
await client.login();
|
|
69004
|
+
const state = await client.doorState();
|
|
69005
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
69006
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "door_state", payload: state });
|
|
69007
|
+
return state;
|
|
69008
|
+
} finally {
|
|
69009
|
+
await client.logout();
|
|
69010
|
+
}
|
|
69011
|
+
}
|
|
69012
|
+
async function executeActions(id, actions) {
|
|
69013
|
+
const reader = await getActiveReader(id);
|
|
69014
|
+
const client = new HidAmicoClient(reader);
|
|
69015
|
+
try {
|
|
69016
|
+
await client.login();
|
|
69017
|
+
const result = await client.executeActions(actions);
|
|
69018
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
69019
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "execute_actions", payload: { actions, result } });
|
|
69020
|
+
return result;
|
|
69021
|
+
} catch (error) {
|
|
69022
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "execute_actions_failed", payload: { actions, message: error.message } });
|
|
69023
|
+
throw error;
|
|
69024
|
+
} finally {
|
|
69025
|
+
await client.logout();
|
|
69026
|
+
}
|
|
69027
|
+
}
|
|
69028
|
+
async function getConfiguration(id, payload) {
|
|
69029
|
+
const reader = await getActiveReader(id);
|
|
69030
|
+
const client = new HidAmicoClient(reader);
|
|
69031
|
+
try {
|
|
69032
|
+
await client.login();
|
|
69033
|
+
const result = await client.getConfiguration(payload);
|
|
69034
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
69035
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "configuration", payload: { request: payload, result } });
|
|
69036
|
+
return result;
|
|
69037
|
+
} catch (error) {
|
|
69038
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "configuration_failed", payload: { request: payload, message: error.message } });
|
|
69039
|
+
throw error;
|
|
69040
|
+
} finally {
|
|
69041
|
+
await client.logout();
|
|
69042
|
+
}
|
|
69043
|
+
}
|
|
69044
|
+
async function setConfiguration(id, payload) {
|
|
69045
|
+
const reader = await getActiveReader(id);
|
|
69046
|
+
const client = new HidAmicoClient(reader);
|
|
69047
|
+
try {
|
|
69048
|
+
await client.login();
|
|
69049
|
+
const result = await client.setConfiguration(payload);
|
|
69050
|
+
await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
|
|
69051
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "set_configuration", payload: { request: payload, result } });
|
|
69052
|
+
return result;
|
|
69053
|
+
} catch (error) {
|
|
69054
|
+
await repo.addEvent({ reader: id, site: reader.site, type: "set_configuration_failed", payload: { request: payload, message: error.message } });
|
|
69055
|
+
throw error;
|
|
69056
|
+
} finally {
|
|
69057
|
+
await client.logout();
|
|
69058
|
+
}
|
|
69059
|
+
}
|
|
69060
|
+
return {
|
|
69061
|
+
listReaders,
|
|
69062
|
+
createReader,
|
|
69063
|
+
updateReader,
|
|
69064
|
+
deleteReader,
|
|
69065
|
+
testReader,
|
|
69066
|
+
syncReader,
|
|
69067
|
+
receiveNotification,
|
|
69068
|
+
listLogs,
|
|
69069
|
+
listIdentities,
|
|
69070
|
+
createIdentity,
|
|
69071
|
+
updateIdentity,
|
|
69072
|
+
deleteIdentity,
|
|
69073
|
+
runObjectOperation,
|
|
69074
|
+
getUserImage,
|
|
69075
|
+
getDoorState,
|
|
69076
|
+
executeActions,
|
|
69077
|
+
getConfiguration,
|
|
69078
|
+
setConfiguration
|
|
69079
|
+
};
|
|
69080
|
+
}
|
|
69081
|
+
|
|
69082
|
+
// src/controllers/hid-amico.controller.ts
|
|
69083
|
+
import { BadRequestError as BadRequestError231 } from "@7365admin1/node-server-utils";
|
|
69084
|
+
function useHidAmicoController() {
|
|
69085
|
+
const service = useHidAmicoService();
|
|
69086
|
+
async function listReaders(req, res, next) {
|
|
69087
|
+
const { error, value } = schemaHidAmicoReaderListQuery.validate(req.query);
|
|
69088
|
+
if (error) {
|
|
69089
|
+
next(new BadRequestError231(error.message));
|
|
69090
|
+
return;
|
|
69091
|
+
}
|
|
69092
|
+
try {
|
|
69093
|
+
res.json(await service.listReaders(value));
|
|
69094
|
+
} catch (error2) {
|
|
69095
|
+
next(error2);
|
|
69096
|
+
}
|
|
69097
|
+
}
|
|
69098
|
+
async function createReader(req, res, next) {
|
|
69099
|
+
const { error, value } = schemaHidAmicoReader.validate(req.body);
|
|
69100
|
+
if (error) {
|
|
69101
|
+
next(new BadRequestError231(error.message));
|
|
69102
|
+
return;
|
|
69103
|
+
}
|
|
69104
|
+
try {
|
|
69105
|
+
res.status(201).json({ data: await service.createReader(value) });
|
|
69106
|
+
} catch (error2) {
|
|
69107
|
+
next(error2);
|
|
69108
|
+
}
|
|
69109
|
+
}
|
|
69110
|
+
async function updateReader(req, res, next) {
|
|
69111
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69112
|
+
const body = schemaUpdateHidAmicoReader.validate(req.body);
|
|
69113
|
+
if (params.error || body.error) {
|
|
69114
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69115
|
+
return;
|
|
69116
|
+
}
|
|
69117
|
+
try {
|
|
69118
|
+
res.json({ data: await service.updateReader(params.value.readerId, body.value) });
|
|
69119
|
+
} catch (error) {
|
|
69120
|
+
next(error);
|
|
69121
|
+
}
|
|
69122
|
+
}
|
|
69123
|
+
async function deleteReader(req, res, next) {
|
|
69124
|
+
const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69125
|
+
if (error) {
|
|
69126
|
+
next(new BadRequestError231(error.message));
|
|
69127
|
+
return;
|
|
69128
|
+
}
|
|
69129
|
+
try {
|
|
69130
|
+
res.json({ data: await service.deleteReader(value.readerId), message: "HID Amico reader deleted." });
|
|
69131
|
+
} catch (error2) {
|
|
69132
|
+
next(error2);
|
|
69133
|
+
}
|
|
69134
|
+
}
|
|
69135
|
+
async function testReader(req, res, next) {
|
|
69136
|
+
const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69137
|
+
if (error) {
|
|
69138
|
+
next(new BadRequestError231(error.message));
|
|
69139
|
+
return;
|
|
69140
|
+
}
|
|
69141
|
+
try {
|
|
69142
|
+
res.json({ data: await service.testReader(value.readerId) });
|
|
69143
|
+
} catch (error2) {
|
|
69144
|
+
next(error2);
|
|
69145
|
+
}
|
|
69146
|
+
}
|
|
69147
|
+
async function syncReader(req, res, next) {
|
|
69148
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69149
|
+
const body = schemaHidAmicoSync.validate(req.body ?? {});
|
|
69150
|
+
if (params.error || body.error) {
|
|
69151
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69152
|
+
return;
|
|
69153
|
+
}
|
|
69154
|
+
try {
|
|
69155
|
+
res.json({ data: await service.syncReader(params.value.readerId, body.value) });
|
|
69156
|
+
} catch (error) {
|
|
69157
|
+
next(error);
|
|
69158
|
+
}
|
|
69159
|
+
}
|
|
69160
|
+
async function listLogs(req, res, next) {
|
|
69161
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69162
|
+
const query = schemaHidAmicoLogQuery.validate(req.query);
|
|
69163
|
+
if (params.error || query.error) {
|
|
69164
|
+
next(new BadRequestError231(params.error?.message || query.error?.message));
|
|
69165
|
+
return;
|
|
69166
|
+
}
|
|
69167
|
+
try {
|
|
69168
|
+
res.json(await service.listLogs({ reader: params.value.readerId, ...query.value }));
|
|
69169
|
+
} catch (error) {
|
|
69170
|
+
next(error);
|
|
69171
|
+
}
|
|
69172
|
+
}
|
|
69173
|
+
async function listIdentities(req, res, next) {
|
|
69174
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69175
|
+
const query = schemaHidAmicoIdentityQuery.validate(req.query);
|
|
69176
|
+
if (params.error || query.error) {
|
|
69177
|
+
next(new BadRequestError231(params.error?.message || query.error?.message));
|
|
69178
|
+
return;
|
|
69179
|
+
}
|
|
69180
|
+
try {
|
|
69181
|
+
res.json(await service.listIdentities({ reader: params.value.readerId, ...query.value }));
|
|
69182
|
+
} catch (error) {
|
|
69183
|
+
next(error);
|
|
69184
|
+
}
|
|
69185
|
+
}
|
|
69186
|
+
async function createIdentity(req, res, next) {
|
|
69187
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69188
|
+
if (params.error) {
|
|
69189
|
+
next(new BadRequestError231(params.error.message));
|
|
69190
|
+
return;
|
|
69191
|
+
}
|
|
69192
|
+
try {
|
|
69193
|
+
const body = schemaCreateHidAmicoIdentity.validate(req.body);
|
|
69194
|
+
if (body.error) {
|
|
69195
|
+
next(new BadRequestError231(body.error.message));
|
|
69196
|
+
return;
|
|
69197
|
+
}
|
|
69198
|
+
res.status(201).json({ data: await service.createIdentity(params.value.readerId, body.value) });
|
|
69199
|
+
} catch (error) {
|
|
69200
|
+
next(error);
|
|
69201
|
+
}
|
|
69202
|
+
}
|
|
69203
|
+
async function updateIdentity(req, res, next) {
|
|
69204
|
+
const params = schemaHidAmicoIdentityIdParams.validate(req.params);
|
|
69205
|
+
const body = schemaUpdateHidAmicoIdentity.validate(req.body ?? {});
|
|
69206
|
+
if (params.error || body.error) {
|
|
69207
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69208
|
+
return;
|
|
69209
|
+
}
|
|
69210
|
+
try {
|
|
69211
|
+
res.json({ data: await service.updateIdentity(params.value.identityId, body.value) });
|
|
69212
|
+
} catch (error) {
|
|
69213
|
+
next(error);
|
|
69214
|
+
}
|
|
69215
|
+
}
|
|
69216
|
+
async function deleteIdentity(req, res, next) {
|
|
69217
|
+
const { error, value } = schemaHidAmicoIdentityIdParams.validate(req.params);
|
|
69218
|
+
if (error) {
|
|
69219
|
+
next(new BadRequestError231(error.message));
|
|
69220
|
+
return;
|
|
69221
|
+
}
|
|
69222
|
+
try {
|
|
69223
|
+
res.json({ data: await service.deleteIdentity(value.identityId), message: "HID Amico identity deleted." });
|
|
69224
|
+
} catch (error2) {
|
|
69225
|
+
next(error2);
|
|
69226
|
+
}
|
|
69227
|
+
}
|
|
69228
|
+
async function receiveNotification(req, res, next) {
|
|
69229
|
+
const validation = schemaHidAmicoNotificationParams.validate(req.params);
|
|
69230
|
+
if (validation.error) {
|
|
69231
|
+
next(new BadRequestError231(validation.error.message));
|
|
69232
|
+
return;
|
|
69233
|
+
}
|
|
69234
|
+
try {
|
|
69235
|
+
const event = await service.receiveNotification(
|
|
69236
|
+
validation.value.readerId,
|
|
69237
|
+
validation.value.type,
|
|
69238
|
+
req.body ?? {}
|
|
69239
|
+
);
|
|
69240
|
+
res.status(202).json({ data: event });
|
|
69241
|
+
} catch (error) {
|
|
69242
|
+
next(error);
|
|
69243
|
+
}
|
|
69244
|
+
}
|
|
69245
|
+
async function getDoorState(req, res, next) {
|
|
69246
|
+
const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69247
|
+
if (error) {
|
|
69248
|
+
next(new BadRequestError231(error.message));
|
|
69249
|
+
return;
|
|
69250
|
+
}
|
|
69251
|
+
try {
|
|
69252
|
+
res.json({ data: await service.getDoorState(value.readerId) });
|
|
69253
|
+
} catch (error2) {
|
|
69254
|
+
next(error2);
|
|
69255
|
+
}
|
|
69256
|
+
}
|
|
69257
|
+
async function getUserImage(req, res, next) {
|
|
69258
|
+
const { error, value } = schemaHidAmicoUserImageParams.validate(req.params);
|
|
69259
|
+
if (error) {
|
|
69260
|
+
next(new BadRequestError231(error.message));
|
|
69261
|
+
return;
|
|
69262
|
+
}
|
|
69263
|
+
try {
|
|
69264
|
+
const image = await service.getUserImage(value.readerId, value.hidUserId);
|
|
69265
|
+
res.json({ data: image });
|
|
69266
|
+
} catch (error2) {
|
|
69267
|
+
next(error2);
|
|
69268
|
+
}
|
|
69269
|
+
}
|
|
69270
|
+
async function executeActions(req, res, next) {
|
|
69271
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69272
|
+
const body = schemaHidAmicoExecuteActions.validate(req.body ?? {});
|
|
69273
|
+
if (params.error || body.error) {
|
|
69274
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69275
|
+
return;
|
|
69276
|
+
}
|
|
69277
|
+
try {
|
|
69278
|
+
res.json({ data: await service.executeActions(params.value.readerId, body.value.actions) });
|
|
69279
|
+
} catch (error) {
|
|
69280
|
+
next(error);
|
|
69281
|
+
}
|
|
69282
|
+
}
|
|
69283
|
+
async function getConfiguration(req, res, next) {
|
|
69284
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69285
|
+
const body = schemaHidAmicoConfiguration.validate(req.body ?? {});
|
|
69286
|
+
if (params.error || body.error) {
|
|
69287
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69288
|
+
return;
|
|
69289
|
+
}
|
|
69290
|
+
try {
|
|
69291
|
+
res.json({ data: await service.getConfiguration(params.value.readerId, body.value) });
|
|
69292
|
+
} catch (error) {
|
|
69293
|
+
next(error);
|
|
69294
|
+
}
|
|
69295
|
+
}
|
|
69296
|
+
async function setConfiguration(req, res, next) {
|
|
69297
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69298
|
+
const body = schemaHidAmicoSetConfiguration.validate(req.body ?? {});
|
|
69299
|
+
if (params.error || body.error) {
|
|
69300
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69301
|
+
return;
|
|
69302
|
+
}
|
|
69303
|
+
try {
|
|
69304
|
+
res.json({ data: await service.setConfiguration(params.value.readerId, body.value) });
|
|
69305
|
+
} catch (error) {
|
|
69306
|
+
next(error);
|
|
69307
|
+
}
|
|
69308
|
+
}
|
|
69309
|
+
async function runObjectOperation(req, res, next) {
|
|
69310
|
+
const params = schemaHidAmicoReaderIdParams.validate(req.params);
|
|
69311
|
+
const body = schemaHidAmicoObjectOperation.validate(req.body ?? {});
|
|
69312
|
+
if (params.error || body.error) {
|
|
69313
|
+
next(new BadRequestError231(params.error?.message || body.error?.message));
|
|
69314
|
+
return;
|
|
69315
|
+
}
|
|
69316
|
+
const { operation, ...payload } = body.value;
|
|
69317
|
+
if (operation === "create" && !Array.isArray(payload.values)) {
|
|
69318
|
+
next(new BadRequestError231("values array is required for HID object create operations."));
|
|
69319
|
+
return;
|
|
69320
|
+
}
|
|
69321
|
+
if (operation === "modify" && (!payload.values || Array.isArray(payload.values) || !payload.where)) {
|
|
69322
|
+
next(new BadRequestError231("values object and where are required for HID object modify operations."));
|
|
69323
|
+
return;
|
|
69324
|
+
}
|
|
69325
|
+
if (operation === "destroy" && !payload.where) {
|
|
69326
|
+
next(new BadRequestError231("where is required for HID object destroy operations."));
|
|
69327
|
+
return;
|
|
69328
|
+
}
|
|
69329
|
+
try {
|
|
69330
|
+
res.json({ data: await service.runObjectOperation(params.value.readerId, operation, payload) });
|
|
69331
|
+
} catch (error) {
|
|
69332
|
+
next(error);
|
|
69333
|
+
}
|
|
69334
|
+
}
|
|
69335
|
+
return {
|
|
69336
|
+
listReaders,
|
|
69337
|
+
createReader,
|
|
69338
|
+
updateReader,
|
|
69339
|
+
deleteReader,
|
|
69340
|
+
testReader,
|
|
69341
|
+
syncReader,
|
|
69342
|
+
listLogs,
|
|
69343
|
+
listIdentities,
|
|
69344
|
+
createIdentity,
|
|
69345
|
+
updateIdentity,
|
|
69346
|
+
deleteIdentity,
|
|
69347
|
+
receiveNotification,
|
|
69348
|
+
getUserImage,
|
|
69349
|
+
getDoorState,
|
|
69350
|
+
executeActions,
|
|
69351
|
+
getConfiguration,
|
|
69352
|
+
setConfiguration,
|
|
69353
|
+
runObjectOperation
|
|
69354
|
+
};
|
|
69355
|
+
}
|
|
67518
69356
|
export {
|
|
67519
69357
|
ANPRMode,
|
|
67520
69358
|
AccessTypeProps,
|
|
67521
69359
|
AppServiceType,
|
|
69360
|
+
BidStatus,
|
|
69361
|
+
BidType,
|
|
67522
69362
|
BuildingLevelStatus,
|
|
67523
69363
|
BuildingStatus,
|
|
67524
69364
|
BulletinOrder,
|
|
@@ -67550,6 +69390,7 @@ export {
|
|
|
67550
69390
|
MAddress,
|
|
67551
69391
|
MAttendance,
|
|
67552
69392
|
MAttendanceSettings,
|
|
69393
|
+
MBidPreloved,
|
|
67553
69394
|
MBillingConfiguration,
|
|
67554
69395
|
MBillingItem,
|
|
67555
69396
|
MBuilding,
|
|
@@ -67570,6 +69411,9 @@ export {
|
|
|
67570
69411
|
MFile,
|
|
67571
69412
|
MFormEntry,
|
|
67572
69413
|
MGuestManagement,
|
|
69414
|
+
MHidAmicoEvent,
|
|
69415
|
+
MHidAmicoIdentity,
|
|
69416
|
+
MHidAmicoReader,
|
|
67573
69417
|
MIncidentReport,
|
|
67574
69418
|
MManpowerDesignations,
|
|
67575
69419
|
MManpowerMonitoring,
|
|
@@ -67657,7 +69501,6 @@ export {
|
|
|
67657
69501
|
building_units_namespace_collection,
|
|
67658
69502
|
buildings_namespace_collection,
|
|
67659
69503
|
bulletin_boards_namespace_collection,
|
|
67660
|
-
calculatePercentage,
|
|
67661
69504
|
chatSchema,
|
|
67662
69505
|
createManpowerRemarksDaily,
|
|
67663
69506
|
customerSchema,
|
|
@@ -67668,7 +69511,6 @@ export {
|
|
|
67668
69511
|
feedbacks2_namespace_collection,
|
|
67669
69512
|
feedbacks_namespace_collection,
|
|
67670
69513
|
formatDahuaDate,
|
|
67671
|
-
getPeriodRangeWithPrevious,
|
|
67672
69514
|
guests_namespace_collection,
|
|
67673
69515
|
incidentReportLog,
|
|
67674
69516
|
incidents_namespace_collection,
|
|
@@ -67691,6 +69533,7 @@ export {
|
|
|
67691
69533
|
schema,
|
|
67692
69534
|
schemaApprovedBy,
|
|
67693
69535
|
schemaApprover,
|
|
69536
|
+
schemaBidPreloved,
|
|
67694
69537
|
schemaBilling,
|
|
67695
69538
|
schemaBillingConfiguration,
|
|
67696
69539
|
schemaBillingItem,
|
|
@@ -67703,6 +69546,7 @@ export {
|
|
|
67703
69546
|
schemaCategoryPreloved,
|
|
67704
69547
|
schemaChannelPreloved,
|
|
67705
69548
|
schemaChatPreloved,
|
|
69549
|
+
schemaCreateHidAmicoIdentity,
|
|
67706
69550
|
schemaCustomerSite,
|
|
67707
69551
|
schemaDocumentManagement,
|
|
67708
69552
|
schemaEntryPassSettings,
|
|
@@ -67710,6 +69554,21 @@ export {
|
|
|
67710
69554
|
schemaFiles,
|
|
67711
69555
|
schemaFormEntry,
|
|
67712
69556
|
schemaGuestManagement,
|
|
69557
|
+
schemaHidAmicoConfiguration,
|
|
69558
|
+
schemaHidAmicoEvent,
|
|
69559
|
+
schemaHidAmicoExecuteActions,
|
|
69560
|
+
schemaHidAmicoIdentity,
|
|
69561
|
+
schemaHidAmicoIdentityIdParams,
|
|
69562
|
+
schemaHidAmicoIdentityQuery,
|
|
69563
|
+
schemaHidAmicoLogQuery,
|
|
69564
|
+
schemaHidAmicoNotificationParams,
|
|
69565
|
+
schemaHidAmicoObjectOperation,
|
|
69566
|
+
schemaHidAmicoReader,
|
|
69567
|
+
schemaHidAmicoReaderIdParams,
|
|
69568
|
+
schemaHidAmicoReaderListQuery,
|
|
69569
|
+
schemaHidAmicoSetConfiguration,
|
|
69570
|
+
schemaHidAmicoSync,
|
|
69571
|
+
schemaHidAmicoUserImageParams,
|
|
67713
69572
|
schemaIncidentReport,
|
|
67714
69573
|
schemaMultipleDocumentManagement,
|
|
67715
69574
|
schemaNfcPatrolLog,
|
|
@@ -67737,6 +69596,7 @@ export {
|
|
|
67737
69596
|
schemaStatementOfAccount,
|
|
67738
69597
|
schemaSubcategoryPreloved,
|
|
67739
69598
|
schemaUnitBilling,
|
|
69599
|
+
schemaUpdateBidPreloved,
|
|
67740
69600
|
schemaUpdateBuildingLevel,
|
|
67741
69601
|
schemaUpdateBulletinBoard,
|
|
67742
69602
|
schemaUpdateBulletinVideo,
|
|
@@ -67747,6 +69607,8 @@ export {
|
|
|
67747
69607
|
schemaUpdateEventManagement,
|
|
67748
69608
|
schemaUpdateFormEntry,
|
|
67749
69609
|
schemaUpdateGuestManagement,
|
|
69610
|
+
schemaUpdateHidAmicoIdentity,
|
|
69611
|
+
schemaUpdateHidAmicoReader,
|
|
67750
69612
|
schemaUpdateIncidentReport,
|
|
67751
69613
|
schemaUpdateOccurrenceBook,
|
|
67752
69614
|
schemaUpdateOccurrenceEntry,
|
|
@@ -67792,6 +69654,8 @@ export {
|
|
|
67792
69654
|
useAuthControllerV2,
|
|
67793
69655
|
useAuthService,
|
|
67794
69656
|
useAuthServiceV2,
|
|
69657
|
+
useBidPrelovedController,
|
|
69658
|
+
useBidPrelovedRepo,
|
|
67795
69659
|
useBuildingController,
|
|
67796
69660
|
useBuildingLevelController,
|
|
67797
69661
|
useBuildingLevelRepo,
|
|
@@ -67814,6 +69678,7 @@ export {
|
|
|
67814
69678
|
useChatController,
|
|
67815
69679
|
useChatPrelovedController,
|
|
67816
69680
|
useChatPrelovedRepo,
|
|
69681
|
+
useChatPrelovedService,
|
|
67817
69682
|
useChatRepo,
|
|
67818
69683
|
useCounterModel,
|
|
67819
69684
|
useCounterRepo,
|
|
@@ -67844,6 +69709,9 @@ export {
|
|
|
67844
69709
|
useGuestManagementController,
|
|
67845
69710
|
useGuestManagementRepo,
|
|
67846
69711
|
useGuestManagementService,
|
|
69712
|
+
useHidAmicoController,
|
|
69713
|
+
useHidAmicoRepo,
|
|
69714
|
+
useHidAmicoService,
|
|
67847
69715
|
useHrmLabsAttendanceCtrl,
|
|
67848
69716
|
useHrmLabsAttendanceSrvc,
|
|
67849
69717
|
useIncidentReportController,
|