@7365admin1/core 2.46.0 → 2.48.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 +121 -59
- package/dist/index.js +1318 -865
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1313 -865
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -289,15 +289,22 @@ import {
|
|
|
289
289
|
logger as logger3
|
|
290
290
|
} from "@7365admin1/node-server-utils";
|
|
291
291
|
var feedbacks_namespace_collection = "feedbacks";
|
|
292
|
+
var feedbacks2_namespace_collection = "feedbacks2";
|
|
292
293
|
function useFeedbackRepo() {
|
|
293
294
|
const db = useAtlas2.getDb();
|
|
294
295
|
if (!db) {
|
|
295
296
|
throw new InternalServerError2("Unable to connect to server.");
|
|
296
297
|
}
|
|
297
298
|
const collection = db.collection(feedbacks_namespace_collection);
|
|
299
|
+
const feedbacks2Collection = db.collection(feedbacks2_namespace_collection);
|
|
298
300
|
const { delNamespace, getCache, setCache } = useCache2(
|
|
299
301
|
feedbacks_namespace_collection
|
|
300
302
|
);
|
|
303
|
+
const {
|
|
304
|
+
delNamespace: delNamespaceFeedbacks2,
|
|
305
|
+
getCache: getCacheFeedbacks2,
|
|
306
|
+
setCache: setCacheFeedbacks2
|
|
307
|
+
} = useCache2(feedbacks2_namespace_collection);
|
|
301
308
|
const { delNamespace: _delDashboardNameSpace } = useCache2("dashboard");
|
|
302
309
|
async function createIndex() {
|
|
303
310
|
try {
|
|
@@ -758,7 +765,7 @@ function useFeedbackRepo() {
|
|
|
758
765
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
759
766
|
deletedAt: /* @__PURE__ */ new Date()
|
|
760
767
|
};
|
|
761
|
-
const res = await
|
|
768
|
+
const res = await feedbacks2Collection.updateOne(
|
|
762
769
|
{ _id },
|
|
763
770
|
{ $set: updateValue },
|
|
764
771
|
{ session }
|
|
@@ -766,13 +773,13 @@ function useFeedbackRepo() {
|
|
|
766
773
|
if (res.modifiedCount === 0) {
|
|
767
774
|
throw new InternalServerError2("Unable to delete feedback.");
|
|
768
775
|
}
|
|
769
|
-
|
|
776
|
+
delNamespaceFeedbacks2().then(() => {
|
|
770
777
|
logger3.info(
|
|
771
|
-
`Cache cleared for namespace: ${
|
|
778
|
+
`Cache cleared for namespace: ${feedbacks2_namespace_collection}`
|
|
772
779
|
);
|
|
773
780
|
}).catch((err) => {
|
|
774
781
|
logger3.error(
|
|
775
|
-
`Failed to clear cache for namespace: ${
|
|
782
|
+
`Failed to clear cache for namespace: ${feedbacks2_namespace_collection}`,
|
|
776
783
|
err
|
|
777
784
|
);
|
|
778
785
|
});
|
|
@@ -2741,6 +2748,7 @@ var APP_POOL_MAINTENANCE = process.env.APP_POOL_MAINTENANCE ?? "http://localhost
|
|
|
2741
2748
|
var ENCRYPTION_KEY = process.env.ENCRYPTION_KEY ?? "";
|
|
2742
2749
|
var DOMAIN = process.env.DOMAIN ?? "localhost";
|
|
2743
2750
|
var OPEN_AI_API_KEY = process.env.OPEN_AI_API_KEY;
|
|
2751
|
+
var STORAGE_API = process.env.STORAGE_API;
|
|
2744
2752
|
|
|
2745
2753
|
// src/services/auth.service.ts
|
|
2746
2754
|
import jwt from "jsonwebtoken";
|
|
@@ -5148,6 +5156,39 @@ function useVerificationRepoV2() {
|
|
|
5148
5156
|
throw new InternalServerError11("Error updating verification status.");
|
|
5149
5157
|
}
|
|
5150
5158
|
}
|
|
5159
|
+
async function countPendingOrgInvites(orgId) {
|
|
5160
|
+
try {
|
|
5161
|
+
orgId = new ObjectId18(orgId);
|
|
5162
|
+
} catch (error) {
|
|
5163
|
+
throw new BadRequestError19("Invalid organization ID format.");
|
|
5164
|
+
}
|
|
5165
|
+
const query = {
|
|
5166
|
+
status: "pending" /* PENDING */,
|
|
5167
|
+
type: { $in: ["user-invite", "member-invite"] },
|
|
5168
|
+
"metadata.org": orgId
|
|
5169
|
+
};
|
|
5170
|
+
const cacheKey = makeCacheKey10(namespace_collection, {
|
|
5171
|
+
status: "pending" /* PENDING */,
|
|
5172
|
+
type: JSON.stringify(["user-invite", "member-invite"]),
|
|
5173
|
+
org: orgId.toString()
|
|
5174
|
+
});
|
|
5175
|
+
const cachedData = await getCache(cacheKey);
|
|
5176
|
+
if (typeof cachedData === "number") {
|
|
5177
|
+
logger13.info(`Cache hit for key: ${cacheKey}`);
|
|
5178
|
+
return cachedData;
|
|
5179
|
+
}
|
|
5180
|
+
try {
|
|
5181
|
+
const count = await collection.countDocuments(query);
|
|
5182
|
+
setCache(cacheKey, count, 15 * 60).then(() => {
|
|
5183
|
+
logger13.info(`Cache set for key: ${cacheKey}`);
|
|
5184
|
+
}).catch((err) => {
|
|
5185
|
+
logger13.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
5186
|
+
});
|
|
5187
|
+
return count;
|
|
5188
|
+
} catch (error) {
|
|
5189
|
+
throw new InternalServerError11("Failed to count pending invitations.");
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5151
5192
|
return {
|
|
5152
5193
|
createIndex,
|
|
5153
5194
|
createTextIndex,
|
|
@@ -5156,7 +5197,8 @@ function useVerificationRepoV2() {
|
|
|
5156
5197
|
getByVerificationCode,
|
|
5157
5198
|
getVerificationById,
|
|
5158
5199
|
getVerifications,
|
|
5159
|
-
updateStatusById
|
|
5200
|
+
updateStatusById,
|
|
5201
|
+
countPendingOrgInvites
|
|
5160
5202
|
};
|
|
5161
5203
|
}
|
|
5162
5204
|
|
|
@@ -5234,6 +5276,46 @@ function useVerificationService() {
|
|
|
5234
5276
|
throw error;
|
|
5235
5277
|
}
|
|
5236
5278
|
}
|
|
5279
|
+
async function createSimpleUserInvite({
|
|
5280
|
+
email,
|
|
5281
|
+
metadata
|
|
5282
|
+
}) {
|
|
5283
|
+
const type = "user-invite";
|
|
5284
|
+
const value = {
|
|
5285
|
+
type,
|
|
5286
|
+
email,
|
|
5287
|
+
metadata,
|
|
5288
|
+
expireAt: new Date(
|
|
5289
|
+
(/* @__PURE__ */ new Date()).getTime() + 72 * 60 * 60 * 1e3
|
|
5290
|
+
).toISOString(),
|
|
5291
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5292
|
+
};
|
|
5293
|
+
if (value.metadata?.org) {
|
|
5294
|
+
await getOrgById(value.metadata?.org);
|
|
5295
|
+
}
|
|
5296
|
+
if (value.metadata?.siteId) {
|
|
5297
|
+
await getSiteById(value.metadata?.siteId);
|
|
5298
|
+
}
|
|
5299
|
+
const res = await add(value);
|
|
5300
|
+
const dir = __dirname;
|
|
5301
|
+
const filePath = getDirectory(dir, "./public/handlebars/user-invite");
|
|
5302
|
+
const link = `${APP_MAIN}/verify/invitation/${res}`;
|
|
5303
|
+
const emailContent = compileHandlebar({
|
|
5304
|
+
context: {
|
|
5305
|
+
email,
|
|
5306
|
+
validity: VERIFICATION_USER_INVITE_DURATION,
|
|
5307
|
+
link
|
|
5308
|
+
},
|
|
5309
|
+
filePath
|
|
5310
|
+
});
|
|
5311
|
+
mailer.sendMail({
|
|
5312
|
+
to: email,
|
|
5313
|
+
subject: "User Invite",
|
|
5314
|
+
html: emailContent,
|
|
5315
|
+
sender: "iService365"
|
|
5316
|
+
});
|
|
5317
|
+
return res;
|
|
5318
|
+
}
|
|
5237
5319
|
const {
|
|
5238
5320
|
add: _add,
|
|
5239
5321
|
updateVerificationStatusById: _updateVerificationStatusById,
|
|
@@ -5527,7 +5609,8 @@ function useVerificationService() {
|
|
|
5527
5609
|
cancelUserInvitation,
|
|
5528
5610
|
updateStatusById,
|
|
5529
5611
|
signUp,
|
|
5530
|
-
checkExpiredInvitation
|
|
5612
|
+
checkExpiredInvitation,
|
|
5613
|
+
createSimpleUserInvite
|
|
5531
5614
|
};
|
|
5532
5615
|
}
|
|
5533
5616
|
|
|
@@ -6773,7 +6856,16 @@ function useUserController() {
|
|
|
6773
6856
|
async function updateUserFieldById(req, res, next) {
|
|
6774
6857
|
const validation = Joi13.object({
|
|
6775
6858
|
_id: Joi13.string().hex().required(),
|
|
6776
|
-
field: Joi13.string().valid(
|
|
6859
|
+
field: Joi13.string().valid(
|
|
6860
|
+
"name",
|
|
6861
|
+
"email",
|
|
6862
|
+
"contact",
|
|
6863
|
+
"nric",
|
|
6864
|
+
"dateOfBirth",
|
|
6865
|
+
"profile",
|
|
6866
|
+
"gender",
|
|
6867
|
+
"defaultOrg"
|
|
6868
|
+
).required(),
|
|
6777
6869
|
value: Joi13.when("field", {
|
|
6778
6870
|
switch: [
|
|
6779
6871
|
{ is: "email", then: Joi13.string().email().required() },
|
|
@@ -7377,6 +7469,7 @@ import Joi16 from "joi";
|
|
|
7377
7469
|
function useVerificationController() {
|
|
7378
7470
|
const {
|
|
7379
7471
|
createUserInvite: _createUserInvite,
|
|
7472
|
+
createSimpleUserInvite: _createSimpleUserInvite,
|
|
7380
7473
|
createServiceProviderInvite: _createServiceProviderInvite,
|
|
7381
7474
|
createForgetPassword: _createForgetPassword,
|
|
7382
7475
|
verify: _verify,
|
|
@@ -7427,6 +7520,58 @@ function useVerificationController() {
|
|
|
7427
7520
|
return;
|
|
7428
7521
|
}
|
|
7429
7522
|
}
|
|
7523
|
+
async function createSimpleUserInvite(req, res, next) {
|
|
7524
|
+
const payload = { ...req.body };
|
|
7525
|
+
const validation = Joi16.object({
|
|
7526
|
+
email: Joi16.string().email().required(),
|
|
7527
|
+
app: Joi16.string().optional().allow("", null),
|
|
7528
|
+
role: Joi16.string().hex().optional().allow("", null),
|
|
7529
|
+
name: Joi16.string().optional().allow("", null),
|
|
7530
|
+
org: Joi16.string().hex().optional().allow("", null),
|
|
7531
|
+
siteId: Joi16.string().hex().optional().allow("", null),
|
|
7532
|
+
siteName: Joi16.string().optional().allow("", null)
|
|
7533
|
+
});
|
|
7534
|
+
const { error } = validation.validate(payload);
|
|
7535
|
+
if (error) {
|
|
7536
|
+
logger22.log({
|
|
7537
|
+
level: "error",
|
|
7538
|
+
message: `${error.message}`
|
|
7539
|
+
});
|
|
7540
|
+
next(new BadRequestError31(error.message));
|
|
7541
|
+
return;
|
|
7542
|
+
}
|
|
7543
|
+
const email = req.body.email ?? "";
|
|
7544
|
+
const app = req.body.app ?? "";
|
|
7545
|
+
const role = req.body.role ?? "";
|
|
7546
|
+
const name = req.body.name ?? "";
|
|
7547
|
+
const org = req.body.org ?? "";
|
|
7548
|
+
const siteId = req.body.siteId ?? "";
|
|
7549
|
+
const siteName = req.body.siteName ?? "";
|
|
7550
|
+
try {
|
|
7551
|
+
await _createSimpleUserInvite({
|
|
7552
|
+
email,
|
|
7553
|
+
metadata: {
|
|
7554
|
+
app,
|
|
7555
|
+
role,
|
|
7556
|
+
name,
|
|
7557
|
+
org,
|
|
7558
|
+
siteId,
|
|
7559
|
+
siteName
|
|
7560
|
+
}
|
|
7561
|
+
});
|
|
7562
|
+
res.status(201).json({
|
|
7563
|
+
message: "Successfully invited user."
|
|
7564
|
+
});
|
|
7565
|
+
return;
|
|
7566
|
+
} catch (error2) {
|
|
7567
|
+
logger22.log({
|
|
7568
|
+
level: "error",
|
|
7569
|
+
message: `${error2.message}`
|
|
7570
|
+
});
|
|
7571
|
+
next(error2);
|
|
7572
|
+
return;
|
|
7573
|
+
}
|
|
7574
|
+
}
|
|
7430
7575
|
async function createServiceProviderInvite(req, res, next) {
|
|
7431
7576
|
const payload = req.body;
|
|
7432
7577
|
const validation = Joi16.object({
|
|
@@ -7568,7 +7713,8 @@ function useVerificationController() {
|
|
|
7568
7713
|
createServiceProviderInvite,
|
|
7569
7714
|
createForgetPassword,
|
|
7570
7715
|
verify,
|
|
7571
|
-
cancelUserInvitation
|
|
7716
|
+
cancelUserInvitation,
|
|
7717
|
+
createSimpleUserInvite
|
|
7572
7718
|
};
|
|
7573
7719
|
}
|
|
7574
7720
|
|
|
@@ -12828,14 +12974,14 @@ import {
|
|
|
12828
12974
|
|
|
12829
12975
|
// src/repositories/site-camera.repo.ts
|
|
12830
12976
|
import {
|
|
12831
|
-
AppError as
|
|
12832
|
-
BadRequestError as
|
|
12833
|
-
logger as
|
|
12834
|
-
makeCacheKey as
|
|
12835
|
-
paginate as
|
|
12836
|
-
toObjectId as
|
|
12837
|
-
useAtlas as
|
|
12838
|
-
useCache as
|
|
12977
|
+
AppError as AppError11,
|
|
12978
|
+
BadRequestError as BadRequestError74,
|
|
12979
|
+
logger as logger54,
|
|
12980
|
+
makeCacheKey as makeCacheKey25,
|
|
12981
|
+
paginate as paginate21,
|
|
12982
|
+
toObjectId as toObjectId11,
|
|
12983
|
+
useAtlas as useAtlas35,
|
|
12984
|
+
useCache as useCache26
|
|
12839
12985
|
} from "@7365admin1/node-server-utils";
|
|
12840
12986
|
|
|
12841
12987
|
// src/models/site-camera.model.ts
|
|
@@ -12901,412 +13047,32 @@ function MSiteCamera(value) {
|
|
|
12901
13047
|
}
|
|
12902
13048
|
|
|
12903
13049
|
// src/repositories/site-camera.repo.ts
|
|
12904
|
-
import { ObjectId as
|
|
12905
|
-
function useSiteCameraRepo() {
|
|
12906
|
-
const db = useAtlas30.getDb();
|
|
12907
|
-
if (!db) {
|
|
12908
|
-
throw new Error("Unable to connect to server.");
|
|
12909
|
-
}
|
|
12910
|
-
const namespace_collection = "site.cameras";
|
|
12911
|
-
const collection = db.collection(namespace_collection);
|
|
12912
|
-
const { delNamespace, getCache, setCache } = useCache23(namespace_collection);
|
|
12913
|
-
async function createIndexes() {
|
|
12914
|
-
try {
|
|
12915
|
-
await collection.createIndexes([
|
|
12916
|
-
{
|
|
12917
|
-
key: { site: 1 }
|
|
12918
|
-
},
|
|
12919
|
-
{
|
|
12920
|
-
key: { type: 1 }
|
|
12921
|
-
},
|
|
12922
|
-
{
|
|
12923
|
-
key: { host: 1, type: 1, status: 1, site: 1 },
|
|
12924
|
-
unique: true,
|
|
12925
|
-
partialFilterExpression: { status: "active" }
|
|
12926
|
-
}
|
|
12927
|
-
]);
|
|
12928
|
-
return `Successfully created ${namespace_collection} indexes.`;
|
|
12929
|
-
} catch (error) {
|
|
12930
|
-
logger47.log({
|
|
12931
|
-
level: "error",
|
|
12932
|
-
message: error.message
|
|
12933
|
-
});
|
|
12934
|
-
}
|
|
12935
|
-
}
|
|
12936
|
-
async function add(value, session) {
|
|
12937
|
-
try {
|
|
12938
|
-
value = MSiteCamera(value);
|
|
12939
|
-
const res = await collection.insertOne(value, { session });
|
|
12940
|
-
delCachedData();
|
|
12941
|
-
return res.insertedId;
|
|
12942
|
-
} catch (error) {
|
|
12943
|
-
logger47.log({
|
|
12944
|
-
level: "error",
|
|
12945
|
-
message: error.message
|
|
12946
|
-
});
|
|
12947
|
-
const isDuplicated = error.message.includes("duplicate");
|
|
12948
|
-
if (isDuplicated) {
|
|
12949
|
-
throw new BadRequestError65("ANPR already exist.");
|
|
12950
|
-
}
|
|
12951
|
-
if (error instanceof AppError8) {
|
|
12952
|
-
throw error;
|
|
12953
|
-
} else {
|
|
12954
|
-
throw new Error("Failed to create ANPR.");
|
|
12955
|
-
}
|
|
12956
|
-
}
|
|
12957
|
-
}
|
|
12958
|
-
async function getAll(value) {
|
|
12959
|
-
value.page = value.page ? value.page - 1 : 0;
|
|
12960
|
-
value.limit = value.limit || 10;
|
|
12961
|
-
const cacheKeyOptions = {
|
|
12962
|
-
type: value.type,
|
|
12963
|
-
page: value.page,
|
|
12964
|
-
limit: value.limit,
|
|
12965
|
-
...value.direction && { direction: value.direction }
|
|
12966
|
-
};
|
|
12967
|
-
const query = {
|
|
12968
|
-
type: value.type,
|
|
12969
|
-
...value.direction && {
|
|
12970
|
-
direction: {
|
|
12971
|
-
$in: Array.isArray(value.direction) ? value.direction : [value.direction]
|
|
12972
|
-
}
|
|
12973
|
-
}
|
|
12974
|
-
};
|
|
12975
|
-
if (value.site) {
|
|
12976
|
-
cacheKeyOptions.site = value.site;
|
|
12977
|
-
try {
|
|
12978
|
-
value.site = new ObjectId38(value.site);
|
|
12979
|
-
query.site = value.site;
|
|
12980
|
-
} catch (error) {
|
|
12981
|
-
throw new BadRequestError65("Invalid site ID format");
|
|
12982
|
-
}
|
|
12983
|
-
}
|
|
12984
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
12985
|
-
const cachedData = await getCache(cacheKey);
|
|
12986
|
-
if (cachedData) {
|
|
12987
|
-
return cachedData;
|
|
12988
|
-
}
|
|
12989
|
-
try {
|
|
12990
|
-
const items = await collection.aggregate([
|
|
12991
|
-
{
|
|
12992
|
-
$match: query
|
|
12993
|
-
},
|
|
12994
|
-
{
|
|
12995
|
-
$skip: value.page * value.limit
|
|
12996
|
-
},
|
|
12997
|
-
{
|
|
12998
|
-
$limit: value.limit
|
|
12999
|
-
},
|
|
13000
|
-
{
|
|
13001
|
-
$project: {
|
|
13002
|
-
password: 0
|
|
13003
|
-
}
|
|
13004
|
-
}
|
|
13005
|
-
]).toArray();
|
|
13006
|
-
const length = await collection.countDocuments(query);
|
|
13007
|
-
const data = paginate17(items, value.page, value.limit, length);
|
|
13008
|
-
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
13009
|
-
logger47.info(`Cache set for key: ${cacheKey}`);
|
|
13010
|
-
}).catch((err) => {
|
|
13011
|
-
logger47.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
13012
|
-
});
|
|
13013
|
-
return data;
|
|
13014
|
-
} catch (error) {
|
|
13015
|
-
if (error instanceof BadRequestError65) {
|
|
13016
|
-
throw error;
|
|
13017
|
-
}
|
|
13018
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13019
|
-
}
|
|
13020
|
-
}
|
|
13021
|
-
async function findSiteCameras({ site, type }) {
|
|
13022
|
-
const pipeline = [];
|
|
13023
|
-
const cacheObject = {};
|
|
13024
|
-
if (type) {
|
|
13025
|
-
cacheObject.type = type;
|
|
13026
|
-
pipeline.push({ $match: { "anprs.type": type } });
|
|
13027
|
-
}
|
|
13028
|
-
if (site) {
|
|
13029
|
-
const _site = new ObjectId38(site);
|
|
13030
|
-
cacheObject.site = site;
|
|
13031
|
-
pipeline.push({ $match: { site: _site } });
|
|
13032
|
-
}
|
|
13033
|
-
pipeline.push({
|
|
13034
|
-
$project: {
|
|
13035
|
-
_id: 1,
|
|
13036
|
-
site: 1,
|
|
13037
|
-
cameras: 1
|
|
13038
|
-
}
|
|
13039
|
-
});
|
|
13040
|
-
try {
|
|
13041
|
-
const items = await collection.aggregate(pipeline).toArray();
|
|
13042
|
-
return items;
|
|
13043
|
-
} catch (error) {
|
|
13044
|
-
if (error instanceof BadRequestError65) {
|
|
13045
|
-
throw error;
|
|
13046
|
-
}
|
|
13047
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13048
|
-
}
|
|
13049
|
-
}
|
|
13050
|
-
function delCachedData() {
|
|
13051
|
-
delNamespace().then(() => {
|
|
13052
|
-
logger47.log({
|
|
13053
|
-
level: "info",
|
|
13054
|
-
message: `Cache namespace cleared for ${namespace_collection}`
|
|
13055
|
-
});
|
|
13056
|
-
}).catch((err) => {
|
|
13057
|
-
logger47.log({
|
|
13058
|
-
level: "error",
|
|
13059
|
-
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
13060
|
-
});
|
|
13061
|
-
});
|
|
13062
|
-
}
|
|
13063
|
-
async function getBySite(site, options = {}) {
|
|
13064
|
-
const _site = toObjectId7(site);
|
|
13065
|
-
const cacheKeyOptions = {
|
|
13066
|
-
site,
|
|
13067
|
-
tag: "get-by-site",
|
|
13068
|
-
...options.category && { category: options.category },
|
|
13069
|
-
...options.type && { type: options.type },
|
|
13070
|
-
...options.guardPost && { guardPost: options.guardPost }
|
|
13071
|
-
};
|
|
13072
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
13073
|
-
const cachedData = await getCache(cacheKey);
|
|
13074
|
-
if (cachedData) {
|
|
13075
|
-
return cachedData;
|
|
13076
|
-
}
|
|
13077
|
-
try {
|
|
13078
|
-
delete cacheKeyOptions.tag;
|
|
13079
|
-
cacheKeyOptions.site = _site;
|
|
13080
|
-
const item = await collection.findOne(cacheKeyOptions);
|
|
13081
|
-
setCache(cacheKey, item, 15 * 60).then(() => {
|
|
13082
|
-
logger47.log({
|
|
13083
|
-
level: "info",
|
|
13084
|
-
message: `Cache set for getBySite: ${cacheKey}`
|
|
13085
|
-
});
|
|
13086
|
-
}).catch((err) => {
|
|
13087
|
-
logger47.log({
|
|
13088
|
-
level: "error",
|
|
13089
|
-
message: `Failed to set cache for getBySite: ${err.message}`
|
|
13090
|
-
});
|
|
13091
|
-
});
|
|
13092
|
-
return item;
|
|
13093
|
-
} catch (error) {
|
|
13094
|
-
if (error instanceof BadRequestError65) {
|
|
13095
|
-
throw error;
|
|
13096
|
-
}
|
|
13097
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13098
|
-
}
|
|
13099
|
-
}
|
|
13100
|
-
async function getBySiteGuardPost(site, guardPost) {
|
|
13101
|
-
try {
|
|
13102
|
-
site = new ObjectId38(site);
|
|
13103
|
-
} catch (error) {
|
|
13104
|
-
throw new BadRequestError65("Invalid site ID format");
|
|
13105
|
-
}
|
|
13106
|
-
const cacheKeyOptions = {
|
|
13107
|
-
site,
|
|
13108
|
-
guardPost,
|
|
13109
|
-
tag: "get-by-site"
|
|
13110
|
-
};
|
|
13111
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
13112
|
-
const cachedData = await getCache(cacheKey);
|
|
13113
|
-
if (cachedData) {
|
|
13114
|
-
return cachedData;
|
|
13115
|
-
}
|
|
13116
|
-
try {
|
|
13117
|
-
delete cacheKeyOptions.tag;
|
|
13118
|
-
const item = await collection.findOne({
|
|
13119
|
-
site,
|
|
13120
|
-
guardPost: { $gt: guardPost }
|
|
13121
|
-
});
|
|
13122
|
-
setCache(cacheKey, item, 15 * 60).then(() => {
|
|
13123
|
-
logger47.log({
|
|
13124
|
-
level: "info",
|
|
13125
|
-
message: `Cache set for getBySite: ${cacheKey}`
|
|
13126
|
-
});
|
|
13127
|
-
}).catch((err) => {
|
|
13128
|
-
logger47.log({
|
|
13129
|
-
level: "error",
|
|
13130
|
-
message: `Failed to set cache for getBySite: ${err.message}`
|
|
13131
|
-
});
|
|
13132
|
-
});
|
|
13133
|
-
return item;
|
|
13134
|
-
} catch (error) {
|
|
13135
|
-
if (error instanceof BadRequestError65) {
|
|
13136
|
-
throw error;
|
|
13137
|
-
}
|
|
13138
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13139
|
-
}
|
|
13140
|
-
}
|
|
13141
|
-
async function getBySites(site, options = {}) {
|
|
13142
|
-
try {
|
|
13143
|
-
site = new ObjectId38(site);
|
|
13144
|
-
} catch (error) {
|
|
13145
|
-
throw new BadRequestError65("Invalid site ID format");
|
|
13146
|
-
}
|
|
13147
|
-
const cacheKeyOptions = { site };
|
|
13148
|
-
if (options.category) {
|
|
13149
|
-
cacheKeyOptions.category = options.category;
|
|
13150
|
-
}
|
|
13151
|
-
if (options.type) {
|
|
13152
|
-
cacheKeyOptions.type = options.type;
|
|
13153
|
-
}
|
|
13154
|
-
if (options.direction) {
|
|
13155
|
-
cacheKeyOptions.direction = options.direction;
|
|
13156
|
-
}
|
|
13157
|
-
const cacheKey = makeCacheKey22(namespace_collection, cacheKeyOptions);
|
|
13158
|
-
const cachedData = await getCache(cacheKey);
|
|
13159
|
-
if (cachedData) {
|
|
13160
|
-
return cachedData;
|
|
13161
|
-
}
|
|
13162
|
-
try {
|
|
13163
|
-
const items = await collection.find(cacheKeyOptions);
|
|
13164
|
-
setCache(cacheKey, items, 15 * 60).then(() => {
|
|
13165
|
-
logger47.log({
|
|
13166
|
-
level: "info",
|
|
13167
|
-
message: `Cache set for getBySite: ${cacheKey}`
|
|
13168
|
-
});
|
|
13169
|
-
}).catch((err) => {
|
|
13170
|
-
logger47.log({
|
|
13171
|
-
level: "error",
|
|
13172
|
-
message: `Failed to set cache for getBySite: ${err.message}`
|
|
13173
|
-
});
|
|
13174
|
-
});
|
|
13175
|
-
return items;
|
|
13176
|
-
} catch (error) {
|
|
13177
|
-
if (error instanceof BadRequestError65) {
|
|
13178
|
-
throw error;
|
|
13179
|
-
}
|
|
13180
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13181
|
-
}
|
|
13182
|
-
}
|
|
13183
|
-
async function updateById(_id, value, session) {
|
|
13184
|
-
const { error } = schemaUpdateSiteCamera.validate(value);
|
|
13185
|
-
if (error) {
|
|
13186
|
-
logger47.info(`Site Camera Management: ${error.message}`);
|
|
13187
|
-
throw new BadRequestError65(error.message);
|
|
13188
|
-
}
|
|
13189
|
-
try {
|
|
13190
|
-
_id = new ObjectId38(_id);
|
|
13191
|
-
} catch (error2) {
|
|
13192
|
-
throw new BadRequestError65("Invalid camera ID format");
|
|
13193
|
-
}
|
|
13194
|
-
try {
|
|
13195
|
-
await collection.updateOne({ _id }, { $set: value }, { session });
|
|
13196
|
-
delCachedData();
|
|
13197
|
-
return "Successfully updated site camera.";
|
|
13198
|
-
} catch (error2) {
|
|
13199
|
-
logger47.log({
|
|
13200
|
-
level: "error",
|
|
13201
|
-
message: error2.message
|
|
13202
|
-
});
|
|
13203
|
-
const isDuplicated = error2.message.includes("duplicate");
|
|
13204
|
-
if (isDuplicated) {
|
|
13205
|
-
throw new BadRequestError65("ANPR already exist.");
|
|
13206
|
-
}
|
|
13207
|
-
if (error2 instanceof AppError8) {
|
|
13208
|
-
throw error2;
|
|
13209
|
-
}
|
|
13210
|
-
throw new Error("Failed to update ANPR.");
|
|
13211
|
-
}
|
|
13212
|
-
}
|
|
13213
|
-
async function deleteById(_id, session) {
|
|
13214
|
-
try {
|
|
13215
|
-
_id = new ObjectId38(_id);
|
|
13216
|
-
} catch (error) {
|
|
13217
|
-
throw new BadRequestError65("Invalid camera ID format");
|
|
13218
|
-
}
|
|
13219
|
-
try {
|
|
13220
|
-
await collection.deleteOne({ _id }, { session });
|
|
13221
|
-
delCachedData();
|
|
13222
|
-
return "Successfully deleted site camera.";
|
|
13223
|
-
} catch (error) {
|
|
13224
|
-
logger47.log({
|
|
13225
|
-
level: "error",
|
|
13226
|
-
message: error.message
|
|
13227
|
-
});
|
|
13228
|
-
if (error instanceof AppError8) {
|
|
13229
|
-
throw error;
|
|
13230
|
-
}
|
|
13231
|
-
throw new Error("Failed to delete site camera.");
|
|
13232
|
-
}
|
|
13233
|
-
}
|
|
13234
|
-
async function getAllCameraWithPassword(value) {
|
|
13235
|
-
value.page = value.page ? value.page - 1 : 0;
|
|
13236
|
-
value.limit = value.limit || 10;
|
|
13237
|
-
const query = {
|
|
13238
|
-
type: value.type,
|
|
13239
|
-
...value.direction && {
|
|
13240
|
-
direction: {
|
|
13241
|
-
$in: Array.isArray(value.direction) ? value.direction : [value.direction]
|
|
13242
|
-
}
|
|
13243
|
-
}
|
|
13244
|
-
};
|
|
13245
|
-
if (value.site) {
|
|
13246
|
-
try {
|
|
13247
|
-
value.site = new ObjectId38(value.site);
|
|
13248
|
-
query.site = value.site;
|
|
13249
|
-
} catch (error) {
|
|
13250
|
-
throw new BadRequestError65("Invalid site ID format");
|
|
13251
|
-
}
|
|
13252
|
-
}
|
|
13253
|
-
try {
|
|
13254
|
-
const items = await collection.aggregate([
|
|
13255
|
-
{
|
|
13256
|
-
$match: query
|
|
13257
|
-
},
|
|
13258
|
-
{
|
|
13259
|
-
$skip: value.page * value.limit
|
|
13260
|
-
},
|
|
13261
|
-
{
|
|
13262
|
-
$limit: value.limit
|
|
13263
|
-
}
|
|
13264
|
-
]).toArray();
|
|
13265
|
-
const length = await collection.countDocuments(query);
|
|
13266
|
-
const data = paginate17(items, value.page, value.limit, length);
|
|
13267
|
-
return data;
|
|
13268
|
-
} catch (error) {
|
|
13269
|
-
if (error instanceof BadRequestError65) {
|
|
13270
|
-
throw error;
|
|
13271
|
-
}
|
|
13272
|
-
throw new BadRequestError65("Failed to retrieve site cameras.");
|
|
13273
|
-
}
|
|
13274
|
-
}
|
|
13275
|
-
return {
|
|
13276
|
-
createIndexes,
|
|
13277
|
-
add,
|
|
13278
|
-
getAll,
|
|
13279
|
-
findSiteCameras,
|
|
13280
|
-
getBySite,
|
|
13281
|
-
getBySites,
|
|
13282
|
-
delCachedData,
|
|
13283
|
-
getBySiteGuardPost,
|
|
13284
|
-
updateById,
|
|
13285
|
-
deleteById,
|
|
13286
|
-
getAllCameraWithPassword
|
|
13287
|
-
};
|
|
13288
|
-
}
|
|
13050
|
+
import { ObjectId as ObjectId47 } from "mongodb";
|
|
13289
13051
|
|
|
13290
|
-
// src/services/
|
|
13291
|
-
import
|
|
13052
|
+
// src/services/dahua.service.ts
|
|
13053
|
+
import { BadRequestError as BadRequestError73 } from "@7365admin1/node-server-utils";
|
|
13054
|
+
import { promises as fsAsync } from "fs";
|
|
13055
|
+
import Joi40 from "joi";
|
|
13056
|
+
import * as path from "path";
|
|
13057
|
+
import { request } from "urllib";
|
|
13292
13058
|
|
|
13293
13059
|
// src/repositories/visitor-transaction.repo.ts
|
|
13294
13060
|
import {
|
|
13295
|
-
BadRequestError as
|
|
13061
|
+
BadRequestError as BadRequestError66,
|
|
13296
13062
|
InternalServerError as InternalServerError24,
|
|
13297
|
-
paginate as
|
|
13298
|
-
toObjectId as
|
|
13299
|
-
useAtlas as
|
|
13063
|
+
paginate as paginate17,
|
|
13064
|
+
toObjectId as toObjectId7,
|
|
13065
|
+
useAtlas as useAtlas30
|
|
13300
13066
|
} from "@7365admin1/node-server-utils";
|
|
13301
13067
|
|
|
13302
13068
|
// src/models/visitor-transactions.model.ts
|
|
13303
13069
|
import Joi36 from "joi";
|
|
13304
|
-
import { ObjectId as
|
|
13070
|
+
import { ObjectId as ObjectId39 } from "mongodb";
|
|
13305
13071
|
|
|
13306
13072
|
// src/models/person.model.ts
|
|
13307
|
-
import { BadRequestError as
|
|
13073
|
+
import { BadRequestError as BadRequestError65 } from "@7365admin1/node-server-utils";
|
|
13308
13074
|
import Joi35 from "joi";
|
|
13309
|
-
import { ObjectId as
|
|
13075
|
+
import { ObjectId as ObjectId38 } from "mongodb";
|
|
13310
13076
|
var PersonTypes = /* @__PURE__ */ ((PersonTypes3) => {
|
|
13311
13077
|
PersonTypes3["WALK_IN"] = "walk-in";
|
|
13312
13078
|
PersonTypes3["DROP_OFF"] = "drop-off";
|
|
@@ -13399,25 +13165,25 @@ var schemaUpdatePerson = Joi35.object({
|
|
|
13399
13165
|
function MPerson(value) {
|
|
13400
13166
|
const { error } = schemaPerson.validate(value);
|
|
13401
13167
|
if (error) {
|
|
13402
|
-
throw new
|
|
13168
|
+
throw new BadRequestError65(error.details[0].message);
|
|
13403
13169
|
}
|
|
13404
13170
|
if (value._id && typeof value._id === "string") {
|
|
13405
13171
|
try {
|
|
13406
|
-
value._id = new
|
|
13172
|
+
value._id = new ObjectId38(value._id);
|
|
13407
13173
|
} catch (error2) {
|
|
13408
13174
|
throw new Error("Invalid ID.");
|
|
13409
13175
|
}
|
|
13410
13176
|
}
|
|
13411
13177
|
if (value.org && typeof value.org === "string") {
|
|
13412
13178
|
try {
|
|
13413
|
-
value.org = new
|
|
13179
|
+
value.org = new ObjectId38(value.org);
|
|
13414
13180
|
} catch (error2) {
|
|
13415
13181
|
throw new Error("Invalid org ID.");
|
|
13416
13182
|
}
|
|
13417
13183
|
}
|
|
13418
13184
|
if (value.site && typeof value.site === "string") {
|
|
13419
13185
|
try {
|
|
13420
|
-
value.site = new
|
|
13186
|
+
value.site = new ObjectId38(value.site);
|
|
13421
13187
|
} catch (error2) {
|
|
13422
13188
|
throw new Error("Invalid site ID.");
|
|
13423
13189
|
}
|
|
@@ -13426,9 +13192,9 @@ function MPerson(value) {
|
|
|
13426
13192
|
value.files = value.files.map((file) => {
|
|
13427
13193
|
if (file.id && typeof file.id === "string") {
|
|
13428
13194
|
try {
|
|
13429
|
-
file.id = new
|
|
13195
|
+
file.id = new ObjectId38(file.id);
|
|
13430
13196
|
} catch {
|
|
13431
|
-
throw new
|
|
13197
|
+
throw new BadRequestError65("Invalid file id format");
|
|
13432
13198
|
}
|
|
13433
13199
|
}
|
|
13434
13200
|
return file;
|
|
@@ -13436,7 +13202,7 @@ function MPerson(value) {
|
|
|
13436
13202
|
}
|
|
13437
13203
|
if (value.user && typeof value.user === "string") {
|
|
13438
13204
|
try {
|
|
13439
|
-
value.user = new
|
|
13205
|
+
value.user = new ObjectId38(value.user);
|
|
13440
13206
|
} catch (error2) {
|
|
13441
13207
|
throw new Error("Invalid user ID.");
|
|
13442
13208
|
}
|
|
@@ -13606,28 +13372,28 @@ function MVisitorTransaction(value) {
|
|
|
13606
13372
|
}
|
|
13607
13373
|
if (value._id && typeof value._id === "string") {
|
|
13608
13374
|
try {
|
|
13609
|
-
value._id = new
|
|
13375
|
+
value._id = new ObjectId39(value._id);
|
|
13610
13376
|
} catch (error2) {
|
|
13611
13377
|
throw new Error("Invalid ID.");
|
|
13612
13378
|
}
|
|
13613
13379
|
}
|
|
13614
13380
|
if (value.org && typeof value.org === "string") {
|
|
13615
13381
|
try {
|
|
13616
|
-
value.org = new
|
|
13382
|
+
value.org = new ObjectId39(value.org);
|
|
13617
13383
|
} catch (error2) {
|
|
13618
13384
|
throw new Error("Invalid org ID.");
|
|
13619
13385
|
}
|
|
13620
13386
|
}
|
|
13621
13387
|
if (value.site && typeof value.site === "string") {
|
|
13622
13388
|
try {
|
|
13623
|
-
value.site = new
|
|
13389
|
+
value.site = new ObjectId39(value.site);
|
|
13624
13390
|
} catch (error2) {
|
|
13625
13391
|
throw new Error("Invalid site ID.");
|
|
13626
13392
|
}
|
|
13627
13393
|
}
|
|
13628
13394
|
if (value.unit && typeof value.unit === "string") {
|
|
13629
13395
|
try {
|
|
13630
|
-
value.unit = new
|
|
13396
|
+
value.unit = new ObjectId39(value.unit);
|
|
13631
13397
|
} catch (error2) {
|
|
13632
13398
|
throw new Error("Invalid unit ID.");
|
|
13633
13399
|
}
|
|
@@ -13642,9 +13408,9 @@ function MVisitorTransaction(value) {
|
|
|
13642
13408
|
if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0) {
|
|
13643
13409
|
value.visitorPass = value.visitorPass.map((v) => {
|
|
13644
13410
|
if (typeof v === "string")
|
|
13645
|
-
return { keyId: new
|
|
13411
|
+
return { keyId: new ObjectId39(v) };
|
|
13646
13412
|
if (v?.keyId && typeof v.keyId === "string") {
|
|
13647
|
-
return { keyId: new
|
|
13413
|
+
return { keyId: new ObjectId39(v.keyId) };
|
|
13648
13414
|
}
|
|
13649
13415
|
return v;
|
|
13650
13416
|
});
|
|
@@ -13652,16 +13418,16 @@ function MVisitorTransaction(value) {
|
|
|
13652
13418
|
if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0) {
|
|
13653
13419
|
value.passKeys = value.passKeys.map((p) => {
|
|
13654
13420
|
if (typeof p === "string")
|
|
13655
|
-
return { keyId: new
|
|
13421
|
+
return { keyId: new ObjectId39(p) };
|
|
13656
13422
|
if (p?.keyId && typeof p.keyId === "string") {
|
|
13657
|
-
return { keyId: new
|
|
13423
|
+
return { keyId: new ObjectId39(p.keyId) };
|
|
13658
13424
|
}
|
|
13659
13425
|
return p;
|
|
13660
13426
|
});
|
|
13661
13427
|
}
|
|
13662
13428
|
if (value.inviterId && typeof value.inviterId === "string") {
|
|
13663
13429
|
try {
|
|
13664
|
-
value.inviterId = new
|
|
13430
|
+
value.inviterId = new ObjectId39(value.inviterId);
|
|
13665
13431
|
} catch (error2) {
|
|
13666
13432
|
throw new Error("Invalid inviter ID.");
|
|
13667
13433
|
}
|
|
@@ -13718,10 +13484,10 @@ function MVisitorTransaction(value) {
|
|
|
13718
13484
|
}
|
|
13719
13485
|
|
|
13720
13486
|
// src/repositories/visitor-transaction.repo.ts
|
|
13721
|
-
import { ObjectId as
|
|
13487
|
+
import { ObjectId as ObjectId40 } from "mongodb";
|
|
13722
13488
|
var visitors_namespace_collection = "visitor.transactions";
|
|
13723
13489
|
function useVisitorTransactionRepo() {
|
|
13724
|
-
const db =
|
|
13490
|
+
const db = useAtlas30.getDb();
|
|
13725
13491
|
if (!db) {
|
|
13726
13492
|
throw new InternalServerError24("Unable to connect to server.");
|
|
13727
13493
|
}
|
|
@@ -13751,7 +13517,7 @@ function useVisitorTransactionRepo() {
|
|
|
13751
13517
|
console.log("Error in add visitor transaction:", error);
|
|
13752
13518
|
const isDuplicated = error.message.includes("duplicate");
|
|
13753
13519
|
if (isDuplicated) {
|
|
13754
|
-
throw new
|
|
13520
|
+
throw new BadRequestError66("Visitor already exists.");
|
|
13755
13521
|
}
|
|
13756
13522
|
throw error;
|
|
13757
13523
|
}
|
|
@@ -13787,8 +13553,8 @@ function useVisitorTransactionRepo() {
|
|
|
13787
13553
|
expectedCheckInFilter.$lte = new Date(dateTo);
|
|
13788
13554
|
}
|
|
13789
13555
|
const query = {
|
|
13790
|
-
...
|
|
13791
|
-
...
|
|
13556
|
+
...ObjectId40.isValid(org) && { org: new ObjectId40(org) },
|
|
13557
|
+
...ObjectId40.isValid(site) && { site: new ObjectId40(site) },
|
|
13792
13558
|
...Object.keys(checkInFilter).length > 0 && { checkIn: checkInFilter },
|
|
13793
13559
|
...Object.keys(expectedCheckInFilter).length > 0 && {
|
|
13794
13560
|
expectedCheckIn: expectedCheckInFilter
|
|
@@ -13973,14 +13739,14 @@ function useVisitorTransactionRepo() {
|
|
|
13973
13739
|
collection.aggregate([...basePipeline, { $count: "total" }]).toArray()
|
|
13974
13740
|
]);
|
|
13975
13741
|
const totalCount = countResult[0]?.total || 0;
|
|
13976
|
-
const data =
|
|
13742
|
+
const data = paginate17(items, page, limit, totalCount);
|
|
13977
13743
|
return data;
|
|
13978
13744
|
} catch (error) {
|
|
13979
13745
|
throw error;
|
|
13980
13746
|
}
|
|
13981
13747
|
}
|
|
13982
13748
|
async function getVisitorTransactionById(id) {
|
|
13983
|
-
const _id =
|
|
13749
|
+
const _id = toObjectId7(id);
|
|
13984
13750
|
try {
|
|
13985
13751
|
const basePipeline = [{ $match: { _id } }];
|
|
13986
13752
|
const [result] = await collection.aggregate([
|
|
@@ -14022,7 +13788,7 @@ function useVisitorTransactionRepo() {
|
|
|
14022
13788
|
}
|
|
14023
13789
|
}
|
|
14024
13790
|
async function getOpenByPlateNumber(plateNumber, site) {
|
|
14025
|
-
const _site = typeof site === "string" ?
|
|
13791
|
+
const _site = typeof site === "string" ? toObjectId7(site) : site;
|
|
14026
13792
|
const query = {
|
|
14027
13793
|
plateNumber,
|
|
14028
13794
|
site: _site,
|
|
@@ -14039,9 +13805,9 @@ function useVisitorTransactionRepo() {
|
|
|
14039
13805
|
}
|
|
14040
13806
|
async function updateById(_id, value, session) {
|
|
14041
13807
|
try {
|
|
14042
|
-
_id = new
|
|
13808
|
+
_id = new ObjectId40(_id);
|
|
14043
13809
|
} catch (error) {
|
|
14044
|
-
throw new
|
|
13810
|
+
throw new BadRequestError66("Invalid visitor transaction ID format.");
|
|
14045
13811
|
}
|
|
14046
13812
|
value.updatedAt = /* @__PURE__ */ new Date();
|
|
14047
13813
|
if (value.checkOut) {
|
|
@@ -14060,9 +13826,9 @@ function useVisitorTransactionRepo() {
|
|
|
14060
13826
|
}
|
|
14061
13827
|
async function deleteVisitorTransaction(_id) {
|
|
14062
13828
|
try {
|
|
14063
|
-
_id = new
|
|
13829
|
+
_id = new ObjectId40(_id);
|
|
14064
13830
|
} catch (error) {
|
|
14065
|
-
throw new
|
|
13831
|
+
throw new BadRequestError66("Invalid customer ID format.");
|
|
14066
13832
|
}
|
|
14067
13833
|
try {
|
|
14068
13834
|
const updateValue = {
|
|
@@ -14106,7 +13872,7 @@ function useVisitorTransactionRepo() {
|
|
|
14106
13872
|
}
|
|
14107
13873
|
}
|
|
14108
13874
|
async function getExpiredCheckedOutTransactionsBySite(siteId) {
|
|
14109
|
-
const site =
|
|
13875
|
+
const site = toObjectId7(siteId);
|
|
14110
13876
|
try {
|
|
14111
13877
|
const now = /* @__PURE__ */ new Date();
|
|
14112
13878
|
const expiredTransactions = await collection.find({
|
|
@@ -14127,7 +13893,7 @@ function useVisitorTransactionRepo() {
|
|
|
14127
13893
|
async function updateManyDahuaSyncStatus(ids, dahuaSyncStatus, session) {
|
|
14128
13894
|
try {
|
|
14129
13895
|
const objectIds = ids.map(
|
|
14130
|
-
(id) => typeof id === "string" ? new
|
|
13896
|
+
(id) => typeof id === "string" ? new ObjectId40(id) : id
|
|
14131
13897
|
);
|
|
14132
13898
|
const res = await collection.updateMany(
|
|
14133
13899
|
{ _id: { $in: objectIds } },
|
|
@@ -14158,10 +13924,22 @@ function useVisitorTransactionRepo() {
|
|
|
14158
13924
|
};
|
|
14159
13925
|
}
|
|
14160
13926
|
|
|
13927
|
+
// src/repositories/vehicle.repo.ts
|
|
13928
|
+
import {
|
|
13929
|
+
AppError as AppError8,
|
|
13930
|
+
BadRequestError as BadRequestError68,
|
|
13931
|
+
InternalServerError as InternalServerError25,
|
|
13932
|
+
logger as logger49,
|
|
13933
|
+
NotFoundError as NotFoundError17,
|
|
13934
|
+
paginate as paginate18,
|
|
13935
|
+
toObjectId as toObjectId8,
|
|
13936
|
+
useAtlas as useAtlas31
|
|
13937
|
+
} from "@7365admin1/node-server-utils";
|
|
13938
|
+
|
|
14161
13939
|
// src/models/vehicle.model.ts
|
|
14162
|
-
import { BadRequestError as
|
|
13940
|
+
import { BadRequestError as BadRequestError67, logger as logger48 } from "@7365admin1/node-server-utils";
|
|
14163
13941
|
import Joi37 from "joi";
|
|
14164
|
-
import { ObjectId as
|
|
13942
|
+
import { ObjectId as ObjectId41 } from "mongodb";
|
|
14165
13943
|
var VehicleType = /* @__PURE__ */ ((VehicleType2) => {
|
|
14166
13944
|
VehicleType2["WHITELIST"] = "whitelist";
|
|
14167
13945
|
VehicleType2["BLOCKLIST"] = "blocklist";
|
|
@@ -14238,35 +14016,35 @@ var vehicleSchema = Joi37.object({
|
|
|
14238
14016
|
function MVehicle(value) {
|
|
14239
14017
|
const { error } = vehicleSchema.validate(value);
|
|
14240
14018
|
if (error) {
|
|
14241
|
-
|
|
14242
|
-
throw new
|
|
14019
|
+
logger48.log({ level: "error", message: error.message });
|
|
14020
|
+
throw new BadRequestError67(error.message);
|
|
14243
14021
|
}
|
|
14244
14022
|
if (value.org) {
|
|
14245
14023
|
try {
|
|
14246
|
-
value.org = new
|
|
14024
|
+
value.org = new ObjectId41(value.org);
|
|
14247
14025
|
} catch (error2) {
|
|
14248
|
-
throw new
|
|
14026
|
+
throw new BadRequestError67("Invalid org ID format.");
|
|
14249
14027
|
}
|
|
14250
14028
|
}
|
|
14251
14029
|
if (value.site) {
|
|
14252
14030
|
try {
|
|
14253
|
-
value.site = new
|
|
14031
|
+
value.site = new ObjectId41(value.site);
|
|
14254
14032
|
} catch (error2) {
|
|
14255
|
-
throw new
|
|
14033
|
+
throw new BadRequestError67("Invalid site ID format.");
|
|
14256
14034
|
}
|
|
14257
14035
|
}
|
|
14258
14036
|
if (value.unit) {
|
|
14259
14037
|
try {
|
|
14260
|
-
value.unit = new
|
|
14038
|
+
value.unit = new ObjectId41(value.unit);
|
|
14261
14039
|
} catch (error2) {
|
|
14262
|
-
throw new
|
|
14040
|
+
throw new BadRequestError67("Invalid building unit ID format.");
|
|
14263
14041
|
}
|
|
14264
14042
|
}
|
|
14265
14043
|
if (value.peopleId) {
|
|
14266
14044
|
try {
|
|
14267
|
-
value.peopleId = new
|
|
14045
|
+
value.peopleId = new ObjectId41(value.peopleId);
|
|
14268
14046
|
} catch (error2) {
|
|
14269
|
-
throw new
|
|
14047
|
+
throw new BadRequestError67("Invalid building unit ID format.");
|
|
14270
14048
|
}
|
|
14271
14049
|
}
|
|
14272
14050
|
const createdAtDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
@@ -14314,20 +14092,20 @@ var schemaVehicleTransaction = Joi37.object({
|
|
|
14314
14092
|
function MVehicleTransaction(value) {
|
|
14315
14093
|
const { error } = schemaVehicleTransaction.validate(value);
|
|
14316
14094
|
if (error) {
|
|
14317
|
-
|
|
14318
|
-
throw new
|
|
14095
|
+
logger48.log({ level: "error", message: error.message });
|
|
14096
|
+
throw new BadRequestError67(error.message);
|
|
14319
14097
|
}
|
|
14320
14098
|
if (value._id) {
|
|
14321
14099
|
try {
|
|
14322
|
-
value._id = new
|
|
14100
|
+
value._id = new ObjectId41(value._id);
|
|
14323
14101
|
} catch (error2) {
|
|
14324
|
-
throw new
|
|
14102
|
+
throw new BadRequestError67("Invalid ID.");
|
|
14325
14103
|
}
|
|
14326
14104
|
}
|
|
14327
14105
|
try {
|
|
14328
|
-
value.site = new
|
|
14106
|
+
value.site = new ObjectId41(value.site);
|
|
14329
14107
|
} catch (error2) {
|
|
14330
|
-
throw new
|
|
14108
|
+
throw new BadRequestError67("Invalid site ID.");
|
|
14331
14109
|
}
|
|
14332
14110
|
return {
|
|
14333
14111
|
_id: value._id,
|
|
@@ -14343,30 +14121,13 @@ function MVehicleTransaction(value) {
|
|
|
14343
14121
|
};
|
|
14344
14122
|
}
|
|
14345
14123
|
|
|
14346
|
-
// src/services/dahua.service.ts
|
|
14347
|
-
import { BadRequestError as BadRequestError74 } from "@7365admin1/node-server-utils";
|
|
14348
|
-
import { promises as fsAsync } from "fs";
|
|
14349
|
-
import Joi40 from "joi";
|
|
14350
|
-
import * as path from "path";
|
|
14351
|
-
import { request } from "urllib";
|
|
14352
|
-
|
|
14353
14124
|
// src/repositories/vehicle.repo.ts
|
|
14354
|
-
import {
|
|
14355
|
-
AppError as AppError9,
|
|
14356
|
-
BadRequestError as BadRequestError69,
|
|
14357
|
-
InternalServerError as InternalServerError25,
|
|
14358
|
-
logger as logger50,
|
|
14359
|
-
NotFoundError as NotFoundError17,
|
|
14360
|
-
paginate as paginate19,
|
|
14361
|
-
toObjectId as toObjectId9,
|
|
14362
|
-
useAtlas as useAtlas32
|
|
14363
|
-
} from "@7365admin1/node-server-utils";
|
|
14364
|
-
import { ObjectId as ObjectId43 } from "mongodb";
|
|
14125
|
+
import { ObjectId as ObjectId42 } from "mongodb";
|
|
14365
14126
|
import Joi38 from "joi";
|
|
14366
14127
|
var vehicles_namespace_collection = "vehicles";
|
|
14367
14128
|
function useVehicleRepo() {
|
|
14368
14129
|
vehicles_namespace_collection;
|
|
14369
|
-
const db =
|
|
14130
|
+
const db = useAtlas31.getDb();
|
|
14370
14131
|
if (!db) {
|
|
14371
14132
|
throw new InternalServerError25("Unable to connect to server.");
|
|
14372
14133
|
}
|
|
@@ -14404,11 +14165,11 @@ function useVehicleRepo() {
|
|
|
14404
14165
|
const res = await collection.insertOne(value, { session });
|
|
14405
14166
|
return res.insertedId;
|
|
14406
14167
|
} catch (error) {
|
|
14407
|
-
|
|
14168
|
+
logger49.log({
|
|
14408
14169
|
level: "error",
|
|
14409
14170
|
message: error.message
|
|
14410
14171
|
});
|
|
14411
|
-
if (error instanceof
|
|
14172
|
+
if (error instanceof AppError8) {
|
|
14412
14173
|
throw error;
|
|
14413
14174
|
} else {
|
|
14414
14175
|
throw new Error("Failed to create vehicle.");
|
|
@@ -14589,7 +14350,7 @@ function useVehicleRepo() {
|
|
|
14589
14350
|
const regexCountResult = await collection.aggregate(buildGroupedCountPipeline(regexQuery)).toArray();
|
|
14590
14351
|
length = regexCountResult[0]?.total || 0;
|
|
14591
14352
|
}
|
|
14592
|
-
const data =
|
|
14353
|
+
const data = paginate18(items, page, limit, length);
|
|
14593
14354
|
return data;
|
|
14594
14355
|
} catch (error) {
|
|
14595
14356
|
throw error;
|
|
@@ -14597,9 +14358,9 @@ function useVehicleRepo() {
|
|
|
14597
14358
|
}
|
|
14598
14359
|
async function getSeasonPassTypes(site) {
|
|
14599
14360
|
try {
|
|
14600
|
-
site = new
|
|
14361
|
+
site = new ObjectId42(site);
|
|
14601
14362
|
} catch (error) {
|
|
14602
|
-
throw new
|
|
14363
|
+
throw new BadRequestError68("Invalid site ID format.");
|
|
14603
14364
|
}
|
|
14604
14365
|
try {
|
|
14605
14366
|
const categories = await collection.aggregate([
|
|
@@ -14622,17 +14383,17 @@ function useVehicleRepo() {
|
|
|
14622
14383
|
]).toArray();
|
|
14623
14384
|
return categories;
|
|
14624
14385
|
} catch (error) {
|
|
14625
|
-
if (error instanceof
|
|
14386
|
+
if (error instanceof BadRequestError68) {
|
|
14626
14387
|
throw error;
|
|
14627
14388
|
}
|
|
14628
|
-
throw new
|
|
14389
|
+
throw new BadRequestError68("Failed to retrieve season pass types.");
|
|
14629
14390
|
}
|
|
14630
14391
|
}
|
|
14631
14392
|
async function getVehicleById(_id) {
|
|
14632
14393
|
try {
|
|
14633
|
-
_id = new
|
|
14394
|
+
_id = new ObjectId42(_id);
|
|
14634
14395
|
} catch (error) {
|
|
14635
|
-
throw new
|
|
14396
|
+
throw new BadRequestError68("Invalid vehicle ID format.");
|
|
14636
14397
|
}
|
|
14637
14398
|
try {
|
|
14638
14399
|
const data = await collection.aggregate([
|
|
@@ -14812,7 +14573,7 @@ function useVehicleRepo() {
|
|
|
14812
14573
|
async function getByPlaceNumber(value) {
|
|
14813
14574
|
const { error } = Joi38.string().required().validate(value);
|
|
14814
14575
|
if (error) {
|
|
14815
|
-
throw new
|
|
14576
|
+
throw new BadRequestError68(error.details[0].message);
|
|
14816
14577
|
}
|
|
14817
14578
|
try {
|
|
14818
14579
|
const data = await collection.findOne({
|
|
@@ -14829,9 +14590,9 @@ function useVehicleRepo() {
|
|
|
14829
14590
|
}
|
|
14830
14591
|
async function updateVehicleById(_id, value, session) {
|
|
14831
14592
|
try {
|
|
14832
|
-
_id = new
|
|
14593
|
+
_id = new ObjectId42(_id);
|
|
14833
14594
|
} catch (error) {
|
|
14834
|
-
throw new
|
|
14595
|
+
throw new BadRequestError68("Invalid vehicle ID format.");
|
|
14835
14596
|
}
|
|
14836
14597
|
try {
|
|
14837
14598
|
const updateValue = {
|
|
@@ -14853,9 +14614,9 @@ function useVehicleRepo() {
|
|
|
14853
14614
|
}
|
|
14854
14615
|
async function deleteVehicle(_id, session) {
|
|
14855
14616
|
try {
|
|
14856
|
-
_id = new
|
|
14617
|
+
_id = new ObjectId42(_id);
|
|
14857
14618
|
} catch (error) {
|
|
14858
|
-
throw new
|
|
14619
|
+
throw new BadRequestError68("Invalid vehicle ID format.");
|
|
14859
14620
|
}
|
|
14860
14621
|
try {
|
|
14861
14622
|
const updateValue = {
|
|
@@ -14877,7 +14638,7 @@ function useVehicleRepo() {
|
|
|
14877
14638
|
async function getVehicleByPlateNumber(plateNumber) {
|
|
14878
14639
|
const { error } = Joi38.string().required().validate(plateNumber);
|
|
14879
14640
|
if (error) {
|
|
14880
|
-
throw new
|
|
14641
|
+
throw new BadRequestError68(error.details[0].message);
|
|
14881
14642
|
}
|
|
14882
14643
|
try {
|
|
14883
14644
|
const data = await collection.findOne(
|
|
@@ -14899,7 +14660,7 @@ function useVehicleRepo() {
|
|
|
14899
14660
|
}) {
|
|
14900
14661
|
page = page > 0 ? page - 1 : 0;
|
|
14901
14662
|
if (!nric) {
|
|
14902
|
-
throw new
|
|
14663
|
+
throw new BadRequestError68("NRIC is required.");
|
|
14903
14664
|
}
|
|
14904
14665
|
const _nric = nric.trim();
|
|
14905
14666
|
const query = {
|
|
@@ -14926,7 +14687,7 @@ function useVehicleRepo() {
|
|
|
14926
14687
|
}
|
|
14927
14688
|
]).toArray();
|
|
14928
14689
|
const length = await collection.countDocuments(query);
|
|
14929
|
-
const data =
|
|
14690
|
+
const data = paginate18(items, page, limit, length);
|
|
14930
14691
|
return data;
|
|
14931
14692
|
} catch (error) {
|
|
14932
14693
|
throw error;
|
|
@@ -14958,7 +14719,7 @@ function useVehicleRepo() {
|
|
|
14958
14719
|
page = page > 0 ? page - 1 : 0;
|
|
14959
14720
|
const skip = page * limit;
|
|
14960
14721
|
try {
|
|
14961
|
-
const unit =
|
|
14722
|
+
const unit = toObjectId8(unitId);
|
|
14962
14723
|
const query = {
|
|
14963
14724
|
unit
|
|
14964
14725
|
};
|
|
@@ -14973,7 +14734,7 @@ function useVehicleRepo() {
|
|
|
14973
14734
|
limit
|
|
14974
14735
|
}).toArray();
|
|
14975
14736
|
const length = await collection.countDocuments(query);
|
|
14976
|
-
const data =
|
|
14737
|
+
const data = paginate18(items, page, limit, length);
|
|
14977
14738
|
return data;
|
|
14978
14739
|
} catch (error) {
|
|
14979
14740
|
throw error;
|
|
@@ -15009,7 +14770,7 @@ function useVehicleRepo() {
|
|
|
15009
14770
|
return {
|
|
15010
14771
|
updateOne: {
|
|
15011
14772
|
filter: {
|
|
15012
|
-
site: new
|
|
14773
|
+
site: new ObjectId42(vehicle.site),
|
|
15013
14774
|
plateNumber,
|
|
15014
14775
|
$or: [
|
|
15015
14776
|
{ deletedAt: "" },
|
|
@@ -15020,9 +14781,9 @@ function useVehicleRepo() {
|
|
|
15020
14781
|
update: {
|
|
15021
14782
|
$set: {
|
|
15022
14783
|
...rest,
|
|
15023
|
-
site: new
|
|
15024
|
-
unit: vehicle.unit ? new
|
|
15025
|
-
org: vehicle.org ? new
|
|
14784
|
+
site: new ObjectId42(vehicle.site),
|
|
14785
|
+
unit: vehicle.unit ? new ObjectId42(vehicle.unit) : null,
|
|
14786
|
+
org: vehicle.org ? new ObjectId42(vehicle.org) : null,
|
|
15026
14787
|
plateNumber,
|
|
15027
14788
|
updatedAt: now
|
|
15028
14789
|
},
|
|
@@ -15042,11 +14803,11 @@ function useVehicleRepo() {
|
|
|
15042
14803
|
upsertedIds: res.upsertedIds
|
|
15043
14804
|
};
|
|
15044
14805
|
} catch (error) {
|
|
15045
|
-
|
|
14806
|
+
logger49.log({
|
|
15046
14807
|
level: "error",
|
|
15047
14808
|
message: error.message
|
|
15048
14809
|
});
|
|
15049
|
-
if (error instanceof
|
|
14810
|
+
if (error instanceof AppError8) {
|
|
15050
14811
|
throw error;
|
|
15051
14812
|
}
|
|
15052
14813
|
throw new Error("Failed to bulk upsert vehicles.");
|
|
@@ -15073,32 +14834,32 @@ function useVehicleRepo() {
|
|
|
15073
14834
|
|
|
15074
14835
|
// src/services/vehicle.service.ts
|
|
15075
14836
|
import {
|
|
15076
|
-
BadRequestError as
|
|
15077
|
-
logger as
|
|
15078
|
-
useAtlas as
|
|
14837
|
+
BadRequestError as BadRequestError72,
|
|
14838
|
+
logger as logger53,
|
|
14839
|
+
useAtlas as useAtlas34
|
|
15079
14840
|
} from "@7365admin1/node-server-utils";
|
|
15080
14841
|
|
|
15081
14842
|
// src/repositories/person.repo.ts
|
|
15082
14843
|
import {
|
|
15083
|
-
BadRequestError as
|
|
14844
|
+
BadRequestError as BadRequestError69,
|
|
15084
14845
|
InternalServerError as InternalServerError26,
|
|
15085
|
-
logger as
|
|
15086
|
-
makeCacheKey as
|
|
15087
|
-
paginate as
|
|
15088
|
-
useAtlas as
|
|
15089
|
-
useCache as
|
|
15090
|
-
AppError as
|
|
15091
|
-
toObjectId as
|
|
14846
|
+
logger as logger50,
|
|
14847
|
+
makeCacheKey as makeCacheKey23,
|
|
14848
|
+
paginate as paginate19,
|
|
14849
|
+
useAtlas as useAtlas32,
|
|
14850
|
+
useCache as useCache24,
|
|
14851
|
+
AppError as AppError9,
|
|
14852
|
+
toObjectId as toObjectId9
|
|
15092
14853
|
} from "@7365admin1/node-server-utils";
|
|
15093
|
-
import { ObjectId as
|
|
14854
|
+
import { ObjectId as ObjectId43 } from "mongodb";
|
|
15094
14855
|
var site_people_namespace_collection = "site.people";
|
|
15095
14856
|
function usePersonRepo() {
|
|
15096
|
-
const db =
|
|
14857
|
+
const db = useAtlas32.getDb();
|
|
15097
14858
|
if (!db) {
|
|
15098
14859
|
throw new InternalServerError26("Unable to connect to server.");
|
|
15099
14860
|
}
|
|
15100
14861
|
const collection = db.collection(site_people_namespace_collection);
|
|
15101
|
-
const { delNamespace, getCache, setCache } =
|
|
14862
|
+
const { delNamespace, getCache, setCache } = useCache24(
|
|
15102
14863
|
site_people_namespace_collection
|
|
15103
14864
|
);
|
|
15104
14865
|
async function createIndexes() {
|
|
@@ -15132,11 +14893,11 @@ function usePersonRepo() {
|
|
|
15132
14893
|
value = MPerson(value);
|
|
15133
14894
|
const res = await collection.insertOne(value, { session });
|
|
15134
14895
|
delNamespace().then(() => {
|
|
15135
|
-
|
|
14896
|
+
logger50.info(
|
|
15136
14897
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
15137
14898
|
);
|
|
15138
14899
|
}).catch((err) => {
|
|
15139
|
-
|
|
14900
|
+
logger50.error(
|
|
15140
14901
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
15141
14902
|
err
|
|
15142
14903
|
);
|
|
@@ -15145,7 +14906,7 @@ function usePersonRepo() {
|
|
|
15145
14906
|
} catch (error) {
|
|
15146
14907
|
const isDuplicated = error.message.includes("duplicate");
|
|
15147
14908
|
if (isDuplicated) {
|
|
15148
|
-
throw new
|
|
14909
|
+
throw new BadRequestError69("Person already exists.");
|
|
15149
14910
|
}
|
|
15150
14911
|
throw error;
|
|
15151
14912
|
}
|
|
@@ -15182,8 +14943,8 @@ function usePersonRepo() {
|
|
|
15182
14943
|
{ "plates.plateNumber": { $regex: search, $options: "i" } }
|
|
15183
14944
|
]
|
|
15184
14945
|
},
|
|
15185
|
-
...
|
|
15186
|
-
...
|
|
14946
|
+
...ObjectId43.isValid(org) && { org: new ObjectId43(org) },
|
|
14947
|
+
...ObjectId43.isValid(site) && { site: new ObjectId43(site) },
|
|
15187
14948
|
...PERSON_TYPES.includes(type) && { type }
|
|
15188
14949
|
};
|
|
15189
14950
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
@@ -15199,13 +14960,13 @@ function usePersonRepo() {
|
|
|
15199
14960
|
...query.site && { site: query.site.toString() },
|
|
15200
14961
|
...PERSON_TYPES.includes(type) && { type }
|
|
15201
14962
|
};
|
|
15202
|
-
const cacheKey =
|
|
14963
|
+
const cacheKey = makeCacheKey23(
|
|
15203
14964
|
site_people_namespace_collection,
|
|
15204
14965
|
cacheOptions
|
|
15205
14966
|
);
|
|
15206
14967
|
const cachedData = await getCache(cacheKey);
|
|
15207
14968
|
if (cachedData) {
|
|
15208
|
-
|
|
14969
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15209
14970
|
return cachedData;
|
|
15210
14971
|
}
|
|
15211
14972
|
try {
|
|
@@ -15237,9 +14998,9 @@ function usePersonRepo() {
|
|
|
15237
14998
|
collection.aggregate([{ $match: query }, { $count: "total" }], { session }).toArray()
|
|
15238
14999
|
]);
|
|
15239
15000
|
const totalCount = countResult[0]?.total || 0;
|
|
15240
|
-
const data =
|
|
15241
|
-
setCache(cacheKey, data, 15 * 60).then(() =>
|
|
15242
|
-
(err) =>
|
|
15001
|
+
const data = paginate19(items, page, limit, totalCount);
|
|
15002
|
+
setCache(cacheKey, data, 15 * 60).then(() => logger50.info(`Cache set for key: ${cacheKey}`)).catch(
|
|
15003
|
+
(err) => logger50.error(`Failed to set cache for key: ${cacheKey}`, err)
|
|
15243
15004
|
);
|
|
15244
15005
|
return data;
|
|
15245
15006
|
} catch (error) {
|
|
@@ -15248,9 +15009,9 @@ function usePersonRepo() {
|
|
|
15248
15009
|
}
|
|
15249
15010
|
async function updateById(_id, value, session) {
|
|
15250
15011
|
try {
|
|
15251
|
-
_id = new
|
|
15012
|
+
_id = new ObjectId43(_id);
|
|
15252
15013
|
} catch (error) {
|
|
15253
|
-
throw new
|
|
15014
|
+
throw new BadRequestError69("Invalid person transaction ID format.");
|
|
15254
15015
|
}
|
|
15255
15016
|
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15256
15017
|
try {
|
|
@@ -15260,11 +15021,11 @@ function usePersonRepo() {
|
|
|
15260
15021
|
{ session }
|
|
15261
15022
|
);
|
|
15262
15023
|
delNamespace().then(() => {
|
|
15263
|
-
|
|
15024
|
+
logger50.info(
|
|
15264
15025
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
15265
15026
|
);
|
|
15266
15027
|
}).catch((err) => {
|
|
15267
|
-
|
|
15028
|
+
logger50.error(
|
|
15268
15029
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
15269
15030
|
err
|
|
15270
15031
|
);
|
|
@@ -15276,9 +15037,9 @@ function usePersonRepo() {
|
|
|
15276
15037
|
}
|
|
15277
15038
|
async function deleteById(_id) {
|
|
15278
15039
|
try {
|
|
15279
|
-
_id = new
|
|
15040
|
+
_id = new ObjectId43(_id);
|
|
15280
15041
|
} catch (error) {
|
|
15281
|
-
throw new
|
|
15042
|
+
throw new BadRequestError69("Invalid customer ID format.");
|
|
15282
15043
|
}
|
|
15283
15044
|
try {
|
|
15284
15045
|
const updateValue = {
|
|
@@ -15291,11 +15052,11 @@ function usePersonRepo() {
|
|
|
15291
15052
|
throw new InternalServerError26("Unable to delete visitor transaction.");
|
|
15292
15053
|
}
|
|
15293
15054
|
delNamespace().then(() => {
|
|
15294
|
-
|
|
15055
|
+
logger50.info(
|
|
15295
15056
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
15296
15057
|
);
|
|
15297
15058
|
}).catch((err) => {
|
|
15298
|
-
|
|
15059
|
+
logger50.error(
|
|
15299
15060
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
15300
15061
|
err
|
|
15301
15062
|
);
|
|
@@ -15307,17 +15068,17 @@ function usePersonRepo() {
|
|
|
15307
15068
|
}
|
|
15308
15069
|
async function getById(_id) {
|
|
15309
15070
|
try {
|
|
15310
|
-
_id = new
|
|
15071
|
+
_id = new ObjectId43(_id);
|
|
15311
15072
|
} catch (error) {
|
|
15312
|
-
throw new
|
|
15073
|
+
throw new BadRequestError69("Invalid person ID.");
|
|
15313
15074
|
}
|
|
15314
|
-
const cacheKey =
|
|
15075
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15315
15076
|
_id: String(_id)
|
|
15316
15077
|
});
|
|
15317
15078
|
try {
|
|
15318
15079
|
const cached = await getCache(cacheKey);
|
|
15319
15080
|
if (cached) {
|
|
15320
|
-
|
|
15081
|
+
logger50.log({
|
|
15321
15082
|
level: "info",
|
|
15322
15083
|
message: `Cache hit for getById person: ${cacheKey}`
|
|
15323
15084
|
});
|
|
@@ -15327,19 +15088,19 @@ function usePersonRepo() {
|
|
|
15327
15088
|
_id
|
|
15328
15089
|
});
|
|
15329
15090
|
setCache(cacheKey, result, 300).then(() => {
|
|
15330
|
-
|
|
15091
|
+
logger50.log({
|
|
15331
15092
|
level: "info",
|
|
15332
15093
|
message: `Cache set for person by id: ${cacheKey}`
|
|
15333
15094
|
});
|
|
15334
15095
|
}).catch((err) => {
|
|
15335
|
-
|
|
15096
|
+
logger50.log({
|
|
15336
15097
|
level: "error",
|
|
15337
15098
|
message: `Failed to set cache for person by id: ${err.message}`
|
|
15338
15099
|
});
|
|
15339
15100
|
});
|
|
15340
15101
|
return result;
|
|
15341
15102
|
} catch (error) {
|
|
15342
|
-
if (error instanceof
|
|
15103
|
+
if (error instanceof AppError9) {
|
|
15343
15104
|
throw error;
|
|
15344
15105
|
} else {
|
|
15345
15106
|
throw new InternalServerError26("Failed to get person by id.");
|
|
@@ -15347,14 +15108,14 @@ function usePersonRepo() {
|
|
|
15347
15108
|
}
|
|
15348
15109
|
}
|
|
15349
15110
|
async function getPersonByPlateNumber(plateNumber) {
|
|
15350
|
-
const cacheKey =
|
|
15111
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15351
15112
|
plateNumber,
|
|
15352
15113
|
key: "get-person-plate-number"
|
|
15353
15114
|
});
|
|
15354
15115
|
try {
|
|
15355
15116
|
const cacheData = await getCache(cacheKey);
|
|
15356
15117
|
if (cacheData) {
|
|
15357
|
-
|
|
15118
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15358
15119
|
return cacheData;
|
|
15359
15120
|
}
|
|
15360
15121
|
const data = await collection.findOne(
|
|
@@ -15362,9 +15123,9 @@ function usePersonRepo() {
|
|
|
15362
15123
|
{ sort: { _id: -1 } }
|
|
15363
15124
|
);
|
|
15364
15125
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15365
|
-
|
|
15126
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15366
15127
|
}).catch((err) => {
|
|
15367
|
-
|
|
15128
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15368
15129
|
});
|
|
15369
15130
|
return data;
|
|
15370
15131
|
} catch (error) {
|
|
@@ -15375,19 +15136,19 @@ function usePersonRepo() {
|
|
|
15375
15136
|
}
|
|
15376
15137
|
async function getByNRIC(value) {
|
|
15377
15138
|
try {
|
|
15378
|
-
const cacheKey =
|
|
15139
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15379
15140
|
nric: value
|
|
15380
15141
|
});
|
|
15381
15142
|
const cachedData = await getCache(cacheKey);
|
|
15382
15143
|
if (cachedData) {
|
|
15383
|
-
|
|
15144
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15384
15145
|
return cachedData;
|
|
15385
15146
|
}
|
|
15386
15147
|
const data = await collection.findOne({ nric: value });
|
|
15387
15148
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15388
|
-
|
|
15149
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15389
15150
|
}).catch((err) => {
|
|
15390
|
-
|
|
15151
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15391
15152
|
});
|
|
15392
15153
|
return data;
|
|
15393
15154
|
} catch (error) {
|
|
@@ -15396,19 +15157,19 @@ function usePersonRepo() {
|
|
|
15396
15157
|
}
|
|
15397
15158
|
async function getPersonByPhoneNumber(value) {
|
|
15398
15159
|
try {
|
|
15399
|
-
const cacheKey =
|
|
15160
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15400
15161
|
contact: value
|
|
15401
15162
|
});
|
|
15402
15163
|
const cachedData = await getCache(cacheKey);
|
|
15403
15164
|
if (cachedData) {
|
|
15404
|
-
|
|
15165
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15405
15166
|
return cachedData;
|
|
15406
15167
|
}
|
|
15407
15168
|
const data = await collection.findOne({ contact: value });
|
|
15408
15169
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15409
|
-
|
|
15170
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15410
15171
|
}).catch((err) => {
|
|
15411
|
-
|
|
15172
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15412
15173
|
});
|
|
15413
15174
|
return data;
|
|
15414
15175
|
} catch (error) {
|
|
@@ -15422,7 +15183,7 @@ function usePersonRepo() {
|
|
|
15422
15183
|
type = [],
|
|
15423
15184
|
unit
|
|
15424
15185
|
}, session) {
|
|
15425
|
-
const cacheKey =
|
|
15186
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15426
15187
|
unit: JSON.stringify(unit),
|
|
15427
15188
|
status,
|
|
15428
15189
|
type,
|
|
@@ -15430,7 +15191,7 @@ function usePersonRepo() {
|
|
|
15430
15191
|
});
|
|
15431
15192
|
const cacheData = await getCache(cacheKey);
|
|
15432
15193
|
if (cacheData) {
|
|
15433
|
-
|
|
15194
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15434
15195
|
return cacheData;
|
|
15435
15196
|
}
|
|
15436
15197
|
try {
|
|
@@ -15443,9 +15204,9 @@ function usePersonRepo() {
|
|
|
15443
15204
|
};
|
|
15444
15205
|
const data = await collection.find(query).sort({ _id: -1 }).toArray();
|
|
15445
15206
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15446
|
-
|
|
15207
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15447
15208
|
}).catch((err) => {
|
|
15448
|
-
|
|
15209
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15449
15210
|
});
|
|
15450
15211
|
return data;
|
|
15451
15212
|
} catch (error) {
|
|
@@ -15456,12 +15217,12 @@ function usePersonRepo() {
|
|
|
15456
15217
|
}
|
|
15457
15218
|
async function getCompany(search) {
|
|
15458
15219
|
try {
|
|
15459
|
-
const cacheKey =
|
|
15220
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15460
15221
|
company: search
|
|
15461
15222
|
});
|
|
15462
15223
|
const cachedData = await getCache(cacheKey);
|
|
15463
15224
|
if (cachedData) {
|
|
15464
|
-
|
|
15225
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15465
15226
|
return cachedData;
|
|
15466
15227
|
}
|
|
15467
15228
|
const baseQuery = {
|
|
@@ -15505,9 +15266,9 @@ function usePersonRepo() {
|
|
|
15505
15266
|
]).toArray();
|
|
15506
15267
|
}
|
|
15507
15268
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15508
|
-
|
|
15269
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15509
15270
|
}).catch((err) => {
|
|
15510
|
-
|
|
15271
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15511
15272
|
});
|
|
15512
15273
|
return data;
|
|
15513
15274
|
} catch (error) {
|
|
@@ -15515,14 +15276,14 @@ function usePersonRepo() {
|
|
|
15515
15276
|
}
|
|
15516
15277
|
}
|
|
15517
15278
|
async function getPeopleByPlateNumber(plateNumber) {
|
|
15518
|
-
const cacheKey =
|
|
15279
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15519
15280
|
plateNumber,
|
|
15520
15281
|
key: "get-people-plate-number"
|
|
15521
15282
|
});
|
|
15522
15283
|
try {
|
|
15523
15284
|
const cacheData = await getCache(cacheKey);
|
|
15524
15285
|
if (cacheData) {
|
|
15525
|
-
|
|
15286
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15526
15287
|
return cacheData;
|
|
15527
15288
|
}
|
|
15528
15289
|
const data = await collection.find(
|
|
@@ -15530,9 +15291,9 @@ function usePersonRepo() {
|
|
|
15530
15291
|
{ sort: { _id: -1 } }
|
|
15531
15292
|
).toArray();
|
|
15532
15293
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15533
|
-
|
|
15294
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15534
15295
|
}).catch((err) => {
|
|
15535
|
-
|
|
15296
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15536
15297
|
});
|
|
15537
15298
|
return data;
|
|
15538
15299
|
} catch (error) {
|
|
@@ -15551,7 +15312,7 @@ function usePersonRepo() {
|
|
|
15551
15312
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
15552
15313
|
const query = {
|
|
15553
15314
|
...nric && { nric: normalizedNric },
|
|
15554
|
-
site: typeof site === "string" ? new
|
|
15315
|
+
site: typeof site === "string" ? new ObjectId43(site) : site
|
|
15555
15316
|
};
|
|
15556
15317
|
const cacheOptions = {
|
|
15557
15318
|
site,
|
|
@@ -15561,22 +15322,22 @@ function usePersonRepo() {
|
|
|
15561
15322
|
sort: JSON.stringify(sort)
|
|
15562
15323
|
};
|
|
15563
15324
|
try {
|
|
15564
|
-
const cacheKey =
|
|
15325
|
+
const cacheKey = makeCacheKey23(
|
|
15565
15326
|
site_people_namespace_collection,
|
|
15566
15327
|
cacheOptions
|
|
15567
15328
|
);
|
|
15568
15329
|
const cachedData = await getCache(cacheKey);
|
|
15569
15330
|
if (cachedData) {
|
|
15570
|
-
|
|
15331
|
+
logger50.info(`Cache hit for key: ${cacheKey}`);
|
|
15571
15332
|
return cachedData;
|
|
15572
15333
|
}
|
|
15573
15334
|
const items = await collection.find(query).sort(sort).skip(page * limit).limit(limit).toArray();
|
|
15574
15335
|
const length = await collection.countDocuments(query);
|
|
15575
|
-
const data =
|
|
15336
|
+
const data = paginate19(items, page, limit, length);
|
|
15576
15337
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
15577
|
-
|
|
15338
|
+
logger50.info(`Cache set for key: ${cacheKey}`);
|
|
15578
15339
|
}).catch((err) => {
|
|
15579
|
-
|
|
15340
|
+
logger50.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
15580
15341
|
});
|
|
15581
15342
|
return data;
|
|
15582
15343
|
} catch (error) {
|
|
@@ -15586,7 +15347,7 @@ function usePersonRepo() {
|
|
|
15586
15347
|
async function pushVehicleById(id, plate, session) {
|
|
15587
15348
|
const { plateNumber, recNo } = plate;
|
|
15588
15349
|
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15589
|
-
const _id =
|
|
15350
|
+
const _id = toObjectId9(id);
|
|
15590
15351
|
try {
|
|
15591
15352
|
const updateExisting = await collection.updateOne(
|
|
15592
15353
|
{
|
|
@@ -15644,14 +15405,14 @@ function usePersonRepo() {
|
|
|
15644
15405
|
}
|
|
15645
15406
|
}
|
|
15646
15407
|
async function getByUserId(userId) {
|
|
15647
|
-
const user =
|
|
15648
|
-
const cacheKey =
|
|
15408
|
+
const user = toObjectId9(userId);
|
|
15409
|
+
const cacheKey = makeCacheKey23(site_people_namespace_collection, {
|
|
15649
15410
|
user: userId
|
|
15650
15411
|
});
|
|
15651
15412
|
try {
|
|
15652
15413
|
const cached = await getCache(cacheKey);
|
|
15653
15414
|
if (cached) {
|
|
15654
|
-
|
|
15415
|
+
logger50.log({
|
|
15655
15416
|
level: "info",
|
|
15656
15417
|
message: `Cache hit for getByUserId person: ${cacheKey}`
|
|
15657
15418
|
});
|
|
@@ -15661,19 +15422,19 @@ function usePersonRepo() {
|
|
|
15661
15422
|
user
|
|
15662
15423
|
});
|
|
15663
15424
|
setCache(cacheKey, result, 15 * 60).then(() => {
|
|
15664
|
-
|
|
15425
|
+
logger50.log({
|
|
15665
15426
|
level: "info",
|
|
15666
15427
|
message: `Cache set for person by user: ${cacheKey}`
|
|
15667
15428
|
});
|
|
15668
15429
|
}).catch((err) => {
|
|
15669
|
-
|
|
15430
|
+
logger50.log({
|
|
15670
15431
|
level: "error",
|
|
15671
15432
|
message: `Failed to set cache for person by user: ${err.message}`
|
|
15672
15433
|
});
|
|
15673
15434
|
});
|
|
15674
15435
|
return result;
|
|
15675
15436
|
} catch (error) {
|
|
15676
|
-
if (error instanceof
|
|
15437
|
+
if (error instanceof AppError9) {
|
|
15677
15438
|
throw error;
|
|
15678
15439
|
} else {
|
|
15679
15440
|
throw new InternalServerError26("Failed to get person by user.");
|
|
@@ -15683,9 +15444,9 @@ function usePersonRepo() {
|
|
|
15683
15444
|
async function reviewResidentPerson(_id, value, session) {
|
|
15684
15445
|
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
15685
15446
|
try {
|
|
15686
|
-
_id = new
|
|
15447
|
+
_id = new ObjectId43(_id);
|
|
15687
15448
|
} catch (error) {
|
|
15688
|
-
throw new
|
|
15449
|
+
throw new BadRequestError69("Invalid ID format.");
|
|
15689
15450
|
}
|
|
15690
15451
|
try {
|
|
15691
15452
|
const res = await collection.updateOne(
|
|
@@ -15697,11 +15458,11 @@ function usePersonRepo() {
|
|
|
15697
15458
|
throw new InternalServerError26(`Unable to ${value.status} person.`);
|
|
15698
15459
|
}
|
|
15699
15460
|
delNamespace().then(() => {
|
|
15700
|
-
|
|
15461
|
+
logger50.info(
|
|
15701
15462
|
`Cache cleared for namespace: ${site_people_namespace_collection}`
|
|
15702
15463
|
);
|
|
15703
15464
|
}).catch((err) => {
|
|
15704
|
-
|
|
15465
|
+
logger50.error(
|
|
15705
15466
|
`Failed to clear cache for namespace: ${site_people_namespace_collection}`,
|
|
15706
15467
|
err
|
|
15707
15468
|
);
|
|
@@ -15734,25 +15495,25 @@ function usePersonRepo() {
|
|
|
15734
15495
|
}
|
|
15735
15496
|
|
|
15736
15497
|
// src/services/vehicle.service.ts
|
|
15737
|
-
import { ObjectId as
|
|
15498
|
+
import { ObjectId as ObjectId46 } from "mongodb";
|
|
15738
15499
|
|
|
15739
15500
|
// src/repositories/building-unit.repository.ts
|
|
15740
15501
|
import {
|
|
15741
|
-
AppError as
|
|
15742
|
-
BadRequestError as
|
|
15502
|
+
AppError as AppError10,
|
|
15503
|
+
BadRequestError as BadRequestError71,
|
|
15743
15504
|
InternalServerError as InternalServerError27,
|
|
15744
|
-
logger as
|
|
15745
|
-
makeCacheKey as
|
|
15746
|
-
paginate as
|
|
15747
|
-
toObjectId as
|
|
15748
|
-
useAtlas as
|
|
15749
|
-
useCache as
|
|
15505
|
+
logger as logger52,
|
|
15506
|
+
makeCacheKey as makeCacheKey24,
|
|
15507
|
+
paginate as paginate20,
|
|
15508
|
+
toObjectId as toObjectId10,
|
|
15509
|
+
useAtlas as useAtlas33,
|
|
15510
|
+
useCache as useCache25
|
|
15750
15511
|
} from "@7365admin1/node-server-utils";
|
|
15751
15512
|
|
|
15752
15513
|
// src/models/building.model.ts
|
|
15753
|
-
import { BadRequestError as
|
|
15514
|
+
import { BadRequestError as BadRequestError70, logger as logger51 } from "@7365admin1/node-server-utils";
|
|
15754
15515
|
import Joi39 from "joi";
|
|
15755
|
-
import { ObjectId as
|
|
15516
|
+
import { ObjectId as ObjectId44 } from "mongodb";
|
|
15756
15517
|
var SortFields = /* @__PURE__ */ ((SortFields2) => {
|
|
15757
15518
|
SortFields2["ID"] = "_id";
|
|
15758
15519
|
SortFields2["CREATED_AT"] = "createdAt";
|
|
@@ -15841,20 +15602,20 @@ var schemaUpdateOptions = Joi39.object({
|
|
|
15841
15602
|
function MBuilding(value) {
|
|
15842
15603
|
const { error } = schemaBuilding.validate(value);
|
|
15843
15604
|
if (error) {
|
|
15844
|
-
|
|
15845
|
-
throw new
|
|
15605
|
+
logger51.info(`Building Model: ${error.message}`);
|
|
15606
|
+
throw new BadRequestError70(error.message);
|
|
15846
15607
|
}
|
|
15847
15608
|
if (value._id && typeof value._id === "string") {
|
|
15848
15609
|
try {
|
|
15849
|
-
value._id = new
|
|
15610
|
+
value._id = new ObjectId44(value._id);
|
|
15850
15611
|
} catch (error2) {
|
|
15851
|
-
throw new
|
|
15612
|
+
throw new BadRequestError70("Invalid _id format");
|
|
15852
15613
|
}
|
|
15853
15614
|
}
|
|
15854
15615
|
try {
|
|
15855
|
-
value.site = new
|
|
15616
|
+
value.site = new ObjectId44(value.site);
|
|
15856
15617
|
} catch (error2) {
|
|
15857
|
-
throw new
|
|
15618
|
+
throw new BadRequestError70("Invalid site format");
|
|
15858
15619
|
}
|
|
15859
15620
|
return {
|
|
15860
15621
|
_id: value._id ?? void 0,
|
|
@@ -15873,40 +15634,40 @@ function MBuilding(value) {
|
|
|
15873
15634
|
function MBuildingUnit(value) {
|
|
15874
15635
|
const { error } = schemaBuildingUnit.validate(value);
|
|
15875
15636
|
if (error) {
|
|
15876
|
-
|
|
15877
|
-
throw new
|
|
15637
|
+
logger51.info(`Building Unit Model: ${error.message}`);
|
|
15638
|
+
throw new BadRequestError70(error.message);
|
|
15878
15639
|
}
|
|
15879
15640
|
if (value._id && typeof value._id === "string") {
|
|
15880
15641
|
try {
|
|
15881
|
-
value._id = new
|
|
15642
|
+
value._id = new ObjectId44(value._id);
|
|
15882
15643
|
} catch (error2) {
|
|
15883
|
-
throw new
|
|
15644
|
+
throw new BadRequestError70("Invalid ID");
|
|
15884
15645
|
}
|
|
15885
15646
|
}
|
|
15886
15647
|
try {
|
|
15887
|
-
value.site = new
|
|
15648
|
+
value.site = new ObjectId44(value.site);
|
|
15888
15649
|
} catch (error2) {
|
|
15889
|
-
throw new
|
|
15650
|
+
throw new BadRequestError70("Invalid site ID");
|
|
15890
15651
|
}
|
|
15891
15652
|
try {
|
|
15892
|
-
value.building = new
|
|
15653
|
+
value.building = new ObjectId44(value.building);
|
|
15893
15654
|
} catch (error2) {
|
|
15894
|
-
throw new
|
|
15655
|
+
throw new BadRequestError70("Invalid building ID");
|
|
15895
15656
|
}
|
|
15896
15657
|
if (value.owner && typeof value.owner === "string") {
|
|
15897
15658
|
try {
|
|
15898
|
-
value.owner = new
|
|
15659
|
+
value.owner = new ObjectId44(value.owner);
|
|
15899
15660
|
} catch (error2) {
|
|
15900
|
-
throw new
|
|
15661
|
+
throw new BadRequestError70("Invalid Owner ID");
|
|
15901
15662
|
}
|
|
15902
15663
|
}
|
|
15903
15664
|
if (value.billing && Array.isArray(value.billing)) {
|
|
15904
15665
|
value.billing = value.billing.map((billing) => {
|
|
15905
15666
|
if (billing._id && typeof billing._id === "string") {
|
|
15906
15667
|
try {
|
|
15907
|
-
billing._id = new
|
|
15668
|
+
billing._id = new ObjectId44(billing._id);
|
|
15908
15669
|
} catch {
|
|
15909
|
-
throw new
|
|
15670
|
+
throw new BadRequestError70("Invalid billing id format");
|
|
15910
15671
|
}
|
|
15911
15672
|
}
|
|
15912
15673
|
return billing;
|
|
@@ -15938,15 +15699,15 @@ function MBuildingUnit(value) {
|
|
|
15938
15699
|
}
|
|
15939
15700
|
|
|
15940
15701
|
// src/repositories/building-unit.repository.ts
|
|
15941
|
-
import { ObjectId as
|
|
15702
|
+
import { ObjectId as ObjectId45 } from "mongodb";
|
|
15942
15703
|
function useBuildingUnitRepo() {
|
|
15943
|
-
const db =
|
|
15704
|
+
const db = useAtlas33.getDb();
|
|
15944
15705
|
if (!db) {
|
|
15945
15706
|
throw new Error("Unable to connect to server.");
|
|
15946
15707
|
}
|
|
15947
15708
|
const namespace_collection = "building-units";
|
|
15948
15709
|
const collection = db.collection(namespace_collection);
|
|
15949
|
-
const { getCache, setCache, delNamespace, delCache } =
|
|
15710
|
+
const { getCache, setCache, delNamespace, delCache } = useCache25(namespace_collection);
|
|
15950
15711
|
async function createIndexes() {
|
|
15951
15712
|
try {
|
|
15952
15713
|
await collection.createIndexes([
|
|
@@ -15970,12 +15731,12 @@ function useBuildingUnitRepo() {
|
|
|
15970
15731
|
}
|
|
15971
15732
|
function delCachedData() {
|
|
15972
15733
|
delNamespace().then(() => {
|
|
15973
|
-
|
|
15734
|
+
logger52.log({
|
|
15974
15735
|
level: "info",
|
|
15975
15736
|
message: `Cache namespace cleared for ${namespace_collection}`
|
|
15976
15737
|
});
|
|
15977
15738
|
}).catch((err) => {
|
|
15978
|
-
|
|
15739
|
+
logger52.log({
|
|
15979
15740
|
level: "error",
|
|
15980
15741
|
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
15981
15742
|
});
|
|
@@ -16000,15 +15761,15 @@ function useBuildingUnitRepo() {
|
|
|
16000
15761
|
delCachedData();
|
|
16001
15762
|
return res.insertedId;
|
|
16002
15763
|
} catch (error) {
|
|
16003
|
-
|
|
15764
|
+
logger52.log({
|
|
16004
15765
|
level: "error",
|
|
16005
15766
|
message: error.message
|
|
16006
15767
|
});
|
|
16007
15768
|
const isDuplicated = error.message.includes("duplicate");
|
|
16008
15769
|
if (isDuplicated) {
|
|
16009
|
-
throw new
|
|
15770
|
+
throw new BadRequestError71("Building unit already exists.");
|
|
16010
15771
|
}
|
|
16011
|
-
if (error instanceof
|
|
15772
|
+
if (error instanceof AppError10) {
|
|
16012
15773
|
throw error;
|
|
16013
15774
|
} else {
|
|
16014
15775
|
throw new Error("Failed to create building unit.");
|
|
@@ -16018,27 +15779,27 @@ function useBuildingUnitRepo() {
|
|
|
16018
15779
|
async function updateById(_id, value, session) {
|
|
16019
15780
|
const { error } = schemaUpdateOptions.validate(value);
|
|
16020
15781
|
if (error) {
|
|
16021
|
-
throw new
|
|
15782
|
+
throw new BadRequestError71(error.message);
|
|
16022
15783
|
}
|
|
16023
15784
|
try {
|
|
16024
|
-
_id = new
|
|
15785
|
+
_id = new ObjectId45(_id);
|
|
16025
15786
|
} catch (error2) {
|
|
16026
|
-
throw new
|
|
15787
|
+
throw new BadRequestError71("Invalid ID.");
|
|
16027
15788
|
}
|
|
16028
15789
|
if (value.billing && Array.isArray(value.billing)) {
|
|
16029
15790
|
value.billing = value.billing.map((billing) => {
|
|
16030
15791
|
if (billing._id && typeof billing._id === "string") {
|
|
16031
15792
|
try {
|
|
16032
|
-
billing._id = new
|
|
15793
|
+
billing._id = new ObjectId45(billing._id);
|
|
16033
15794
|
} catch {
|
|
16034
|
-
throw new
|
|
15795
|
+
throw new BadRequestError71("Invalid billing id format");
|
|
16035
15796
|
}
|
|
16036
15797
|
}
|
|
16037
15798
|
return billing;
|
|
16038
15799
|
});
|
|
16039
15800
|
}
|
|
16040
15801
|
if (value.owner) {
|
|
16041
|
-
value.owner = new
|
|
15802
|
+
value.owner = new ObjectId45(value.owner);
|
|
16042
15803
|
}
|
|
16043
15804
|
try {
|
|
16044
15805
|
const res = await collection.updateOne(
|
|
@@ -16049,15 +15810,15 @@ function useBuildingUnitRepo() {
|
|
|
16049
15810
|
delCachedData();
|
|
16050
15811
|
return res;
|
|
16051
15812
|
} catch (error2) {
|
|
16052
|
-
|
|
15813
|
+
logger52.log({
|
|
16053
15814
|
level: "error",
|
|
16054
15815
|
message: error2.message
|
|
16055
15816
|
});
|
|
16056
15817
|
const isDuplicated = error2.message.includes("duplicate");
|
|
16057
15818
|
if (isDuplicated) {
|
|
16058
|
-
throw new
|
|
15819
|
+
throw new BadRequestError71("Building unit already exists.");
|
|
16059
15820
|
}
|
|
16060
|
-
if (error2 instanceof
|
|
15821
|
+
if (error2 instanceof AppError10) {
|
|
16061
15822
|
throw error2;
|
|
16062
15823
|
} else {
|
|
16063
15824
|
throw new Error("Failed to create building unit.");
|
|
@@ -16067,12 +15828,12 @@ function useBuildingUnitRepo() {
|
|
|
16067
15828
|
async function updateByBuildingId(building, value, session) {
|
|
16068
15829
|
const { error } = schemaUpdateOptions.validate(value);
|
|
16069
15830
|
if (error) {
|
|
16070
|
-
throw new
|
|
15831
|
+
throw new BadRequestError71(error.message);
|
|
16071
15832
|
}
|
|
16072
15833
|
try {
|
|
16073
|
-
building = new
|
|
15834
|
+
building = new ObjectId45(building);
|
|
16074
15835
|
} catch (error2) {
|
|
16075
|
-
throw new
|
|
15836
|
+
throw new BadRequestError71("Invalid building ID.");
|
|
16076
15837
|
}
|
|
16077
15838
|
try {
|
|
16078
15839
|
const res = await collection.updateMany(
|
|
@@ -16083,15 +15844,15 @@ function useBuildingUnitRepo() {
|
|
|
16083
15844
|
delCachedData();
|
|
16084
15845
|
return res;
|
|
16085
15846
|
} catch (error2) {
|
|
16086
|
-
|
|
15847
|
+
logger52.log({
|
|
16087
15848
|
level: "error",
|
|
16088
15849
|
message: error2.message
|
|
16089
15850
|
});
|
|
16090
15851
|
const isDuplicated = error2.message.includes("duplicate");
|
|
16091
15852
|
if (isDuplicated) {
|
|
16092
|
-
throw new
|
|
15853
|
+
throw new BadRequestError71("Building unit already exists.");
|
|
16093
15854
|
}
|
|
16094
|
-
if (error2 instanceof
|
|
15855
|
+
if (error2 instanceof AppError10) {
|
|
16095
15856
|
throw error2;
|
|
16096
15857
|
} else {
|
|
16097
15858
|
throw new Error("Failed to create building unit.");
|
|
@@ -16111,8 +15872,8 @@ function useBuildingUnitRepo() {
|
|
|
16111
15872
|
const query = {
|
|
16112
15873
|
status,
|
|
16113
15874
|
...search && { $text: { $search: search } },
|
|
16114
|
-
...site && { site:
|
|
16115
|
-
...building && { building:
|
|
15875
|
+
...site && { site: toObjectId10(site) },
|
|
15876
|
+
...building && { building: toObjectId10(building) }
|
|
16116
15877
|
};
|
|
16117
15878
|
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
16118
15879
|
const cacheParams = {
|
|
@@ -16124,15 +15885,15 @@ function useBuildingUnitRepo() {
|
|
|
16124
15885
|
...building && { building },
|
|
16125
15886
|
...status && { status }
|
|
16126
15887
|
};
|
|
16127
|
-
const cacheKey =
|
|
16128
|
-
|
|
15888
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheParams);
|
|
15889
|
+
logger52.log({
|
|
16129
15890
|
level: "info",
|
|
16130
15891
|
message: `Cache key for getAll building units: ${cacheKey}`
|
|
16131
15892
|
});
|
|
16132
15893
|
try {
|
|
16133
15894
|
const cached = await getCache(cacheKey);
|
|
16134
15895
|
if (cached) {
|
|
16135
|
-
|
|
15896
|
+
logger52.log({
|
|
16136
15897
|
level: "info",
|
|
16137
15898
|
message: `Cache hit for getAll building units: ${cacheKey}`
|
|
16138
15899
|
});
|
|
@@ -16171,35 +15932,35 @@ function useBuildingUnitRepo() {
|
|
|
16171
15932
|
{ $limit: limit }
|
|
16172
15933
|
]).toArray();
|
|
16173
15934
|
const length = await collection.countDocuments(query);
|
|
16174
|
-
const data =
|
|
15935
|
+
const data = paginate20(items, page, limit, length);
|
|
16175
15936
|
setCache(cacheKey, data, 600).then(() => {
|
|
16176
|
-
|
|
15937
|
+
logger52.log({
|
|
16177
15938
|
level: "info",
|
|
16178
15939
|
message: `Cache set for getAll building units: ${cacheKey}`
|
|
16179
15940
|
});
|
|
16180
15941
|
}).catch((err) => {
|
|
16181
|
-
|
|
15942
|
+
logger52.log({
|
|
16182
15943
|
level: "error",
|
|
16183
15944
|
message: `Failed to set cache for getAll building units: ${err.message}`
|
|
16184
15945
|
});
|
|
16185
15946
|
});
|
|
16186
15947
|
return data;
|
|
16187
15948
|
} catch (error) {
|
|
16188
|
-
|
|
15949
|
+
logger52.log({ level: "error", message: `${error}` });
|
|
16189
15950
|
throw error;
|
|
16190
15951
|
}
|
|
16191
15952
|
}
|
|
16192
15953
|
async function getById(_id, session) {
|
|
16193
15954
|
try {
|
|
16194
|
-
_id = new
|
|
15955
|
+
_id = new ObjectId45(_id);
|
|
16195
15956
|
} catch (error) {
|
|
16196
|
-
throw new
|
|
15957
|
+
throw new BadRequestError71("Invalid ID.");
|
|
16197
15958
|
}
|
|
16198
|
-
const cacheKey =
|
|
15959
|
+
const cacheKey = makeCacheKey24(namespace_collection, { _id: String(_id) });
|
|
16199
15960
|
try {
|
|
16200
15961
|
const cached = await getCache(cacheKey);
|
|
16201
15962
|
if (cached) {
|
|
16202
|
-
|
|
15963
|
+
logger52.log({
|
|
16203
15964
|
level: "info",
|
|
16204
15965
|
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
16205
15966
|
});
|
|
@@ -16210,22 +15971,22 @@ function useBuildingUnitRepo() {
|
|
|
16210
15971
|
deletedAt: { $in: ["", null] }
|
|
16211
15972
|
});
|
|
16212
15973
|
if (!result) {
|
|
16213
|
-
throw new
|
|
15974
|
+
throw new BadRequestError71("Building unit not found.");
|
|
16214
15975
|
}
|
|
16215
15976
|
setCache(cacheKey, result, 300).then(() => {
|
|
16216
|
-
|
|
15977
|
+
logger52.log({
|
|
16217
15978
|
level: "info",
|
|
16218
15979
|
message: `Cache set for building unit by id: ${cacheKey}`
|
|
16219
15980
|
});
|
|
16220
15981
|
}).catch((err) => {
|
|
16221
|
-
|
|
15982
|
+
logger52.log({
|
|
16222
15983
|
level: "error",
|
|
16223
15984
|
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
16224
15985
|
});
|
|
16225
15986
|
});
|
|
16226
15987
|
return result;
|
|
16227
15988
|
} catch (error) {
|
|
16228
|
-
if (error instanceof
|
|
15989
|
+
if (error instanceof AppError10) {
|
|
16229
15990
|
throw error;
|
|
16230
15991
|
} else {
|
|
16231
15992
|
throw new InternalServerError27("Failed to get building unit.");
|
|
@@ -16234,18 +15995,18 @@ function useBuildingUnitRepo() {
|
|
|
16234
15995
|
}
|
|
16235
15996
|
async function getByBuildingLevel(building, level) {
|
|
16236
15997
|
try {
|
|
16237
|
-
building = new
|
|
15998
|
+
building = new ObjectId45(building);
|
|
16238
15999
|
} catch (error) {
|
|
16239
|
-
throw new
|
|
16000
|
+
throw new BadRequestError71("Invalid building ID.");
|
|
16240
16001
|
}
|
|
16241
|
-
const cacheKey =
|
|
16002
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
16242
16003
|
building: String(building),
|
|
16243
16004
|
level
|
|
16244
16005
|
});
|
|
16245
16006
|
try {
|
|
16246
16007
|
const cached = await getCache(cacheKey);
|
|
16247
16008
|
if (cached) {
|
|
16248
|
-
|
|
16009
|
+
logger52.log({
|
|
16249
16010
|
level: "info",
|
|
16250
16011
|
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
16251
16012
|
});
|
|
@@ -16257,19 +16018,19 @@ function useBuildingUnitRepo() {
|
|
|
16257
16018
|
status: "active"
|
|
16258
16019
|
});
|
|
16259
16020
|
setCache(cacheKey, result, 300).then(() => {
|
|
16260
|
-
|
|
16021
|
+
logger52.log({
|
|
16261
16022
|
level: "info",
|
|
16262
16023
|
message: `Cache set for building unit by id: ${cacheKey}`
|
|
16263
16024
|
});
|
|
16264
16025
|
}).catch((err) => {
|
|
16265
|
-
|
|
16026
|
+
logger52.log({
|
|
16266
16027
|
level: "error",
|
|
16267
16028
|
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
16268
16029
|
});
|
|
16269
16030
|
});
|
|
16270
16031
|
return result;
|
|
16271
16032
|
} catch (error) {
|
|
16272
|
-
if (error instanceof
|
|
16033
|
+
if (error instanceof AppError10) {
|
|
16273
16034
|
throw error;
|
|
16274
16035
|
} else {
|
|
16275
16036
|
throw new InternalServerError27("Failed to get building unit.");
|
|
@@ -16278,9 +16039,9 @@ function useBuildingUnitRepo() {
|
|
|
16278
16039
|
}
|
|
16279
16040
|
async function updateLevelByBuildingLevel(building, level, newLevel, session) {
|
|
16280
16041
|
try {
|
|
16281
|
-
building = new
|
|
16042
|
+
building = new ObjectId45(building);
|
|
16282
16043
|
} catch (error) {
|
|
16283
|
-
throw new
|
|
16044
|
+
throw new BadRequestError71("Invalid building ID.");
|
|
16284
16045
|
}
|
|
16285
16046
|
try {
|
|
16286
16047
|
const result = await collection.updateMany(
|
|
@@ -16299,7 +16060,7 @@ function useBuildingUnitRepo() {
|
|
|
16299
16060
|
delCachedData();
|
|
16300
16061
|
return result;
|
|
16301
16062
|
} catch (error) {
|
|
16302
|
-
if (error instanceof
|
|
16063
|
+
if (error instanceof AppError10) {
|
|
16303
16064
|
throw error;
|
|
16304
16065
|
} else {
|
|
16305
16066
|
throw new InternalServerError27("Failed to update building unit level.");
|
|
@@ -16308,17 +16069,17 @@ function useBuildingUnitRepo() {
|
|
|
16308
16069
|
}
|
|
16309
16070
|
async function getByBuilding(building) {
|
|
16310
16071
|
try {
|
|
16311
|
-
building = new
|
|
16072
|
+
building = new ObjectId45(building);
|
|
16312
16073
|
} catch (error) {
|
|
16313
|
-
throw new
|
|
16074
|
+
throw new BadRequestError71("Invalid building ID.");
|
|
16314
16075
|
}
|
|
16315
|
-
const cacheKey =
|
|
16076
|
+
const cacheKey = makeCacheKey24(namespace_collection, {
|
|
16316
16077
|
building: String(building)
|
|
16317
16078
|
});
|
|
16318
16079
|
try {
|
|
16319
16080
|
const cached = await getCache(cacheKey);
|
|
16320
16081
|
if (cached) {
|
|
16321
|
-
|
|
16082
|
+
logger52.log({
|
|
16322
16083
|
level: "info",
|
|
16323
16084
|
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
16324
16085
|
});
|
|
@@ -16329,19 +16090,19 @@ function useBuildingUnitRepo() {
|
|
|
16329
16090
|
status: "active"
|
|
16330
16091
|
});
|
|
16331
16092
|
setCache(cacheKey, result, 300).then(() => {
|
|
16332
|
-
|
|
16093
|
+
logger52.log({
|
|
16333
16094
|
level: "info",
|
|
16334
16095
|
message: `Cache set for building unit by id: ${cacheKey}`
|
|
16335
16096
|
});
|
|
16336
16097
|
}).catch((err) => {
|
|
16337
|
-
|
|
16098
|
+
logger52.log({
|
|
16338
16099
|
level: "error",
|
|
16339
16100
|
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
16340
16101
|
});
|
|
16341
16102
|
});
|
|
16342
16103
|
return result;
|
|
16343
16104
|
} catch (error) {
|
|
16344
|
-
if (error instanceof
|
|
16105
|
+
if (error instanceof AppError10) {
|
|
16345
16106
|
throw error;
|
|
16346
16107
|
} else {
|
|
16347
16108
|
throw new InternalServerError27("Failed to get building unit.");
|
|
@@ -16350,9 +16111,9 @@ function useBuildingUnitRepo() {
|
|
|
16350
16111
|
}
|
|
16351
16112
|
async function deleteById(_id, session) {
|
|
16352
16113
|
try {
|
|
16353
|
-
_id = new
|
|
16114
|
+
_id = new ObjectId45(_id);
|
|
16354
16115
|
} catch (error) {
|
|
16355
|
-
throw new
|
|
16116
|
+
throw new BadRequestError71("Invalid ID.");
|
|
16356
16117
|
}
|
|
16357
16118
|
try {
|
|
16358
16119
|
const res = await collection.updateOne(
|
|
@@ -16363,11 +16124,11 @@ function useBuildingUnitRepo() {
|
|
|
16363
16124
|
delCachedData();
|
|
16364
16125
|
return "Room/Facility deleted successfully.";
|
|
16365
16126
|
} catch (error) {
|
|
16366
|
-
|
|
16127
|
+
logger52.log({
|
|
16367
16128
|
level: "error",
|
|
16368
16129
|
message: error.message
|
|
16369
16130
|
});
|
|
16370
|
-
if (error instanceof
|
|
16131
|
+
if (error instanceof AppError10) {
|
|
16371
16132
|
throw error;
|
|
16372
16133
|
} else {
|
|
16373
16134
|
throw new Error("Failed to deleted room/facility.");
|
|
@@ -16376,9 +16137,9 @@ function useBuildingUnitRepo() {
|
|
|
16376
16137
|
}
|
|
16377
16138
|
async function getBuildingUnits(site, block, level) {
|
|
16378
16139
|
try {
|
|
16379
|
-
site = new
|
|
16140
|
+
site = new ObjectId45(site);
|
|
16380
16141
|
} catch (error) {
|
|
16381
|
-
throw new
|
|
16142
|
+
throw new BadRequestError71("Invalid site ID format.");
|
|
16382
16143
|
}
|
|
16383
16144
|
const query = { site, block, level };
|
|
16384
16145
|
const cacheOptions = {
|
|
@@ -16386,22 +16147,22 @@ function useBuildingUnitRepo() {
|
|
|
16386
16147
|
block,
|
|
16387
16148
|
level
|
|
16388
16149
|
};
|
|
16389
|
-
const cacheKey =
|
|
16150
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheOptions);
|
|
16390
16151
|
const cachedData = await getCache(cacheKey);
|
|
16391
16152
|
if (cachedData) {
|
|
16392
|
-
|
|
16153
|
+
logger52.info(`Cache hit for key: ${cacheKey}`);
|
|
16393
16154
|
return cachedData;
|
|
16394
16155
|
}
|
|
16395
16156
|
try {
|
|
16396
16157
|
const data = await collection.aggregate([{ $match: query }, { $project: { name: 1 } }]).toArray();
|
|
16397
16158
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16398
|
-
|
|
16159
|
+
logger52.info(`Cache set for key: ${cacheKey}`);
|
|
16399
16160
|
}).catch((err) => {
|
|
16400
|
-
|
|
16161
|
+
logger52.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16401
16162
|
});
|
|
16402
16163
|
return data;
|
|
16403
16164
|
} catch (error) {
|
|
16404
|
-
if (error instanceof
|
|
16165
|
+
if (error instanceof AppError10) {
|
|
16405
16166
|
throw error;
|
|
16406
16167
|
} else {
|
|
16407
16168
|
throw new InternalServerError27("Failed to get building units.");
|
|
@@ -16410,9 +16171,9 @@ function useBuildingUnitRepo() {
|
|
|
16410
16171
|
}
|
|
16411
16172
|
async function getBuildingUnitsWithOwner(site, unitIds) {
|
|
16412
16173
|
try {
|
|
16413
|
-
site = new
|
|
16174
|
+
site = new ObjectId45(site);
|
|
16414
16175
|
} catch (error) {
|
|
16415
|
-
throw new
|
|
16176
|
+
throw new BadRequestError71("Invalid site ID format.");
|
|
16416
16177
|
}
|
|
16417
16178
|
const query = {
|
|
16418
16179
|
site,
|
|
@@ -16424,22 +16185,22 @@ function useBuildingUnitRepo() {
|
|
|
16424
16185
|
const cacheOptions = {
|
|
16425
16186
|
site: site.toString()
|
|
16426
16187
|
};
|
|
16427
|
-
const cacheKey =
|
|
16188
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheOptions);
|
|
16428
16189
|
const cachedData = await getCache(cacheKey);
|
|
16429
16190
|
if (cachedData) {
|
|
16430
|
-
|
|
16191
|
+
logger52.info(`Cache hit for key: ${cacheKey}`);
|
|
16431
16192
|
return cachedData;
|
|
16432
16193
|
}
|
|
16433
16194
|
try {
|
|
16434
16195
|
const data = await collection.aggregate([{ $match: query }]).toArray();
|
|
16435
16196
|
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
16436
|
-
|
|
16197
|
+
logger52.info(`Cache set for key: ${cacheKey}`);
|
|
16437
16198
|
}).catch((err) => {
|
|
16438
|
-
|
|
16199
|
+
logger52.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
16439
16200
|
});
|
|
16440
16201
|
return data;
|
|
16441
16202
|
} catch (error) {
|
|
16442
|
-
if (error instanceof
|
|
16203
|
+
if (error instanceof AppError10) {
|
|
16443
16204
|
throw error;
|
|
16444
16205
|
} else {
|
|
16445
16206
|
throw new InternalServerError27(
|
|
@@ -16451,9 +16212,9 @@ function useBuildingUnitRepo() {
|
|
|
16451
16212
|
async function getUnitByBlockLevelUnitNumber(block, level, unitNumber, site, session) {
|
|
16452
16213
|
let _site;
|
|
16453
16214
|
try {
|
|
16454
|
-
_site = new
|
|
16215
|
+
_site = new ObjectId45(site);
|
|
16455
16216
|
} catch (error) {
|
|
16456
|
-
throw new
|
|
16217
|
+
throw new BadRequestError71("Invalid ID.");
|
|
16457
16218
|
}
|
|
16458
16219
|
const cacheOptions = {
|
|
16459
16220
|
block,
|
|
@@ -16472,11 +16233,11 @@ function useBuildingUnitRepo() {
|
|
|
16472
16233
|
{ deletedAt: "" }
|
|
16473
16234
|
]
|
|
16474
16235
|
};
|
|
16475
|
-
const cacheKey =
|
|
16236
|
+
const cacheKey = makeCacheKey24(namespace_collection, cacheOptions);
|
|
16476
16237
|
try {
|
|
16477
16238
|
const cached = await getCache(cacheKey);
|
|
16478
16239
|
if (cached) {
|
|
16479
|
-
|
|
16240
|
+
logger52.log({
|
|
16480
16241
|
level: "info",
|
|
16481
16242
|
message: `Cache hit for getById building unit: ${cacheKey}`
|
|
16482
16243
|
});
|
|
@@ -16486,22 +16247,22 @@ function useBuildingUnitRepo() {
|
|
|
16486
16247
|
session
|
|
16487
16248
|
});
|
|
16488
16249
|
if (!result) {
|
|
16489
|
-
throw new
|
|
16250
|
+
throw new BadRequestError71("Building unit not found.");
|
|
16490
16251
|
}
|
|
16491
16252
|
setCache(cacheKey, result, 300).then(() => {
|
|
16492
|
-
|
|
16253
|
+
logger52.log({
|
|
16493
16254
|
level: "info",
|
|
16494
16255
|
message: `Cache set for building unit by id: ${cacheKey}`
|
|
16495
16256
|
});
|
|
16496
16257
|
}).catch((err) => {
|
|
16497
|
-
|
|
16258
|
+
logger52.log({
|
|
16498
16259
|
level: "error",
|
|
16499
16260
|
message: `Failed to set cache for building unit by id: ${err.message}`
|
|
16500
16261
|
});
|
|
16501
16262
|
});
|
|
16502
16263
|
return result;
|
|
16503
16264
|
} catch (error) {
|
|
16504
|
-
if (error instanceof
|
|
16265
|
+
if (error instanceof AppError10) {
|
|
16505
16266
|
throw error;
|
|
16506
16267
|
} else {
|
|
16507
16268
|
throw new InternalServerError27("Failed to get building unit.");
|
|
@@ -16573,7 +16334,7 @@ function useVehicleService() {
|
|
|
16573
16334
|
async function add(value, session) {
|
|
16574
16335
|
const isExternalSession = !!session;
|
|
16575
16336
|
if (!session) {
|
|
16576
|
-
session = await
|
|
16337
|
+
session = await useAtlas34.getClient()?.startSession();
|
|
16577
16338
|
if (!session) {
|
|
16578
16339
|
throw new Error("Unable to start session for vehicle service.");
|
|
16579
16340
|
}
|
|
@@ -16584,11 +16345,11 @@ function useVehicleService() {
|
|
|
16584
16345
|
_getById(value.org)
|
|
16585
16346
|
]);
|
|
16586
16347
|
if (!org)
|
|
16587
|
-
throw new
|
|
16348
|
+
throw new BadRequestError72("Org not found");
|
|
16588
16349
|
if (existingPlateNumber)
|
|
16589
|
-
throw new
|
|
16350
|
+
throw new BadRequestError72("Vehicle plate number already exists");
|
|
16590
16351
|
if (!Object.values(OrgNature).includes(org.nature)) {
|
|
16591
|
-
throw new
|
|
16352
|
+
throw new BadRequestError72(
|
|
16592
16353
|
"This organization is not allowed to add vehicles."
|
|
16593
16354
|
);
|
|
16594
16355
|
}
|
|
@@ -16655,7 +16416,7 @@ function useVehicleService() {
|
|
|
16655
16416
|
page++;
|
|
16656
16417
|
} while (page <= pages);
|
|
16657
16418
|
if (!siteCameras.length) {
|
|
16658
|
-
throw new
|
|
16419
|
+
throw new BadRequestError72("No site cameras found.");
|
|
16659
16420
|
}
|
|
16660
16421
|
}
|
|
16661
16422
|
for (const plateNumber of plateNumbers) {
|
|
@@ -16691,7 +16452,7 @@ function useVehicleService() {
|
|
|
16691
16452
|
};
|
|
16692
16453
|
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
16693
16454
|
if (dahuaResponse?.statusCode !== 200) {
|
|
16694
|
-
throw new
|
|
16455
|
+
throw new BadRequestError72(
|
|
16695
16456
|
`Failed to add plate number to ANPR ${_type}`
|
|
16696
16457
|
);
|
|
16697
16458
|
}
|
|
@@ -16712,7 +16473,7 @@ function useVehicleService() {
|
|
|
16712
16473
|
};
|
|
16713
16474
|
const dahuaResponse = await _updatePlateNumber(dahuaPayload);
|
|
16714
16475
|
if (dahuaResponse?.statusCode !== 200) {
|
|
16715
|
-
throw new
|
|
16476
|
+
throw new BadRequestError72(
|
|
16716
16477
|
`Failed to update plate number to ANPR ${_type}`
|
|
16717
16478
|
);
|
|
16718
16479
|
}
|
|
@@ -16738,7 +16499,7 @@ function useVehicleService() {
|
|
|
16738
16499
|
}
|
|
16739
16500
|
return message;
|
|
16740
16501
|
} catch (error) {
|
|
16741
|
-
|
|
16502
|
+
logger53.error("Error in vehicle service add:", error);
|
|
16742
16503
|
if (!isExternalSession) {
|
|
16743
16504
|
await session.abortTransaction();
|
|
16744
16505
|
}
|
|
@@ -16750,7 +16511,7 @@ function useVehicleService() {
|
|
|
16750
16511
|
}
|
|
16751
16512
|
}
|
|
16752
16513
|
async function deleteVehicle(_id, recno, site, type, bypass = false) {
|
|
16753
|
-
const session =
|
|
16514
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
16754
16515
|
if (!session) {
|
|
16755
16516
|
throw new Error("Unable to start session for vehicle service.");
|
|
16756
16517
|
}
|
|
@@ -16773,7 +16534,7 @@ function useVehicleService() {
|
|
|
16773
16534
|
page++;
|
|
16774
16535
|
} while (page < pages);
|
|
16775
16536
|
if (!siteCameras.length) {
|
|
16776
|
-
throw new
|
|
16537
|
+
throw new BadRequestError72("No site cameras found.");
|
|
16777
16538
|
}
|
|
16778
16539
|
for (const camera of siteCameras) {
|
|
16779
16540
|
const host = camera.host;
|
|
@@ -16788,7 +16549,7 @@ function useVehicleService() {
|
|
|
16788
16549
|
};
|
|
16789
16550
|
const dahuaResponse = await _removePlateNumber(dahuaPayload);
|
|
16790
16551
|
if (!bypass && dahuaResponse?.statusCode !== 200) {
|
|
16791
|
-
throw new
|
|
16552
|
+
throw new BadRequestError72(
|
|
16792
16553
|
`Failed to remove plate number to ANPR from ${type}`
|
|
16793
16554
|
);
|
|
16794
16555
|
}
|
|
@@ -16800,7 +16561,7 @@ function useVehicleService() {
|
|
|
16800
16561
|
await session.commitTransaction();
|
|
16801
16562
|
return `Vehicle plate number deleted from ${type} record successfully.`;
|
|
16802
16563
|
} catch (error) {
|
|
16803
|
-
|
|
16564
|
+
logger53.error("Error in vehicle service delete:", error);
|
|
16804
16565
|
await session.abortTransaction();
|
|
16805
16566
|
throw error;
|
|
16806
16567
|
} finally {
|
|
@@ -16808,16 +16569,16 @@ function useVehicleService() {
|
|
|
16808
16569
|
}
|
|
16809
16570
|
}
|
|
16810
16571
|
async function approveVehicleById(id, orgId, siteId) {
|
|
16811
|
-
const session =
|
|
16572
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
16812
16573
|
if (!session) {
|
|
16813
16574
|
throw new Error("Unable to start session for vehicle service.");
|
|
16814
16575
|
}
|
|
16815
16576
|
const org = await _getById(orgId);
|
|
16816
16577
|
if (!org)
|
|
16817
|
-
throw new
|
|
16578
|
+
throw new BadRequestError72("Org not found");
|
|
16818
16579
|
const allowedNatures2 = "property_management_agency" /* PROPERTY_MANAGEMENT_AGENCY */;
|
|
16819
16580
|
if (!allowedNatures2.includes(org.nature)) {
|
|
16820
|
-
throw new
|
|
16581
|
+
throw new BadRequestError72(
|
|
16821
16582
|
"Only property management can approve vehicles."
|
|
16822
16583
|
);
|
|
16823
16584
|
}
|
|
@@ -16825,7 +16586,7 @@ function useVehicleService() {
|
|
|
16825
16586
|
const plate = vehicle.plates.find((p) => p._id.toString() === id);
|
|
16826
16587
|
const _plateNumber = plate?.plateNumber;
|
|
16827
16588
|
if (!vehicle) {
|
|
16828
|
-
throw new
|
|
16589
|
+
throw new BadRequestError72("Vehicle not found");
|
|
16829
16590
|
}
|
|
16830
16591
|
const owner = vehicle.name;
|
|
16831
16592
|
const hasStart = typeof vehicle.start === "string" ? vehicle.start.trim() !== "" : !!vehicle.start;
|
|
@@ -16867,7 +16628,7 @@ function useVehicleService() {
|
|
|
16867
16628
|
page++;
|
|
16868
16629
|
} while (page < pages);
|
|
16869
16630
|
if (!siteCameras.length) {
|
|
16870
|
-
throw new
|
|
16631
|
+
throw new BadRequestError72("No site cameras found.");
|
|
16871
16632
|
}
|
|
16872
16633
|
for (const camera of siteCameras) {
|
|
16873
16634
|
const { host, username, password } = camera;
|
|
@@ -16883,7 +16644,7 @@ function useVehicleService() {
|
|
|
16883
16644
|
};
|
|
16884
16645
|
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
16885
16646
|
if (dahuaResponse?.statusCode !== 200) {
|
|
16886
|
-
throw new
|
|
16647
|
+
throw new BadRequestError72("Failed to add plate number to ANPR");
|
|
16887
16648
|
}
|
|
16888
16649
|
const responseData = dahuaResponse?.data.toString("utf-8");
|
|
16889
16650
|
value.recNo = responseData.split("=")[1]?.trim();
|
|
@@ -16908,7 +16669,7 @@ function useVehicleService() {
|
|
|
16908
16669
|
await session.commitTransaction();
|
|
16909
16670
|
return "Vehicle plate number approved and added successfully.";
|
|
16910
16671
|
} catch (error) {
|
|
16911
|
-
|
|
16672
|
+
logger53.error("Error in vehicle service approving and adding:", error);
|
|
16912
16673
|
await session.abortTransaction();
|
|
16913
16674
|
throw error;
|
|
16914
16675
|
} finally {
|
|
@@ -16916,7 +16677,7 @@ function useVehicleService() {
|
|
|
16916
16677
|
}
|
|
16917
16678
|
}
|
|
16918
16679
|
async function processDeletingExpiredVehicles() {
|
|
16919
|
-
const session =
|
|
16680
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
16920
16681
|
if (!session) {
|
|
16921
16682
|
throw new Error("Unable to start session for vehicle service.");
|
|
16922
16683
|
}
|
|
@@ -16943,7 +16704,7 @@ function useVehicleService() {
|
|
|
16943
16704
|
page++;
|
|
16944
16705
|
} while (page < pages);
|
|
16945
16706
|
if (!siteCameras.length) {
|
|
16946
|
-
throw new
|
|
16707
|
+
throw new BadRequestError72("No site cameras found.");
|
|
16947
16708
|
}
|
|
16948
16709
|
for (const camera of siteCameras) {
|
|
16949
16710
|
const host = camera.host;
|
|
@@ -16963,7 +16724,7 @@ function useVehicleService() {
|
|
|
16963
16724
|
await session.commitTransaction();
|
|
16964
16725
|
return `Expired Vehicle plate numbers deleted successfully.`;
|
|
16965
16726
|
} catch (error) {
|
|
16966
|
-
|
|
16727
|
+
logger53.error(
|
|
16967
16728
|
"Error in vehicle service process deleting expired vehicles:",
|
|
16968
16729
|
error
|
|
16969
16730
|
);
|
|
@@ -16974,16 +16735,16 @@ function useVehicleService() {
|
|
|
16974
16735
|
}
|
|
16975
16736
|
}
|
|
16976
16737
|
async function reactivateVehicleById(id, orgId, siteId) {
|
|
16977
|
-
const session =
|
|
16738
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
16978
16739
|
if (!session) {
|
|
16979
16740
|
throw new Error("Unable to start session for vehicle service.");
|
|
16980
16741
|
}
|
|
16981
16742
|
const org = await _getById(orgId);
|
|
16982
16743
|
if (!org)
|
|
16983
|
-
throw new
|
|
16744
|
+
throw new BadRequestError72("Org not found");
|
|
16984
16745
|
const allowedNatures2 = "property_management_agency" /* PROPERTY_MANAGEMENT_AGENCY */;
|
|
16985
16746
|
if (!allowedNatures2.includes(org.nature)) {
|
|
16986
|
-
throw new
|
|
16747
|
+
throw new BadRequestError72(
|
|
16987
16748
|
"Only property management can reactivate vehicles."
|
|
16988
16749
|
);
|
|
16989
16750
|
}
|
|
@@ -16991,7 +16752,7 @@ function useVehicleService() {
|
|
|
16991
16752
|
const plate = vehicle.plates.find((p) => p._id.toString() === id);
|
|
16992
16753
|
const _plateNumber = plate?.plateNumber;
|
|
16993
16754
|
if (!vehicle) {
|
|
16994
|
-
throw new
|
|
16755
|
+
throw new BadRequestError72("Vehicle not found");
|
|
16995
16756
|
}
|
|
16996
16757
|
const owner = vehicle.name;
|
|
16997
16758
|
let startDate = /* @__PURE__ */ new Date();
|
|
@@ -17021,7 +16782,7 @@ function useVehicleService() {
|
|
|
17021
16782
|
page++;
|
|
17022
16783
|
} while (page < pages);
|
|
17023
16784
|
if (!siteCameras.length) {
|
|
17024
|
-
throw new
|
|
16785
|
+
throw new BadRequestError72("No site cameras found.");
|
|
17025
16786
|
}
|
|
17026
16787
|
for (const camera of siteCameras) {
|
|
17027
16788
|
const { host, username, password } = camera;
|
|
@@ -17037,7 +16798,7 @@ function useVehicleService() {
|
|
|
17037
16798
|
};
|
|
17038
16799
|
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
17039
16800
|
if (dahuaResponse?.statusCode !== 200) {
|
|
17040
|
-
throw new
|
|
16801
|
+
throw new BadRequestError72("Failed to add plate number to ANPR");
|
|
17041
16802
|
}
|
|
17042
16803
|
const responseData = dahuaResponse?.data.toString("utf-8");
|
|
17043
16804
|
value.recNo = responseData.split("=")[1]?.trim();
|
|
@@ -17063,7 +16824,7 @@ function useVehicleService() {
|
|
|
17063
16824
|
await session.commitTransaction();
|
|
17064
16825
|
return "Vehicle reactivated successfully.";
|
|
17065
16826
|
} catch (error) {
|
|
17066
|
-
|
|
16827
|
+
logger53.error("Error in vehicle service reactivation:", error);
|
|
17067
16828
|
await session.abortTransaction();
|
|
17068
16829
|
throw error;
|
|
17069
16830
|
} finally {
|
|
@@ -17071,7 +16832,7 @@ function useVehicleService() {
|
|
|
17071
16832
|
}
|
|
17072
16833
|
}
|
|
17073
16834
|
async function updateVehicleById(_id, value) {
|
|
17074
|
-
const session =
|
|
16835
|
+
const session = useAtlas34.getClient()?.startSession();
|
|
17075
16836
|
if (!session) {
|
|
17076
16837
|
throw new Error("Unable to start session for vehicle service.");
|
|
17077
16838
|
}
|
|
@@ -17106,7 +16867,7 @@ function useVehicleService() {
|
|
|
17106
16867
|
page++;
|
|
17107
16868
|
} while (page < pages);
|
|
17108
16869
|
if (!siteCameras.length) {
|
|
17109
|
-
throw new
|
|
16870
|
+
throw new BadRequestError72("No site cameras found.");
|
|
17110
16871
|
}
|
|
17111
16872
|
for (const camera of siteCameras) {
|
|
17112
16873
|
const { host, username, password } = camera;
|
|
@@ -17123,7 +16884,7 @@ function useVehicleService() {
|
|
|
17123
16884
|
removePlateNumber
|
|
17124
16885
|
);
|
|
17125
16886
|
if (responseForDeletion?.statusCode !== 200) {
|
|
17126
|
-
throw new
|
|
16887
|
+
throw new BadRequestError72(
|
|
17127
16888
|
"Failed to delete plate number to ANPR"
|
|
17128
16889
|
);
|
|
17129
16890
|
}
|
|
@@ -17140,7 +16901,7 @@ function useVehicleService() {
|
|
|
17140
16901
|
};
|
|
17141
16902
|
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
17142
16903
|
if (dahuaResponse?.statusCode !== 200) {
|
|
17143
|
-
throw new
|
|
16904
|
+
throw new BadRequestError72(
|
|
17144
16905
|
"Failed to update plate number to ANPR"
|
|
17145
16906
|
);
|
|
17146
16907
|
}
|
|
@@ -17160,7 +16921,7 @@ function useVehicleService() {
|
|
|
17160
16921
|
};
|
|
17161
16922
|
const dahuaResponse = await _updatePlateNumber(dahuaPayload);
|
|
17162
16923
|
if (dahuaResponse?.statusCode !== 200) {
|
|
17163
|
-
throw new
|
|
16924
|
+
throw new BadRequestError72(
|
|
17164
16925
|
"Failed to update plate number to ANPR"
|
|
17165
16926
|
);
|
|
17166
16927
|
}
|
|
@@ -17174,7 +16935,7 @@ function useVehicleService() {
|
|
|
17174
16935
|
...start && { start },
|
|
17175
16936
|
...end && { end },
|
|
17176
16937
|
...unit && {
|
|
17177
|
-
unit: typeof unit === "string" ? new
|
|
16938
|
+
unit: typeof unit === "string" ? new ObjectId46(unit) : unit
|
|
17178
16939
|
},
|
|
17179
16940
|
...value.recNo && { recNo: value.recNo },
|
|
17180
16941
|
...type && { type: value.type }
|
|
@@ -17182,7 +16943,7 @@ function useVehicleService() {
|
|
|
17182
16943
|
await _updateVehicleById(_id, formattedValue, session);
|
|
17183
16944
|
await session.commitTransaction();
|
|
17184
16945
|
} catch (error) {
|
|
17185
|
-
|
|
16946
|
+
logger53.error("Error in vehicle service update:", error);
|
|
17186
16947
|
await session.abortTransaction();
|
|
17187
16948
|
throw error;
|
|
17188
16949
|
} finally {
|
|
@@ -17204,7 +16965,7 @@ function useVehicleService() {
|
|
|
17204
16965
|
item.unit,
|
|
17205
16966
|
site
|
|
17206
16967
|
);
|
|
17207
|
-
const unitId = unit && unit._id &&
|
|
16968
|
+
const unitId = unit && unit._id && ObjectId46.isValid(unit._id) ? unit._id.toString() : unit?._id;
|
|
17208
16969
|
return {
|
|
17209
16970
|
...item,
|
|
17210
16971
|
org,
|
|
@@ -17317,6 +17078,7 @@ var loggerDahua = winston.createLogger({
|
|
|
17317
17078
|
});
|
|
17318
17079
|
|
|
17319
17080
|
// src/services/dahua.service.ts
|
|
17081
|
+
var cameraRegistry = /* @__PURE__ */ new Map();
|
|
17320
17082
|
function useDahuaDigest({
|
|
17321
17083
|
host = "",
|
|
17322
17084
|
username = "",
|
|
@@ -17665,7 +17427,33 @@ function useDahuaService() {
|
|
|
17665
17427
|
throw error;
|
|
17666
17428
|
}
|
|
17667
17429
|
}
|
|
17668
|
-
async function
|
|
17430
|
+
async function listenToCamera(camera) {
|
|
17431
|
+
if (!camera?._id) {
|
|
17432
|
+
loggerDahua.error(`Camera _id is required to listen to camera.`);
|
|
17433
|
+
throw new BadRequestError73("Camera _id is required to listen to camera.");
|
|
17434
|
+
}
|
|
17435
|
+
const cameraId = camera._id.toString();
|
|
17436
|
+
if (cameraRegistry.has(cameraId)) {
|
|
17437
|
+
loggerDahua.info(`[${camera.host}] Stopping existing connection for update.`);
|
|
17438
|
+
cameraRegistry.get(cameraId)?.abort();
|
|
17439
|
+
cameraRegistry.delete(cameraId);
|
|
17440
|
+
}
|
|
17441
|
+
const controller = new AbortController();
|
|
17442
|
+
cameraRegistry.set(cameraId, controller);
|
|
17443
|
+
getTrafficJunction(
|
|
17444
|
+
camera.host,
|
|
17445
|
+
camera.username,
|
|
17446
|
+
camera.password,
|
|
17447
|
+
camera.site.toString(),
|
|
17448
|
+
`guard-post-${camera.guardPost}`,
|
|
17449
|
+
camera.direction,
|
|
17450
|
+
cameraId,
|
|
17451
|
+
controller.signal
|
|
17452
|
+
);
|
|
17453
|
+
}
|
|
17454
|
+
async function getTrafficJunction(host = "", username = "", password = "", site = "", gate = "", designation = "", cameraId, signal) {
|
|
17455
|
+
if (signal.aborted)
|
|
17456
|
+
return;
|
|
17669
17457
|
try {
|
|
17670
17458
|
const response = await useDahuaDigest({
|
|
17671
17459
|
host,
|
|
@@ -17689,32 +17477,58 @@ function useDahuaService() {
|
|
|
17689
17477
|
password
|
|
17690
17478
|
);
|
|
17691
17479
|
bufferQueue.setStream(response.res);
|
|
17480
|
+
const onAbort = () => {
|
|
17481
|
+
loggerDahua.info(`[${site}]-[${host}] Abort triggered. Cleaning up...`);
|
|
17482
|
+
if (response.res && !response.res.destroyed) {
|
|
17483
|
+
response.res.once("error", (err) => {
|
|
17484
|
+
if (err?.code === "UND_ERR_ABORTED") {
|
|
17485
|
+
loggerDahua.debug(`[${site}]-[${host}] Stream aborted successfully.`);
|
|
17486
|
+
} else {
|
|
17487
|
+
loggerDahua.error(`[${site}]-[${host}] Stream error during abort:`, err);
|
|
17488
|
+
}
|
|
17489
|
+
});
|
|
17490
|
+
response.res.destroy();
|
|
17491
|
+
}
|
|
17492
|
+
};
|
|
17493
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
17692
17494
|
if ([400, 401, 403, 500].includes(response.statusCode)) {
|
|
17693
17495
|
loggerDahua.error(
|
|
17694
|
-
`[${
|
|
17496
|
+
`[${host}] Connection error:`,
|
|
17695
17497
|
response.statusCode
|
|
17696
17498
|
);
|
|
17697
|
-
throw new
|
|
17499
|
+
throw new BadRequestError73(
|
|
17698
17500
|
`Failed to connect to ANPR: ${response.statusCode}`
|
|
17699
17501
|
);
|
|
17700
17502
|
}
|
|
17701
17503
|
if ([200, 201, 202].includes(response.statusCode)) {
|
|
17702
|
-
loggerDahua.info(`[${
|
|
17703
|
-
console.log(`[${
|
|
17504
|
+
loggerDahua.info(`[${host}] Successfully connected to ANPR.`);
|
|
17505
|
+
console.log(`[${host}] Successfully connected to ANPR.`);
|
|
17704
17506
|
}
|
|
17705
17507
|
response.res.on("data", (chunk) => {
|
|
17508
|
+
if (signal.aborted) {
|
|
17509
|
+
response.res.destroy();
|
|
17510
|
+
return;
|
|
17511
|
+
}
|
|
17706
17512
|
bufferQueue.enqueue(chunk);
|
|
17707
17513
|
});
|
|
17708
17514
|
const handleDisconnect = async (reason, err) => {
|
|
17515
|
+
signal.removeEventListener("abort", onAbort);
|
|
17516
|
+
if (bufferQueue.destroy)
|
|
17517
|
+
bufferQueue.destroy();
|
|
17518
|
+
if (response.res.destroy)
|
|
17519
|
+
response.res.destroy();
|
|
17520
|
+
if (signal.aborted) {
|
|
17521
|
+
loggerDahua.info(`[${site}]-[${host}] Loop terminated. Not reconnecting.`);
|
|
17522
|
+
return;
|
|
17523
|
+
}
|
|
17709
17524
|
loggerDahua.error(
|
|
17710
|
-
`[${site}][${
|
|
17525
|
+
`[${site}]-[${host}] ${reason}`,
|
|
17711
17526
|
err ? err.code || err : ""
|
|
17712
17527
|
);
|
|
17713
|
-
bufferQueue.destroy();
|
|
17714
|
-
if (response.res.destroy)
|
|
17715
|
-
response.res.destroy();
|
|
17716
17528
|
await new Promise((res) => setTimeout(res, 5e3));
|
|
17717
|
-
|
|
17529
|
+
if (signal.aborted)
|
|
17530
|
+
return;
|
|
17531
|
+
getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal);
|
|
17718
17532
|
};
|
|
17719
17533
|
response.res.on(
|
|
17720
17534
|
"end",
|
|
@@ -17729,12 +17543,16 @@ function useDahuaService() {
|
|
|
17729
17543
|
(err) => handleDisconnect("Connection error:", err)
|
|
17730
17544
|
);
|
|
17731
17545
|
} catch (error) {
|
|
17546
|
+
if (signal.aborted)
|
|
17547
|
+
return;
|
|
17732
17548
|
loggerDahua.error(
|
|
17733
17549
|
`[${site}][${gate}] Initial connect error:`,
|
|
17734
17550
|
error.code || error
|
|
17735
17551
|
);
|
|
17736
17552
|
await new Promise((res) => setTimeout(res, 5e3));
|
|
17737
|
-
|
|
17553
|
+
if (signal.aborted)
|
|
17554
|
+
return;
|
|
17555
|
+
getTrafficJunction(host, username, password, site, gate, designation, cameraId, signal);
|
|
17738
17556
|
}
|
|
17739
17557
|
}
|
|
17740
17558
|
async function addPlateNumber(value) {
|
|
@@ -17751,7 +17569,7 @@ function useDahuaService() {
|
|
|
17751
17569
|
});
|
|
17752
17570
|
const { error } = validation.validate(value);
|
|
17753
17571
|
if (error) {
|
|
17754
|
-
throw new
|
|
17572
|
+
throw new BadRequestError73(`Validation error: ${error.message}`);
|
|
17755
17573
|
}
|
|
17756
17574
|
value.owner = String(value.owner ?? "").substring(0, 15) || "unknown";
|
|
17757
17575
|
const _openGate = String(value.isOpenGate);
|
|
@@ -17767,7 +17585,7 @@ function useDahuaService() {
|
|
|
17767
17585
|
return response;
|
|
17768
17586
|
} catch (error2) {
|
|
17769
17587
|
loggerDahua.error(`[${value.host}] Error adding plate number:`, error2);
|
|
17770
|
-
throw new
|
|
17588
|
+
throw new BadRequestError73(`Failed to add plate number: ${error2.message}`);
|
|
17771
17589
|
}
|
|
17772
17590
|
}
|
|
17773
17591
|
async function updatePlateNumber(value) {
|
|
@@ -17785,7 +17603,7 @@ function useDahuaService() {
|
|
|
17785
17603
|
});
|
|
17786
17604
|
const { error } = validation.validate(value);
|
|
17787
17605
|
if (error) {
|
|
17788
|
-
throw new
|
|
17606
|
+
throw new BadRequestError73(`Validation error: ${error.message}`);
|
|
17789
17607
|
}
|
|
17790
17608
|
value.owner = value.owner || "unknown";
|
|
17791
17609
|
let _isOpenGate;
|
|
@@ -17804,7 +17622,7 @@ function useDahuaService() {
|
|
|
17804
17622
|
return response;
|
|
17805
17623
|
} catch (error2) {
|
|
17806
17624
|
loggerDahua.error(`[${value.host}] Error updating plate number:`, error2);
|
|
17807
|
-
throw new
|
|
17625
|
+
throw new BadRequestError73(
|
|
17808
17626
|
`Failed to update plate number: ${error2.message}`
|
|
17809
17627
|
);
|
|
17810
17628
|
}
|
|
@@ -17819,7 +17637,7 @@ function useDahuaService() {
|
|
|
17819
17637
|
});
|
|
17820
17638
|
const { error } = validation.validate(value);
|
|
17821
17639
|
if (error) {
|
|
17822
|
-
throw new
|
|
17640
|
+
throw new BadRequestError73(`Validation error: ${error.message}`);
|
|
17823
17641
|
}
|
|
17824
17642
|
try {
|
|
17825
17643
|
const response = await useDahuaDigest({
|
|
@@ -17843,7 +17661,7 @@ function useDahuaService() {
|
|
|
17843
17661
|
});
|
|
17844
17662
|
const { error } = validation.validate(value);
|
|
17845
17663
|
if (error) {
|
|
17846
|
-
throw new
|
|
17664
|
+
throw new BadRequestError73(`Validation error: ${error.message}`);
|
|
17847
17665
|
}
|
|
17848
17666
|
try {
|
|
17849
17667
|
const response = await useDahuaDigest({
|
|
@@ -17875,7 +17693,7 @@ function useDahuaService() {
|
|
|
17875
17693
|
});
|
|
17876
17694
|
const { error } = validation.validate(value);
|
|
17877
17695
|
if (error) {
|
|
17878
|
-
throw new
|
|
17696
|
+
throw new BadRequestError73(`Validation error: ${error.message}`);
|
|
17879
17697
|
}
|
|
17880
17698
|
value.owner = String(value.owner ?? "").substring(0, 15) || "unknown";
|
|
17881
17699
|
value.vehicleType = String(value.vehicleType ?? "").substring(0, 31) || "unknown";
|
|
@@ -17893,14 +17711,14 @@ function useDahuaService() {
|
|
|
17893
17711
|
return response;
|
|
17894
17712
|
} catch (error2) {
|
|
17895
17713
|
loggerDahua.error(`[${value.host}] Error bulk add plate number:`, error2);
|
|
17896
|
-
throw new
|
|
17714
|
+
throw new BadRequestError73(
|
|
17897
17715
|
`Failed bulk adding plate number: ${error2.message}`
|
|
17898
17716
|
);
|
|
17899
17717
|
}
|
|
17900
17718
|
}
|
|
17901
17719
|
return {
|
|
17902
17720
|
getSnapshot,
|
|
17903
|
-
|
|
17721
|
+
listenToCamera,
|
|
17904
17722
|
addPlateNumber,
|
|
17905
17723
|
removePlateNumber,
|
|
17906
17724
|
updatePlateNumber,
|
|
@@ -17909,7 +17727,400 @@ function useDahuaService() {
|
|
|
17909
17727
|
};
|
|
17910
17728
|
}
|
|
17911
17729
|
|
|
17730
|
+
// src/repositories/site-camera.repo.ts
|
|
17731
|
+
function useSiteCameraRepo() {
|
|
17732
|
+
const db = useAtlas35.getDb();
|
|
17733
|
+
if (!db) {
|
|
17734
|
+
throw new Error("Unable to connect to server.");
|
|
17735
|
+
}
|
|
17736
|
+
const namespace_collection = "site.cameras";
|
|
17737
|
+
const collection = db.collection(namespace_collection);
|
|
17738
|
+
const { delNamespace, getCache, setCache } = useCache26(namespace_collection);
|
|
17739
|
+
async function createIndexes() {
|
|
17740
|
+
try {
|
|
17741
|
+
await collection.createIndexes([
|
|
17742
|
+
{
|
|
17743
|
+
key: { site: 1 }
|
|
17744
|
+
},
|
|
17745
|
+
{
|
|
17746
|
+
key: { type: 1 }
|
|
17747
|
+
},
|
|
17748
|
+
{
|
|
17749
|
+
key: { host: 1, type: 1, status: 1, site: 1 },
|
|
17750
|
+
unique: true,
|
|
17751
|
+
partialFilterExpression: { status: "active" }
|
|
17752
|
+
}
|
|
17753
|
+
]);
|
|
17754
|
+
return `Successfully created ${namespace_collection} indexes.`;
|
|
17755
|
+
} catch (error) {
|
|
17756
|
+
logger54.log({
|
|
17757
|
+
level: "error",
|
|
17758
|
+
message: error.message
|
|
17759
|
+
});
|
|
17760
|
+
}
|
|
17761
|
+
}
|
|
17762
|
+
async function add(value, session) {
|
|
17763
|
+
try {
|
|
17764
|
+
value = MSiteCamera(value);
|
|
17765
|
+
const res = await collection.insertOne(value, { session });
|
|
17766
|
+
delCachedData();
|
|
17767
|
+
return res.insertedId;
|
|
17768
|
+
} catch (error) {
|
|
17769
|
+
logger54.log({
|
|
17770
|
+
level: "error",
|
|
17771
|
+
message: error.message
|
|
17772
|
+
});
|
|
17773
|
+
const isDuplicated = error.message.includes("duplicate");
|
|
17774
|
+
if (isDuplicated) {
|
|
17775
|
+
throw new BadRequestError74("ANPR already exist.");
|
|
17776
|
+
}
|
|
17777
|
+
if (error instanceof AppError11) {
|
|
17778
|
+
throw error;
|
|
17779
|
+
} else {
|
|
17780
|
+
throw new Error("Failed to create ANPR.");
|
|
17781
|
+
}
|
|
17782
|
+
}
|
|
17783
|
+
}
|
|
17784
|
+
async function getAll(value) {
|
|
17785
|
+
value.page = value.page ? value.page - 1 : 0;
|
|
17786
|
+
value.limit = value.limit || 10;
|
|
17787
|
+
const cacheKeyOptions = {
|
|
17788
|
+
type: value.type,
|
|
17789
|
+
page: value.page,
|
|
17790
|
+
limit: value.limit,
|
|
17791
|
+
...value.direction && { direction: value.direction }
|
|
17792
|
+
};
|
|
17793
|
+
const query = {
|
|
17794
|
+
type: value.type,
|
|
17795
|
+
...value.direction && {
|
|
17796
|
+
direction: {
|
|
17797
|
+
$in: Array.isArray(value.direction) ? value.direction : [value.direction]
|
|
17798
|
+
}
|
|
17799
|
+
}
|
|
17800
|
+
};
|
|
17801
|
+
if (value.site) {
|
|
17802
|
+
cacheKeyOptions.site = value.site;
|
|
17803
|
+
try {
|
|
17804
|
+
value.site = new ObjectId47(value.site);
|
|
17805
|
+
query.site = value.site;
|
|
17806
|
+
} catch (error) {
|
|
17807
|
+
throw new BadRequestError74("Invalid site ID format");
|
|
17808
|
+
}
|
|
17809
|
+
}
|
|
17810
|
+
const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
|
|
17811
|
+
const cachedData = await getCache(cacheKey);
|
|
17812
|
+
if (cachedData) {
|
|
17813
|
+
return cachedData;
|
|
17814
|
+
}
|
|
17815
|
+
try {
|
|
17816
|
+
const items = await collection.aggregate([
|
|
17817
|
+
{
|
|
17818
|
+
$match: query
|
|
17819
|
+
},
|
|
17820
|
+
{
|
|
17821
|
+
$skip: value.page * value.limit
|
|
17822
|
+
},
|
|
17823
|
+
{
|
|
17824
|
+
$limit: value.limit
|
|
17825
|
+
},
|
|
17826
|
+
{
|
|
17827
|
+
$project: {
|
|
17828
|
+
password: 0
|
|
17829
|
+
}
|
|
17830
|
+
}
|
|
17831
|
+
]).toArray();
|
|
17832
|
+
const length = await collection.countDocuments(query);
|
|
17833
|
+
const data = paginate21(items, value.page, value.limit, length);
|
|
17834
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
17835
|
+
logger54.info(`Cache set for key: ${cacheKey}`);
|
|
17836
|
+
}).catch((err) => {
|
|
17837
|
+
logger54.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
17838
|
+
});
|
|
17839
|
+
return data;
|
|
17840
|
+
} catch (error) {
|
|
17841
|
+
if (error instanceof BadRequestError74) {
|
|
17842
|
+
throw error;
|
|
17843
|
+
}
|
|
17844
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
17845
|
+
}
|
|
17846
|
+
}
|
|
17847
|
+
async function findSiteCameras({ site, type }) {
|
|
17848
|
+
const pipeline = [];
|
|
17849
|
+
const cacheObject = {};
|
|
17850
|
+
if (type) {
|
|
17851
|
+
cacheObject.type = type;
|
|
17852
|
+
pipeline.push({ $match: { "anprs.type": type } });
|
|
17853
|
+
}
|
|
17854
|
+
if (site) {
|
|
17855
|
+
const _site = new ObjectId47(site);
|
|
17856
|
+
cacheObject.site = site;
|
|
17857
|
+
pipeline.push({ $match: { site: _site } });
|
|
17858
|
+
}
|
|
17859
|
+
pipeline.push({
|
|
17860
|
+
$project: {
|
|
17861
|
+
_id: 1,
|
|
17862
|
+
site: 1,
|
|
17863
|
+
cameras: 1
|
|
17864
|
+
}
|
|
17865
|
+
});
|
|
17866
|
+
try {
|
|
17867
|
+
const items = await collection.aggregate(pipeline).toArray();
|
|
17868
|
+
return items;
|
|
17869
|
+
} catch (error) {
|
|
17870
|
+
if (error instanceof BadRequestError74) {
|
|
17871
|
+
throw error;
|
|
17872
|
+
}
|
|
17873
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
17874
|
+
}
|
|
17875
|
+
}
|
|
17876
|
+
function delCachedData() {
|
|
17877
|
+
delNamespace().then(() => {
|
|
17878
|
+
logger54.log({
|
|
17879
|
+
level: "info",
|
|
17880
|
+
message: `Cache namespace cleared for ${namespace_collection}`
|
|
17881
|
+
});
|
|
17882
|
+
}).catch((err) => {
|
|
17883
|
+
logger54.log({
|
|
17884
|
+
level: "error",
|
|
17885
|
+
message: `Failed to clear cache namespace for ${namespace_collection}: ${err.message}`
|
|
17886
|
+
});
|
|
17887
|
+
});
|
|
17888
|
+
}
|
|
17889
|
+
async function getBySite(site, options = {}) {
|
|
17890
|
+
const _site = toObjectId11(site);
|
|
17891
|
+
const cacheKeyOptions = {
|
|
17892
|
+
site,
|
|
17893
|
+
tag: "get-by-site",
|
|
17894
|
+
...options.category && { category: options.category },
|
|
17895
|
+
...options.type && { type: options.type },
|
|
17896
|
+
...options.guardPost && { guardPost: options.guardPost }
|
|
17897
|
+
};
|
|
17898
|
+
const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
|
|
17899
|
+
const cachedData = await getCache(cacheKey);
|
|
17900
|
+
if (cachedData) {
|
|
17901
|
+
return cachedData;
|
|
17902
|
+
}
|
|
17903
|
+
try {
|
|
17904
|
+
delete cacheKeyOptions.tag;
|
|
17905
|
+
cacheKeyOptions.site = _site;
|
|
17906
|
+
const item = await collection.findOne(cacheKeyOptions);
|
|
17907
|
+
setCache(cacheKey, item, 15 * 60).then(() => {
|
|
17908
|
+
logger54.log({
|
|
17909
|
+
level: "info",
|
|
17910
|
+
message: `Cache set for getBySite: ${cacheKey}`
|
|
17911
|
+
});
|
|
17912
|
+
}).catch((err) => {
|
|
17913
|
+
logger54.log({
|
|
17914
|
+
level: "error",
|
|
17915
|
+
message: `Failed to set cache for getBySite: ${err.message}`
|
|
17916
|
+
});
|
|
17917
|
+
});
|
|
17918
|
+
return item;
|
|
17919
|
+
} catch (error) {
|
|
17920
|
+
if (error instanceof BadRequestError74) {
|
|
17921
|
+
throw error;
|
|
17922
|
+
}
|
|
17923
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
17924
|
+
}
|
|
17925
|
+
}
|
|
17926
|
+
async function getBySiteGuardPost(site, guardPost) {
|
|
17927
|
+
try {
|
|
17928
|
+
site = new ObjectId47(site);
|
|
17929
|
+
} catch (error) {
|
|
17930
|
+
throw new BadRequestError74("Invalid site ID format");
|
|
17931
|
+
}
|
|
17932
|
+
const cacheKeyOptions = {
|
|
17933
|
+
site,
|
|
17934
|
+
guardPost,
|
|
17935
|
+
tag: "get-by-site"
|
|
17936
|
+
};
|
|
17937
|
+
const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
|
|
17938
|
+
const cachedData = await getCache(cacheKey);
|
|
17939
|
+
if (cachedData) {
|
|
17940
|
+
return cachedData;
|
|
17941
|
+
}
|
|
17942
|
+
try {
|
|
17943
|
+
delete cacheKeyOptions.tag;
|
|
17944
|
+
const item = await collection.findOne({
|
|
17945
|
+
site,
|
|
17946
|
+
guardPost: { $gt: guardPost }
|
|
17947
|
+
});
|
|
17948
|
+
setCache(cacheKey, item, 15 * 60).then(() => {
|
|
17949
|
+
logger54.log({
|
|
17950
|
+
level: "info",
|
|
17951
|
+
message: `Cache set for getBySite: ${cacheKey}`
|
|
17952
|
+
});
|
|
17953
|
+
}).catch((err) => {
|
|
17954
|
+
logger54.log({
|
|
17955
|
+
level: "error",
|
|
17956
|
+
message: `Failed to set cache for getBySite: ${err.message}`
|
|
17957
|
+
});
|
|
17958
|
+
});
|
|
17959
|
+
return item;
|
|
17960
|
+
} catch (error) {
|
|
17961
|
+
if (error instanceof BadRequestError74) {
|
|
17962
|
+
throw error;
|
|
17963
|
+
}
|
|
17964
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
17965
|
+
}
|
|
17966
|
+
}
|
|
17967
|
+
async function getBySites(site, options = {}) {
|
|
17968
|
+
try {
|
|
17969
|
+
site = new ObjectId47(site);
|
|
17970
|
+
} catch (error) {
|
|
17971
|
+
throw new BadRequestError74("Invalid site ID format");
|
|
17972
|
+
}
|
|
17973
|
+
const cacheKeyOptions = { site };
|
|
17974
|
+
if (options.category) {
|
|
17975
|
+
cacheKeyOptions.category = options.category;
|
|
17976
|
+
}
|
|
17977
|
+
if (options.type) {
|
|
17978
|
+
cacheKeyOptions.type = options.type;
|
|
17979
|
+
}
|
|
17980
|
+
if (options.direction) {
|
|
17981
|
+
cacheKeyOptions.direction = options.direction;
|
|
17982
|
+
}
|
|
17983
|
+
const cacheKey = makeCacheKey25(namespace_collection, cacheKeyOptions);
|
|
17984
|
+
const cachedData = await getCache(cacheKey);
|
|
17985
|
+
if (cachedData) {
|
|
17986
|
+
return cachedData;
|
|
17987
|
+
}
|
|
17988
|
+
try {
|
|
17989
|
+
const items = await collection.find(cacheKeyOptions);
|
|
17990
|
+
setCache(cacheKey, items, 15 * 60).then(() => {
|
|
17991
|
+
logger54.log({
|
|
17992
|
+
level: "info",
|
|
17993
|
+
message: `Cache set for getBySite: ${cacheKey}`
|
|
17994
|
+
});
|
|
17995
|
+
}).catch((err) => {
|
|
17996
|
+
logger54.log({
|
|
17997
|
+
level: "error",
|
|
17998
|
+
message: `Failed to set cache for getBySite: ${err.message}`
|
|
17999
|
+
});
|
|
18000
|
+
});
|
|
18001
|
+
return items;
|
|
18002
|
+
} catch (error) {
|
|
18003
|
+
if (error instanceof BadRequestError74) {
|
|
18004
|
+
throw error;
|
|
18005
|
+
}
|
|
18006
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
18007
|
+
}
|
|
18008
|
+
}
|
|
18009
|
+
async function updateById(_id, value, session) {
|
|
18010
|
+
const { error } = schemaUpdateSiteCamera.validate(value);
|
|
18011
|
+
if (error) {
|
|
18012
|
+
logger54.info(`Site Camera Management: ${error.message}`);
|
|
18013
|
+
throw new BadRequestError74(error.message);
|
|
18014
|
+
}
|
|
18015
|
+
try {
|
|
18016
|
+
_id = new ObjectId47(_id);
|
|
18017
|
+
} catch (error2) {
|
|
18018
|
+
throw new BadRequestError74("Invalid camera ID format");
|
|
18019
|
+
}
|
|
18020
|
+
try {
|
|
18021
|
+
value.updatedAt = /* @__PURE__ */ new Date();
|
|
18022
|
+
const result = await collection.findOneAndUpdate({ _id }, { $set: value }, { session, returnDocument: "after" });
|
|
18023
|
+
if (!result?._id) {
|
|
18024
|
+
throw new BadRequestError74("Site camera not found.");
|
|
18025
|
+
}
|
|
18026
|
+
const { listenToCamera } = useDahuaService();
|
|
18027
|
+
await listenToCamera(result);
|
|
18028
|
+
delCachedData();
|
|
18029
|
+
return "Successfully updated site camera.";
|
|
18030
|
+
} catch (error2) {
|
|
18031
|
+
logger54.log({
|
|
18032
|
+
level: "error",
|
|
18033
|
+
message: error2.message
|
|
18034
|
+
});
|
|
18035
|
+
const isDuplicated = error2.message.includes("duplicate");
|
|
18036
|
+
if (isDuplicated) {
|
|
18037
|
+
throw new BadRequestError74("ANPR already exist.");
|
|
18038
|
+
}
|
|
18039
|
+
if (error2 instanceof AppError11) {
|
|
18040
|
+
throw error2;
|
|
18041
|
+
}
|
|
18042
|
+
throw new Error("Failed to update ANPR.");
|
|
18043
|
+
}
|
|
18044
|
+
}
|
|
18045
|
+
async function deleteById(_id, session) {
|
|
18046
|
+
try {
|
|
18047
|
+
_id = new ObjectId47(_id);
|
|
18048
|
+
} catch (error) {
|
|
18049
|
+
throw new BadRequestError74("Invalid camera ID format");
|
|
18050
|
+
}
|
|
18051
|
+
try {
|
|
18052
|
+
await collection.deleteOne({ _id }, { session });
|
|
18053
|
+
delCachedData();
|
|
18054
|
+
return "Successfully deleted site camera.";
|
|
18055
|
+
} catch (error) {
|
|
18056
|
+
logger54.log({
|
|
18057
|
+
level: "error",
|
|
18058
|
+
message: error.message
|
|
18059
|
+
});
|
|
18060
|
+
if (error instanceof AppError11) {
|
|
18061
|
+
throw error;
|
|
18062
|
+
}
|
|
18063
|
+
throw new Error("Failed to delete site camera.");
|
|
18064
|
+
}
|
|
18065
|
+
}
|
|
18066
|
+
async function getAllCameraWithPassword(value) {
|
|
18067
|
+
value.page = value.page ? value.page - 1 : 0;
|
|
18068
|
+
value.limit = value.limit || 10;
|
|
18069
|
+
const query = {
|
|
18070
|
+
type: value.type,
|
|
18071
|
+
...value.direction && {
|
|
18072
|
+
direction: {
|
|
18073
|
+
$in: Array.isArray(value.direction) ? value.direction : [value.direction]
|
|
18074
|
+
}
|
|
18075
|
+
}
|
|
18076
|
+
};
|
|
18077
|
+
if (value.site) {
|
|
18078
|
+
try {
|
|
18079
|
+
value.site = new ObjectId47(value.site);
|
|
18080
|
+
query.site = value.site;
|
|
18081
|
+
} catch (error) {
|
|
18082
|
+
throw new BadRequestError74("Invalid site ID format");
|
|
18083
|
+
}
|
|
18084
|
+
}
|
|
18085
|
+
try {
|
|
18086
|
+
const items = await collection.aggregate([
|
|
18087
|
+
{
|
|
18088
|
+
$match: query
|
|
18089
|
+
},
|
|
18090
|
+
{
|
|
18091
|
+
$skip: value.page * value.limit
|
|
18092
|
+
},
|
|
18093
|
+
{
|
|
18094
|
+
$limit: value.limit
|
|
18095
|
+
}
|
|
18096
|
+
]).toArray();
|
|
18097
|
+
const length = await collection.countDocuments(query);
|
|
18098
|
+
const data = paginate21(items, value.page, value.limit, length);
|
|
18099
|
+
return data;
|
|
18100
|
+
} catch (error) {
|
|
18101
|
+
if (error instanceof BadRequestError74) {
|
|
18102
|
+
throw error;
|
|
18103
|
+
}
|
|
18104
|
+
throw new BadRequestError74("Failed to retrieve site cameras.");
|
|
18105
|
+
}
|
|
18106
|
+
}
|
|
18107
|
+
return {
|
|
18108
|
+
createIndexes,
|
|
18109
|
+
add,
|
|
18110
|
+
getAll,
|
|
18111
|
+
findSiteCameras,
|
|
18112
|
+
getBySite,
|
|
18113
|
+
getBySites,
|
|
18114
|
+
delCachedData,
|
|
18115
|
+
getBySiteGuardPost,
|
|
18116
|
+
updateById,
|
|
18117
|
+
deleteById,
|
|
18118
|
+
getAllCameraWithPassword
|
|
18119
|
+
};
|
|
18120
|
+
}
|
|
18121
|
+
|
|
17912
18122
|
// src/services/site.service.ts
|
|
18123
|
+
import Joi41 from "joi";
|
|
17913
18124
|
function useSiteService() {
|
|
17914
18125
|
const {
|
|
17915
18126
|
createSite: _createSite,
|
|
@@ -19473,7 +19684,7 @@ function useVehicleController() {
|
|
|
19473
19684
|
next(new BadRequestError84("Spreadsheet file is required."));
|
|
19474
19685
|
return;
|
|
19475
19686
|
}
|
|
19476
|
-
const { originalname, path:
|
|
19687
|
+
const { originalname, path: path4 } = req.file;
|
|
19477
19688
|
const lowerName = originalname.toLowerCase();
|
|
19478
19689
|
const rowSchema = Joi46.object({
|
|
19479
19690
|
fullName: Joi46.string().trim().required(),
|
|
@@ -19512,7 +19723,7 @@ function useVehicleController() {
|
|
|
19512
19723
|
let rows = [];
|
|
19513
19724
|
if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
|
|
19514
19725
|
const workbook = new ExcelJS.Workbook();
|
|
19515
|
-
await workbook.xlsx.readFile(
|
|
19726
|
+
await workbook.xlsx.readFile(path4);
|
|
19516
19727
|
const worksheet = workbook.worksheets[0];
|
|
19517
19728
|
if (!worksheet) {
|
|
19518
19729
|
next(
|
|
@@ -19538,7 +19749,7 @@ function useVehicleController() {
|
|
|
19538
19749
|
} else if (lowerName.endsWith(".csv")) {
|
|
19539
19750
|
rows = await new Promise((resolve, reject) => {
|
|
19540
19751
|
const parsed = [];
|
|
19541
|
-
fs.createReadStream(
|
|
19752
|
+
fs.createReadStream(path4).pipe(csv()).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
|
|
19542
19753
|
});
|
|
19543
19754
|
} else {
|
|
19544
19755
|
next(
|
|
@@ -19577,7 +19788,7 @@ function useVehicleController() {
|
|
|
19577
19788
|
validationErrors: invalidRows,
|
|
19578
19789
|
data
|
|
19579
19790
|
});
|
|
19580
|
-
fs.unlink(
|
|
19791
|
+
fs.unlink(path4, () => {
|
|
19581
19792
|
});
|
|
19582
19793
|
} catch (error) {
|
|
19583
19794
|
logger65.log({ level: "error", message: error.message });
|
|
@@ -19976,14 +20187,7 @@ function useSiteCameraService() {
|
|
|
19976
20187
|
for (let index = 0; index < siteCameras.length; index++) {
|
|
19977
20188
|
const siteCamera = siteCameras[index];
|
|
19978
20189
|
if (siteCamera && siteCamera.status === "active" && siteCamera.host && siteCamera.username && siteCamera.password && siteCamera.site && siteCamera.guardPost) {
|
|
19979
|
-
dahuaService.
|
|
19980
|
-
siteCamera.host,
|
|
19981
|
-
siteCamera.username,
|
|
19982
|
-
siteCamera.password,
|
|
19983
|
-
siteCamera.site.toString(),
|
|
19984
|
-
`guard-post-${siteCamera.guardPost}`,
|
|
19985
|
-
siteCamera.direction
|
|
19986
|
-
);
|
|
20190
|
+
dahuaService.listenToCamera(siteCamera);
|
|
19987
20191
|
}
|
|
19988
20192
|
}
|
|
19989
20193
|
}
|
|
@@ -24037,7 +24241,6 @@ import {
|
|
|
24037
24241
|
compileHandlebar as compileHandlebar3,
|
|
24038
24242
|
getDirectory as getDirectory3
|
|
24039
24243
|
} from "@7365admin1/node-server-utils";
|
|
24040
|
-
import path2 from "path";
|
|
24041
24244
|
function usePersonService() {
|
|
24042
24245
|
const MailerConfig = {
|
|
24043
24246
|
host: MAILER_TRANSPORT_HOST,
|
|
@@ -24252,13 +24455,8 @@ function usePersonService() {
|
|
|
24252
24455
|
value.status = "active";
|
|
24253
24456
|
}
|
|
24254
24457
|
await _reviewResidentPerson(id, value, session);
|
|
24255
|
-
const logoPath =
|
|
24256
|
-
|
|
24257
|
-
"public",
|
|
24258
|
-
"images",
|
|
24259
|
-
"seven-365.svg"
|
|
24260
|
-
);
|
|
24261
|
-
const statusIconPath = path2.join(__dirname, "public", "icons");
|
|
24458
|
+
const logoPath = `${STORAGE_API}/seven-365.svg`;
|
|
24459
|
+
const statusIconPath = STORAGE_API;
|
|
24262
24460
|
let title = "";
|
|
24263
24461
|
let message2 = "";
|
|
24264
24462
|
let hideLogin = true;
|
|
@@ -31342,14 +31540,36 @@ function useSiteBillingConfigurationController() {
|
|
|
31342
31540
|
// src/models/event-management.model.ts
|
|
31343
31541
|
import { ObjectId as ObjectId84 } from "mongodb";
|
|
31344
31542
|
import Joi81 from "joi";
|
|
31543
|
+
var EventStatus = /* @__PURE__ */ ((EventStatus2) => {
|
|
31544
|
+
EventStatus2["PLANNED"] = "planned";
|
|
31545
|
+
EventStatus2["IN_PROGRESS"] = "in_progress";
|
|
31546
|
+
EventStatus2["COMPLETED"] = "completed";
|
|
31547
|
+
return EventStatus2;
|
|
31548
|
+
})(EventStatus || {});
|
|
31549
|
+
var EventSort = /* @__PURE__ */ ((EventSort2) => {
|
|
31550
|
+
EventSort2["CREATED_AT"] = "createdAt";
|
|
31551
|
+
EventSort2["NAME"] = "name";
|
|
31552
|
+
EventSort2["ID"] = "_id";
|
|
31553
|
+
return EventSort2;
|
|
31554
|
+
})(EventSort || {});
|
|
31555
|
+
var EventOrder = /* @__PURE__ */ ((EventOrder2) => {
|
|
31556
|
+
EventOrder2["ASC"] = "asc";
|
|
31557
|
+
EventOrder2["DESC"] = "desc";
|
|
31558
|
+
return EventOrder2;
|
|
31559
|
+
})(EventOrder || {});
|
|
31560
|
+
var EventType = /* @__PURE__ */ ((EventType2) => {
|
|
31561
|
+
EventType2["TASK"] = "TASK";
|
|
31562
|
+
EventType2["EVENT"] = "EVENT";
|
|
31563
|
+
return EventType2;
|
|
31564
|
+
})(EventType || {});
|
|
31345
31565
|
var schemaEventManagement = Joi81.object({
|
|
31346
31566
|
_id: Joi81.string().optional().allow(null, ""),
|
|
31347
31567
|
site: Joi81.string().required(),
|
|
31348
31568
|
title: Joi81.string().required(),
|
|
31349
31569
|
description: Joi81.string().optional().allow(""),
|
|
31350
31570
|
dateTime: Joi81.date().iso().required(),
|
|
31351
|
-
status: Joi81.string().optional().default("planned"),
|
|
31352
|
-
type: Joi81.string().optional().default("TASK")
|
|
31571
|
+
status: Joi81.string().optional().default("planned" /* PLANNED */),
|
|
31572
|
+
type: Joi81.string().optional().default("TASK" /* TASK */)
|
|
31353
31573
|
});
|
|
31354
31574
|
var schemaUpdateEventManagement = Joi81.object({
|
|
31355
31575
|
_id: Joi81.string().hex().required(),
|
|
@@ -31380,8 +31600,8 @@ function MEventManagement(value) {
|
|
|
31380
31600
|
title: value.title,
|
|
31381
31601
|
description: value.description ?? "",
|
|
31382
31602
|
dateTime: new Date(value.dateTime),
|
|
31383
|
-
status: value.status ?? "planned"
|
|
31384
|
-
type: value.type ?? "TASK"
|
|
31603
|
+
status: value.status ?? "planned" /* PLANNED */,
|
|
31604
|
+
type: value.type ?? "TASK" /* TASK */,
|
|
31385
31605
|
createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
|
|
31386
31606
|
updatedAt: value.updatedAt,
|
|
31387
31607
|
deletedAt: value.deletedAt
|
|
@@ -31489,7 +31709,8 @@ function useEventManagementRepo() {
|
|
|
31489
31709
|
sort: JSON.stringify(sort),
|
|
31490
31710
|
page,
|
|
31491
31711
|
limit,
|
|
31492
|
-
...type && { type }
|
|
31712
|
+
...type && { type },
|
|
31713
|
+
...date && { dateTime: date }
|
|
31493
31714
|
};
|
|
31494
31715
|
if (search) {
|
|
31495
31716
|
query.$or = [{ title: { $regex: search, $options: "i" } }];
|
|
@@ -31692,8 +31913,8 @@ function useEventManagementService() {
|
|
|
31692
31913
|
} = useEventManagementRepo();
|
|
31693
31914
|
async function add(value) {
|
|
31694
31915
|
const session = useAtlas73.getClient()?.startSession();
|
|
31695
|
-
session?.startTransaction();
|
|
31696
31916
|
try {
|
|
31917
|
+
session?.startTransaction();
|
|
31697
31918
|
await _add(value, session);
|
|
31698
31919
|
await session?.commitTransaction();
|
|
31699
31920
|
return "Successfully added event.";
|
|
@@ -31756,67 +31977,51 @@ function useEventManagementController() {
|
|
|
31756
31977
|
deleteEventManagementById: _deleteEventManagementById
|
|
31757
31978
|
} = useEventManagementRepo();
|
|
31758
31979
|
async function add(req, res, next) {
|
|
31759
|
-
const payload = { ...req.body };
|
|
31760
|
-
const { error } = schemaEventManagement.validate(payload, {
|
|
31761
|
-
abortEarly: false
|
|
31762
|
-
});
|
|
31763
|
-
if (error) {
|
|
31764
|
-
const messages = error.details.map((d) => d.message).join(", ");
|
|
31765
|
-
logger115.log({ level: "error", message: messages });
|
|
31766
|
-
next(new BadRequestError137(messages));
|
|
31767
|
-
return;
|
|
31768
|
-
}
|
|
31769
31980
|
try {
|
|
31770
|
-
const
|
|
31981
|
+
const { error, value } = schemaEventManagement.validate(req.body, {
|
|
31982
|
+
abortEarly: false
|
|
31983
|
+
});
|
|
31984
|
+
if (error) {
|
|
31985
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
31986
|
+
logger115.log({ level: "error", message: messages });
|
|
31987
|
+
next(new BadRequestError137(messages));
|
|
31988
|
+
return;
|
|
31989
|
+
}
|
|
31990
|
+
const data = await _add(value);
|
|
31771
31991
|
res.status(201).json(data);
|
|
31772
31992
|
return;
|
|
31773
|
-
} catch (
|
|
31774
|
-
logger115.log({ level: "error", message:
|
|
31775
|
-
next(
|
|
31993
|
+
} catch (error) {
|
|
31994
|
+
logger115.log({ level: "error", message: error.message });
|
|
31995
|
+
next(error);
|
|
31776
31996
|
return;
|
|
31777
31997
|
}
|
|
31778
31998
|
}
|
|
31779
31999
|
async function getAll(req, res, next) {
|
|
31780
|
-
const allowedFields = ["createdAt", "name"];
|
|
31781
|
-
const allowedOrder = ["asc", "desc"];
|
|
31782
|
-
const validation = Joi82.object({
|
|
31783
|
-
search: Joi82.string().optional().allow("", null),
|
|
31784
|
-
page: Joi82.number().integer().min(1).allow("", null).default(1),
|
|
31785
|
-
limit: Joi82.number().integer().min(1).max(100).allow("", null).default(10),
|
|
31786
|
-
sort: Joi82.string().pattern(/^([a-zA-Z0-9_]+)(,[a-zA-Z0-9_]+)*$/).optional().allow("", ...allowedFields),
|
|
31787
|
-
order: Joi82.string().pattern(/^(asc|desc)(,(asc|desc))*$/).optional().allow("", ...allowedOrder),
|
|
31788
|
-
site: Joi82.string().hex().required(),
|
|
31789
|
-
status: Joi82.string().optional(),
|
|
31790
|
-
type: Joi82.string().optional().valid("TASK", "EVENT").allow(null, ""),
|
|
31791
|
-
date: Joi82.string().optional().allow(null, "")
|
|
31792
|
-
});
|
|
31793
|
-
const query = { ...req.query };
|
|
31794
|
-
const { error } = validation.validate(query, {
|
|
31795
|
-
abortEarly: false
|
|
31796
|
-
});
|
|
31797
|
-
if (error) {
|
|
31798
|
-
const messages = error.details.map((d) => d.message).join(", ");
|
|
31799
|
-
logger115.log({ level: "error", message: messages });
|
|
31800
|
-
next(new BadRequestError137(messages));
|
|
31801
|
-
return;
|
|
31802
|
-
}
|
|
31803
|
-
const search = req.query.search ?? "";
|
|
31804
|
-
const page = parseInt(req.query.page ?? "1");
|
|
31805
|
-
const limit = parseInt(req.query.limit ?? "10");
|
|
31806
|
-
const site = req.query.site ?? "";
|
|
31807
|
-
const status = req.query.status ?? "";
|
|
31808
|
-
const type = req.query.type ?? "";
|
|
31809
|
-
const date = req.query.date ?? "";
|
|
31810
|
-
const sortObj = {};
|
|
31811
|
-
const sortFields = String(req.query.sort).split(",");
|
|
31812
|
-
const sortOrders = String(req.query.order).split(",");
|
|
31813
|
-
sortFields.forEach((field, index) => {
|
|
31814
|
-
if (allowedFields.includes(field)) {
|
|
31815
|
-
const order = sortOrders[index] === "asc" ? 1 : -1;
|
|
31816
|
-
sortObj[field] = order;
|
|
31817
|
-
}
|
|
31818
|
-
});
|
|
31819
32000
|
try {
|
|
32001
|
+
const validation = Joi82.object({
|
|
32002
|
+
search: Joi82.string().optional().allow("", null),
|
|
32003
|
+
page: Joi82.number().integer().min(1).allow("", null).default(1),
|
|
32004
|
+
limit: Joi82.number().integer().min(1).max(100).allow("", null).default(10),
|
|
32005
|
+
sort: Joi82.string().valid(...Object.values(EventSort)).default("_id" /* ID */),
|
|
32006
|
+
order: Joi82.string().valid(...Object.values(EventOrder)).default("desc" /* DESC */),
|
|
32007
|
+
site: Joi82.string().hex().length(24).required(),
|
|
32008
|
+
status: Joi82.string().valid(...Object.values(EventStatus)).allow(null, ""),
|
|
32009
|
+
type: Joi82.string().optional().valid(...Object.values(EventType)).allow(null, ""),
|
|
32010
|
+
date: Joi82.string().optional().allow(null, "")
|
|
32011
|
+
});
|
|
32012
|
+
const { error, value } = validation.validate(req.query, {
|
|
32013
|
+
abortEarly: false
|
|
32014
|
+
});
|
|
32015
|
+
if (error) {
|
|
32016
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
32017
|
+
logger115.log({ level: "error", message: messages });
|
|
32018
|
+
next(new BadRequestError137(messages));
|
|
32019
|
+
return;
|
|
32020
|
+
}
|
|
32021
|
+
const { search, page, limit, site, status, type, date, sort, order } = value;
|
|
32022
|
+
const sortObj = {
|
|
32023
|
+
[sort ?? "_id" /* ID */]: order === "asc" /* ASC */ ? 1 : -1
|
|
32024
|
+
};
|
|
31820
32025
|
const data = await _getAll({
|
|
31821
32026
|
search,
|
|
31822
32027
|
page,
|
|
@@ -31829,35 +32034,36 @@ function useEventManagementController() {
|
|
|
31829
32034
|
});
|
|
31830
32035
|
res.status(200).json(data);
|
|
31831
32036
|
return;
|
|
31832
|
-
} catch (
|
|
31833
|
-
logger115.log({ level: "error", message:
|
|
31834
|
-
next(
|
|
32037
|
+
} catch (error) {
|
|
32038
|
+
logger115.log({ level: "error", message: error.message });
|
|
32039
|
+
next(error);
|
|
31835
32040
|
return;
|
|
31836
32041
|
}
|
|
31837
32042
|
}
|
|
31838
32043
|
async function getEventManagementById(req, res, next) {
|
|
31839
|
-
const validation = Joi82.string().hex().required();
|
|
31840
|
-
const _id = req.params.id;
|
|
31841
|
-
const { error } = validation.validate(_id);
|
|
31842
|
-
if (error) {
|
|
31843
|
-
logger115.log({ level: "error", message: error.message });
|
|
31844
|
-
next(new BadRequestError137(error.message));
|
|
31845
|
-
return;
|
|
31846
|
-
}
|
|
31847
32044
|
try {
|
|
32045
|
+
const schema2 = Joi82.object({
|
|
32046
|
+
_id: Joi82.string().hex().length(24).required()
|
|
32047
|
+
});
|
|
32048
|
+
const { error, value } = schema2.validate({ _id: req.params.id });
|
|
32049
|
+
if (error) {
|
|
32050
|
+
logger115.log({ level: "error", message: error.message });
|
|
32051
|
+
next(new BadRequestError137(error.message));
|
|
32052
|
+
return;
|
|
32053
|
+
}
|
|
32054
|
+
const { _id } = value;
|
|
31848
32055
|
const data = await _getEventManagementById(_id);
|
|
31849
32056
|
res.status(200).json(data);
|
|
31850
32057
|
return;
|
|
31851
|
-
} catch (
|
|
31852
|
-
logger115.log({ level: "error", message:
|
|
31853
|
-
next(
|
|
32058
|
+
} catch (error) {
|
|
32059
|
+
logger115.log({ level: "error", message: error.message });
|
|
32060
|
+
next(error);
|
|
31854
32061
|
return;
|
|
31855
32062
|
}
|
|
31856
32063
|
}
|
|
31857
32064
|
async function updateEventManagementById(req, res, next) {
|
|
31858
|
-
const
|
|
31859
|
-
const
|
|
31860
|
-
const { error } = schemaUpdateEventManagement.validate(payload, {
|
|
32065
|
+
const payload = { _id: req.params.id, ...req.body };
|
|
32066
|
+
const { error, value } = schemaUpdateEventManagement.validate(payload, {
|
|
31861
32067
|
abortEarly: false
|
|
31862
32068
|
});
|
|
31863
32069
|
if (error) {
|
|
@@ -31866,8 +32072,9 @@ function useEventManagementController() {
|
|
|
31866
32072
|
next(new BadRequestError137(messages));
|
|
31867
32073
|
return;
|
|
31868
32074
|
}
|
|
32075
|
+
const { _id, ...rest } = value;
|
|
31869
32076
|
try {
|
|
31870
|
-
const result = await _updateEventManagementById(_id,
|
|
32077
|
+
const result = await _updateEventManagementById(_id, rest);
|
|
31871
32078
|
res.status(200).json({ message: result });
|
|
31872
32079
|
return;
|
|
31873
32080
|
} catch (error2) {
|
|
@@ -33212,7 +33419,7 @@ import { ObjectId as ObjectId90 } from "mongodb";
|
|
|
33212
33419
|
|
|
33213
33420
|
// src/utils/access-management.ts
|
|
33214
33421
|
import fs2 from "fs";
|
|
33215
|
-
import
|
|
33422
|
+
import path2 from "path";
|
|
33216
33423
|
import axios from "axios";
|
|
33217
33424
|
import { parseStringPromise } from "xml2js";
|
|
33218
33425
|
import crypto from "crypto";
|
|
@@ -33242,7 +33449,7 @@ var minifyXml = (xml) => {
|
|
|
33242
33449
|
};
|
|
33243
33450
|
var readTemplate = (name, params) => {
|
|
33244
33451
|
const template = fs2.readFileSync(
|
|
33245
|
-
|
|
33452
|
+
path2.join(__dirname, `../dist/public/xml-templates/${name}.xml`),
|
|
33246
33453
|
"utf-8"
|
|
33247
33454
|
);
|
|
33248
33455
|
if (!params)
|
|
@@ -33315,6 +33522,15 @@ var formatEntryPassDate = (date) => {
|
|
|
33315
33522
|
const day = String(newDate.getDate()).padStart(2, "0");
|
|
33316
33523
|
return `${year}${month}${day}`;
|
|
33317
33524
|
};
|
|
33525
|
+
var entryPassDate = (TRDATE, TRTIME) => {
|
|
33526
|
+
const year = parseInt(TRDATE.substring(0, 4), 10);
|
|
33527
|
+
const month = parseInt(TRDATE.substring(4, 6), 10) - 1;
|
|
33528
|
+
const day = parseInt(TRDATE.substring(6, 8), 10);
|
|
33529
|
+
const hours = parseInt(TRTIME.substring(0, 2), 10);
|
|
33530
|
+
const minutes = parseInt(TRTIME.substring(2, 4), 10);
|
|
33531
|
+
const seconds = parseInt(TRTIME.substring(4, 6), 10);
|
|
33532
|
+
return new Date(year, month, day, hours, minutes, seconds);
|
|
33533
|
+
};
|
|
33318
33534
|
async function removeAccessGroup({
|
|
33319
33535
|
cardNo,
|
|
33320
33536
|
staffNo,
|
|
@@ -33347,6 +33563,16 @@ async function removeAccessGroup({
|
|
|
33347
33563
|
console.log(error);
|
|
33348
33564
|
}
|
|
33349
33565
|
}
|
|
33566
|
+
async function getTransactions(index, url) {
|
|
33567
|
+
try {
|
|
33568
|
+
const decrypt = decryptAcmUrl(url);
|
|
33569
|
+
const response = await axios.get(`${decrypt}transactions?from=${index}`);
|
|
33570
|
+
if (response.status === 200 || response.status === 201)
|
|
33571
|
+
return response.data;
|
|
33572
|
+
} catch (error) {
|
|
33573
|
+
return Promise.reject(error);
|
|
33574
|
+
}
|
|
33575
|
+
}
|
|
33350
33576
|
|
|
33351
33577
|
// src/repositories/access-management.repo.ts
|
|
33352
33578
|
import { parseStringPromise as parseStringPromise2 } from "xml2js";
|
|
@@ -33354,9 +33580,9 @@ import { parseStringPromise as parseStringPromise2 } from "xml2js";
|
|
|
33354
33580
|
// src/utils/rsa-encryption.ts
|
|
33355
33581
|
import * as crypto2 from "crypto";
|
|
33356
33582
|
import fs3 from "fs";
|
|
33357
|
-
import
|
|
33358
|
-
var pub =
|
|
33359
|
-
var priv =
|
|
33583
|
+
import path3 from "path";
|
|
33584
|
+
var pub = path3.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_pub.pem");
|
|
33585
|
+
var priv = path3.resolve(process.cwd(), "./src/public/rsa-keys/new_rsa_512_priv.pem");
|
|
33360
33586
|
var EncryptionCredentials = class {
|
|
33361
33587
|
};
|
|
33362
33588
|
EncryptionCredentials.RAW_PUBLIC_KEY = fs3.readFileSync(pub, "utf8");
|
|
@@ -35333,6 +35559,116 @@ function UseAccessManagementRepo() {
|
|
|
35333
35559
|
throw new Error(error.message);
|
|
35334
35560
|
}
|
|
35335
35561
|
}
|
|
35562
|
+
async function getTransactionsRepo({ page = 1, limit = 10, site, cardNo, url }) {
|
|
35563
|
+
page = page ? page - 1 : 0;
|
|
35564
|
+
site = new ObjectId90(site);
|
|
35565
|
+
try {
|
|
35566
|
+
let index = await collectionName("access-card-transactions").findOne({}, { sort: { index: -1 } });
|
|
35567
|
+
index = index ? index.index : 0;
|
|
35568
|
+
const response = await getTransactions(index, url);
|
|
35569
|
+
if (response && Array.isArray(response.items) && response.items.length > 0) {
|
|
35570
|
+
let result2 = response.items.map((item) => ({
|
|
35571
|
+
id: item.id,
|
|
35572
|
+
data: JSON.parse(item.data),
|
|
35573
|
+
timestamp: item.timestamp
|
|
35574
|
+
}));
|
|
35575
|
+
result2 = result2.filter((item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== "");
|
|
35576
|
+
if (result2.length > 0) {
|
|
35577
|
+
const transactions = result2.map(
|
|
35578
|
+
(item) => new MAccessCardTransaction({
|
|
35579
|
+
index: item.id,
|
|
35580
|
+
cardNo: item.data.Event.CARDNO,
|
|
35581
|
+
staffNo: item.data.Event.STAFFNO,
|
|
35582
|
+
staffName: item.data.Event.STAFFNAME,
|
|
35583
|
+
accessType: item.data.Event.DEVNAME,
|
|
35584
|
+
accessStatus: item.data.Event.TRCODE,
|
|
35585
|
+
description: item.data.Event.TRDESC,
|
|
35586
|
+
accessTime: entryPassDate(item.data.Event.TRDATE, item.data.Event.TRTIME),
|
|
35587
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
35588
|
+
})
|
|
35589
|
+
);
|
|
35590
|
+
await collectionName("access-card-transactions").insertMany(transactions);
|
|
35591
|
+
}
|
|
35592
|
+
}
|
|
35593
|
+
const result = await collectionName("access-card-transactions").aggregate([
|
|
35594
|
+
{
|
|
35595
|
+
$match: { cardNo }
|
|
35596
|
+
},
|
|
35597
|
+
{
|
|
35598
|
+
$lookup: {
|
|
35599
|
+
from: "access-card",
|
|
35600
|
+
let: { cardNo: "$cardNo" },
|
|
35601
|
+
pipeline: [
|
|
35602
|
+
{
|
|
35603
|
+
$match: {
|
|
35604
|
+
$expr: {
|
|
35605
|
+
$eq: ["$cardNo", "$$cardNo"]
|
|
35606
|
+
}
|
|
35607
|
+
}
|
|
35608
|
+
},
|
|
35609
|
+
{
|
|
35610
|
+
$lookup: {
|
|
35611
|
+
from: "users",
|
|
35612
|
+
let: { userId: "$userId" },
|
|
35613
|
+
pipeline: [
|
|
35614
|
+
{
|
|
35615
|
+
$match: {
|
|
35616
|
+
$expr: {
|
|
35617
|
+
$eq: ["$_id", "$$userId"]
|
|
35618
|
+
}
|
|
35619
|
+
}
|
|
35620
|
+
},
|
|
35621
|
+
{
|
|
35622
|
+
$project: {
|
|
35623
|
+
_id: 1,
|
|
35624
|
+
givenName: 1,
|
|
35625
|
+
surname: 1
|
|
35626
|
+
}
|
|
35627
|
+
}
|
|
35628
|
+
],
|
|
35629
|
+
as: "user"
|
|
35630
|
+
}
|
|
35631
|
+
},
|
|
35632
|
+
{
|
|
35633
|
+
$project: {
|
|
35634
|
+
_id: 1,
|
|
35635
|
+
user: { $arrayElemAt: ["$user", 0] },
|
|
35636
|
+
type: 1,
|
|
35637
|
+
cardNo: 1
|
|
35638
|
+
}
|
|
35639
|
+
}
|
|
35640
|
+
],
|
|
35641
|
+
as: "accessCard"
|
|
35642
|
+
}
|
|
35643
|
+
},
|
|
35644
|
+
{
|
|
35645
|
+
$project: {
|
|
35646
|
+
_id: 1,
|
|
35647
|
+
cardNo: 1,
|
|
35648
|
+
staffNo: 1,
|
|
35649
|
+
staffName: 1,
|
|
35650
|
+
accessType: 1,
|
|
35651
|
+
accessStatus: 1,
|
|
35652
|
+
description: 1,
|
|
35653
|
+
accessTime: 1,
|
|
35654
|
+
createdAt: 1,
|
|
35655
|
+
accessCard: { $arrayElemAt: ["$accessCard", 0] }
|
|
35656
|
+
}
|
|
35657
|
+
},
|
|
35658
|
+
{
|
|
35659
|
+
$facet: {
|
|
35660
|
+
totalCount: [{ $count: "count" }],
|
|
35661
|
+
items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
|
|
35662
|
+
}
|
|
35663
|
+
}
|
|
35664
|
+
]).toArray();
|
|
35665
|
+
const length = result[0].totalCount[0] ? result[0].totalCount[0].count : 0;
|
|
35666
|
+
const items = result[0].items;
|
|
35667
|
+
return paginate39(items, page, limit, length);
|
|
35668
|
+
} catch (error) {
|
|
35669
|
+
return Promise.reject("Server internal error.");
|
|
35670
|
+
}
|
|
35671
|
+
}
|
|
35336
35672
|
return {
|
|
35337
35673
|
createIndexes,
|
|
35338
35674
|
createIndexForEntrypass,
|
|
@@ -35364,7 +35700,8 @@ function UseAccessManagementRepo() {
|
|
|
35364
35700
|
signQrCodeRepo,
|
|
35365
35701
|
checkoutVisitorRepo,
|
|
35366
35702
|
getBlockLevelAndUnitListRepo,
|
|
35367
|
-
indexCombination
|
|
35703
|
+
indexCombination,
|
|
35704
|
+
getTransactionsRepo
|
|
35368
35705
|
};
|
|
35369
35706
|
}
|
|
35370
35707
|
|
|
@@ -35404,7 +35741,8 @@ function useAccessManagementSvc() {
|
|
|
35404
35741
|
addVisitorAccessCardRepo,
|
|
35405
35742
|
signQrCodeRepo,
|
|
35406
35743
|
checkoutVisitorRepo,
|
|
35407
|
-
getBlockLevelAndUnitListRepo
|
|
35744
|
+
getBlockLevelAndUnitListRepo,
|
|
35745
|
+
getTransactionsRepo
|
|
35408
35746
|
} = UseAccessManagementRepo();
|
|
35409
35747
|
const addPhysicalCardSvc = async (payload) => {
|
|
35410
35748
|
try {
|
|
@@ -35696,6 +36034,14 @@ function useAccessManagementSvc() {
|
|
|
35696
36034
|
throw new Error(err.message);
|
|
35697
36035
|
}
|
|
35698
36036
|
};
|
|
36037
|
+
const getTransactionsSvc = async ({ page, limit, site, cardNo, url }) => {
|
|
36038
|
+
try {
|
|
36039
|
+
const response = await getTransactionsRepo({ page, limit, site, cardNo, url });
|
|
36040
|
+
return response;
|
|
36041
|
+
} catch (err) {
|
|
36042
|
+
return Promise.reject("Server internal error.");
|
|
36043
|
+
}
|
|
36044
|
+
};
|
|
35699
36045
|
return {
|
|
35700
36046
|
addPhysicalCardSvc,
|
|
35701
36047
|
addNonPhysicalCardSvc,
|
|
@@ -35730,7 +36076,8 @@ function useAccessManagementSvc() {
|
|
|
35730
36076
|
addVisitorAccessCardSvc,
|
|
35731
36077
|
signQrCodeSvc,
|
|
35732
36078
|
checkoutVisitorSvc,
|
|
35733
|
-
getBlockLevelAndUnitListSvc
|
|
36079
|
+
getBlockLevelAndUnitListSvc,
|
|
36080
|
+
getTransactionsSvc
|
|
35734
36081
|
};
|
|
35735
36082
|
}
|
|
35736
36083
|
|
|
@@ -35770,7 +36117,8 @@ function useAccessManagementController() {
|
|
|
35770
36117
|
addVisitorAccessCardSvc,
|
|
35771
36118
|
signQrCodeSvc,
|
|
35772
36119
|
checkoutVisitorSvc,
|
|
35773
|
-
getBlockLevelAndUnitListSvc
|
|
36120
|
+
getBlockLevelAndUnitListSvc,
|
|
36121
|
+
getTransactionsSvc
|
|
35774
36122
|
} = useAccessManagementSvc();
|
|
35775
36123
|
const addPhysicalCard = async (req, res) => {
|
|
35776
36124
|
try {
|
|
@@ -36532,6 +36880,31 @@ function useAccessManagementController() {
|
|
|
36532
36880
|
});
|
|
36533
36881
|
}
|
|
36534
36882
|
};
|
|
36883
|
+
const getTransactions2 = async (req, res) => {
|
|
36884
|
+
const { page = 1, limit = 10, site, cardNo, url } = req.query;
|
|
36885
|
+
const schema2 = Joi85.object({
|
|
36886
|
+
page: Joi85.number().required(),
|
|
36887
|
+
limit: Joi85.number().optional().default(10),
|
|
36888
|
+
site: Joi85.string().hex().required(),
|
|
36889
|
+
cardNo: Joi85.string().required()
|
|
36890
|
+
});
|
|
36891
|
+
const { value, error } = schema2.validate({ page, limit, site, cardNo });
|
|
36892
|
+
if (error) {
|
|
36893
|
+
return res.status(400).json({ message: error.message });
|
|
36894
|
+
}
|
|
36895
|
+
try {
|
|
36896
|
+
const result = await getTransactionsSvc({
|
|
36897
|
+
page: Number(page),
|
|
36898
|
+
limit: Number(value.limit),
|
|
36899
|
+
site,
|
|
36900
|
+
cardNo,
|
|
36901
|
+
url
|
|
36902
|
+
});
|
|
36903
|
+
return res.json(result);
|
|
36904
|
+
} catch (error2) {
|
|
36905
|
+
return Promise.reject("Internal Server Error");
|
|
36906
|
+
}
|
|
36907
|
+
};
|
|
36535
36908
|
return {
|
|
36536
36909
|
addPhysicalCard,
|
|
36537
36910
|
addNonPhysicalCard,
|
|
@@ -36564,7 +36937,8 @@ function useAccessManagementController() {
|
|
|
36564
36937
|
signQrCode,
|
|
36565
36938
|
checkoutVisitor,
|
|
36566
36939
|
removeAccessCard,
|
|
36567
|
-
getBlockLevelAndUnitList
|
|
36940
|
+
getBlockLevelAndUnitList,
|
|
36941
|
+
getTransactions: getTransactions2
|
|
36568
36942
|
};
|
|
36569
36943
|
}
|
|
36570
36944
|
|
|
@@ -44418,14 +44792,15 @@ async function hrmLabsAuthentication({
|
|
|
44418
44792
|
showPassword: false
|
|
44419
44793
|
},
|
|
44420
44794
|
{
|
|
44421
|
-
headers: { "Content-Type": "application/json" }
|
|
44795
|
+
headers: { "Content-Type": "application/json" },
|
|
44796
|
+
validateStatus: () => true
|
|
44422
44797
|
}
|
|
44423
44798
|
);
|
|
44424
44799
|
if (res.data?.success && res.data.data?.token) {
|
|
44425
44800
|
return res.data.data.token;
|
|
44426
44801
|
}
|
|
44427
44802
|
throw new Error(
|
|
44428
|
-
"HRMLabs Authentication failed. Please check your credentials."
|
|
44803
|
+
res.status === 401 || res.status === 403 ? "HRMLabs Authentication failed. Please check your credentials." : `HRMLabs Authentication failed with status ${res.status}.`
|
|
44429
44804
|
);
|
|
44430
44805
|
}
|
|
44431
44806
|
async function fetchAttendanceData({
|
|
@@ -46649,7 +47024,7 @@ function useHrmLabsAttendanceSrvc() {
|
|
|
46649
47024
|
} catch (error) {
|
|
46650
47025
|
logger168.error(error.message || error);
|
|
46651
47026
|
console.log("Error fetching attendance data:", error);
|
|
46652
|
-
|
|
47027
|
+
return { success: false, message: error?.message || "Internal Server Error!", items: [], pages: 0, pageRange: "0-0 of 0", count: {} };
|
|
46653
47028
|
}
|
|
46654
47029
|
}
|
|
46655
47030
|
async function getAttendanceDataCount(payload) {
|
|
@@ -46763,7 +47138,7 @@ function useHrmLabsAttendanceSrvc() {
|
|
|
46763
47138
|
} catch (error) {
|
|
46764
47139
|
logger168.error(error.message || error);
|
|
46765
47140
|
console.log("Error fetching attendance data count:", error);
|
|
46766
|
-
|
|
47141
|
+
return { success: false, message: error?.message || "Internal Server Error!", totalCount: null };
|
|
46767
47142
|
}
|
|
46768
47143
|
}
|
|
46769
47144
|
async function getAllAttendance(payload) {
|
|
@@ -46935,7 +47310,7 @@ function useHrmLabsAttendanceSrvc() {
|
|
|
46935
47310
|
} catch (error) {
|
|
46936
47311
|
logger168.error(error.message || error);
|
|
46937
47312
|
console.log("Error fetching attendance data:", error);
|
|
46938
|
-
|
|
47313
|
+
return { success: false, message: error?.message || "Internal Server Error!", items: [], count: {}, countPerJobTitle: {}, totalCount: null, countPerStatus: {} };
|
|
46939
47314
|
}
|
|
46940
47315
|
}
|
|
46941
47316
|
async function getChartAttendanceData(payload) {
|
|
@@ -47042,7 +47417,7 @@ function useHrmLabsAttendanceSrvc() {
|
|
|
47042
47417
|
} catch (error) {
|
|
47043
47418
|
logger168.error(error.message || error);
|
|
47044
47419
|
console.log("Error fetching attendance data:", error);
|
|
47045
|
-
|
|
47420
|
+
return { success: false, message: error?.message || "Internal Server Error!", chartCount: null };
|
|
47046
47421
|
}
|
|
47047
47422
|
}
|
|
47048
47423
|
return {
|
|
@@ -48700,7 +49075,8 @@ function useVerificationServiceV2() {
|
|
|
48700
49075
|
add: _add,
|
|
48701
49076
|
updateVerificationStatusById: _updateVerificationStatusById,
|
|
48702
49077
|
getByVerificationCode: _getByVerificationCode,
|
|
48703
|
-
updateStatusById: _updateStatusById
|
|
49078
|
+
updateStatusById: _updateStatusById,
|
|
49079
|
+
countPendingOrgInvites: _countPendingOrgInvites
|
|
48704
49080
|
} = useVerificationRepoV2();
|
|
48705
49081
|
const {
|
|
48706
49082
|
getUserByEmailStatus: _getUserByEmailStatus,
|
|
@@ -48708,6 +49084,8 @@ function useVerificationServiceV2() {
|
|
|
48708
49084
|
} = useUserRepo();
|
|
48709
49085
|
const { getById: getOrgById, getByEmail: _getByEmail } = useOrgRepo();
|
|
48710
49086
|
const { getSiteById } = useSiteRepo();
|
|
49087
|
+
const { getByOrgId: _getSubscriptionByOrgId } = useSubscriptionRepo();
|
|
49088
|
+
const { countByOrg: _countMemberByOrg } = useMemberRepo();
|
|
48711
49089
|
function errorByType(type, status) {
|
|
48712
49090
|
if ((type === "user-invite" /* USER_INVITE */ || type === "member-invite" /* MEMBER_INVITE */ || type === "service-provider-invite" /* SERVICE_PROVIDER_INVITE */ || type === "service-provider-create-org" /* SERVICE_PROVIDER_CREATE_ORG */) && status === "expired" /* EXPIRED */) {
|
|
48713
49091
|
throw new BadRequestError199(
|
|
@@ -48971,6 +49349,30 @@ function useVerificationServiceV2() {
|
|
|
48971
49349
|
throw error2;
|
|
48972
49350
|
}
|
|
48973
49351
|
}
|
|
49352
|
+
async function createOrganizationInvite({
|
|
49353
|
+
email,
|
|
49354
|
+
metadata
|
|
49355
|
+
}) {
|
|
49356
|
+
const orgId = metadata.org?.toString() ?? "";
|
|
49357
|
+
if (!orgId) {
|
|
49358
|
+
throw new BadRequestError199("Organization is required.");
|
|
49359
|
+
}
|
|
49360
|
+
await getOrgById(orgId);
|
|
49361
|
+
const [subscription, memberCount, pendingInviteCount] = await Promise.all([
|
|
49362
|
+
_getSubscriptionByOrgId(orgId),
|
|
49363
|
+
_countMemberByOrg(orgId),
|
|
49364
|
+
_countPendingOrgInvites(orgId)
|
|
49365
|
+
]);
|
|
49366
|
+
const maxSeats = subscription?.maxSeats ?? 0;
|
|
49367
|
+
if (!maxSeats) {
|
|
49368
|
+
throw new BadRequestError199("No seats configured for organization.");
|
|
49369
|
+
}
|
|
49370
|
+
const usedSeats = memberCount + pendingInviteCount;
|
|
49371
|
+
if (usedSeats >= maxSeats) {
|
|
49372
|
+
throw new BadRequestError199("No available seats for new invitation.");
|
|
49373
|
+
}
|
|
49374
|
+
return createUserInvite({ email, metadata });
|
|
49375
|
+
}
|
|
48974
49376
|
async function createForgetPassword(email) {
|
|
48975
49377
|
const value = {
|
|
48976
49378
|
type: "forget-password" /* FORGET_PASSWORD */,
|
|
@@ -49021,6 +49423,7 @@ function useVerificationServiceV2() {
|
|
|
49021
49423
|
signUp,
|
|
49022
49424
|
verify,
|
|
49023
49425
|
createUserInvite,
|
|
49426
|
+
createOrganizationInvite,
|
|
49024
49427
|
createServiceProviderInvite,
|
|
49025
49428
|
createForgetPassword,
|
|
49026
49429
|
cancelUserInvitation
|
|
@@ -49034,6 +49437,7 @@ function useVerificationControllerV2() {
|
|
|
49034
49437
|
const {
|
|
49035
49438
|
verify: _verify,
|
|
49036
49439
|
createUserInvite: _createUserInvite,
|
|
49440
|
+
createOrganizationInvite: _createOrganizationInvite,
|
|
49037
49441
|
createServiceProviderInvite: _createServiceProviderInvite,
|
|
49038
49442
|
createForgetPassword: _createForgetPassword,
|
|
49039
49443
|
cancelUserInvitation: _cancelUserInvitation
|
|
@@ -49130,6 +49534,44 @@ function useVerificationControllerV2() {
|
|
|
49130
49534
|
return;
|
|
49131
49535
|
}
|
|
49132
49536
|
}
|
|
49537
|
+
async function createOrganizationInvite(req, res, next) {
|
|
49538
|
+
const schema2 = Joi127.object({
|
|
49539
|
+
email: Joi127.string().email().lowercase().required(),
|
|
49540
|
+
role: Joi127.string().hex().length(24).required(),
|
|
49541
|
+
org: Joi127.string().hex().length(24).required(),
|
|
49542
|
+
app: Joi127.string().optional().allow("", null).default("organization"),
|
|
49543
|
+
name: Joi127.string().optional().allow("", null),
|
|
49544
|
+
siteId: Joi127.string().hex().length(24).optional().allow("", null),
|
|
49545
|
+
siteName: Joi127.string().optional().allow("", null)
|
|
49546
|
+
});
|
|
49547
|
+
const { error, value } = schema2.validate(req.body, { abortEarly: false });
|
|
49548
|
+
if (error) {
|
|
49549
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
49550
|
+
logger178.log({ level: "error", message: messages });
|
|
49551
|
+
next(new BadRequestError200(messages));
|
|
49552
|
+
return;
|
|
49553
|
+
}
|
|
49554
|
+
try {
|
|
49555
|
+
const { email, app, role, name, org, siteId, siteName } = value;
|
|
49556
|
+
await _createOrganizationInvite({
|
|
49557
|
+
email,
|
|
49558
|
+
metadata: {
|
|
49559
|
+
app,
|
|
49560
|
+
role,
|
|
49561
|
+
name,
|
|
49562
|
+
org,
|
|
49563
|
+
siteId,
|
|
49564
|
+
siteName
|
|
49565
|
+
}
|
|
49566
|
+
});
|
|
49567
|
+
res.status(201).json({ message: "Successfully invited user." });
|
|
49568
|
+
return;
|
|
49569
|
+
} catch (error2) {
|
|
49570
|
+
logger178.log({ level: "error", message: `${error2.message}` });
|
|
49571
|
+
next(error2);
|
|
49572
|
+
return;
|
|
49573
|
+
}
|
|
49574
|
+
}
|
|
49133
49575
|
async function createForgetPassword(req, res, next) {
|
|
49134
49576
|
const schema2 = Joi127.object({
|
|
49135
49577
|
email: Joi127.string().email().lowercase().required()
|
|
@@ -49215,6 +49657,7 @@ function useVerificationControllerV2() {
|
|
|
49215
49657
|
return {
|
|
49216
49658
|
verify,
|
|
49217
49659
|
createUserInvite,
|
|
49660
|
+
createOrganizationInvite,
|
|
49218
49661
|
createServiceProviderInvite,
|
|
49219
49662
|
createForgetPassword,
|
|
49220
49663
|
getVerifications,
|
|
@@ -50612,6 +51055,10 @@ export {
|
|
|
50612
51055
|
EmailSender,
|
|
50613
51056
|
EntryOrder,
|
|
50614
51057
|
EntrySort,
|
|
51058
|
+
EventOrder,
|
|
51059
|
+
EventSort,
|
|
51060
|
+
EventStatus,
|
|
51061
|
+
EventType,
|
|
50615
51062
|
FacilitySort,
|
|
50616
51063
|
FacilityStatus,
|
|
50617
51064
|
GuestSort,
|
|
@@ -50724,6 +51171,7 @@ export {
|
|
|
50724
51171
|
events_namespace_collection,
|
|
50725
51172
|
facility_bookings_namespace_collection,
|
|
50726
51173
|
feedbackSchema,
|
|
51174
|
+
feedbacks2_namespace_collection,
|
|
50727
51175
|
feedbacks_namespace_collection,
|
|
50728
51176
|
formatDahuaDate,
|
|
50729
51177
|
getPeriodRangeWithPrevious,
|