@7365admin1/core 2.76.0 → 2.77.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 +6 -0
- package/dist/index.d.ts +40 -6
- package/dist/index.js +587 -120
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +590 -120
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3298,6 +3298,20 @@ function useMemberRepo() {
|
|
|
3298
3298
|
{ $sort: { _id: -1 } },
|
|
3299
3299
|
{ $skip: page * limit },
|
|
3300
3300
|
{ $limit: limit },
|
|
3301
|
+
{
|
|
3302
|
+
$lookup: {
|
|
3303
|
+
from: "organizations",
|
|
3304
|
+
localField: "org",
|
|
3305
|
+
foreignField: "_id",
|
|
3306
|
+
as: "orgData"
|
|
3307
|
+
}
|
|
3308
|
+
},
|
|
3309
|
+
{
|
|
3310
|
+
$unwind: {
|
|
3311
|
+
path: "$orgData",
|
|
3312
|
+
preserveNullAndEmptyArrays: true
|
|
3313
|
+
}
|
|
3314
|
+
},
|
|
3301
3315
|
{
|
|
3302
3316
|
$lookup: {
|
|
3303
3317
|
from: "organizations",
|
|
@@ -3317,7 +3331,16 @@ function useMemberRepo() {
|
|
|
3317
3331
|
_id: "$org",
|
|
3318
3332
|
text: { $first: "$orgName" },
|
|
3319
3333
|
value: { $first: "$org" },
|
|
3320
|
-
defaultSite: { $first: "$defaultSite.defaultSite" }
|
|
3334
|
+
defaultSite: { $first: "$defaultSite.defaultSite" },
|
|
3335
|
+
onboardingRequired: {
|
|
3336
|
+
$first: "$orgData.onboardingRequired"
|
|
3337
|
+
},
|
|
3338
|
+
onboardingCompleted: {
|
|
3339
|
+
$first: "$orgData.onboardingCompleted"
|
|
3340
|
+
},
|
|
3341
|
+
onboardingCompletedAt: {
|
|
3342
|
+
$first: "$orgData.onboardingCompletedAt"
|
|
3343
|
+
}
|
|
3321
3344
|
}
|
|
3322
3345
|
},
|
|
3323
3346
|
{
|
|
@@ -3325,15 +3348,16 @@ function useMemberRepo() {
|
|
|
3325
3348
|
_id: 0,
|
|
3326
3349
|
text: 1,
|
|
3327
3350
|
value: 1,
|
|
3328
|
-
defaultSite: 1
|
|
3351
|
+
defaultSite: 1,
|
|
3352
|
+
onboardingRequired: 1,
|
|
3353
|
+
onboardingCompleted: 1,
|
|
3354
|
+
onboardingCompletedAt: 1
|
|
3329
3355
|
}
|
|
3330
3356
|
}
|
|
3331
3357
|
]).toArray();
|
|
3332
3358
|
const length = await collection.distinct("org", query).then((orgs) => orgs.length);
|
|
3333
3359
|
const data = paginate5(items, page, limit, length);
|
|
3334
|
-
setCache(cacheKey, data, 15 * 60).
|
|
3335
|
-
logger8.info(`Cache set for key: ${cacheKey}`);
|
|
3336
|
-
}).catch((err) => {
|
|
3360
|
+
setCache(cacheKey, data, 15 * 60).catch((err) => {
|
|
3337
3361
|
logger8.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
3338
3362
|
});
|
|
3339
3363
|
return data;
|
|
@@ -4208,6 +4232,9 @@ var orgSchema = Joi8.object({
|
|
|
4208
4232
|
busInst: Joi8.string().optional().allow("", null),
|
|
4209
4233
|
status: Joi8.string().optional().allow("", null),
|
|
4210
4234
|
defaultSite: Joi8.string().hex().optional().allow("", null),
|
|
4235
|
+
onboardingRequired: Joi8.boolean().optional(),
|
|
4236
|
+
onboardingCompleted: Joi8.boolean().optional(),
|
|
4237
|
+
onboardingCompletedAt: Joi8.date().optional().allow(null),
|
|
4211
4238
|
terms: Joi8.string().optional().allow("", null),
|
|
4212
4239
|
policies: Joi8.string().optional().allow("", null),
|
|
4213
4240
|
createdAt: Joi8.string().optional().allow("", null),
|
|
@@ -4237,6 +4264,9 @@ function MOrg(value) {
|
|
|
4237
4264
|
busInst: value.busInst,
|
|
4238
4265
|
status: value.status || "active",
|
|
4239
4266
|
defaultSite: value.defaultSite,
|
|
4267
|
+
onboardingRequired: value.onboardingRequired || false,
|
|
4268
|
+
onboardingCompleted: value.onboardingCompleted || false,
|
|
4269
|
+
onboardingCompletedAt: value.onboardingCompletedAt || null,
|
|
4240
4270
|
terms: value.terms ?? "",
|
|
4241
4271
|
policies: value.policies ?? "",
|
|
4242
4272
|
createdAt: value.createdAt || /* @__PURE__ */ new Date(),
|
|
@@ -8990,7 +9020,7 @@ function useOrgController() {
|
|
|
8990
9020
|
return;
|
|
8991
9021
|
}
|
|
8992
9022
|
try {
|
|
8993
|
-
const _id = await _add(req.body);
|
|
9023
|
+
const _id = await _add({ ...req.body, onboardingRequired: true, onboardingCompleted: false, onboardingCompletedAt: null });
|
|
8994
9024
|
const data = await _getById(_id);
|
|
8995
9025
|
res.status(201).json({
|
|
8996
9026
|
message: "Successfully created organization.",
|
|
@@ -15393,10 +15423,10 @@ import {
|
|
|
15393
15423
|
import { BadRequestError as BadRequestError68, logger as logger49 } from "@7365admin1/node-server-utils";
|
|
15394
15424
|
import Joi38 from "joi";
|
|
15395
15425
|
import { ObjectId as ObjectId41 } from "mongodb";
|
|
15396
|
-
var VehicleType = /* @__PURE__ */ ((
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
return
|
|
15426
|
+
var VehicleType = /* @__PURE__ */ ((VehicleType3) => {
|
|
15427
|
+
VehicleType3["WHITELIST"] = "whitelist";
|
|
15428
|
+
VehicleType3["BLOCKLIST"] = "blocklist";
|
|
15429
|
+
return VehicleType3;
|
|
15400
15430
|
})(VehicleType || {});
|
|
15401
15431
|
var VehicleCategory = /* @__PURE__ */ ((VehicleCategory2) => {
|
|
15402
15432
|
VehicleCategory2["RESIDENT"] = "resident";
|
|
@@ -16456,6 +16486,77 @@ function useDahuaDigest({
|
|
|
16456
16486
|
streaming
|
|
16457
16487
|
});
|
|
16458
16488
|
}
|
|
16489
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
16490
|
+
function isDahuaInvalidAuthority(value) {
|
|
16491
|
+
const text = String(value || "").toLowerCase();
|
|
16492
|
+
return text.includes("invalid authority");
|
|
16493
|
+
}
|
|
16494
|
+
function getDahuaResponseText(response) {
|
|
16495
|
+
return response?.data?.toString?.("utf-8") ?? "";
|
|
16496
|
+
}
|
|
16497
|
+
function getDahuaStatusCode(response) {
|
|
16498
|
+
return response?.statusCode || response?.status || response?.res?.status;
|
|
16499
|
+
}
|
|
16500
|
+
async function useDahuaDigestWithRetry({
|
|
16501
|
+
host,
|
|
16502
|
+
username,
|
|
16503
|
+
password,
|
|
16504
|
+
endpoint,
|
|
16505
|
+
method = "GET",
|
|
16506
|
+
headers = {},
|
|
16507
|
+
timeout = 1e4,
|
|
16508
|
+
streaming = false,
|
|
16509
|
+
retries = 3,
|
|
16510
|
+
retryDelayMs = 0
|
|
16511
|
+
}) {
|
|
16512
|
+
let lastError;
|
|
16513
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
16514
|
+
try {
|
|
16515
|
+
const response = await useDahuaDigest({
|
|
16516
|
+
host,
|
|
16517
|
+
username,
|
|
16518
|
+
password,
|
|
16519
|
+
endpoint,
|
|
16520
|
+
method,
|
|
16521
|
+
headers,
|
|
16522
|
+
timeout,
|
|
16523
|
+
streaming
|
|
16524
|
+
});
|
|
16525
|
+
const text = getDahuaResponseText(response);
|
|
16526
|
+
const statusCode = getDahuaStatusCode(response);
|
|
16527
|
+
const isOk = statusCode === 200 && text.includes("OK");
|
|
16528
|
+
if (isOk) {
|
|
16529
|
+
return response;
|
|
16530
|
+
}
|
|
16531
|
+
const shouldRetry = isDahuaInvalidAuthority(text);
|
|
16532
|
+
if (shouldRetry && attempt < retries) {
|
|
16533
|
+
loggerDahua.warn(
|
|
16534
|
+
`[${host}] Dahua Invalid Authority. Retrying ${attempt}/${retries}`
|
|
16535
|
+
);
|
|
16536
|
+
if (retryDelayMs > 0) {
|
|
16537
|
+
await sleep(retryDelayMs);
|
|
16538
|
+
}
|
|
16539
|
+
continue;
|
|
16540
|
+
}
|
|
16541
|
+
throw new Error(`Dahua response: ${text || `HTTP ${statusCode}`}`);
|
|
16542
|
+
} catch (error) {
|
|
16543
|
+
lastError = error;
|
|
16544
|
+
const message = error?.message || String(error);
|
|
16545
|
+
const shouldRetry = isDahuaInvalidAuthority(message);
|
|
16546
|
+
if (shouldRetry && attempt < retries) {
|
|
16547
|
+
loggerDahua.warn(
|
|
16548
|
+
`[${host}] Dahua Invalid Authority error. Retrying ${attempt}/${retries}`
|
|
16549
|
+
);
|
|
16550
|
+
if (retryDelayMs > 0) {
|
|
16551
|
+
await sleep(retryDelayMs);
|
|
16552
|
+
}
|
|
16553
|
+
continue;
|
|
16554
|
+
}
|
|
16555
|
+
throw error;
|
|
16556
|
+
}
|
|
16557
|
+
}
|
|
16558
|
+
throw lastError;
|
|
16559
|
+
}
|
|
16459
16560
|
function createFileNameFromEvent(utcSeconds, utcMilliseconds) {
|
|
16460
16561
|
const date = new Date(utcSeconds * 1e3 + utcMilliseconds);
|
|
16461
16562
|
const year = date.getUTCFullYear();
|
|
@@ -17106,6 +17207,50 @@ function useDahuaService() {
|
|
|
17106
17207
|
);
|
|
17107
17208
|
}
|
|
17108
17209
|
}
|
|
17210
|
+
async function openBarrier(value) {
|
|
17211
|
+
const validation = Joi40.object({
|
|
17212
|
+
host: Joi40.string().required(),
|
|
17213
|
+
username: Joi40.string().required(),
|
|
17214
|
+
password: Joi40.string().required(),
|
|
17215
|
+
plateNumber: Joi40.string().required(),
|
|
17216
|
+
channel: Joi40.number().integer().min(1).default(1)
|
|
17217
|
+
});
|
|
17218
|
+
const { error, value: payload } = validation.validate(value, {
|
|
17219
|
+
stripUnknown: true
|
|
17220
|
+
});
|
|
17221
|
+
if (error) {
|
|
17222
|
+
throw new BadRequestError70(`Validation error: ${error.message}`);
|
|
17223
|
+
}
|
|
17224
|
+
try {
|
|
17225
|
+
const query = new URLSearchParams({
|
|
17226
|
+
action: "openStrobe",
|
|
17227
|
+
channel: String(payload.channel),
|
|
17228
|
+
"info.openType": "Normal",
|
|
17229
|
+
"info.plateNumber": payload.plateNumber || "VISITOR"
|
|
17230
|
+
});
|
|
17231
|
+
const endpoint = `/cgi-bin/trafficSnap.cgi?${query.toString()}`;
|
|
17232
|
+
const response = await useDahuaDigestWithRetry({
|
|
17233
|
+
host: payload.host,
|
|
17234
|
+
username: payload.username,
|
|
17235
|
+
password: payload.password,
|
|
17236
|
+
endpoint,
|
|
17237
|
+
retries: 10,
|
|
17238
|
+
retryDelayMs: 0
|
|
17239
|
+
});
|
|
17240
|
+
const text = response?.data?.toString?.("utf-8") ?? "";
|
|
17241
|
+
if (!text.includes("OK")) {
|
|
17242
|
+
throw new Error(`Failed to open barrier. Dahua response: ${text}`);
|
|
17243
|
+
}
|
|
17244
|
+
return {
|
|
17245
|
+
success: true,
|
|
17246
|
+
message: "Barrier opened successfully",
|
|
17247
|
+
raw: text
|
|
17248
|
+
};
|
|
17249
|
+
} catch (error2) {
|
|
17250
|
+
loggerDahua.error(`[${value.host}] Error opening barrier:`, error2);
|
|
17251
|
+
throw error2;
|
|
17252
|
+
}
|
|
17253
|
+
}
|
|
17109
17254
|
return {
|
|
17110
17255
|
getSnapshot,
|
|
17111
17256
|
listenToCamera,
|
|
@@ -17113,7 +17258,8 @@ function useDahuaService() {
|
|
|
17113
17258
|
removePlateNumber,
|
|
17114
17259
|
updatePlateNumber,
|
|
17115
17260
|
getPlateNumber,
|
|
17116
|
-
bulkInsertPlateNumber
|
|
17261
|
+
bulkInsertPlateNumber,
|
|
17262
|
+
openBarrier
|
|
17117
17263
|
};
|
|
17118
17264
|
}
|
|
17119
17265
|
|
|
@@ -17320,6 +17466,43 @@ function useSiteCameraRepo() {
|
|
|
17320
17466
|
throw new BadRequestError71("Failed to retrieve site cameras.");
|
|
17321
17467
|
}
|
|
17322
17468
|
}
|
|
17469
|
+
async function getVisitorsInBySite(site) {
|
|
17470
|
+
try {
|
|
17471
|
+
const pipeline = [
|
|
17472
|
+
{ $match: { site: toObjectId9(site), type: "anpr", status: "active", direction: { $in: ["visitors", "entry", "both"] } } },
|
|
17473
|
+
{ $limit: 1 },
|
|
17474
|
+
{
|
|
17475
|
+
$lookup: {
|
|
17476
|
+
from: "anpr-settings",
|
|
17477
|
+
localField: "site",
|
|
17478
|
+
foreignField: "site",
|
|
17479
|
+
as: "anprSettingsDetails"
|
|
17480
|
+
}
|
|
17481
|
+
},
|
|
17482
|
+
{
|
|
17483
|
+
$unwind: {
|
|
17484
|
+
path: "$anprSettingsDetails",
|
|
17485
|
+
preserveNullAndEmptyArrays: true
|
|
17486
|
+
}
|
|
17487
|
+
},
|
|
17488
|
+
{
|
|
17489
|
+
$addFields: {
|
|
17490
|
+
ANPRSwitches: "$anprSettingsDetails.ANPRSwitches"
|
|
17491
|
+
}
|
|
17492
|
+
},
|
|
17493
|
+
{
|
|
17494
|
+
$project: { anprSettingsDetails: 0 }
|
|
17495
|
+
}
|
|
17496
|
+
];
|
|
17497
|
+
const cameras = await collection.aggregate(pipeline).toArray();
|
|
17498
|
+
return cameras?.find((cam) => cam.direction === "visitors" || cam.direction === "entry" || cam.direction === "both");
|
|
17499
|
+
} catch (error) {
|
|
17500
|
+
if (error instanceof BadRequestError71) {
|
|
17501
|
+
throw error;
|
|
17502
|
+
}
|
|
17503
|
+
throw new BadRequestError71("Failed to retrieve site cameras.");
|
|
17504
|
+
}
|
|
17505
|
+
}
|
|
17323
17506
|
async function getBySiteGuardPost(site, guardPost) {
|
|
17324
17507
|
try {
|
|
17325
17508
|
site = new ObjectId43(site);
|
|
@@ -17674,6 +17857,7 @@ function useSiteCameraRepo() {
|
|
|
17674
17857
|
getAll,
|
|
17675
17858
|
findSiteCameras,
|
|
17676
17859
|
getBySite,
|
|
17860
|
+
getVisitorsInBySite,
|
|
17677
17861
|
getBySites,
|
|
17678
17862
|
delCachedData,
|
|
17679
17863
|
getBySiteGuardPost,
|
|
@@ -25969,13 +26153,14 @@ function useVisitorTransactionService() {
|
|
|
25969
26153
|
getByNRIC,
|
|
25970
26154
|
updateById: _updateById
|
|
25971
26155
|
} = usePersonRepo();
|
|
25972
|
-
const { getBySite: _getBySite } = useSiteCameraRepo();
|
|
26156
|
+
const { getBySite: _getBySite, getVisitorsInBySite: _getVisitorsInBySite } = useSiteCameraRepo();
|
|
25973
26157
|
const { getSiteById: _getSiteById } = useSiteRepo();
|
|
25974
26158
|
const {
|
|
25975
26159
|
addPlateNumber: _addPlateNumber,
|
|
25976
26160
|
removePlateNumber: _removePlateNumber,
|
|
25977
26161
|
getPlateNumber: _getPlateNumber,
|
|
25978
|
-
updatePlateNumber: _updatePlateNumber
|
|
26162
|
+
updatePlateNumber: _updatePlateNumber,
|
|
26163
|
+
openBarrier: _openBarrier
|
|
25979
26164
|
} = useDahuaService();
|
|
25980
26165
|
const { getAllSites: _getAllSites } = useSiteRepo();
|
|
25981
26166
|
const { getByUserId: _getByUserId } = usePersonRepo();
|
|
@@ -26051,28 +26236,30 @@ function useVisitorTransactionService() {
|
|
|
26051
26236
|
"contractor" /* CONTRACTOR */,
|
|
26052
26237
|
"walk-in" /* WALK_IN */,
|
|
26053
26238
|
"guest" /* GUEST */,
|
|
26054
|
-
"delivery" /* DELIVERY
|
|
26055
|
-
|
|
26239
|
+
"delivery" /* DELIVERY */
|
|
26240
|
+
// PersonTypes.PICK_UP,
|
|
26056
26241
|
];
|
|
26057
26242
|
const start = value.checkIn ? new Date(value.checkIn) : /* @__PURE__ */ new Date();
|
|
26058
26243
|
try {
|
|
26059
26244
|
session?.startTransaction();
|
|
26060
26245
|
let camera;
|
|
26061
|
-
|
|
26062
|
-
|
|
26063
|
-
|
|
26064
|
-
|
|
26065
|
-
|
|
26066
|
-
|
|
26246
|
+
if (value.site && value.plateNumber) {
|
|
26247
|
+
try {
|
|
26248
|
+
camera = await _getVisitorsInBySite(value.site);
|
|
26249
|
+
if (!camera) {
|
|
26250
|
+
logger80.warn(`No camera document found for site: ${value.site}`);
|
|
26251
|
+
}
|
|
26252
|
+
} catch (error) {
|
|
26253
|
+
logger80.error(
|
|
26254
|
+
`Error _getVisitorsInBySite camera for site ${value.site}:`,
|
|
26255
|
+
error
|
|
26256
|
+
);
|
|
26257
|
+
}
|
|
26067
26258
|
}
|
|
26068
26259
|
if (!value.unitName && value.unit) {
|
|
26069
26260
|
const unit = await _getUnitById(value.unit);
|
|
26070
26261
|
value.unitName = unit?.name;
|
|
26071
26262
|
}
|
|
26072
|
-
const hourExpiration = site?.dahuaTimeExpiration ? site?.dahuaTimeExpiration : 24 * 60;
|
|
26073
|
-
const end = value.checkOut ? new Date(value.checkOut) : new Date(start.getTime() + hourExpiration * 60 * 1e3);
|
|
26074
|
-
const startDahuaDate = formatDahuaDate(start);
|
|
26075
|
-
const endDahuaDate = formatDahuaDate(end);
|
|
26076
26263
|
if (allowedPersonTypes.includes(value?.type)) {
|
|
26077
26264
|
const nric = value?.nric || "";
|
|
26078
26265
|
const person = await getByNRIC(nric);
|
|
@@ -26109,7 +26296,7 @@ function useVisitorTransactionService() {
|
|
|
26109
26296
|
block,
|
|
26110
26297
|
level,
|
|
26111
26298
|
unit,
|
|
26112
|
-
site
|
|
26299
|
+
site,
|
|
26113
26300
|
org,
|
|
26114
26301
|
type,
|
|
26115
26302
|
company,
|
|
@@ -26165,14 +26352,14 @@ function useVisitorTransactionService() {
|
|
|
26165
26352
|
level,
|
|
26166
26353
|
unit,
|
|
26167
26354
|
unitName,
|
|
26168
|
-
site
|
|
26355
|
+
site,
|
|
26169
26356
|
org,
|
|
26170
26357
|
type,
|
|
26171
26358
|
company,
|
|
26172
26359
|
remarks,
|
|
26173
26360
|
contractorType,
|
|
26174
26361
|
checkIn: start,
|
|
26175
|
-
expiredAt: end,
|
|
26362
|
+
// expiredAt: end,
|
|
26176
26363
|
visitorPass: visitorPass ?? [],
|
|
26177
26364
|
passKeys: passKeys ?? [],
|
|
26178
26365
|
status: "registered" /* REGISTERED */
|
|
@@ -26183,11 +26370,13 @@ function useVisitorTransactionService() {
|
|
|
26183
26370
|
);
|
|
26184
26371
|
}
|
|
26185
26372
|
}
|
|
26373
|
+
let host;
|
|
26374
|
+
let username;
|
|
26375
|
+
let password;
|
|
26186
26376
|
if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
|
|
26187
|
-
|
|
26188
|
-
|
|
26189
|
-
|
|
26190
|
-
const redlist = "TrafficRedList" /* TRAFFIC_REDLIST */;
|
|
26377
|
+
host = camera.host;
|
|
26378
|
+
username = camera.username;
|
|
26379
|
+
password = camera.password;
|
|
26191
26380
|
const blacklist = "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
|
|
26192
26381
|
const _plateNumber = value.plateNumber;
|
|
26193
26382
|
const dahuaBlocklistQuery = {
|
|
@@ -26203,74 +26392,6 @@ function useVisitorTransactionService() {
|
|
|
26203
26392
|
const found = foundMatch ? Number(foundMatch[1]) : 0;
|
|
26204
26393
|
if (found === 1)
|
|
26205
26394
|
throw new BadRequestError100("This plate number is blocklisted");
|
|
26206
|
-
const dahuaQuery = {
|
|
26207
|
-
host,
|
|
26208
|
-
username,
|
|
26209
|
-
password,
|
|
26210
|
-
plateNumber: _plateNumber,
|
|
26211
|
-
mode: redlist
|
|
26212
|
-
};
|
|
26213
|
-
const raw = await _getPlateNumber(dahuaQuery);
|
|
26214
|
-
const parsed = parseDahuaFind(raw);
|
|
26215
|
-
if (!parsed.exists) {
|
|
26216
|
-
const dahuaPayload = {
|
|
26217
|
-
host,
|
|
26218
|
-
username,
|
|
26219
|
-
password,
|
|
26220
|
-
plateNumber: _plateNumber,
|
|
26221
|
-
mode: redlist,
|
|
26222
|
-
start: startDahuaDate,
|
|
26223
|
-
end: endDahuaDate,
|
|
26224
|
-
owner: value.name ?? "",
|
|
26225
|
-
isOpenGate: site?.isOpenGate ?? true
|
|
26226
|
-
};
|
|
26227
|
-
const dahuaResponse = await _addPlateNumber(dahuaPayload);
|
|
26228
|
-
if (dahuaResponse?.statusCode !== 200) {
|
|
26229
|
-
throw new BadRequestError100(
|
|
26230
|
-
`Failed to add plate number to ANPR whitelist`
|
|
26231
|
-
);
|
|
26232
|
-
}
|
|
26233
|
-
const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
|
|
26234
|
-
value.recNo = responseData.split("=")[1]?.trim();
|
|
26235
|
-
value.checkIn = start;
|
|
26236
|
-
value.expiredAt = end;
|
|
26237
|
-
const vehiclePayload = {
|
|
26238
|
-
name: value.name ?? "",
|
|
26239
|
-
category: value.type,
|
|
26240
|
-
org: value.org,
|
|
26241
|
-
site: value.site,
|
|
26242
|
-
plateNumber: value.plateNumber,
|
|
26243
|
-
type: "whitelist" /* WHITELIST */,
|
|
26244
|
-
nric: value.nric,
|
|
26245
|
-
start,
|
|
26246
|
-
end,
|
|
26247
|
-
recNo: value.recNo,
|
|
26248
|
-
...value.block && { block: value.block },
|
|
26249
|
-
...value.level && { level: value.level },
|
|
26250
|
-
...value.unit && { unit: value.unit }
|
|
26251
|
-
};
|
|
26252
|
-
await addVehicle(vehiclePayload);
|
|
26253
|
-
} else {
|
|
26254
|
-
const dahuaPayload = {
|
|
26255
|
-
host,
|
|
26256
|
-
username,
|
|
26257
|
-
password,
|
|
26258
|
-
plateNumber: _plateNumber,
|
|
26259
|
-
recno: parsed.recNo,
|
|
26260
|
-
mode: redlist,
|
|
26261
|
-
start: startDahuaDate,
|
|
26262
|
-
end: endDahuaDate,
|
|
26263
|
-
owner: value.name ?? "",
|
|
26264
|
-
isOpenGate: site?.isOpenGate ?? true
|
|
26265
|
-
};
|
|
26266
|
-
const dahuaResponse = await _updatePlateNumber(dahuaPayload);
|
|
26267
|
-
if (dahuaResponse?.statusCode !== 200) {
|
|
26268
|
-
throw new BadRequestError100(
|
|
26269
|
-
`Failed to update plate number to ANPR ${"whitelist" /* WHITELIST */}`
|
|
26270
|
-
);
|
|
26271
|
-
}
|
|
26272
|
-
value.recNo = parsed.recNo;
|
|
26273
|
-
}
|
|
26274
26395
|
}
|
|
26275
26396
|
if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0 && value.visitorPass) {
|
|
26276
26397
|
for (const vp of value.visitorPass) {
|
|
@@ -26308,6 +26429,27 @@ function useVisitorTransactionService() {
|
|
|
26308
26429
|
}
|
|
26309
26430
|
const result = await _add(value, session);
|
|
26310
26431
|
await session?.commitTransaction();
|
|
26432
|
+
let openBarrier = null;
|
|
26433
|
+
const isOpenBarrier = allowedPersonTypes.includes(value?.type) || camera?.ANPRSwitches?.openBarrierPickUpDropOff == true;
|
|
26434
|
+
if (isOpenBarrier && value.plateNumber && host && username && password) {
|
|
26435
|
+
try {
|
|
26436
|
+
logger80.info(`Attempting to open barrier at host: ${host}`);
|
|
26437
|
+
openBarrier = await _openBarrier({
|
|
26438
|
+
host,
|
|
26439
|
+
username,
|
|
26440
|
+
password,
|
|
26441
|
+
plateNumber: value?.plateNumber
|
|
26442
|
+
});
|
|
26443
|
+
logger80.info(`Barrier command sent successfully to ${host}`, { response: openBarrier });
|
|
26444
|
+
} catch (error) {
|
|
26445
|
+
logger80.error(
|
|
26446
|
+
`Failed to open barrier at host ${host}. Critical system error:`,
|
|
26447
|
+
error
|
|
26448
|
+
);
|
|
26449
|
+
openBarrier = { success: false, error: error?.message };
|
|
26450
|
+
}
|
|
26451
|
+
}
|
|
26452
|
+
console.log("Open barrier response:", openBarrier);
|
|
26311
26453
|
return result;
|
|
26312
26454
|
} catch (error) {
|
|
26313
26455
|
await session?.abortTransaction();
|
|
@@ -26320,6 +26462,43 @@ function useVisitorTransactionService() {
|
|
|
26320
26462
|
const session = useAtlas50.getClient()?.startSession();
|
|
26321
26463
|
session?.startTransaction();
|
|
26322
26464
|
try {
|
|
26465
|
+
let camera;
|
|
26466
|
+
let host;
|
|
26467
|
+
let username;
|
|
26468
|
+
let password;
|
|
26469
|
+
if (value.site && value.plateNumber) {
|
|
26470
|
+
try {
|
|
26471
|
+
camera = await _getVisitorsInBySite(value.site);
|
|
26472
|
+
if (!camera) {
|
|
26473
|
+
logger80.warn(`No camera document found for site: ${value.site}`);
|
|
26474
|
+
}
|
|
26475
|
+
} catch (error) {
|
|
26476
|
+
logger80.error(
|
|
26477
|
+
`Error _getVisitorsInBySite camera for site ${value.site}:`,
|
|
26478
|
+
error
|
|
26479
|
+
);
|
|
26480
|
+
}
|
|
26481
|
+
}
|
|
26482
|
+
if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
|
|
26483
|
+
host = camera.host;
|
|
26484
|
+
username = camera.username;
|
|
26485
|
+
password = camera.password;
|
|
26486
|
+
const blacklist = "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
|
|
26487
|
+
const _plateNumber = value.plateNumber;
|
|
26488
|
+
const dahuaBlocklistQuery = {
|
|
26489
|
+
host,
|
|
26490
|
+
username,
|
|
26491
|
+
password,
|
|
26492
|
+
plateNumber: _plateNumber,
|
|
26493
|
+
mode: blacklist
|
|
26494
|
+
};
|
|
26495
|
+
const isBlocklistedRaw = await _getPlateNumber(dahuaBlocklistQuery);
|
|
26496
|
+
const rawString = isBlocklistedRaw?.toString?.("utf-8") ?? String(isBlocklistedRaw);
|
|
26497
|
+
const foundMatch = rawString.match(/found=(\d+)/);
|
|
26498
|
+
const found = foundMatch ? Number(foundMatch[1]) : 0;
|
|
26499
|
+
if (found === 1)
|
|
26500
|
+
throw new BadRequestError100("This plate number is blocklisted");
|
|
26501
|
+
}
|
|
26323
26502
|
if (Array.isArray(value.visitorPass) && value.visitorPass.length > 0) {
|
|
26324
26503
|
const keptVisitorPass = [];
|
|
26325
26504
|
for (const vp of value.visitorPass) {
|
|
@@ -26383,6 +26562,34 @@ function useVisitorTransactionService() {
|
|
|
26383
26562
|
value.unitName = unit?.name;
|
|
26384
26563
|
}
|
|
26385
26564
|
await _updateVisitorTansactionById(id, value, session);
|
|
26565
|
+
const allowedPersonTypes = [
|
|
26566
|
+
"contractor" /* CONTRACTOR */,
|
|
26567
|
+
"walk-in" /* WALK_IN */,
|
|
26568
|
+
"guest" /* GUEST */,
|
|
26569
|
+
"delivery" /* DELIVERY */
|
|
26570
|
+
// PersonTypes.PICK_UP,
|
|
26571
|
+
];
|
|
26572
|
+
let openBarrier = null;
|
|
26573
|
+
const isOpenBarrier = allowedPersonTypes.includes(value?.type) || camera?.ANPRSwitches?.openBarrierPickUpDropOff == true;
|
|
26574
|
+
if (isOpenBarrier && value.plateNumber && host && username && password) {
|
|
26575
|
+
try {
|
|
26576
|
+
logger80.info(`Attempting to open barrier at host: ${host}`);
|
|
26577
|
+
openBarrier = await _openBarrier({
|
|
26578
|
+
host,
|
|
26579
|
+
username,
|
|
26580
|
+
password,
|
|
26581
|
+
plateNumber: value?.plateNumber
|
|
26582
|
+
});
|
|
26583
|
+
logger80.info(`Barrier command sent successfully to ${host}`, { response: openBarrier });
|
|
26584
|
+
} catch (error) {
|
|
26585
|
+
logger80.error(
|
|
26586
|
+
`Failed to open barrier at host ${host}. Critical system error:`,
|
|
26587
|
+
error
|
|
26588
|
+
);
|
|
26589
|
+
openBarrier = { success: false, error: error?.message };
|
|
26590
|
+
}
|
|
26591
|
+
}
|
|
26592
|
+
console.log("Open barrier response:", openBarrier);
|
|
26386
26593
|
await session?.commitTransaction();
|
|
26387
26594
|
return "Successfully updated visitor transaction.";
|
|
26388
26595
|
} catch (error) {
|
|
@@ -49603,7 +49810,7 @@ function filterByStatus(attendance, shiftData, timezone, format2, status) {
|
|
|
49603
49810
|
}
|
|
49604
49811
|
});
|
|
49605
49812
|
}
|
|
49606
|
-
function
|
|
49813
|
+
function sleep2(ms) {
|
|
49607
49814
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
49608
49815
|
}
|
|
49609
49816
|
async function fetchSites({ siteUrl, token }) {
|
|
@@ -49630,7 +49837,7 @@ async function fetchSites({ siteUrl, token }) {
|
|
|
49630
49837
|
}
|
|
49631
49838
|
if (attempt < maxRetries) {
|
|
49632
49839
|
const delay = 1e3 * attempt;
|
|
49633
|
-
await
|
|
49840
|
+
await sleep2(delay);
|
|
49634
49841
|
}
|
|
49635
49842
|
}
|
|
49636
49843
|
} while (attempt < maxRetries);
|
|
@@ -56179,7 +56386,7 @@ function usePostPrelovedController() {
|
|
|
56179
56386
|
Joi134.string().valid(...Object.values(PostStatus))
|
|
56180
56387
|
).optional().allow(null),
|
|
56181
56388
|
category: Joi134.string().hex().length(24).optional().allow("", null),
|
|
56182
|
-
subcategory: Joi134.
|
|
56389
|
+
subcategory: Joi134.array().items(Joi134.string()).single().optional().allow(null),
|
|
56183
56390
|
userId: Joi134.string().optional().allow("", null)
|
|
56184
56391
|
});
|
|
56185
56392
|
const { error, value } = validation.validate(req.query, {
|
|
@@ -56389,6 +56596,17 @@ function usePostFavoriteRepo() {
|
|
|
56389
56596
|
throw new NotFoundError58("Favorite not found.");
|
|
56390
56597
|
return result;
|
|
56391
56598
|
}
|
|
56599
|
+
async function getByPostId(postId) {
|
|
56600
|
+
try {
|
|
56601
|
+
postId = new ObjectId135(postId);
|
|
56602
|
+
} catch {
|
|
56603
|
+
throw new BadRequestError214("Invalid post ID format.");
|
|
56604
|
+
}
|
|
56605
|
+
const result = await collection.findOne({ postId });
|
|
56606
|
+
if (!result)
|
|
56607
|
+
throw new NotFoundError58("Favorite not found.");
|
|
56608
|
+
return result;
|
|
56609
|
+
}
|
|
56392
56610
|
async function updateById(_id, userId, session) {
|
|
56393
56611
|
try {
|
|
56394
56612
|
_id = new ObjectId135(_id);
|
|
@@ -56414,6 +56632,7 @@ function usePostFavoriteRepo() {
|
|
|
56414
56632
|
return {
|
|
56415
56633
|
addFavorite,
|
|
56416
56634
|
getById,
|
|
56635
|
+
getByPostId,
|
|
56417
56636
|
updateById
|
|
56418
56637
|
};
|
|
56419
56638
|
}
|
|
@@ -56461,7 +56680,7 @@ import { BadRequestError as BadRequestError215, logger as logger189 } from "@736
|
|
|
56461
56680
|
import Joi136 from "joi";
|
|
56462
56681
|
function usePostFavoriteController() {
|
|
56463
56682
|
const { addFavorite: _addFavorite, toggleFavorite: _toggleFavorite } = usePostFavoriteService();
|
|
56464
|
-
const { getById: _getById } = usePostFavoriteRepo();
|
|
56683
|
+
const { getById: _getById, getByPostId: _getByPostId } = usePostFavoriteRepo();
|
|
56465
56684
|
async function addFavorite(req, res, next) {
|
|
56466
56685
|
const { error, value } = schemaPostFavorite.validate(req.body, {
|
|
56467
56686
|
abortEarly: false
|
|
@@ -56502,6 +56721,26 @@ function usePostFavoriteController() {
|
|
|
56502
56721
|
return;
|
|
56503
56722
|
}
|
|
56504
56723
|
}
|
|
56724
|
+
async function getByPostId(req, res, next) {
|
|
56725
|
+
const schema2 = Joi136.object({
|
|
56726
|
+
postId: Joi136.string().hex().length(24).required()
|
|
56727
|
+
});
|
|
56728
|
+
const { error, value } = schema2.validate({ postId: req.params.postId });
|
|
56729
|
+
if (error) {
|
|
56730
|
+
logger189.log({ level: "error", message: error.message });
|
|
56731
|
+
next(new BadRequestError215(error.message));
|
|
56732
|
+
return;
|
|
56733
|
+
}
|
|
56734
|
+
try {
|
|
56735
|
+
const data = await _getByPostId(value.postId);
|
|
56736
|
+
res.status(200).json(data);
|
|
56737
|
+
return;
|
|
56738
|
+
} catch (error2) {
|
|
56739
|
+
logger189.log({ level: "error", message: error2.message });
|
|
56740
|
+
next(error2);
|
|
56741
|
+
return;
|
|
56742
|
+
}
|
|
56743
|
+
}
|
|
56505
56744
|
async function updateById(req, res, next) {
|
|
56506
56745
|
const paramsSchema = Joi136.object({
|
|
56507
56746
|
_id: Joi136.string().hex().length(24).required()
|
|
@@ -56531,6 +56770,7 @@ function usePostFavoriteController() {
|
|
|
56531
56770
|
return {
|
|
56532
56771
|
addFavorite,
|
|
56533
56772
|
getById,
|
|
56773
|
+
getByPostId,
|
|
56534
56774
|
updateById
|
|
56535
56775
|
};
|
|
56536
56776
|
}
|
|
@@ -56837,7 +57077,50 @@ function useSubcategoryPrelovedRepo() {
|
|
|
56837
57077
|
throw error;
|
|
56838
57078
|
}
|
|
56839
57079
|
}
|
|
56840
|
-
|
|
57080
|
+
async function updateById(_id, value, session) {
|
|
57081
|
+
let objectId2;
|
|
57082
|
+
try {
|
|
57083
|
+
objectId2 = new ObjectId139(_id);
|
|
57084
|
+
} catch {
|
|
57085
|
+
throw new BadRequestError218("Invalid subcategory ID format.");
|
|
57086
|
+
}
|
|
57087
|
+
if (value.category_id && typeof value.category_id === "string") {
|
|
57088
|
+
try {
|
|
57089
|
+
value.category_id = new ObjectId139(value.category_id);
|
|
57090
|
+
} catch {
|
|
57091
|
+
throw new BadRequestError218("Invalid category ID format.");
|
|
57092
|
+
}
|
|
57093
|
+
}
|
|
57094
|
+
if (value.site && typeof value.site === "string") {
|
|
57095
|
+
try {
|
|
57096
|
+
value.site = new ObjectId139(value.site);
|
|
57097
|
+
} catch {
|
|
57098
|
+
throw new BadRequestError218("Invalid site ID format.");
|
|
57099
|
+
}
|
|
57100
|
+
}
|
|
57101
|
+
value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
57102
|
+
const res = await collection.updateOne(
|
|
57103
|
+
{ _id: objectId2 },
|
|
57104
|
+
{ $set: value },
|
|
57105
|
+
{ session }
|
|
57106
|
+
);
|
|
57107
|
+
if (res.modifiedCount === 0)
|
|
57108
|
+
throw new InternalServerError78("Unable to update subcategory.");
|
|
57109
|
+
return res;
|
|
57110
|
+
}
|
|
57111
|
+
async function deleteById(_id, session) {
|
|
57112
|
+
let objectId2;
|
|
57113
|
+
try {
|
|
57114
|
+
objectId2 = new ObjectId139(_id);
|
|
57115
|
+
} catch {
|
|
57116
|
+
throw new BadRequestError218("Invalid subcategory ID format.");
|
|
57117
|
+
}
|
|
57118
|
+
const res = await collection.deleteOne({ _id: objectId2 }, { session });
|
|
57119
|
+
if (res.deletedCount === 0)
|
|
57120
|
+
throw new InternalServerError78("Unable to delete subcategory.");
|
|
57121
|
+
return res.deletedCount;
|
|
57122
|
+
}
|
|
57123
|
+
return { getAll, getById, addSubcategory, updateById, deleteById };
|
|
56841
57124
|
}
|
|
56842
57125
|
|
|
56843
57126
|
// src/controllers/subcategory-preloved.controller.ts
|
|
@@ -56847,7 +57130,9 @@ function useSubcategoryPrelovedController() {
|
|
|
56847
57130
|
const {
|
|
56848
57131
|
getAll: _getAll,
|
|
56849
57132
|
getById: _getById,
|
|
56850
|
-
addSubcategory: _addSubcategory
|
|
57133
|
+
addSubcategory: _addSubcategory,
|
|
57134
|
+
updateById: _updateById,
|
|
57135
|
+
deleteById: _deleteById
|
|
56851
57136
|
} = useSubcategoryPrelovedRepo();
|
|
56852
57137
|
async function getAll(req, res, next) {
|
|
56853
57138
|
const schema2 = Joi140.object({
|
|
@@ -56910,7 +57195,50 @@ function useSubcategoryPrelovedController() {
|
|
|
56910
57195
|
next(error2);
|
|
56911
57196
|
}
|
|
56912
57197
|
}
|
|
56913
|
-
|
|
57198
|
+
async function updateById(req, res, next) {
|
|
57199
|
+
const paramsSchema = Joi140.object({
|
|
57200
|
+
_id: Joi140.string().hex().length(24).required()
|
|
57201
|
+
});
|
|
57202
|
+
const { error: paramsError, value: paramsValue } = paramsSchema.validate({
|
|
57203
|
+
_id: req.params.id
|
|
57204
|
+
});
|
|
57205
|
+
if (paramsError) {
|
|
57206
|
+
next(new BadRequestError219(paramsError.message));
|
|
57207
|
+
return;
|
|
57208
|
+
}
|
|
57209
|
+
const { error: bodyError, value: bodyValue } = schemaUpdateSubcategoryPreloved.validate(req.body, { abortEarly: false });
|
|
57210
|
+
if (bodyError) {
|
|
57211
|
+
const messages = bodyError.details.map((d) => d.message).join(", ");
|
|
57212
|
+
logger191.log({ level: "error", message: messages });
|
|
57213
|
+
next(new BadRequestError219(messages));
|
|
57214
|
+
return;
|
|
57215
|
+
}
|
|
57216
|
+
try {
|
|
57217
|
+
const data = await _updateById(paramsValue._id, bodyValue);
|
|
57218
|
+
res.status(200).json(data);
|
|
57219
|
+
} catch (error) {
|
|
57220
|
+
logger191.log({ level: "error", message: error.message });
|
|
57221
|
+
next(error);
|
|
57222
|
+
}
|
|
57223
|
+
}
|
|
57224
|
+
async function deleteById(req, res, next) {
|
|
57225
|
+
const schema2 = Joi140.object({
|
|
57226
|
+
_id: Joi140.string().hex().length(24).required()
|
|
57227
|
+
});
|
|
57228
|
+
const { error, value } = schema2.validate({ _id: req.params.id });
|
|
57229
|
+
if (error) {
|
|
57230
|
+
next(new BadRequestError219(error.message));
|
|
57231
|
+
return;
|
|
57232
|
+
}
|
|
57233
|
+
try {
|
|
57234
|
+
const data = await _deleteById(value._id);
|
|
57235
|
+
res.status(200).json(data);
|
|
57236
|
+
} catch (error2) {
|
|
57237
|
+
logger191.log({ level: "error", message: error2.message });
|
|
57238
|
+
next(error2);
|
|
57239
|
+
}
|
|
57240
|
+
}
|
|
57241
|
+
return { getAll, getById, addSubcategory, updateById, deleteById };
|
|
56914
57242
|
}
|
|
56915
57243
|
|
|
56916
57244
|
// src/models/online-forms-v2.model.ts
|
|
@@ -57007,9 +57335,13 @@ import {
|
|
|
57007
57335
|
BadRequestError as BadRequestError220,
|
|
57008
57336
|
InternalServerError as InternalServerError79,
|
|
57009
57337
|
logger as logger192,
|
|
57338
|
+
makeCacheKey as makeCacheKey66,
|
|
57339
|
+
NotFoundError as NotFoundError61,
|
|
57340
|
+
paginate as paginate62,
|
|
57010
57341
|
useAtlas as useAtlas123,
|
|
57011
57342
|
useCache as useCache70
|
|
57012
57343
|
} from "@7365admin1/node-server-utils";
|
|
57344
|
+
import { ObjectId as ObjectId141 } from "mongodb";
|
|
57013
57345
|
var online_forms_namespace_collection = "online-forms";
|
|
57014
57346
|
function useFormEntryRepo() {
|
|
57015
57347
|
const db = useAtlas123.getDb();
|
|
@@ -57054,18 +57386,105 @@ function useFormEntryRepo() {
|
|
|
57054
57386
|
throw error;
|
|
57055
57387
|
}
|
|
57056
57388
|
}
|
|
57389
|
+
async function getAll({
|
|
57390
|
+
search = "",
|
|
57391
|
+
page = 1,
|
|
57392
|
+
limit = 10,
|
|
57393
|
+
sort = {},
|
|
57394
|
+
status = "active",
|
|
57395
|
+
org = "",
|
|
57396
|
+
site = ""
|
|
57397
|
+
}) {
|
|
57398
|
+
page = page > 0 ? page - 1 : 0;
|
|
57399
|
+
sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
|
|
57400
|
+
const cacheOptions = {
|
|
57401
|
+
page,
|
|
57402
|
+
limit,
|
|
57403
|
+
status,
|
|
57404
|
+
sort: JSON.stringify(sort),
|
|
57405
|
+
...site && { site },
|
|
57406
|
+
...search && { search }
|
|
57407
|
+
};
|
|
57408
|
+
const query = {
|
|
57409
|
+
...status ? { $and: [{ status }, { status: { $ne: "deleted" } }] } : { status: { $ne: "deleted" } },
|
|
57410
|
+
...site && { site: new ObjectId141(site) },
|
|
57411
|
+
...search && { search: [{ name: { $regex: search, $options: "i" } }] }
|
|
57412
|
+
};
|
|
57413
|
+
const cacheKey = makeCacheKey66(
|
|
57414
|
+
online_forms_namespace_collection,
|
|
57415
|
+
cacheOptions
|
|
57416
|
+
);
|
|
57417
|
+
const cachedData = await getCache(cacheKey);
|
|
57418
|
+
if (cachedData) {
|
|
57419
|
+
logger192.info(`Cache hit for key: ${cacheKey}`);
|
|
57420
|
+
return cachedData;
|
|
57421
|
+
}
|
|
57422
|
+
try {
|
|
57423
|
+
const items = await collection.aggregate([
|
|
57424
|
+
{ $match: query },
|
|
57425
|
+
{ $sort: sort },
|
|
57426
|
+
{ $skip: page * limit },
|
|
57427
|
+
{ $limit: limit }
|
|
57428
|
+
]).toArray();
|
|
57429
|
+
const length = await collection.countDocuments(query);
|
|
57430
|
+
const data = paginate62(items, page, limit, length);
|
|
57431
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
57432
|
+
logger192.info(`Cache set for key: ${cacheKey}`);
|
|
57433
|
+
}).catch((err) => {
|
|
57434
|
+
logger192.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
57435
|
+
});
|
|
57436
|
+
return data;
|
|
57437
|
+
} catch (error) {
|
|
57438
|
+
throw error;
|
|
57439
|
+
}
|
|
57440
|
+
}
|
|
57441
|
+
async function getFormEntryById(_id) {
|
|
57442
|
+
const cacheKey = makeCacheKey66(online_forms_namespace_collection, { _id });
|
|
57443
|
+
const cachedData = await getCache(cacheKey);
|
|
57444
|
+
if (cachedData) {
|
|
57445
|
+
logger192.info(`Cache hit for key: ${cacheKey}`);
|
|
57446
|
+
return cachedData;
|
|
57447
|
+
}
|
|
57448
|
+
try {
|
|
57449
|
+
_id = new ObjectId141(_id);
|
|
57450
|
+
} catch (error) {
|
|
57451
|
+
throw new BadRequestError220("Invalid online form ID format.");
|
|
57452
|
+
}
|
|
57453
|
+
const query = { _id, status: { $ne: "deleted" } };
|
|
57454
|
+
try {
|
|
57455
|
+
const [data] = await collection.aggregate([{ $match: query }]).toArray();
|
|
57456
|
+
if (!data) {
|
|
57457
|
+
throw new NotFoundError61("Document not found.");
|
|
57458
|
+
}
|
|
57459
|
+
setCache(cacheKey, data, 15 * 60).then(() => {
|
|
57460
|
+
logger192.info(`Cache set for key: ${cacheKey}`);
|
|
57461
|
+
}).catch((err) => {
|
|
57462
|
+
logger192.error(`Failed to set cache for key: ${cacheKey}`, err);
|
|
57463
|
+
});
|
|
57464
|
+
return data;
|
|
57465
|
+
} catch (error) {
|
|
57466
|
+
throw error;
|
|
57467
|
+
}
|
|
57468
|
+
}
|
|
57057
57469
|
return {
|
|
57058
57470
|
add,
|
|
57471
|
+
getAll,
|
|
57472
|
+
getFormEntryById,
|
|
57059
57473
|
createTextIndex
|
|
57060
57474
|
};
|
|
57061
57475
|
}
|
|
57062
57476
|
|
|
57063
57477
|
// src/controllers/online-forms-v2.controller.ts
|
|
57064
57478
|
import { BadRequestError as BadRequestError221, logger as logger193 } from "@7365admin1/node-server-utils";
|
|
57479
|
+
import Joi142 from "joi";
|
|
57065
57480
|
import ExcelJS3 from "exceljs";
|
|
57066
57481
|
import fs5 from "fs";
|
|
57067
57482
|
function useFormEntryController() {
|
|
57068
|
-
const {
|
|
57483
|
+
const {
|
|
57484
|
+
add: _add,
|
|
57485
|
+
getAll: _getAll,
|
|
57486
|
+
getFormEntryById: _getFormEntryById
|
|
57487
|
+
} = useFormEntryRepo();
|
|
57069
57488
|
function toCamelCase(str) {
|
|
57070
57489
|
return str.replace(/\s(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
|
|
57071
57490
|
}
|
|
@@ -57127,8 +57546,59 @@ function useFormEntryController() {
|
|
|
57127
57546
|
next(error);
|
|
57128
57547
|
}
|
|
57129
57548
|
}
|
|
57549
|
+
async function getAll(req, res, next) {
|
|
57550
|
+
try {
|
|
57551
|
+
const schema2 = Joi142.object({
|
|
57552
|
+
search: Joi142.string().optional().allow("", null),
|
|
57553
|
+
page: Joi142.number().integer().min(1).allow("", null).default(1),
|
|
57554
|
+
limit: Joi142.number().integer().min(1).max(100).allow("", null).default(10),
|
|
57555
|
+
status: Joi142.string().optional().allow(null, ""),
|
|
57556
|
+
org: Joi142.string().hex().optional().allow("", null),
|
|
57557
|
+
site: Joi142.string().hex().optional().allow("", null)
|
|
57558
|
+
});
|
|
57559
|
+
const { error, value } = schema2.validate(req.query);
|
|
57560
|
+
if (error) {
|
|
57561
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
57562
|
+
logger193.log({ level: "error", message: messages });
|
|
57563
|
+
next(new BadRequestError221(messages));
|
|
57564
|
+
return;
|
|
57565
|
+
}
|
|
57566
|
+
const { search, page, limit, status, org, site } = value;
|
|
57567
|
+
const data = await _getAll({ search, page, limit, status, org, site });
|
|
57568
|
+
res.json(data);
|
|
57569
|
+
return;
|
|
57570
|
+
} catch (error) {
|
|
57571
|
+
logger193.log({ level: "error", message: error.message });
|
|
57572
|
+
next(error);
|
|
57573
|
+
return;
|
|
57574
|
+
}
|
|
57575
|
+
}
|
|
57576
|
+
async function getFormEntryById(req, res, next) {
|
|
57577
|
+
try {
|
|
57578
|
+
const schema2 = Joi142.object({
|
|
57579
|
+
_id: Joi142.string().hex().length(24).required()
|
|
57580
|
+
});
|
|
57581
|
+
const { error, value } = schema2.validate({ _id: req.params.id });
|
|
57582
|
+
if (error) {
|
|
57583
|
+
const messages = error.details.map((d) => d.message).join(", ");
|
|
57584
|
+
logger193.log({ level: "error", message: messages });
|
|
57585
|
+
next(new BadRequestError221(messages));
|
|
57586
|
+
return;
|
|
57587
|
+
}
|
|
57588
|
+
const { _id } = value;
|
|
57589
|
+
const data = await _getFormEntryById(_id);
|
|
57590
|
+
res.json(data);
|
|
57591
|
+
return;
|
|
57592
|
+
} catch (error) {
|
|
57593
|
+
logger193.log({ level: "error", message: error.message });
|
|
57594
|
+
next(error);
|
|
57595
|
+
return;
|
|
57596
|
+
}
|
|
57597
|
+
}
|
|
57130
57598
|
return {
|
|
57131
|
-
uploadFormEntrys
|
|
57599
|
+
uploadFormEntrys,
|
|
57600
|
+
getAll,
|
|
57601
|
+
getFormEntryById
|
|
57132
57602
|
};
|
|
57133
57603
|
}
|
|
57134
57604
|
|
|
@@ -57172,7 +57642,7 @@ function useBuildingLevelService() {
|
|
|
57172
57642
|
|
|
57173
57643
|
// src/controllers/building-level.controller.ts
|
|
57174
57644
|
import { BadRequestError as BadRequestError222, logger as logger194 } from "@7365admin1/node-server-utils";
|
|
57175
|
-
import
|
|
57645
|
+
import Joi143 from "joi";
|
|
57176
57646
|
function useBuildingLevelController() {
|
|
57177
57647
|
const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelService();
|
|
57178
57648
|
const {
|
|
@@ -57199,12 +57669,12 @@ function useBuildingLevelController() {
|
|
|
57199
57669
|
}
|
|
57200
57670
|
async function getAll(req, res, next) {
|
|
57201
57671
|
try {
|
|
57202
|
-
const validation =
|
|
57203
|
-
page:
|
|
57204
|
-
limit:
|
|
57205
|
-
search:
|
|
57206
|
-
site:
|
|
57207
|
-
status:
|
|
57672
|
+
const validation = Joi143.object({
|
|
57673
|
+
page: Joi143.number().min(1).optional().default(1),
|
|
57674
|
+
limit: Joi143.number().min(1).optional().default(20),
|
|
57675
|
+
search: Joi143.string().optional().allow("", null),
|
|
57676
|
+
site: Joi143.string().hex().length(24).optional().allow("", null),
|
|
57677
|
+
status: Joi143.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
|
|
57208
57678
|
});
|
|
57209
57679
|
const { error, value } = validation.validate(req.query, {
|
|
57210
57680
|
abortEarly: false
|
|
@@ -57231,8 +57701,8 @@ function useBuildingLevelController() {
|
|
|
57231
57701
|
}
|
|
57232
57702
|
async function getById(req, res, next) {
|
|
57233
57703
|
try {
|
|
57234
|
-
const schema2 =
|
|
57235
|
-
id:
|
|
57704
|
+
const schema2 = Joi143.object({
|
|
57705
|
+
id: Joi143.string().hex().length(24).required()
|
|
57236
57706
|
});
|
|
57237
57707
|
const { error, value } = schema2.validate({ id: req.params.id });
|
|
57238
57708
|
if (error) {
|
|
@@ -57270,8 +57740,8 @@ function useBuildingLevelController() {
|
|
|
57270
57740
|
}
|
|
57271
57741
|
async function deleteById(req, res, next) {
|
|
57272
57742
|
try {
|
|
57273
|
-
const schema2 =
|
|
57274
|
-
id:
|
|
57743
|
+
const schema2 = Joi143.object({
|
|
57744
|
+
id: Joi143.string().hex().required()
|
|
57275
57745
|
});
|
|
57276
57746
|
const { error, value } = schema2.validate({ id: req.params.id });
|
|
57277
57747
|
if (error) {
|