@7365admin1/core 2.49.0 → 2.51.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/dist/index.mjs CHANGED
@@ -3952,6 +3952,9 @@ function useVerificationRepo() {
3952
3952
  return Promise.reject(error);
3953
3953
  }
3954
3954
  }
3955
+ async function findOne(query) {
3956
+ return await collection.findOne(query);
3957
+ }
3955
3958
  return {
3956
3959
  createIndex,
3957
3960
  createTextIndex,
@@ -3960,7 +3963,8 @@ function useVerificationRepo() {
3960
3963
  getVerifications,
3961
3964
  getByIdByType,
3962
3965
  updateStatusById,
3963
- getByStatus
3966
+ getByStatus,
3967
+ findOne
3964
3968
  };
3965
3969
  }
3966
3970
 
@@ -5297,29 +5301,28 @@ function useVerificationService() {
5297
5301
  throw error;
5298
5302
  }
5299
5303
  }
5300
- async function createSimpleUserInvite({
5301
- email,
5302
- metadata
5303
- }) {
5304
+ async function createSimpleUserInvite({ email, metadata }) {
5304
5305
  const type = "user-invite";
5306
+ if (metadata?.org)
5307
+ await getOrgById(metadata.org);
5308
+ if (metadata?.siteId)
5309
+ await getSiteById(metadata.siteId);
5310
+ const existing = await useVerificationRepo().findOne({
5311
+ type,
5312
+ email,
5313
+ "metadata.org": metadata?.org,
5314
+ "metadata.siteId": metadata?.siteId
5315
+ });
5316
+ if (existing)
5317
+ return existing._id;
5305
5318
  const value = {
5306
5319
  type,
5307
5320
  email,
5308
5321
  metadata,
5309
- expireAt: new Date(
5310
- (/* @__PURE__ */ new Date()).getTime() + 72 * 60 * 60 * 1e3
5311
- ).toISOString(),
5322
+ expireAt: new Date(Date.now() + 72 * 60 * 60 * 1e3).toISOString(),
5312
5323
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
5313
5324
  };
5314
- if (value.metadata?.org) {
5315
- await getOrgById(value.metadata?.org);
5316
- }
5317
- if (value.metadata?.siteId) {
5318
- await getSiteById(value.metadata?.siteId);
5319
- }
5320
5325
  const res = await add(value);
5321
- const dir = __dirname;
5322
- const filePath = getDirectory(dir, "./public/handlebars/user-invite");
5323
5326
  const link = `${APP_MAIN}/verify/invitation/${res}`;
5324
5327
  const emailContent = compileHandlebar({
5325
5328
  context: {
@@ -5327,9 +5330,9 @@ function useVerificationService() {
5327
5330
  validity: VERIFICATION_USER_INVITE_DURATION,
5328
5331
  link
5329
5332
  },
5330
- filePath
5333
+ filePath: getDirectory(__dirname, "./public/handlebars/user-invite")
5331
5334
  });
5332
- mailer.sendMail({
5335
+ await mailer.sendMail({
5333
5336
  to: email,
5334
5337
  subject: "User Invite",
5335
5338
  html: emailContent,
@@ -7181,7 +7184,7 @@ function useMemberService() {
7181
7184
  getByRoles
7182
7185
  } = useMemberRepo();
7183
7186
  const { getById: _getVerificationById, updateStatusById } = useVerificationRepo();
7184
- const { getUserByEmail, updateDefaultOrgByEmail } = useUserRepo();
7187
+ const { getUserByEmail, updateDefaultOrgByEmail, getUserById } = useUserRepo();
7185
7188
  const { getById: getOrgById } = useOrgRepo();
7186
7189
  const { getSiteById } = useSiteRepo();
7187
7190
  const { getOwnerRolesByTypeOrg } = useRoleRepo();
@@ -7243,6 +7246,52 @@ function useMemberService() {
7243
7246
  session?.endSession();
7244
7247
  }
7245
7248
  }
7249
+ async function createMemberDirect({
7250
+ userId,
7251
+ orgId,
7252
+ roleId,
7253
+ app,
7254
+ siteId,
7255
+ siteName
7256
+ }) {
7257
+ const session = useAtlas15.getClient()?.startSession();
7258
+ session?.startTransaction();
7259
+ try {
7260
+ const org = await getOrgById(orgId);
7261
+ if (!org)
7262
+ throw new BadRequestError29("Organization not found.");
7263
+ const user = await getUserById(userId);
7264
+ if (!user)
7265
+ throw new BadRequestError29("User not found.");
7266
+ const member = await addMember(
7267
+ {
7268
+ org: org._id?.toString() || "",
7269
+ orgName: org.name || "",
7270
+ user: user._id?.toString() || "",
7271
+ name: user?.email,
7272
+ role: roleId,
7273
+ type: app,
7274
+ siteId: siteId ?? "",
7275
+ siteName: siteName ?? ""
7276
+ },
7277
+ session
7278
+ );
7279
+ if (!user.defaultOrg) {
7280
+ await updateDefaultOrgByEmail(
7281
+ user.email,
7282
+ org._id?.toString() || "",
7283
+ session
7284
+ );
7285
+ }
7286
+ await session?.commitTransaction();
7287
+ return { member };
7288
+ } catch (error) {
7289
+ await session?.abortTransaction();
7290
+ throw error;
7291
+ } finally {
7292
+ session?.endSession();
7293
+ }
7294
+ }
7246
7295
  async function updateRoleById(id, role, type, org) {
7247
7296
  const owner = await getOwnerRolesByTypeOrg(type, org);
7248
7297
  if (!owner.length) {
@@ -7270,6 +7319,7 @@ function useMemberService() {
7270
7319
  }
7271
7320
  return {
7272
7321
  createMember,
7322
+ createMemberDirect,
7273
7323
  updateRoleById
7274
7324
  };
7275
7325
  }
@@ -7284,7 +7334,7 @@ function useMemberController() {
7284
7334
  updateMemberStatus: _updateMemberStatus,
7285
7335
  updateStatusByUserId: _updateStatusByUserId
7286
7336
  } = useMemberRepo();
7287
- const { createMember: _createMember, updateRoleById: _updateRoleById } = useMemberService();
7337
+ const { createMember: _createMember, createMemberDirect: _createMemberDirect, updateRoleById: _updateRoleById } = useMemberService();
7288
7338
  async function createMember(req, res, next) {
7289
7339
  const validation = Joi15.string().hex().required();
7290
7340
  const _id = req.params.id;
@@ -7473,6 +7523,32 @@ function useMemberController() {
7473
7523
  return;
7474
7524
  }
7475
7525
  }
7526
+ async function createMemberDirect(req, res, next) {
7527
+ const validation = Joi15.object({
7528
+ userId: Joi15.string().hex().required(),
7529
+ orgId: Joi15.string().hex().required(),
7530
+ roleId: Joi15.string().hex().required(),
7531
+ app: Joi15.string().required(),
7532
+ siteId: Joi15.string().hex().optional().allow("", null),
7533
+ siteName: Joi15.string().optional().allow("", null)
7534
+ });
7535
+ const { error } = validation.validate(req.body);
7536
+ if (error) {
7537
+ logger21.log({ level: "error", message: error.message });
7538
+ next(new BadRequestError30(error.message));
7539
+ return;
7540
+ }
7541
+ const { userId, orgId, roleId, app, siteId, siteName } = req.body;
7542
+ try {
7543
+ const data = await _createMemberDirect({ userId, orgId, roleId, app, siteId, siteName });
7544
+ res.status(201).json(data);
7545
+ return;
7546
+ } catch (error2) {
7547
+ logger21.log({ level: "error", message: error2.message });
7548
+ next(error2);
7549
+ return;
7550
+ }
7551
+ }
7476
7552
  return {
7477
7553
  createMember,
7478
7554
  getByUserId,
@@ -7480,7 +7556,8 @@ function useMemberController() {
7480
7556
  getAll,
7481
7557
  getOrgsByMembership,
7482
7558
  updateMemberStatus,
7483
- updateRoleById
7559
+ updateRoleById,
7560
+ createMemberDirect
7484
7561
  };
7485
7562
  }
7486
7563
 
@@ -13831,14 +13908,14 @@ function useVisitorTransactionRepo() {
13831
13908
  );
13832
13909
  }
13833
13910
  }
13834
- async function updateById(_id, value, session) {
13911
+ async function updateById(_id, value, session, isNotManualCheckOut = true) {
13835
13912
  try {
13836
13913
  _id = new ObjectId40(_id);
13837
13914
  } catch (error) {
13838
13915
  throw new BadRequestError66("Invalid visitor transaction ID format.");
13839
13916
  }
13840
13917
  value.updatedAt = /* @__PURE__ */ new Date();
13841
- if (value.checkOut) {
13918
+ if (value.checkOut && isNotManualCheckOut) {
13842
13919
  value.manualCheckout = true;
13843
13920
  }
13844
13921
  try {
@@ -14598,6 +14675,22 @@ function useVehicleRepo() {
14598
14675
  throw error;
14599
14676
  }
14600
14677
  }
14678
+ async function getSpecificVehicleById(_id) {
14679
+ try {
14680
+ _id = new ObjectId42(_id);
14681
+ } catch (error) {
14682
+ throw new BadRequestError68("Invalid vehicle ID format.");
14683
+ }
14684
+ try {
14685
+ const result = await collection.findOne({ _id });
14686
+ if (!result) {
14687
+ throw new NotFoundError17("Vehicle not found.");
14688
+ }
14689
+ return result;
14690
+ } catch (error) {
14691
+ throw error;
14692
+ }
14693
+ }
14601
14694
  async function getByPlaceNumber(value) {
14602
14695
  const { error } = Joi38.string().required().validate(value);
14603
14696
  if (error) {
@@ -14856,7 +14949,8 @@ function useVehicleRepo() {
14856
14949
  deleteExpiredVehicles,
14857
14950
  getAllVehiclesByUnitId,
14858
14951
  getAllExpiredVehicles,
14859
- bulkUpsertVehicles
14952
+ bulkUpsertVehicles,
14953
+ getSpecificVehicleById
14860
14954
  };
14861
14955
  }
14862
14956
 
@@ -17136,6 +17230,7 @@ var loggerDahua = winston.createLogger({
17136
17230
 
17137
17231
  // src/services/dahua.service.ts
17138
17232
  var cameraRegistry = /* @__PURE__ */ new Map();
17233
+ var _savedOnDetected;
17139
17234
  function useDahuaDigest({
17140
17235
  host = "",
17141
17236
  username = "",
@@ -17200,7 +17295,7 @@ function useDahuaService() {
17200
17295
  queue.push(buffer);
17201
17296
  if (queue.length >= BACKPRESSURE_THRESHOLD && streamRef && !streamRef.isPaused()) {
17202
17297
  loggerDahua.warn(
17203
- `[${site}][${gate}] Queue at ${queue.length}/${MAX_QUEUE_SIZE}, pausing stream`
17298
+ `[${site}][${host}] Queue at ${queue.length}/${MAX_QUEUE_SIZE}, pausing stream`
17204
17299
  );
17205
17300
  streamRef.pause();
17206
17301
  }
@@ -17217,7 +17312,7 @@ function useDahuaService() {
17217
17312
  streamRef.resume();
17218
17313
  }
17219
17314
  loggerDahua.info(
17220
- `[${site}][${gate}] BufferQueue destroyed. Processed=${processedChunks}, Dropped=${droppedChunks}`
17315
+ `[${site}][${host}] BufferQueue destroyed. Processed=${processedChunks}, Dropped=${droppedChunks}`
17221
17316
  );
17222
17317
  }
17223
17318
  async function processNext(onDetected2) {
@@ -17265,9 +17360,9 @@ function useDahuaService() {
17265
17360
  const transactionId = existingOpenTransaction?._id?.toString() || "";
17266
17361
  if (existingOpenTransaction && !existingOpenTransaction.checkOut && transactionId) {
17267
17362
  await updateById(transactionId, {
17268
- checkOut: (/* @__PURE__ */ new Date()).toISOString(),
17269
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
17270
- });
17363
+ checkOut: /* @__PURE__ */ new Date(),
17364
+ updatedAt: /* @__PURE__ */ new Date()
17365
+ }, void 0, false);
17271
17366
  }
17272
17367
  } catch (error) {
17273
17368
  loggerDahua.error(
@@ -17326,7 +17421,7 @@ function useDahuaService() {
17326
17421
  currentTransactionId = transactionId?.toString();
17327
17422
  currentSnapshotField = "snapshotEntryImage";
17328
17423
  if (onDetected2) {
17329
- onDetected2({ _id: transactionId, site: result?.site?.toString(), plateNumber: result.plateNumber });
17424
+ onDetected2({ _id: transactionId, site: result?.site?.toString(), plateNumber: result.plateNumber, host, direction });
17330
17425
  }
17331
17426
  } catch (error) {
17332
17427
  console.log("failed to create visitor transaction", error);
@@ -17335,8 +17430,7 @@ function useDahuaService() {
17335
17430
  error
17336
17431
  );
17337
17432
  }
17338
- }
17339
- if (["exit", "both"].includes(designation) && direction.toLowerCase() === "leave" && plateNumber) {
17433
+ } else if (["exit", "both"].includes(designation) && direction.toLowerCase() === "leave" && plateNumber) {
17340
17434
  const vehicle = await getVehicleByPlateNumber(plateNumber);
17341
17435
  const existingOpenTransaction = await getOpenByPlateNumber(
17342
17436
  plateNumber,
@@ -17358,6 +17452,9 @@ function useDahuaService() {
17358
17452
  await removePlateNumber(dahuaPayload);
17359
17453
  }
17360
17454
  await closeOpenTransaction(plateNumber);
17455
+ if (onDetected2) {
17456
+ onDetected2({ reload: true, site: existingOpenTransaction?.site?.toString(), host, direction });
17457
+ }
17361
17458
  }
17362
17459
  }
17363
17460
  }
@@ -17414,7 +17511,7 @@ function useDahuaService() {
17414
17511
  try {
17415
17512
  await fsAsync.mkdir(dir, { recursive: true });
17416
17513
  await fsAsync.writeFile(snapFolder, accumulatedImageBuffer);
17417
- loggerDahua.debug(`[${host}] Saved image locally: ${filename}`);
17514
+ loggerDahua.info(`[${host}] Saved image locally: ${filename}`);
17418
17515
  const fileId = await _createFile(
17419
17516
  {
17420
17517
  originalname: filename,
@@ -17489,9 +17586,12 @@ function useDahuaService() {
17489
17586
  }
17490
17587
  }
17491
17588
  async function listenToCamera(camera, onDetected) {
17589
+ if (onDetected) {
17590
+ _savedOnDetected = onDetected;
17591
+ }
17492
17592
  if (!camera?._id) {
17493
17593
  loggerDahua.error(`Camera _id is required to listen to camera.`);
17494
- throw new BadRequestError73("Camera _id is required to listen to camera.");
17594
+ return;
17495
17595
  }
17496
17596
  const cameraId = camera._id.toString();
17497
17597
  if (cameraRegistry.has(cameraId)) {
@@ -17501,6 +17601,11 @@ function useDahuaService() {
17501
17601
  }
17502
17602
  const controller = new AbortController();
17503
17603
  cameraRegistry.set(cameraId, controller);
17604
+ const onDetectedHandler = onDetected || _savedOnDetected;
17605
+ if (!onDetectedHandler) {
17606
+ loggerDahua.error(`No plate detection handler registered for camera ${cameraId}`);
17607
+ return;
17608
+ }
17504
17609
  getTrafficJunction(
17505
17610
  camera.host,
17506
17611
  camera.username,
@@ -17510,7 +17615,7 @@ function useDahuaService() {
17510
17615
  camera.direction,
17511
17616
  cameraId,
17512
17617
  controller.signal,
17513
- onDetected
17618
+ onDetectedHandler
17514
17619
  );
17515
17620
  }
17516
17621
  async function getTrafficJunctionOld(host = "", username = "", password = "", site = "", gate = "", designation = "", cameraId, signal, onDetected) {
@@ -17631,9 +17736,12 @@ function useDahuaService() {
17631
17736
  timeout: 2e4,
17632
17737
  streaming: true
17633
17738
  });
17634
- if ([400, 401, 403, 500].includes(response.statusCode)) {
17739
+ if (response.statusCode === 401) {
17740
+ loggerDahua.error(`[${host}] 401 Unauthorized. Potential handshake or wrong credentials.`);
17741
+ continue;
17742
+ } else if ([400, 401, 403, 500].includes(response.statusCode)) {
17635
17743
  loggerDahua.error(`[${host}] Connection error: ${response.statusCode}`);
17636
- throw new Error(`Failed to connect to ANPR: ${response.statusCode}`);
17744
+ return;
17637
17745
  }
17638
17746
  loggerDahua.info(`[${host}] Successfully connected to ANPR.`);
17639
17747
  const contentType = response.res.headers["content-type"];
@@ -17680,16 +17788,31 @@ function useDahuaService() {
17680
17788
  });
17681
17789
  });
17682
17790
  } catch (error) {
17683
- if (signal.aborted)
17791
+ if (signal.aborted || error.name === "AbortError" || error.code === "UND_ERR_ABORTED") {
17792
+ loggerDahua.info(`[${host}] Connection closed by system (Abort).`);
17684
17793
  break;
17794
+ }
17685
17795
  loggerDahua.error(
17686
17796
  `[${host}] Connection lost or error: ${error.message || error}. Retrying in 5s...`
17687
17797
  );
17688
17798
  } finally {
17689
- if (bufferQueue?.destroy)
17690
- bufferQueue.destroy();
17691
- if (response?.res && !response.res.destroyed)
17692
- response.res.destroy();
17799
+ if (bufferQueue?.destroy) {
17800
+ try {
17801
+ bufferQueue.destroy();
17802
+ } catch (e) {
17803
+ loggerDahua.error(`[${host}] Error destroying buffer queue:`, e);
17804
+ }
17805
+ }
17806
+ if (response?.res && typeof response.res.destroy === "function" && !response.res.destroyed) {
17807
+ try {
17808
+ response.res.on("error", () => {
17809
+ loggerDahua.error(`[${host}] Stream error during cleanup, likely already closed.`);
17810
+ });
17811
+ response.res.destroy();
17812
+ } catch (err) {
17813
+ loggerDahua.debug(`Cleanup: stream already closing: ${err?.message}`);
17814
+ }
17815
+ }
17693
17816
  }
17694
17817
  if (!signal.aborted) {
17695
17818
  await new Promise((res) => setTimeout(res, 5e3));
@@ -17905,6 +18028,8 @@ function useSiteCameraRepo() {
17905
18028
  try {
17906
18029
  value = MSiteCamera(value);
17907
18030
  const res = await collection.insertOne(value, { session });
18031
+ const { listenToCamera } = useDahuaService();
18032
+ await listenToCamera({ ...value, _id: res.insertedId });
17908
18033
  delCachedData();
17909
18034
  return res.insertedId;
17910
18035
  } catch (error) {
@@ -19760,7 +19885,8 @@ function useVehicleController() {
19760
19885
  getVehicles: _getVehicles,
19761
19886
  getVehicleById: _getVehicleById,
19762
19887
  getVehiclesByNRIC: _getVehiclesByNRIC,
19763
- getAllVehiclesByUnitId: _getAllVehiclesByUnitId
19888
+ getAllVehiclesByUnitId: _getAllVehiclesByUnitId,
19889
+ getSpecificVehicleById: _getSpecificVehicleById
19764
19890
  } = useVehicleRepo();
19765
19891
  function normalizeRow(row) {
19766
19892
  return Object.fromEntries(
@@ -19874,7 +20000,9 @@ function useVehicleController() {
19874
20000
  return;
19875
20001
  }
19876
20002
  const headerRow = worksheet.getRow(1);
19877
- const headers = (headerRow.values || []).slice(1).map((header) => String(header ?? "").trim());
20003
+ const headers = (headerRow.values || []).slice(1).map(
20004
+ (header) => String(header ?? "").trim().replace(/\(.*\)/, "").trim()
20005
+ );
19878
20006
  worksheet.eachRow((row, rowNumber) => {
19879
20007
  if (rowNumber === 1)
19880
20008
  return;
@@ -19891,7 +20019,11 @@ function useVehicleController() {
19891
20019
  } else if (lowerName.endsWith(".csv")) {
19892
20020
  rows = await new Promise((resolve, reject) => {
19893
20021
  const parsed = [];
19894
- fs.createReadStream(path4).pipe(csv()).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
20022
+ fs.createReadStream(path4).pipe(csv()).on("headers", (headers) => {
20023
+ headers = headers.map(
20024
+ (h) => h.trim().replace(/\(.*\)/, "").trim()
20025
+ );
20026
+ }).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
19895
20027
  });
19896
20028
  } else {
19897
20029
  next(
@@ -20056,6 +20188,31 @@ function useVehicleController() {
20056
20188
  return;
20057
20189
  }
20058
20190
  }
20191
+ async function getSpecificVehicleById(req, res, next) {
20192
+ const schema2 = Joi46.object({
20193
+ _id: Joi46.string().hex().length(24).required()
20194
+ });
20195
+ const { error, value } = schema2.validate(
20196
+ { _id: req.params.id },
20197
+ { abortEarly: false }
20198
+ );
20199
+ if (error) {
20200
+ const messages = error.details.map((d) => d.message).join(", ");
20201
+ logger65.log({ level: "error", message: messages });
20202
+ next(new BadRequestError84(messages));
20203
+ return;
20204
+ }
20205
+ const { _id } = value;
20206
+ try {
20207
+ const site = await _getSpecificVehicleById(_id);
20208
+ res.json(site);
20209
+ return;
20210
+ } catch (error2) {
20211
+ logger65.log({ level: "error", message: error2.message });
20212
+ next(error2);
20213
+ return;
20214
+ }
20215
+ }
20059
20216
  async function updateVehicleById(req, res, next) {
20060
20217
  try {
20061
20218
  const schema2 = Joi46.object({
@@ -20275,7 +20432,8 @@ function useVehicleController() {
20275
20432
  getVehiclesByNRIC,
20276
20433
  reactivateVehicleById,
20277
20434
  getAllVehiclesByUnitId,
20278
- uploadSpreadsheetVehicles
20435
+ uploadSpreadsheetVehicles,
20436
+ getSpecificVehicleById
20279
20437
  };
20280
20438
  }
20281
20439
 
@@ -23421,6 +23579,12 @@ function useVisitorTransactionService() {
23421
23579
  const parsed = new Date(value.checkOut);
23422
23580
  value.checkOut = isNaN(parsed.getTime()) ? null : parsed;
23423
23581
  }
23582
+ if (value.site) {
23583
+ value.site = typeof value.site === "string" ? new ObjectId59(value.site) : value.site;
23584
+ }
23585
+ if (value.unit) {
23586
+ value.unit = typeof value.unit === "string" ? new ObjectId59(value.unit) : value.unit;
23587
+ }
23424
23588
  await _updateVisitorTansactionById(id, value, session);
23425
23589
  await session?.commitTransaction();
23426
23590
  return "Successfully updated visitor transaction.";
@@ -26260,7 +26424,7 @@ function usePatrolRouteRepo() {
26260
26424
  id: "$_id",
26261
26425
  start: startOfDay,
26262
26426
  end: endOfDay,
26263
- site: new ObjectId67(site)
26427
+ site: ObjectId67.isValid(site) ? new ObjectId67(site) : null
26264
26428
  },
26265
26429
  pipeline: [
26266
26430
  {
@@ -26291,10 +26455,8 @@ function usePatrolRouteRepo() {
26291
26455
  { $skip: page * limit },
26292
26456
  { $limit: limit }
26293
26457
  ];
26294
- const [items, countResult] = await Promise.all([
26295
- collection.aggregate(basePipeline, { session }).toArray(),
26296
- collection.aggregate([{ $match: query }, { $count: "total" }], { session }).toArray()
26297
- ]);
26458
+ const items = await collection.aggregate(basePipeline, { session }).toArray();
26459
+ const countResult = await collection.aggregate([{ $match: query }, { $count: "total" }], { session }).toArray();
26298
26460
  const totalCount = countResult[0]?.total || 0;
26299
26461
  const data = paginate28(items, page, limit, totalCount);
26300
26462
  setCache(cacheKey, data, 15 * 60).then(() => logger90.info(`Cache set for key: ${cacheKey}`)).catch(
@@ -26302,6 +26464,7 @@ function usePatrolRouteRepo() {
26302
26464
  );
26303
26465
  return data;
26304
26466
  } catch (error) {
26467
+ console.error("[getScheduledRoute] ERROR:", error?.message, error?.stack);
26305
26468
  throw error;
26306
26469
  }
26307
26470
  }
@@ -26588,6 +26751,7 @@ var schemaPatrolLog = Joi65.object({
26588
26751
  cameras: Joi65.array().items(schemeLogCamera).required(),
26589
26752
  status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).required(),
26590
26753
  incidentReport: incidentReportLog,
26754
+ platform: Joi65.string().valid("web", "mobile").optional().allow(null, ""),
26591
26755
  createdAt: Joi65.date().optional(),
26592
26756
  updatedAt: Joi65.date().optional(),
26593
26757
  deletedAt: Joi65.date().optional()
@@ -26601,7 +26765,8 @@ var schemaUpdatePatrolLog = Joi65.object({
26601
26765
  end: Joi65.string().optional().allow(null, ""),
26602
26766
  cameras: Joi65.array().items(schemeLogCamera).optional().allow(null, ""),
26603
26767
  status: Joi65.array().items(Joi65.string().valid("complete", "late", "incomplete")).optional().allow(null, ""),
26604
- incidentReport: incidentReportLog
26768
+ incidentReport: incidentReportLog,
26769
+ platform: Joi65.string().valid("web", "mobile").optional().allow(null, "")
26605
26770
  });
26606
26771
  function MPatrolLog(value) {
26607
26772
  const { error } = schemaPatrolLog.validate(value);
@@ -26655,6 +26820,7 @@ function MPatrolLog(value) {
26655
26820
  status: value.status ?? [],
26656
26821
  route: value.route,
26657
26822
  incidentReport: value.incidentReport,
26823
+ platForm: value.platform ?? "",
26658
26824
  createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
26659
26825
  updatedAt: value.updatedAt ?? "",
26660
26826
  deletedAt: value.deletedAt ?? ""
@@ -27021,6 +27187,7 @@ function usePatrolLogService() {
27021
27187
  }
27022
27188
  }
27023
27189
  }
27190
+ value.platform = value.platform === "web" ? "web" : "mobile";
27024
27191
  const result = await _add(value, session);
27025
27192
  await session.commitTransaction();
27026
27193
  return result;
@@ -41257,6 +41424,7 @@ var schemaIncidentReport = Joi99.object({
41257
41424
  approvedBy: Joi99.string().hex().allow(null, "").optional(),
41258
41425
  approvedByName: Joi99.string().optional().allow("", null),
41259
41426
  remarks: Joi99.string().optional().allow("", null),
41427
+ platform: Joi99.string().valid("web", "mobile").optional().allow(null, ""),
41260
41428
  status: Joi99.string().valid("pending", "approved", "rejected").default("pending")
41261
41429
  });
41262
41430
  var schemaUpdateIncidentReport = Joi99.object({
@@ -41337,6 +41505,7 @@ var schemaUpdateIncidentReport = Joi99.object({
41337
41505
  approvedBy: Joi99.string().hex().allow(null, "").optional(),
41338
41506
  approvedByName: Joi99.string().optional().allow("", null),
41339
41507
  remarks: Joi99.string().optional().allow("", null),
41508
+ platform: Joi99.string().valid("web", "mobile").optional().allow(null, ""),
41340
41509
  status: Joi99.string().valid("pending", "approved", "rejected").default("pending")
41341
41510
  });
41342
41511
  function MIncidentReport(value) {
@@ -41398,6 +41567,7 @@ function MIncidentReport(value) {
41398
41567
  approvedByName: value.approvedByName ?? "",
41399
41568
  remarks: value.remarks ?? null,
41400
41569
  status: value.status ?? "pending",
41570
+ platForm: value.platform ?? "",
41401
41571
  createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
41402
41572
  updatedAt: value.updatedAt,
41403
41573
  deletedAt: value.deletedAt
@@ -41876,6 +42046,7 @@ function useIncidentReportService() {
41876
42046
  }
41877
42047
  }
41878
42048
  }
42049
+ value.platform = value.platform === "web" ? "web" : "mobile";
41879
42050
  const result = await _add(value, session);
41880
42051
  await session?.commitTransaction();
41881
42052
  return result;
@@ -42969,6 +43140,11 @@ function useOccurrenceEntryService() {
42969
43140
  if (!occurrenceEntry) {
42970
43141
  throw new Error("Occurrence entry not found.");
42971
43142
  }
43143
+ if (value.incidentReportId) {
43144
+ await _updateOccurrenceEntryById(id, value, session);
43145
+ await session?.commitTransaction();
43146
+ return "Successfully updated occurrence entry (incident report).";
43147
+ }
42972
43148
  const entryCount = await _getLatestSerialNumberInGroup(
42973
43149
  occurrenceEntry.dailyOccurrenceBookId,
42974
43150
  Number(occurrenceEntry.serialNumber)
@@ -43001,6 +43177,8 @@ function useOccurrenceEntryService() {
43001
43177
  value.date = value.date ? value.date : occurrenceEntry.date;
43002
43178
  value.userName = value.userName ? value.userName : occurrenceEntry.signature.name;
43003
43179
  value.createdByName = value.createdByName ? value.createdByName : occurrenceEntry.createdByName;
43180
+ if (occurrenceEntry.incidentReportId)
43181
+ value.incidentReportId = occurrenceEntry.incidentReportId;
43004
43182
  await _updateOccurrenceBookById(dobId, {
43005
43183
  totalInput: book.totalInput + 1
43006
43184
  });