@7365admin1/core 2.28.1 → 2.30.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.js CHANGED
@@ -168,6 +168,7 @@ __export(src_exports, {
168
168
  occurrence_book_namespace_collection: () => occurrence_book_namespace_collection,
169
169
  orgSchema: () => orgSchema,
170
170
  overnight_parking_requests_namespace_collection: () => overnight_parking_requests_namespace_collection,
171
+ parseDahuaFind: () => parseDahuaFind,
171
172
  pestDashboardCollection: () => pestDashboardCollection,
172
173
  poolDashboardCollection: () => poolDashboardCollection,
173
174
  promoCodeSchema: () => promoCodeSchema,
@@ -1812,7 +1813,7 @@ var import_node_server_utils8 = require("@7365admin1/node-server-utils");
1812
1813
  var import_mongodb6 = require("mongodb");
1813
1814
  var import_joi5 = __toESM(require("joi"));
1814
1815
  var schemaOccurrenceEntry = import_joi5.default.object({
1815
- site: import_joi5.default.string().hex().required(),
1816
+ site: import_joi5.default.string().hex().length(24).required(),
1816
1817
  dailyOccurrenceBookId: import_joi5.default.string().hex().optional().allow(null, ""),
1817
1818
  serialNumber: import_joi5.default.string().optional().allow(null, ""),
1818
1819
  date: import_joi5.default.date().iso().optional().allow(null, ""),
@@ -1824,14 +1825,14 @@ var schemaOccurrenceEntry = import_joi5.default.object({
1824
1825
  createdByName: import_joi5.default.string().optional().allow(null, "")
1825
1826
  });
1826
1827
  var schemaUpdateOccurrenceEntry = import_joi5.default.object({
1827
- _id: import_joi5.default.string().hex().required(),
1828
+ _id: import_joi5.default.string().hex().length(24).required(),
1828
1829
  serialNumber: import_joi5.default.string().optional().allow(null, ""),
1829
1830
  date: import_joi5.default.date().iso().optional().allow(null, ""),
1830
1831
  subject: import_joi5.default.string().hex().optional().allow(null, ""),
1831
1832
  occurrence: import_joi5.default.string().optional().allow(null, ""),
1832
1833
  signature: import_joi5.default.string().hex().optional().allow(null, ""),
1833
1834
  incidentReportId: import_joi5.default.string().hex().optional().allow(null, ""),
1834
- eSignature: import_joi5.default.string().required(),
1835
+ eSignature: import_joi5.default.string().hex().length(24).required(),
1835
1836
  createdByName: import_joi5.default.string().optional().allow(null, "")
1836
1837
  });
1837
1838
  function MOccurrenceEntry(value) {
@@ -1877,6 +1878,13 @@ function MOccurrenceEntry(value) {
1877
1878
  throw new Error("Invalid incident report ID.");
1878
1879
  }
1879
1880
  }
1881
+ if (value.eSignature && typeof value.eSignature === "string") {
1882
+ try {
1883
+ value.eSignature = new import_mongodb6.ObjectId(value.eSignature);
1884
+ } catch {
1885
+ throw new Error("Invalid incident report ID.");
1886
+ }
1887
+ }
1880
1888
  return {
1881
1889
  _id: value._id ?? new import_mongodb6.ObjectId(),
1882
1890
  site: value.site,
@@ -13099,6 +13107,7 @@ var PersonTypes = /* @__PURE__ */ ((PersonTypes3) => {
13099
13107
  PersonTypes3["GUEST"] = "guest";
13100
13108
  PersonTypes3["TENANT"] = "tenant";
13101
13109
  PersonTypes3["RESIDENT"] = "resident";
13110
+ PersonTypes3["VISITOR"] = "visitor";
13102
13111
  return PersonTypes3;
13103
13112
  })(PersonTypes || {});
13104
13113
  var PersonStatus = /* @__PURE__ */ ((PersonStatus2) => {
@@ -13276,7 +13285,7 @@ var schemaVisitorTransaction = import_joi36.default.object({
13276
13285
  checkIn: import_joi36.default.date().optional().allow(null, ""),
13277
13286
  checkOut: import_joi36.default.date().optional().allow(null, ""),
13278
13287
  deliveryType: import_joi36.default.string().optional().allow(null, ""),
13279
- status: import_joi36.default.string().optional().valid(...Object.values(VisitorStatus)).default("registered" /* REGISTERED */),
13288
+ status: import_joi36.default.string().optional().valid(...Object.values(VisitorStatus)).default("pending" /* PENDING */),
13280
13289
  remarks: import_joi36.default.string().optional().allow(null, ""),
13281
13290
  members: import_joi36.default.array().items(
13282
13291
  import_joi36.default.object({
@@ -13286,7 +13295,6 @@ var schemaVisitorTransaction = import_joi36.default.object({
13286
13295
  contact: import_joi36.default.string().optional().allow(null, "")
13287
13296
  })
13288
13297
  ).optional().allow(null),
13289
- visitorPass: import_joi36.default.string().optional().allow(null, ""),
13290
13298
  unitName: import_joi36.default.string().optional().allow(null, ""),
13291
13299
  expiredAt: import_joi36.default.date().iso().optional().allow(null, ""),
13292
13300
  arrivalTime: import_joi36.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
@@ -13295,7 +13303,15 @@ var schemaVisitorTransaction = import_joi36.default.object({
13295
13303
  duration: import_joi36.default.number().integer().optional().allow(null),
13296
13304
  isOvernightParking: import_joi36.default.boolean().optional().default(false),
13297
13305
  email: import_joi36.default.string().email().optional().allow(null, ""),
13298
- numberOfPassengers: import_joi36.default.number().integer().optional().allow(null, "")
13306
+ numberOfPassengers: import_joi36.default.number().integer().optional().allow(null, ""),
13307
+ visitorPass: import_joi36.default.array().items(
13308
+ import_joi36.default.string().hex().length(24).optional().allow(null)
13309
+ ),
13310
+ passKeys: import_joi36.default.array().items(
13311
+ import_joi36.default.string().hex().length(24).optional().allow(null)
13312
+ ),
13313
+ checkInRemarks: import_joi36.default.string().optional().allow("", null),
13314
+ checkOutRemarks: import_joi36.default.string().optional().allow("", null)
13299
13315
  });
13300
13316
  var schemaUpdateVisTrans = import_joi36.default.object({
13301
13317
  _id: import_joi36.default.string().hex().length(24).required(),
@@ -13321,7 +13337,15 @@ var schemaUpdateVisTrans = import_joi36.default.object({
13321
13337
  status: import_joi36.default.string().optional().allow(null, ""),
13322
13338
  remarks: import_joi36.default.string().optional().allow(null, ""),
13323
13339
  manualCheckout: import_joi36.default.boolean().optional().allow(null),
13324
- expiredAt: import_joi36.default.date().iso().optional().allow(null, "")
13340
+ expiredAt: import_joi36.default.date().iso().optional().allow(null, ""),
13341
+ visitorPass: import_joi36.default.array().items(
13342
+ import_joi36.default.string().hex().length(24).optional().allow(null)
13343
+ ),
13344
+ passKeys: import_joi36.default.array().items(
13345
+ import_joi36.default.string().hex().length(24).optional().allow(null)
13346
+ ),
13347
+ checkInRemarks: import_joi36.default.string().optional().allow("", null),
13348
+ checkOutRemarks: import_joi36.default.string().optional().allow("", null)
13325
13349
  });
13326
13350
  function MVisitorTransaction(value) {
13327
13351
  const { error } = schemaVisitorTransaction.validate(value, {
@@ -13365,6 +13389,14 @@ function MVisitorTransaction(value) {
13365
13389
  throw new Error("Invalid type for manualCheckout key.");
13366
13390
  }
13367
13391
  }
13392
+ if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0)
13393
+ value.visitorPass = value.visitorPass.map(
13394
+ (v) => typeof v === "string" ? new import_mongodb39.ObjectId(v) : v
13395
+ );
13396
+ if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0)
13397
+ value.passKeys = value.passKeys.map(
13398
+ (p) => typeof p === "string" ? new import_mongodb39.ObjectId(p) : p
13399
+ );
13368
13400
  const newDate = (/* @__PURE__ */ new Date()).toISOString();
13369
13401
  return {
13370
13402
  _id: value._id,
@@ -13391,7 +13423,10 @@ function MVisitorTransaction(value) {
13391
13423
  contractorType: value.contractorType,
13392
13424
  manualCheckout: value.manualCheckout ?? false,
13393
13425
  direction: value.direction,
13394
- visitorPass: value.visitorPass,
13426
+ visitorPass: value.visitorPass ?? [],
13427
+ passKeys: value.passKeys ?? [],
13428
+ checkInRemarks: value.checkInRemarks,
13429
+ checkOutRemarks: value.checkOutRemarks,
13395
13430
  unitName: value.unitName,
13396
13431
  expiredAt: value.expiredAt ?? null,
13397
13432
  createdAt: value.createdAt ?? newDate,
@@ -13409,9 +13444,6 @@ function useVisitorTransactionRepo() {
13409
13444
  throw new import_node_server_utils68.InternalServerError("Unable to connect to server.");
13410
13445
  }
13411
13446
  const collection = db.collection(visitors_namespace_collection);
13412
- const { delNamespace, getCache, setCache } = (0, import_node_server_utils68.useCache)(
13413
- visitors_namespace_collection
13414
- );
13415
13447
  async function createTextIndex() {
13416
13448
  try {
13417
13449
  await collection.createIndex({
@@ -13432,16 +13464,6 @@ function useVisitorTransactionRepo() {
13432
13464
  try {
13433
13465
  value = MVisitorTransaction(value);
13434
13466
  const res = await collection.insertOne(value, { session });
13435
- delNamespace().then(() => {
13436
- import_node_server_utils68.logger.info(
13437
- `Cache cleared for namespace: ${visitors_namespace_collection}`
13438
- );
13439
- }).catch((err) => {
13440
- import_node_server_utils68.logger.error(
13441
- `Failed to clear cache for namespace: ${visitors_namespace_collection}`,
13442
- err
13443
- );
13444
- });
13445
13467
  return res.insertedId;
13446
13468
  } catch (error) {
13447
13469
  const isDuplicated = error.message.includes("duplicate");
@@ -13464,7 +13486,7 @@ function useVisitorTransactionRepo() {
13464
13486
  type = "",
13465
13487
  checkedOut,
13466
13488
  plateNumber = ""
13467
- }, session) {
13489
+ }) {
13468
13490
  page = page > 0 ? page - 1 : 0;
13469
13491
  const skip = page * limit;
13470
13492
  let checkOutFilter;
@@ -13499,26 +13521,6 @@ function useVisitorTransactionRepo() {
13499
13521
  ...plateNumber && { plateNumber }
13500
13522
  };
13501
13523
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
13502
- const cacheOptions = {
13503
- status,
13504
- page,
13505
- limit,
13506
- sort: JSON.stringify(sort),
13507
- ...search && { search },
13508
- ...query.org && { org: query.org.toString() },
13509
- ...query.site && { site: query.site.toString() },
13510
- ...checkIn && { checkIn: JSON.stringify(checkIn) },
13511
- ...checkOutFilter && { checkOut: JSON.stringify(checkOutFilter) },
13512
- ...type && (Array.isArray(type) ? { type: JSON.stringify(type) } : { type }),
13513
- ...checkedOut !== void 0 && { checkedOut },
13514
- ...plateNumber && { plateNumber }
13515
- };
13516
- const cacheKey = (0, import_node_server_utils68.makeCacheKey)(visitors_namespace_collection, cacheOptions);
13517
- const cachedData = await getCache(cacheKey);
13518
- if (cachedData) {
13519
- import_node_server_utils68.logger.info(`Cache hit for key: ${cacheKey}`);
13520
- return cachedData;
13521
- }
13522
13524
  try {
13523
13525
  const basePipeline = [{ $match: query }];
13524
13526
  const [items, countResult] = await Promise.all([
@@ -13562,23 +13564,12 @@ function useVisitorTransactionRepo() {
13562
13564
  ]);
13563
13565
  const totalCount = countResult[0]?.total || 0;
13564
13566
  const data = (0, import_node_server_utils68.paginate)(items, page, limit, totalCount);
13565
- setCache(cacheKey, data, 15 * 60).then(() => {
13566
- import_node_server_utils68.logger.info(`Cache set for key: ${cacheKey}`);
13567
- }).catch((err) => {
13568
- import_node_server_utils68.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
13569
- });
13570
13567
  return data;
13571
13568
  } catch (error) {
13572
13569
  throw error;
13573
13570
  }
13574
13571
  }
13575
13572
  async function getVisitorTransactionById(id) {
13576
- const cacheKey = (0, import_node_server_utils68.makeCacheKey)(visitors_namespace_collection, { id });
13577
- const cachedData = await getCache(cacheKey);
13578
- if (cachedData) {
13579
- import_node_server_utils68.logger.info(`Cache hit for key: ${cacheKey}`);
13580
- return cachedData;
13581
- }
13582
13573
  const _id = (0, import_node_server_utils68.toObjectId)(id);
13583
13574
  try {
13584
13575
  const basePipeline = [{ $match: { _id } }];
@@ -13615,38 +13606,20 @@ function useVisitorTransactionRepo() {
13615
13606
  }
13616
13607
  }
13617
13608
  ]).toArray();
13618
- setCache(cacheKey, result, 15 * 60).then(() => {
13619
- import_node_server_utils68.logger.info(`Cache set for key: ${cacheKey}`);
13620
- }).catch((err) => {
13621
- import_node_server_utils68.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
13622
- });
13623
13609
  return result;
13624
13610
  } catch (error) {
13625
13611
  throw error;
13626
13612
  }
13627
13613
  }
13628
13614
  async function getOpenByPlateNumber(plateNumber, site) {
13629
- const _site = typeof site === "string" ? site : (0, import_node_server_utils68.toObjectId)(site);
13630
- const cacheKey = (0, import_node_server_utils68.makeCacheKey)(visitors_namespace_collection, {
13615
+ const _site = typeof site === "string" ? (0, import_node_server_utils68.toObjectId)(site) : site;
13616
+ const query = {
13631
13617
  plateNumber,
13632
- key: "get-open-transaction-plate-number",
13633
- site
13634
- });
13618
+ site: _site,
13619
+ checkOut: null
13620
+ };
13635
13621
  try {
13636
- const cacheData = await getCache(cacheKey);
13637
- if (cacheData) {
13638
- import_node_server_utils68.logger.info(`Cache hit for key: ${cacheKey}`);
13639
- return cacheData;
13640
- }
13641
- const data = await collection.findOne(
13642
- { plateNumber, site: _site, checkOut: null },
13643
- { sort: { _id: -1 } }
13644
- );
13645
- setCache(cacheKey, data, 15 * 60).then(() => {
13646
- import_node_server_utils68.logger.info(`Cache set for key: ${cacheKey}`);
13647
- }).catch((err) => {
13648
- import_node_server_utils68.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
13649
- });
13622
+ const data = await collection.findOne(query);
13650
13623
  return data;
13651
13624
  } catch (error) {
13652
13625
  throw new import_node_server_utils68.InternalServerError(
@@ -13670,16 +13643,6 @@ function useVisitorTransactionRepo() {
13670
13643
  { $set: value },
13671
13644
  { session }
13672
13645
  );
13673
- delNamespace().then(() => {
13674
- import_node_server_utils68.logger.info(
13675
- `Cache cleared for namespace: ${visitors_namespace_collection}`
13676
- );
13677
- }).catch((err) => {
13678
- import_node_server_utils68.logger.error(
13679
- `Failed to clear cache for namespace: ${visitors_namespace_collection}`,
13680
- err
13681
- );
13682
- });
13683
13646
  return result;
13684
13647
  } catch (error) {
13685
13648
  throw error;
@@ -13701,16 +13664,6 @@ function useVisitorTransactionRepo() {
13701
13664
  if (res.modifiedCount === 0) {
13702
13665
  throw new import_node_server_utils68.InternalServerError("Unable to delete visitor transaction.");
13703
13666
  }
13704
- delNamespace().then(() => {
13705
- import_node_server_utils68.logger.info(
13706
- `Cache cleared for namespace: ${visitors_namespace_collection}`
13707
- );
13708
- }).catch((err) => {
13709
- import_node_server_utils68.logger.error(
13710
- `Failed to clear cache for namespace: ${visitors_namespace_collection}`,
13711
- err
13712
- );
13713
- });
13714
13667
  return res.modifiedCount;
13715
13668
  } catch (error) {
13716
13669
  throw error;
@@ -13776,16 +13729,6 @@ function useVisitorTransactionRepo() {
13776
13729
  },
13777
13730
  { session }
13778
13731
  );
13779
- delNamespace().then(() => {
13780
- import_node_server_utils68.logger.info(
13781
- `Cache cleared for namespace: ${visitors_namespace_collection}`
13782
- );
13783
- }).catch((err) => {
13784
- import_node_server_utils68.logger.error(
13785
- `Failed to clear cache for namespace: ${visitors_namespace_collection}`,
13786
- err
13787
- );
13788
- });
13789
13732
  return res;
13790
13733
  } catch (error) {
13791
13734
  throw error;
@@ -13817,6 +13760,7 @@ var VehicleType = /* @__PURE__ */ ((VehicleType2) => {
13817
13760
  var VehicleCategory = /* @__PURE__ */ ((VehicleCategory2) => {
13818
13761
  VehicleCategory2["RESIDENT"] = "resident";
13819
13762
  VehicleCategory2["VISITOR"] = "visitor";
13763
+ VehicleCategory2["GUEST"] = "guest";
13820
13764
  return VehicleCategory2;
13821
13765
  })(VehicleCategory || {});
13822
13766
  var VehicleStatus = /* @__PURE__ */ ((VehicleStatus2) => {
@@ -13861,7 +13805,7 @@ var vehicleSchema = import_joi37.default.object({
13861
13805
  return value;
13862
13806
  }).required(),
13863
13807
  type: import_joi37.default.string().required().valid(...Object.values(VehicleType)),
13864
- category: import_joi37.default.string().required().valid(...Object.values(VehicleCategory)),
13808
+ category: import_joi37.default.string().required().valid(...Object.values(PersonTypes)),
13865
13809
  name: import_joi37.default.string().required(),
13866
13810
  phoneNumber: import_joi37.default.string().optional().allow("", null),
13867
13811
  recNo: import_joi37.default.string().optional().allow("", null),
@@ -14005,9 +13949,6 @@ function useVehicleRepo() {
14005
13949
  throw new import_node_server_utils70.InternalServerError("Unable to connect to server.");
14006
13950
  }
14007
13951
  const collection = db.collection(vehicles_namespace_collection);
14008
- const { delNamespace, setCache, getCache } = (0, import_node_server_utils70.useCache)(
14009
- vehicles_namespace_collection
14010
- );
14011
13952
  async function createIndex() {
14012
13953
  try {
14013
13954
  await collection.createIndexes([
@@ -14039,16 +13980,6 @@ function useVehicleRepo() {
14039
13980
  try {
14040
13981
  value = MVehicle(value);
14041
13982
  const res = await collection.insertOne(value, { session });
14042
- delNamespace().then(() => {
14043
- import_node_server_utils70.logger.info(
14044
- `Cache cleared for namespace: ${vehicles_namespace_collection}`
14045
- );
14046
- }).catch((err) => {
14047
- import_node_server_utils70.logger.error(
14048
- `Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
14049
- err
14050
- );
14051
- });
14052
13983
  return res.insertedId;
14053
13984
  } catch (error) {
14054
13985
  import_node_server_utils70.logger.log({
@@ -14073,29 +14004,12 @@ function useVehicleRepo() {
14073
14004
  }) {
14074
14005
  page = page > 0 ? page - 1 : 0;
14075
14006
  const baseQuery = {
14076
- ...status && { status },
14077
- ...type && { type },
14078
- ...category && { category }
14079
- };
14080
- let query = { ...baseQuery };
14081
- const cacheOptions = {
14082
14007
  ...status && { status },
14083
14008
  ...type && { type },
14084
14009
  ...category && { category },
14085
- page: String(page),
14086
- limit: String(limit),
14087
- sort: JSON.stringify(sort)
14010
+ ...search && { $text: { search } }
14088
14011
  };
14089
- if (search) {
14090
- query.$text = { $search: search };
14091
- cacheOptions.search = search;
14092
- }
14093
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, cacheOptions);
14094
- const cachedData = await getCache(cacheKey);
14095
- if (cachedData) {
14096
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14097
- return cachedData;
14098
- }
14012
+ let query = { ...baseQuery };
14099
14013
  const escapeRegex = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14100
14014
  const buildGroupedPipeline = (matchQuery) => [
14101
14015
  { $match: matchQuery },
@@ -14253,9 +14167,6 @@ function useVehicleRepo() {
14253
14167
  length = regexCountResult[0]?.total || 0;
14254
14168
  }
14255
14169
  const data = (0, import_node_server_utils70.paginate)(items, page, limit, length);
14256
- setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`)).catch(
14257
- (err) => import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
14258
- );
14259
14170
  return data;
14260
14171
  } catch (error) {
14261
14172
  throw error;
@@ -14267,14 +14178,6 @@ function useVehicleRepo() {
14267
14178
  } catch (error) {
14268
14179
  throw new import_node_server_utils70.BadRequestError("Invalid site ID format.");
14269
14180
  }
14270
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, {
14271
- site,
14272
- type: "season-pass-type-as-options"
14273
- });
14274
- const cachedData = await getCache(cacheKey);
14275
- if (cachedData) {
14276
- return cachedData;
14277
- }
14278
14181
  try {
14279
14182
  const categories = await collection.aggregate([
14280
14183
  { $match: { site } },
@@ -14294,17 +14197,6 @@ function useVehicleRepo() {
14294
14197
  },
14295
14198
  { $sort: { title: 1 } }
14296
14199
  ]).toArray();
14297
- setCache(cacheKey, categories).then(() => {
14298
- import_node_server_utils70.logger.log({
14299
- level: "info",
14300
- message: `Cache set for get season pass type: ${cacheKey}`
14301
- });
14302
- }).catch((err) => {
14303
- import_node_server_utils70.logger.log({
14304
- level: "error",
14305
- message: `Failed to set cache for season pass type: ${err.message}`
14306
- });
14307
- });
14308
14200
  return categories;
14309
14201
  } catch (error) {
14310
14202
  if (error instanceof import_node_server_utils70.BadRequestError) {
@@ -14320,12 +14212,6 @@ function useVehicleRepo() {
14320
14212
  throw new import_node_server_utils70.BadRequestError("Invalid vehicle ID format.");
14321
14213
  }
14322
14214
  try {
14323
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, { _id });
14324
- const cachedData = await getCache(cacheKey);
14325
- if (cachedData) {
14326
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14327
- return cachedData;
14328
- }
14329
14215
  const data = await collection.aggregate([
14330
14216
  { $match: { _id } },
14331
14217
  { $limit: 1 },
@@ -14495,11 +14381,6 @@ function useVehicleRepo() {
14495
14381
  throw new import_node_server_utils70.NotFoundError("Vehicle not found.");
14496
14382
  }
14497
14383
  const result = data[0];
14498
- setCache(cacheKey, result, 15 * 60).then(() => {
14499
- import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`);
14500
- }).catch((err) => {
14501
- import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
14502
- });
14503
14384
  return result;
14504
14385
  } catch (error) {
14505
14386
  throw error;
@@ -14511,15 +14392,6 @@ function useVehicleRepo() {
14511
14392
  throw new import_node_server_utils70.BadRequestError(error.details[0].message);
14512
14393
  }
14513
14394
  try {
14514
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, {
14515
- plateNumber: value,
14516
- status: "active"
14517
- });
14518
- const cachedData = await getCache(cacheKey);
14519
- if (cachedData) {
14520
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14521
- return cachedData;
14522
- }
14523
14395
  const data = await collection.findOne({
14524
14396
  plateNumber: value,
14525
14397
  status: "active"
@@ -14527,11 +14399,6 @@ function useVehicleRepo() {
14527
14399
  if (!data) {
14528
14400
  throw new import_node_server_utils70.NotFoundError("Vehicle not found.");
14529
14401
  }
14530
- setCache(cacheKey, data, 15 * 60).then(() => {
14531
- import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`);
14532
- }).catch((err) => {
14533
- import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
14534
- });
14535
14402
  return data;
14536
14403
  } catch (error2) {
14537
14404
  throw error2;
@@ -14556,16 +14423,6 @@ function useVehicleRepo() {
14556
14423
  if (res.modifiedCount === 0) {
14557
14424
  throw new import_node_server_utils70.InternalServerError("Unable to update vehicle.");
14558
14425
  }
14559
- delNamespace().then(() => {
14560
- import_node_server_utils70.logger.info(
14561
- `Cache cleared for namespace: ${vehicles_namespace_collection}`
14562
- );
14563
- }).catch((err) => {
14564
- import_node_server_utils70.logger.error(
14565
- `Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
14566
- err
14567
- );
14568
- });
14569
14426
  return res.modifiedCount;
14570
14427
  } catch (error) {
14571
14428
  throw error;
@@ -14589,16 +14446,6 @@ function useVehicleRepo() {
14589
14446
  );
14590
14447
  if (res.modifiedCount === 0)
14591
14448
  throw new import_node_server_utils70.InternalServerError("Unable to delete vehicle.");
14592
- delNamespace().then(() => {
14593
- import_node_server_utils70.logger.info(
14594
- `Cache cleared for namespace: ${vehicles_namespace_collection}`
14595
- );
14596
- }).catch((err) => {
14597
- import_node_server_utils70.logger.error(
14598
- `Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
14599
- err
14600
- );
14601
- });
14602
14449
  return res.modifiedCount;
14603
14450
  } catch (error) {
14604
14451
  throw error;
@@ -14609,25 +14456,11 @@ function useVehicleRepo() {
14609
14456
  if (error) {
14610
14457
  throw new import_node_server_utils70.BadRequestError(error.details[0].message);
14611
14458
  }
14612
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, {
14613
- plateNumber,
14614
- status: "active"
14615
- });
14616
14459
  try {
14617
- const cacheData = await getCache(cacheKey);
14618
- if (cacheData) {
14619
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14620
- return cacheData;
14621
- }
14622
14460
  const data = await collection.findOne(
14623
14461
  { plateNumber, status: "active" },
14624
14462
  { sort: { _id: -1 } }
14625
14463
  );
14626
- setCache(cacheKey, data, 15 * 60).then(() => {
14627
- import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`);
14628
- }).catch((err) => {
14629
- import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
14630
- });
14631
14464
  return data;
14632
14465
  } catch (error2) {
14633
14466
  throw new import_node_server_utils70.InternalServerError(
@@ -14651,19 +14484,6 @@ function useVehicleRepo() {
14651
14484
  nric: _nric
14652
14485
  };
14653
14486
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
14654
- const cacheOptions = {
14655
- deletedAt: "",
14656
- nric: _nric,
14657
- page: String(page),
14658
- limit: String(limit),
14659
- sort: JSON.stringify(sort)
14660
- };
14661
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(vehicles_namespace_collection, cacheOptions);
14662
- const cachedData = await getCache(cacheKey);
14663
- if (cachedData) {
14664
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14665
- return cachedData;
14666
- }
14667
14487
  try {
14668
14488
  const items = await collection.aggregate([
14669
14489
  { $match: query },
@@ -14684,9 +14504,6 @@ function useVehicleRepo() {
14684
14504
  ]).toArray();
14685
14505
  const length = await collection.countDocuments(query);
14686
14506
  const data = (0, import_node_server_utils70.paginate)(items, page, limit, length);
14687
- setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`)).catch(
14688
- (err) => import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
14689
- );
14690
14507
  return data;
14691
14508
  } catch (error) {
14692
14509
  throw error;
@@ -14701,19 +14518,9 @@ function useVehicleRepo() {
14701
14518
  end: { $exists: true, $lte: now }
14702
14519
  // check only end
14703
14520
  },
14704
- { $set: { status: "deleted", deletedAt: now } },
14521
+ { $set: { status: "deleted", deletedAt: now, isDeletedInDahua: true } },
14705
14522
  { session }
14706
14523
  );
14707
- delNamespace().then(() => {
14708
- import_node_server_utils70.logger.info(
14709
- `Cache cleared for namespace: ${vehicles_namespace_collection}`
14710
- );
14711
- }).catch((err) => {
14712
- import_node_server_utils70.logger.error(
14713
- `Failed to clear cache for namespace: ${vehicles_namespace_collection}`,
14714
- err
14715
- );
14716
- });
14717
14524
  return res.modifiedCount;
14718
14525
  } catch (error) {
14719
14526
  throw error;
@@ -14732,21 +14539,6 @@ function useVehicleRepo() {
14732
14539
  const query = {
14733
14540
  unit
14734
14541
  };
14735
- const cacheOptions = {
14736
- unit: unitId,
14737
- page,
14738
- limit,
14739
- sort: JSON.stringify(sort)
14740
- };
14741
- const cacheKey = (0, import_node_server_utils70.makeCacheKey)(
14742
- vehicles_namespace_collection,
14743
- cacheOptions
14744
- );
14745
- const cachedData = await getCache(cacheKey);
14746
- if (cachedData) {
14747
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14748
- return cachedData;
14749
- }
14750
14542
  const items = await collection.find(query, {
14751
14543
  projection: {
14752
14544
  createdAt: 0,
@@ -14759,14 +14551,24 @@ function useVehicleRepo() {
14759
14551
  }).toArray();
14760
14552
  const length = await collection.countDocuments(query);
14761
14553
  const data = (0, import_node_server_utils70.paginate)(items, page, limit, length);
14762
- setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`)).catch(
14763
- (err) => import_node_server_utils70.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
14764
- );
14765
14554
  return data;
14766
14555
  } catch (error) {
14767
14556
  throw error;
14768
14557
  }
14769
14558
  }
14559
+ async function getAllExpiredVehicles() {
14560
+ try {
14561
+ const now = (/* @__PURE__ */ new Date()).toISOString();
14562
+ const query = {
14563
+ end: { $lte: now },
14564
+ status: { $ne: "deleted" }
14565
+ };
14566
+ const items = await collection.find(query).toArray();
14567
+ return items;
14568
+ } catch (error) {
14569
+ throw error;
14570
+ }
14571
+ }
14770
14572
  return {
14771
14573
  createIndex,
14772
14574
  createTextIndex,
@@ -14780,7 +14582,8 @@ function useVehicleRepo() {
14780
14582
  getVehicleByPlateNumber,
14781
14583
  getVehiclesByNRIC,
14782
14584
  deleteExpiredVehicles,
14783
- getAllVehiclesByUnitId
14585
+ getAllVehiclesByUnitId,
14586
+ getAllExpiredVehicles
14784
14587
  };
14785
14588
  }
14786
14589
 
@@ -15393,18 +15196,32 @@ function formatDahuaDate(date) {
15393
15196
  date.getSeconds()
15394
15197
  )}`;
15395
15198
  }
15199
+ function parseDahuaFind(text) {
15200
+ const found = Number(text.match(/found=(\d+)/)?.[1] || 0);
15201
+ if (!found) {
15202
+ return { exists: false };
15203
+ }
15204
+ return {
15205
+ exists: true,
15206
+ recNo: text.match(/records\[0\]\.RecNo=(.*)/)?.[1]?.trim(),
15207
+ plateNumber: text.match(/records\[0\]\.PlateNumber=(.*)/)?.[1]?.trim()
15208
+ };
15209
+ }
15396
15210
  function useVehicleService() {
15397
15211
  const {
15398
15212
  add: _add,
15399
15213
  deleteVehicle: _deleteVehicle,
15400
15214
  updateVehicleById: _updateVehicleById,
15401
15215
  getVehicleById: _getVehicleById,
15402
- deleteExpiredVehicles: _deleteExpiredVehicles
15216
+ deleteExpiredVehicles: _deleteExpiredVehicles,
15217
+ getVehicleByPlateNumber: _getVehicleByPlateNumber,
15218
+ getAllExpiredVehicles: _getAllExpiredVehicles
15403
15219
  } = useVehicleRepo();
15404
15220
  const {
15405
15221
  addPlateNumber: _addPlateNumber,
15406
15222
  removePlateNumber: _removePlateNumber,
15407
- updatePlateNumber: _updatePlateNumber
15223
+ updatePlateNumber: _updatePlateNumber,
15224
+ getPlateNumber: _getPlateNumber
15408
15225
  } = useDahuaService();
15409
15226
  const { getAllCameraWithPassword: _getAllSiteCameras } = useSiteCameraRepo();
15410
15227
  const { getById: _getById } = useOrgRepo();
@@ -15415,9 +15232,15 @@ function useVehicleService() {
15415
15232
  if (!session) {
15416
15233
  throw new Error("Unable to start session for vehicle service.");
15417
15234
  }
15418
- const org = await _getById(value.org);
15235
+ const [_vehiclePlateNumber] = value.plateNumber;
15236
+ const [existingPlateNumber, org] = await Promise.all([
15237
+ _getVehicleByPlateNumber(_vehiclePlateNumber),
15238
+ _getById(value.org)
15239
+ ]);
15419
15240
  if (!org)
15420
15241
  throw new import_node_server_utils72.BadRequestError("Org not found");
15242
+ if (existingPlateNumber)
15243
+ throw new import_node_server_utils72.BadRequestError("Vehicle plate number already exists");
15421
15244
  if (!Object.values(OrgNature).includes(org.nature)) {
15422
15245
  throw new import_node_server_utils72.BadRequestError(
15423
15246
  "This organization is not allowed to add vehicles."
@@ -15497,29 +15320,61 @@ function useVehicleService() {
15497
15320
  if (vehicleValue.status && vehicleValue.status !== "pending" /* PENDING */) {
15498
15321
  for (const camera of siteCameras) {
15499
15322
  const { host, username, password } = camera;
15500
- const dahuaPayload = {
15323
+ const plateNumber2 = vehicleValue.plateNumber;
15324
+ const dahuaQuery = {
15501
15325
  host,
15502
15326
  username,
15503
15327
  password,
15504
- plateNumber,
15505
- mode: _mode,
15506
- owner,
15507
- ...startDateDahua ? { start: startDateDahua } : {},
15508
- ...endDateDahua ? { end: endDateDahua } : {}
15328
+ plateNumber: plateNumber2,
15329
+ mode: _mode
15509
15330
  };
15510
- const dahuaResponse = await _addPlateNumber(dahuaPayload);
15511
- if (dahuaResponse?.statusCode !== 200) {
15512
- throw new import_node_server_utils72.BadRequestError(
15513
- `Failed to add plate number to ANPR ${_type}`
15514
- );
15331
+ const raw = await _getPlateNumber(dahuaQuery);
15332
+ const parsed = parseDahuaFind(raw);
15333
+ if (!parsed.exists) {
15334
+ const dahuaPayload = {
15335
+ host,
15336
+ username,
15337
+ password,
15338
+ plateNumber: plateNumber2,
15339
+ mode: _mode,
15340
+ owner,
15341
+ ...startDateDahua ? { start: startDateDahua } : {},
15342
+ ...endDateDahua ? { end: endDateDahua } : {}
15343
+ };
15344
+ const dahuaResponse = await _addPlateNumber(dahuaPayload);
15345
+ if (dahuaResponse?.statusCode !== 200) {
15346
+ throw new import_node_server_utils72.BadRequestError(
15347
+ `Failed to add plate number to ANPR ${_type}`
15348
+ );
15349
+ }
15350
+ const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
15351
+ vehicleValue.recNo = responseData.split("=")[1]?.trim();
15352
+ } else {
15353
+ const dahuaPayload = {
15354
+ host,
15355
+ username,
15356
+ password,
15357
+ plateNumber: plateNumber2,
15358
+ recno: parsed.recNo,
15359
+ mode: _mode,
15360
+ ...startDateDahua ? { start: startDateDahua } : {},
15361
+ ...endDateDahua ? { end: endDateDahua } : {},
15362
+ owner,
15363
+ isOpenGate: true
15364
+ };
15365
+ const dahuaResponse = await _updatePlateNumber(dahuaPayload);
15366
+ if (dahuaResponse?.statusCode !== 200) {
15367
+ throw new import_node_server_utils72.BadRequestError(
15368
+ `Failed to update plate number to ANPR ${_type}`
15369
+ );
15370
+ }
15371
+ vehicleValue.recNo = parsed.recNo;
15515
15372
  }
15516
- const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
15517
- vehicleValue.recNo = responseData.split("=")[1]?.trim();
15518
15373
  if (value.peopleId && vehicleValue.recNo) {
15519
15374
  await _pushVehicleById(
15520
15375
  value.peopleId,
15521
15376
  {
15522
- plateNumber,
15377
+ plateNumber: plateNumber2,
15523
15378
  recNo: vehicleValue.recNo
15524
15379
  },
15525
15380
  session
@@ -15710,6 +15565,43 @@ function useVehicleService() {
15710
15565
  }
15711
15566
  try {
15712
15567
  session.startTransaction();
15568
+ const vehicles = await _getAllExpiredVehicles();
15569
+ let siteCameras = [];
15570
+ for (const vehicle of vehicles) {
15571
+ const site = vehicle.site;
15572
+ const recno = vehicle.recNo;
15573
+ let page = 1;
15574
+ let pages = 1;
15575
+ const limit = 20;
15576
+ do {
15577
+ const siteCameraReq = await _getAllSiteCameras({
15578
+ site,
15579
+ type: "anpr",
15580
+ direction: ["both", "entry"],
15581
+ page,
15582
+ limit
15583
+ });
15584
+ pages = siteCameraReq.pages || 1;
15585
+ siteCameras.push(...siteCameraReq.items);
15586
+ page++;
15587
+ } while (page < pages);
15588
+ if (!siteCameras.length) {
15589
+ throw new import_node_server_utils72.BadRequestError("No site cameras found.");
15590
+ }
15591
+ for (const camera of siteCameras) {
15592
+ const host = camera.host;
15593
+ const username = camera.username;
15594
+ const password = camera.password;
15595
+ const dahuaPayload = {
15596
+ host,
15597
+ username,
15598
+ password,
15599
+ recno,
15600
+ mode: "TrafficRedList" /* TRAFFIC_REDLIST */
15601
+ };
15602
+ await _removePlateNumber(dahuaPayload);
15603
+ }
15604
+ }
15713
15605
  await _deleteExpiredVehicles();
15714
15606
  await session.commitTransaction();
15715
15607
  return `Expired Vehicle plate numbers deleted successfully.`;
@@ -16105,16 +15997,20 @@ function useDahuaService() {
16105
15997
  "resident" /* RESIDENT */,
16106
15998
  "tenant" /* TENANT */
16107
15999
  ];
16000
+ let startDate = vehicle?.start ? new Date(vehicle?.start) : /* @__PURE__ */ new Date();
16001
+ let endDate = vehicle?.end ? new Date(vehicle?.end) : new Date(startDate.getTime() + 60 * 60 * 1e3);
16108
16002
  if (vehicle && typeof vehicle.category === "string" && typesForAutoRegister.includes(vehicle.category)) {
16109
16003
  visitorTransaction.name = vehicle.name;
16110
16004
  visitorTransaction.nric = vehicle.nric;
16111
16005
  visitorTransaction.contact = vehicle.phoneNumber;
16112
16006
  visitorTransaction.block = Number(vehicle.block);
16113
16007
  visitorTransaction.level = vehicle.level;
16114
- visitorTransaction.unit = vehicle.unit;
16008
+ visitorTransaction.unit = vehicle.unit?.toString();
16115
16009
  visitorTransaction.unitName = vehicle.unitName;
16116
- visitorTransaction.type = vehicle.category;
16010
+ visitorTransaction.type = "resident" /* RESIDENT */;
16117
16011
  visitorTransaction.status = "registered" /* REGISTERED */;
16012
+ visitorTransaction.recNo = vehicle.recNo;
16013
+ visitorTransaction.expiredAt = vehicle.end;
16118
16014
  }
16119
16015
  const dahuaPayload = {
16120
16016
  host,
@@ -16124,13 +16020,15 @@ function useDahuaService() {
16124
16020
  mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
16125
16021
  owner: vehicle?.name ?? ""
16126
16022
  };
16023
+ dahuaPayload.start = formatDahuaDate(startDate);
16024
+ dahuaPayload.end = formatDahuaDate(endDate);
16127
16025
  const shouldHaveTimeLimit = visitorTransaction.type === "guest" /* GUEST */ || visitorTransaction.status === "unregistered" /* UNREGISTERED */;
16128
16026
  if (shouldHaveTimeLimit) {
16129
- const startDate = /* @__PURE__ */ new Date();
16130
- const endDate = new Date(startDate.getTime() + 15 * 60 * 1e3);
16131
- dahuaPayload.start = formatDahuaDate(startDate);
16132
- dahuaPayload.end = formatDahuaDate(endDate);
16133
- visitorTransaction.expiredAt = endDate.toISOString();
16027
+ const startDate2 = /* @__PURE__ */ new Date();
16028
+ const endDate2 = new Date(startDate2.getTime() + 60 * 60 * 1e3);
16029
+ dahuaPayload.start = formatDahuaDate(startDate2);
16030
+ dahuaPayload.end = formatDahuaDate(endDate2);
16031
+ visitorTransaction.expiredAt = endDate2.toISOString();
16134
16032
  }
16135
16033
  try {
16136
16034
  await addPlateNumber(dahuaPayload);
@@ -16379,14 +16277,14 @@ function useDahuaService() {
16379
16277
  start: import_joi39.default.string().isoDate().optional().allow("", null),
16380
16278
  end: import_joi39.default.string().isoDate().optional().allow("", null),
16381
16279
  owner: import_joi39.default.string().optional().allow("", null),
16382
- openGate: import_joi39.default.boolean().optional().allow(null)
16280
+ isOpenGate: import_joi39.default.boolean().optional().allow(null)
16383
16281
  });
16384
16282
  const { error } = validation.validate(value);
16385
16283
  if (error) {
16386
16284
  throw new import_node_server_utils73.BadRequestError(`Validation error: ${error.message}`);
16387
16285
  }
16388
16286
  value.owner = String(value.owner ?? "").substring(0, 15) || "unknown";
16389
- const _openGate = String(value.openGate);
16287
+ const _openGate = String(value.isOpenGate);
16390
16288
  const isOpenGateString = _openGate && _openGate !== "undefined" ? _openGate : "true";
16391
16289
  const endpoint = `/cgi-bin/recordUpdater.cgi?action=insert&name=${value.mode}&PlateNumber=${value.plateNumber}&BeginTime=${value.start}&CancelTime=${value.end}&+OpenGate=${isOpenGateString}&MasterOfCar=${value.owner}`;
16392
16290
  try {
@@ -16447,7 +16345,7 @@ function useDahuaService() {
16447
16345
  username: import_joi39.default.string().required(),
16448
16346
  password: import_joi39.default.string().required(),
16449
16347
  recno: import_joi39.default.string().required(),
16450
- mode: import_joi39.default.string().valid("TrafficBlackList", "TrafficRedList").required()
16348
+ mode: import_joi39.default.string().valid(...Object.values(ANPRMode)).required()
16451
16349
  });
16452
16350
  const { error } = validation.validate(value);
16453
16351
  if (error) {
@@ -16465,12 +16363,39 @@ function useDahuaService() {
16465
16363
  import_node_server_utils73.logger.error(`[${value.host}] Error removing plate number:`, error2);
16466
16364
  }
16467
16365
  }
16366
+ async function getPlateNumber(value) {
16367
+ const validation = import_joi39.default.object({
16368
+ host: import_joi39.default.string().required(),
16369
+ username: import_joi39.default.string().required(),
16370
+ password: import_joi39.default.string().required(),
16371
+ plateNumber: import_joi39.default.string().required(),
16372
+ mode: import_joi39.default.string().valid(...Object.values(ANPRMode)).required()
16373
+ });
16374
+ const { error } = validation.validate(value);
16375
+ if (error) {
16376
+ throw new import_node_server_utils73.BadRequestError(`Validation error: ${error.message}`);
16377
+ }
16378
+ try {
16379
+ const response = await useDahuaDigest({
16380
+ host: value.host,
16381
+ username: value.username,
16382
+ password: value.password,
16383
+ endpoint: `/cgi-bin/recordFinder.cgi?action=find&name=${value.mode}&condition.PlateNumber=${encodeURIComponent(value.plateNumber)}`
16384
+ });
16385
+ const text = response?.data?.toString?.("utf-8");
16386
+ return text;
16387
+ } catch (error2) {
16388
+ import_node_server_utils73.logger.error(`[${value.host}] Error finding plate number:`, error2);
16389
+ throw error2;
16390
+ }
16391
+ }
16468
16392
  return {
16469
16393
  getSnapshot,
16470
16394
  getTrafficJunction,
16471
16395
  addPlateNumber,
16472
16396
  removePlateNumber,
16473
- updatePlateNumber
16397
+ updatePlateNumber,
16398
+ getPlateNumber
16474
16399
  };
16475
16400
  }
16476
16401
 
@@ -20726,10 +20651,13 @@ function useVisitorTransactionService() {
20726
20651
  const { getSiteById: _getSiteById } = useSiteRepo();
20727
20652
  const {
20728
20653
  addPlateNumber: _addPlateNumber,
20729
- removePlateNumber: _removePlateNumber
20654
+ removePlateNumber: _removePlateNumber,
20655
+ getPlateNumber: _getPlateNumber,
20656
+ updatePlateNumber: _updatePlateNumber
20730
20657
  } = useDahuaService();
20731
20658
  const { getAllSites: _getAllSites } = useSiteRepo();
20732
20659
  const { getByUserId: _getByUserId } = usePersonRepo();
20660
+ const { add: addVehicle } = useVehicleRepo();
20733
20661
  async function add(value) {
20734
20662
  const session = import_node_server_utils100.useAtlas.getClient()?.startSession();
20735
20663
  const allowedPersonTypes = [
@@ -20746,12 +20674,12 @@ function useVisitorTransactionService() {
20746
20674
  let site;
20747
20675
  if (value.site) {
20748
20676
  [camera, site] = await Promise.all([
20749
- _getBySite(value.site, { type: "anpr" }),
20677
+ _getBySite(value.site, { type: "anpr" /* ANPR */ }),
20750
20678
  _getSiteById(value.site)
20751
20679
  ]);
20752
20680
  }
20753
- const minutesExpiration = site?.dahuaTimeExpiration ? site?.dahuaTimeExpiration : 60;
20754
- const end = value.checkOut ? new Date(value.checkOut) : new Date(start.getTime() + minutesExpiration * 60 * 1e3);
20681
+ const hourExpiration = site?.dahuaTimeExpiration ? site?.dahuaTimeExpiration : 24 * 60;
20682
+ const end = value.checkOut ? new Date(value.checkOut) : new Date(start.getTime() + hourExpiration * 60 * 1e3);
20755
20683
  const startString = start.toISOString();
20756
20684
  const endString = end.toISOString();
20757
20685
  const startDahuaDate = formatDahuaDate(start);
@@ -20827,27 +20755,76 @@ function useVisitorTransactionService() {
20827
20755
  }
20828
20756
  }
20829
20757
  if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
20830
- const dahuaPayload = {
20831
- host: camera.host,
20832
- username: camera.username,
20833
- password: camera.password,
20834
- plateNumber: value.plateNumber,
20835
- mode: "TrafficRedList" /* TRAFFIC_REDLIST */,
20836
- start: startDahuaDate,
20837
- end: endDahuaDate,
20838
- owner: value.name ?? "",
20839
- openGate: site?.isOpenGate ?? true
20758
+ const host = camera.host;
20759
+ const username = camera.username;
20760
+ const password = camera.password;
20761
+ const mode = "TrafficRedList" /* TRAFFIC_REDLIST */;
20762
+ const _plateNumber = value.plateNumber;
20763
+ const dahuaQuery = {
20764
+ host,
20765
+ username,
20766
+ password,
20767
+ plateNumber: _plateNumber,
20768
+ mode
20840
20769
  };
20841
- const dahuaResponse = await _addPlateNumber(dahuaPayload);
20842
- if (dahuaResponse?.statusCode !== 200) {
20843
- throw new import_node_server_utils100.BadRequestError(
20844
- `Failed to add plate number to ANPR whitelist`
20845
- );
20770
+ const raw = await _getPlateNumber(dahuaQuery);
20771
+ const parsed = parseDahuaFind(raw);
20772
+ if (!parsed.exists) {
20773
+ const dahuaPayload = {
20774
+ host,
20775
+ username,
20776
+ password,
20777
+ plateNumber: _plateNumber,
20778
+ mode,
20779
+ start: startDahuaDate,
20780
+ end: endDahuaDate,
20781
+ owner: value.name ?? "",
20782
+ isOpenGate: site?.isOpenGate ?? true
20783
+ };
20784
+ const dahuaResponse = await _addPlateNumber(dahuaPayload);
20785
+ if (dahuaResponse?.statusCode !== 200) {
20786
+ throw new import_node_server_utils100.BadRequestError(
20787
+ `Failed to add plate number to ANPR whitelist`
20788
+ );
20789
+ }
20790
+ const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
20791
+ value.recNo = responseData.split("=")[1]?.trim();
20792
+ value.checkIn = startString;
20793
+ value.expiredAt = endString;
20794
+ const vehiclePayload = {
20795
+ name: value.name ?? "",
20796
+ category: value.type,
20797
+ org: value.org,
20798
+ site: value.site,
20799
+ plateNumber: value.plateNumber,
20800
+ type: "whitelist" /* WHITELIST */,
20801
+ nric: value.nric,
20802
+ start: startString,
20803
+ end: endString,
20804
+ recNo: value.recNo
20805
+ };
20806
+ await addVehicle(vehiclePayload);
20807
+ } else {
20808
+ const dahuaPayload = {
20809
+ host,
20810
+ username,
20811
+ password,
20812
+ plateNumber: _plateNumber,
20813
+ recno: parsed.recNo,
20814
+ mode,
20815
+ start: startDahuaDate,
20816
+ end: endDahuaDate,
20817
+ owner: value.name ?? "",
20818
+ isOpenGate: site?.isOpenGate ?? true
20819
+ };
20820
+ const dahuaResponse = await _updatePlateNumber(dahuaPayload);
20821
+ if (dahuaResponse?.statusCode !== 200) {
20822
+ throw new import_node_server_utils100.BadRequestError(
20823
+ `Failed to update plate number to ANPR ${"whitelist" /* WHITELIST */}`
20824
+ );
20825
+ }
20826
+ value.recNo = parsed.recNo;
20846
20827
  }
20847
- const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
20848
- value.recNo = responseData.split("=")[1]?.trim();
20849
- value.checkIn = startString;
20850
- value.expiredAt = endString;
20851
20828
  }
20852
20829
  const result = await _add(value, session);
20853
20830
  await session?.commitTransaction();
@@ -21181,7 +21158,6 @@ function useVisitorTransactionController() {
21181
21158
  }
21182
21159
  }
21183
21160
  async function inviteVisitor(req, res, next) {
21184
- const inviter = req.params.inviterId;
21185
21161
  const schema2 = import_joi55.default.object({
21186
21162
  name: import_joi55.default.string().required(),
21187
21163
  contact: import_joi55.default.string().required(),
@@ -34040,7 +34016,7 @@ function useOccurrenceBookRepo() {
34040
34016
  date = "",
34041
34017
  status = ""
34042
34018
  }, session) {
34043
- page = page > 0 ? page - 1 : 0;
34019
+ page = page > 0 && !date ? page - 1 : 0;
34044
34020
  const _site = (0, import_node_server_utils156.toObjectId)(site);
34045
34021
  const query = {
34046
34022
  site: _site,
@@ -37454,12 +37430,15 @@ function useIncidentReportRepo() {
37454
37430
  }
37455
37431
  if (dateFrom) {
37456
37432
  const [year, month, day] = dateFrom.split("-").map(Number);
37457
- const start = new Date(year, month - 1, day, 0, 0, 0, 0).toISOString();
37458
- const end = new Date(year, month - 1, day, 23, 59, 59, 999).toISOString();
37433
+ const offset = 8;
37434
+ const start = new Date(Date.UTC(year, month - 1, day, -offset, 0, 0, 0));
37435
+ const end = new Date(
37436
+ Date.UTC(year, month - 1, day, 23 - offset, 59, 59, 999)
37437
+ );
37459
37438
  dateExpr = {
37460
37439
  "incidentInformation.incidentTypeAndTime.dateOfIncident": {
37461
- $gte: start,
37462
- $lte: end
37440
+ $gte: start.toISOString(),
37441
+ $lte: end.toISOString()
37463
37442
  }
37464
37443
  };
37465
37444
  }
@@ -45245,12 +45224,6 @@ function useVerificationRepoV2() {
45245
45224
  err
45246
45225
  );
45247
45226
  });
45248
- const cacheKey = (0, import_node_server_utils217.makeCacheKey)(namespace_collection, { _id });
45249
- delCache(cacheKey).then(() => {
45250
- import_node_server_utils217.logger.info(`Cache deleted for key: ${cacheKey}`);
45251
- }).catch((err) => {
45252
- import_node_server_utils217.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
45253
- });
45254
45227
  return result;
45255
45228
  } catch (error) {
45256
45229
  throw new import_node_server_utils217.InternalServerError("Error updating verification status.");
@@ -45656,9 +45629,12 @@ function useVerificationControllerV2() {
45656
45629
  async function verify(req, res, next) {
45657
45630
  try {
45658
45631
  const schema2 = import_joi126.default.object({ verificationCode: import_joi126.default.string().required() });
45659
- const { error, value } = schema2.validate({
45660
- verificationCode: req.params.verificationCode
45661
- });
45632
+ const { error, value } = schema2.validate(
45633
+ {
45634
+ verificationCode: req.params.verificationCode
45635
+ },
45636
+ { abortEarly: false }
45637
+ );
45662
45638
  if (error) {
45663
45639
  const messages = error.details.map((d) => d.message).join(", ");
45664
45640
  import_node_server_utils219.logger.log({ level: "error", message: messages });
@@ -45684,7 +45660,7 @@ function useVerificationControllerV2() {
45684
45660
  siteId: import_joi126.default.string().hex().length(24).optional().allow("", null),
45685
45661
  siteName: import_joi126.default.string().optional().allow("", null)
45686
45662
  });
45687
- const { error, value } = schema2.validate(req.body);
45663
+ const { error, value } = schema2.validate(req.body, { abortEarly: false });
45688
45664
  if (error) {
45689
45665
  const messages = error.details.map((d) => d.message).join(", ");
45690
45666
  import_node_server_utils219.logger.log({ level: "error", message: messages });
@@ -45719,7 +45695,7 @@ function useVerificationControllerV2() {
45719
45695
  siteId: import_joi126.default.string().hex().length(24).required(),
45720
45696
  siteName: import_joi126.default.string().required()
45721
45697
  });
45722
- const { error, value } = schema2.validate(req.body);
45698
+ const { error, value } = schema2.validate(req.body, { abortEarly: false });
45723
45699
  if (error) {
45724
45700
  const messages = error.details.map((d) => d.message).join(", ");
45725
45701
  import_node_server_utils219.logger.log({ level: "error", message: messages });
@@ -45745,7 +45721,7 @@ function useVerificationControllerV2() {
45745
45721
  const schema2 = import_joi126.default.object({
45746
45722
  email: import_joi126.default.string().email().lowercase().required()
45747
45723
  });
45748
- const { error, value } = schema2.validate(req.body);
45724
+ const { error, value } = schema2.validate(req.body, { abortEarly: false });
45749
45725
  if (error) {
45750
45726
  const messages = error.details.map((d) => d.message).join(", ");
45751
45727
  import_node_server_utils219.logger.log({ level: "error", message: messages });
@@ -45775,13 +45751,14 @@ function useVerificationControllerV2() {
45775
45751
 
45776
45752
  // src/controllers/auth-v2.controller.ts
45777
45753
  var import_joi127 = __toESM(require("joi"));
45778
- var import_node_server_utils222 = require("@7365admin1/node-server-utils");
45754
+ var import_node_server_utils223 = require("@7365admin1/node-server-utils");
45779
45755
 
45780
45756
  // src/services/auth-v2.service.ts
45781
45757
  var import_node_server_utils221 = require("@7365admin1/node-server-utils");
45782
45758
  var import_uuid2 = require("uuid");
45783
45759
 
45784
45760
  // src/repositories/user-v2.repo.ts
45761
+ var import_mongodb123 = require("mongodb");
45785
45762
  var import_node_server_utils220 = require("@7365admin1/node-server-utils");
45786
45763
  function useUserRepoV2() {
45787
45764
  const { updateFeedbackCreatedByName } = useFeedbackRepo();
@@ -45793,6 +45770,7 @@ function useUserRepoV2() {
45793
45770
  }
45794
45771
  const namespace_collection = "users";
45795
45772
  const collection = db.collection(namespace_collection);
45773
+ const { delNamespace, setCache, getCache, delCache } = (0, import_node_server_utils220.useCache)(namespace_collection);
45796
45774
  async function createIndex() {
45797
45775
  try {
45798
45776
  await collection.createIndexes([{ key: { email: 1 } }]);
@@ -45802,10 +45780,7 @@ function useUserRepoV2() {
45802
45780
  }
45803
45781
  async function createTextIndex() {
45804
45782
  try {
45805
- await collection.createIndex({
45806
- name: "text",
45807
- email: "text"
45808
- });
45783
+ await collection.createIndex({ name: "text", email: "text" });
45809
45784
  } catch (error) {
45810
45785
  throw new import_node_server_utils220.InternalServerError("Failed to create text index on user.");
45811
45786
  }
@@ -45820,24 +45795,22 @@ function useUserRepoV2() {
45820
45795
  throw new import_node_server_utils220.InternalServerError("Failed to create unique index on user.");
45821
45796
  }
45822
45797
  }
45823
- const { delNamespace, setCache, getCache, delCache } = (0, import_node_server_utils220.useCache)(namespace_collection);
45824
45798
  async function createUser(value, session) {
45825
45799
  try {
45826
45800
  value = MUser(value);
45827
45801
  const res = await collection.insertOne(value, { session });
45828
- delNamespace().then(() => {
45829
- import_node_server_utils220.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
45830
- }).catch((err) => {
45831
- import_node_server_utils220.logger.error(
45802
+ delNamespace().then(
45803
+ () => import_node_server_utils220.logger.info(`Cache cleared for namespace: ${namespace_collection}`)
45804
+ ).catch(
45805
+ (err) => import_node_server_utils220.logger.error(
45832
45806
  `Failed to clear cache for namespace: ${namespace_collection}`,
45833
45807
  err
45834
- );
45835
- });
45808
+ )
45809
+ );
45836
45810
  return res.insertedId;
45837
45811
  } catch (error) {
45838
45812
  import_node_server_utils220.logger.log({ level: "error", message: `${error}` });
45839
- const isDuplicated = error.message.includes("duplicate");
45840
- if (isDuplicated) {
45813
+ if (error.message.includes("duplicate")) {
45841
45814
  throw new import_node_server_utils220.BadRequestError("User already exists.");
45842
45815
  }
45843
45816
  throw error;
@@ -45854,11 +45827,9 @@ function useUserRepoV2() {
45854
45827
  const data = await collection.findOne({
45855
45828
  email: { $regex: `^${email}$`, $options: "i" }
45856
45829
  });
45857
- setCache(cacheKey, data, 15 * 60).then(() => {
45858
- import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`);
45859
- }).catch((err) => {
45860
- import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
45861
- });
45830
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
45831
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
45832
+ );
45862
45833
  return data;
45863
45834
  } catch (error) {
45864
45835
  throw new import_node_server_utils220.InternalServerError("Failed to get user by email.");
@@ -45866,26 +45837,22 @@ function useUserRepoV2() {
45866
45837
  }
45867
45838
  async function getUserByEmailStatus(email) {
45868
45839
  try {
45869
- const cacheOptions = {
45840
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, {
45870
45841
  email,
45871
45842
  status: "complete" /* COMPLETE */
45872
- };
45873
- const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, cacheOptions);
45843
+ });
45874
45844
  const cachedData = await getCache(cacheKey);
45875
45845
  if (cachedData) {
45876
45846
  import_node_server_utils220.logger.info(`Cache hit for key: ${cacheKey}`);
45877
45847
  return cachedData;
45878
45848
  }
45879
- const query = {
45849
+ const data = await collection.findOne({
45880
45850
  email: { $regex: `^${email}$`, $options: "i" },
45881
45851
  status: "complete" /* COMPLETE */
45882
- };
45883
- const data = await collection.findOne(query);
45884
- setCache(cacheKey, data, 15 * 60).then(() => {
45885
- import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`);
45886
- }).catch((err) => {
45887
- import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err);
45888
45852
  });
45853
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
45854
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
45855
+ );
45889
45856
  return data;
45890
45857
  } catch (error) {
45891
45858
  throw new import_node_server_utils220.InternalServerError("Failed to get user by email.");
@@ -45908,17 +45875,10 @@ function useUserRepoV2() {
45908
45875
  let: { userOrgId: "$defaultOrg" },
45909
45876
  pipeline: [
45910
45877
  {
45911
- $match: {
45912
- $expr: { $eq: ["$orgId", "$$userOrgId"] }
45913
- }
45878
+ $match: { $expr: { $eq: ["$orgId", "$$userOrgId"] } }
45914
45879
  },
45915
45880
  {
45916
- $project: {
45917
- _id: 1,
45918
- name: 1,
45919
- type: 1,
45920
- siteId: 1
45921
- }
45881
+ $project: { _id: 1, name: 1, type: 1, siteId: 1 }
45922
45882
  }
45923
45883
  ],
45924
45884
  as: "serviceProviders"
@@ -45926,9 +45886,117 @@ function useUserRepoV2() {
45926
45886
  }
45927
45887
  ]).toArray();
45928
45888
  const data = results.length > 0 ? results[0] : null;
45929
- if (!data) {
45889
+ if (!data)
45930
45890
  throw new import_node_server_utils220.NotFoundError("User not found.");
45891
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
45892
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
45893
+ );
45894
+ return data;
45895
+ } catch (error) {
45896
+ if (error instanceof import_node_server_utils220.AppError)
45897
+ throw error;
45898
+ throw new import_node_server_utils220.InternalServerError("Failed to get user by id.");
45899
+ }
45900
+ }
45901
+ async function getUserByReferralCode(referralCode) {
45902
+ try {
45903
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { referralCode });
45904
+ const cachedData = await getCache(cacheKey);
45905
+ if (cachedData) {
45906
+ import_node_server_utils220.logger.info(`Cache hit for key: ${cacheKey}`);
45907
+ return cachedData;
45908
+ }
45909
+ const data = await collection.findOne({ referralCode });
45910
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
45911
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
45912
+ );
45913
+ return data;
45914
+ } catch (error) {
45915
+ throw new import_node_server_utils220.InternalServerError("Failed to get user by referral code.");
45916
+ }
45917
+ }
45918
+ async function getByEmailApp(email, app) {
45919
+ try {
45920
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { email, app });
45921
+ const cachedData = await getCache(cacheKey);
45922
+ if (cachedData) {
45923
+ import_node_server_utils220.logger.info(`Cache hit for key: ${cacheKey}`);
45924
+ return cachedData;
45925
+ }
45926
+ const data = await collection.findOne({
45927
+ email,
45928
+ "roles.app": app
45929
+ });
45930
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
45931
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
45932
+ );
45933
+ return data;
45934
+ } catch (error) {
45935
+ throw new import_node_server_utils220.InternalServerError("Failed to get user by email and app.");
45936
+ }
45937
+ }
45938
+ async function getUsersByOrgId({
45939
+ organization = "",
45940
+ search = "",
45941
+ page = 1,
45942
+ limit = 10,
45943
+ sort = {},
45944
+ type = "",
45945
+ status = "active"
45946
+ }) {
45947
+ page = page > 0 ? page - 1 : 0;
45948
+ const query = { status };
45949
+ const cacheOptions = { status };
45950
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
45951
+ cacheOptions.sort = JSON.stringify(sort);
45952
+ if (search) {
45953
+ query.$text = { $search: search };
45954
+ cacheOptions.search = search;
45955
+ }
45956
+ if (type) {
45957
+ query.type = type;
45958
+ cacheOptions.type = type;
45959
+ }
45960
+ if (organization) {
45961
+ try {
45962
+ query.defaultOrg = new import_mongodb123.ObjectId(organization);
45963
+ cacheOptions.organization = organization.toString();
45964
+ } catch (error) {
45965
+ throw new import_node_server_utils220.BadRequestError("Invalid organization ID format.");
45931
45966
  }
45967
+ }
45968
+ delNamespace().then(() => {
45969
+ import_node_server_utils220.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
45970
+ }).catch((err) => {
45971
+ import_node_server_utils220.logger.error(
45972
+ `Failed to clear cache for namespace: ${namespace_collection}`,
45973
+ err
45974
+ );
45975
+ });
45976
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, cacheOptions);
45977
+ const cachedData = await getCache(cacheKey);
45978
+ if (cachedData) {
45979
+ import_node_server_utils220.logger.info(`Cache hit for key: ${cacheKey}`);
45980
+ return cachedData;
45981
+ }
45982
+ try {
45983
+ const items = await collection.aggregate([
45984
+ { $match: query },
45985
+ { $sort: sort },
45986
+ { $skip: page * limit },
45987
+ { $limit: limit },
45988
+ {
45989
+ $project: {
45990
+ _id: 1,
45991
+ name: 1,
45992
+ email: 1,
45993
+ type: 1,
45994
+ status: 1
45995
+ }
45996
+ }
45997
+ ]).toArray();
45998
+ const length = await collection.countDocuments(query);
45999
+ const data = (0, import_node_server_utils220.paginate)(items, page, limit, length);
45932
46000
  setCache(cacheKey, data, 15 * 60).then(() => {
45933
46001
  import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`);
45934
46002
  }).catch((err) => {
@@ -45936,12 +46004,197 @@ function useUserRepoV2() {
45936
46004
  });
45937
46005
  return data;
45938
46006
  } catch (error) {
45939
- if (error instanceof import_node_server_utils220.AppError) {
46007
+ import_node_server_utils220.logger.log({ level: "error", message: `${error}` });
46008
+ throw error;
46009
+ }
46010
+ }
46011
+ async function getUsers({
46012
+ search = "",
46013
+ page = 1,
46014
+ limit = 10,
46015
+ sort = {},
46016
+ type = "",
46017
+ status = "active"
46018
+ }) {
46019
+ page = page > 0 ? page - 1 : 0;
46020
+ const query = { status };
46021
+ const cacheOptions = { status };
46022
+ sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
46023
+ cacheOptions.sort = JSON.stringify(sort);
46024
+ if (search) {
46025
+ query.$text = { $search: search };
46026
+ cacheOptions.search = search;
46027
+ }
46028
+ if (type) {
46029
+ query.type = type;
46030
+ cacheOptions.type = type;
46031
+ }
46032
+ delNamespace().then(
46033
+ () => import_node_server_utils220.logger.info(`Cache cleared for namespace: ${namespace_collection}`)
46034
+ ).catch(
46035
+ (err) => import_node_server_utils220.logger.error(
46036
+ `Failed to clear cache for namespace: ${namespace_collection}`,
46037
+ err
46038
+ )
46039
+ );
46040
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, cacheOptions);
46041
+ const cachedData = await getCache(cacheKey);
46042
+ if (cachedData) {
46043
+ import_node_server_utils220.logger.info(`Cache hit for key: ${cacheKey}`);
46044
+ return cachedData;
46045
+ }
46046
+ try {
46047
+ const items = await collection.aggregate([
46048
+ { $match: query },
46049
+ { $sort: sort },
46050
+ { $skip: page * limit },
46051
+ { $limit: limit },
46052
+ { $project: { _id: 1, name: 1, email: 1, type: 1, status: 1 } }
46053
+ ]).toArray();
46054
+ const length = await collection.countDocuments(query);
46055
+ const data = (0, import_node_server_utils220.paginate)(items, page, limit, length);
46056
+ setCache(cacheKey, data, 15 * 60).then(() => import_node_server_utils220.logger.info(`Cache set for key: ${cacheKey}`)).catch(
46057
+ (err) => import_node_server_utils220.logger.error(`Failed to set cache for key: ${cacheKey}`, err)
46058
+ );
46059
+ return data;
46060
+ } catch (error) {
46061
+ import_node_server_utils220.logger.log({ level: "error", message: `${error}` });
46062
+ throw error;
46063
+ }
46064
+ }
46065
+ async function updatePasswordById({ _id, password }, session) {
46066
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { _id });
46067
+ _id = (0, import_node_server_utils220.toObjectId)(_id);
46068
+ try {
46069
+ const result = await collection.updateOne(
46070
+ { _id },
46071
+ { $set: { password, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
46072
+ { session }
46073
+ );
46074
+ delCache(cacheKey).then(() => {
46075
+ import_node_server_utils220.logger.info(`Cache deleted for key: ${cacheKey}`);
46076
+ }).catch((err) => {
46077
+ import_node_server_utils220.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
46078
+ });
46079
+ return result;
46080
+ } catch (error) {
46081
+ throw new import_node_server_utils220.InternalServerError("Failed to update user password.");
46082
+ }
46083
+ }
46084
+ async function updateUserFieldById({ _id, field, value } = {}, session) {
46085
+ const allowedFields = [
46086
+ "name",
46087
+ "email",
46088
+ "contact",
46089
+ "nric",
46090
+ "dateOfBirth",
46091
+ "profile",
46092
+ "gender",
46093
+ "defaultOrg"
46094
+ ];
46095
+ if (!allowedFields.includes(field)) {
46096
+ throw new import_node_server_utils220.BadRequestError(
46097
+ `Field "${field}" is not allowed to be updated.`
46098
+ );
46099
+ }
46100
+ try {
46101
+ _id = new import_mongodb123.ObjectId(_id);
46102
+ } catch (error) {
46103
+ throw new import_node_server_utils220.BadRequestError("Invalid ID.");
46104
+ }
46105
+ if (field === "defaultOrg") {
46106
+ try {
46107
+ value = new import_mongodb123.ObjectId(value);
46108
+ } catch (error) {
46109
+ throw new import_node_server_utils220.BadRequestError("Invalid organization ID.");
46110
+ }
46111
+ }
46112
+ if (field === "name") {
46113
+ try {
46114
+ await Promise.all([
46115
+ updateFeedbackCreatedByName(_id, value, session),
46116
+ updateWorkOrderCreatedByName(_id, value, session),
46117
+ updateUserNameBySignatureId(_id, value, session)
46118
+ ]);
46119
+ } catch (error) {
45940
46120
  throw error;
45941
- } else {
45942
- throw new import_node_server_utils220.InternalServerError("Failed to get user by email.");
45943
46121
  }
45944
46122
  }
46123
+ try {
46124
+ await collection.updateOne(
46125
+ { _id },
46126
+ { $set: { [field]: value, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
46127
+ // Dynamically set the field
46128
+ { session }
46129
+ );
46130
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { _id });
46131
+ delCache(cacheKey).then(() => {
46132
+ import_node_server_utils220.logger.info(`Cache deleted for key: ${cacheKey}`);
46133
+ }).catch((err) => {
46134
+ import_node_server_utils220.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
46135
+ });
46136
+ return `Successfully updated user ${field}.`;
46137
+ } catch (error) {
46138
+ throw new import_node_server_utils220.InternalServerError(`Failed to update user ${field}.`);
46139
+ }
46140
+ }
46141
+ async function updateBirthday({
46142
+ _id,
46143
+ month,
46144
+ day,
46145
+ year
46146
+ }, session) {
46147
+ try {
46148
+ _id = new import_mongodb123.ObjectId(_id);
46149
+ } catch (error) {
46150
+ throw new import_node_server_utils220.BadRequestError("Invalid user ID format.");
46151
+ }
46152
+ try {
46153
+ await collection.updateOne(
46154
+ { _id },
46155
+ {
46156
+ $set: {
46157
+ birthMonth: month,
46158
+ birthDay: day,
46159
+ birthYear: year,
46160
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
46161
+ }
46162
+ },
46163
+ { session }
46164
+ );
46165
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { _id });
46166
+ delCache(cacheKey).then(() => {
46167
+ import_node_server_utils220.logger.info(`Cache deleted for key: ${cacheKey}`);
46168
+ }).catch((err) => {
46169
+ import_node_server_utils220.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
46170
+ });
46171
+ return "Successfully updated user birthday.";
46172
+ } catch (error) {
46173
+ throw new import_node_server_utils220.InternalServerError("Failed to update user birthday.");
46174
+ }
46175
+ }
46176
+ async function updatePassword({ _id, password }, session) {
46177
+ try {
46178
+ _id = new import_mongodb123.ObjectId(_id);
46179
+ } catch (error) {
46180
+ throw new import_node_server_utils220.BadRequestError("Invalid user ID format.");
46181
+ }
46182
+ try {
46183
+ const result = await collection.updateOne(
46184
+ { _id },
46185
+ { $set: { password, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } },
46186
+ { session }
46187
+ );
46188
+ const cacheKey = (0, import_node_server_utils220.makeCacheKey)(namespace_collection, { _id });
46189
+ delCache(cacheKey).then(() => {
46190
+ import_node_server_utils220.logger.info(`Cache deleted for key: ${cacheKey}`);
46191
+ }).catch((err) => {
46192
+ import_node_server_utils220.logger.error(`Failed to delete cache for key: ${cacheKey}`, err);
46193
+ });
46194
+ return result;
46195
+ } catch (error) {
46196
+ throw new import_node_server_utils220.InternalServerError("Failed to update user password.");
46197
+ }
45945
46198
  }
45946
46199
  return {
45947
46200
  createIndex,
@@ -45950,7 +46203,13 @@ function useUserRepoV2() {
45950
46203
  createUser,
45951
46204
  getUserByEmail,
45952
46205
  getUserByEmailStatus,
45953
- getUserById
46206
+ getUserById,
46207
+ getUsers,
46208
+ getUsersByOrgId,
46209
+ updatePasswordById,
46210
+ updateUserFieldById,
46211
+ updateBirthday,
46212
+ updatePassword
45954
46213
  };
45955
46214
  }
45956
46215
 
@@ -46017,10 +46276,212 @@ function useAuthServiceV2() {
46017
46276
  };
46018
46277
  }
46019
46278
 
46279
+ // src/services/user-v2.service.ts
46280
+ var import_node_server_utils222 = require("@7365admin1/node-server-utils");
46281
+ var import_multer2 = require("multer");
46282
+ function useUserServiceV2() {
46283
+ const {
46284
+ createUser: _createUser,
46285
+ getUserByEmail: _getUserByEmail,
46286
+ updatePasswordById: _updatePasswordById,
46287
+ updateUserFieldById: _updateUserFieldById,
46288
+ getUserById,
46289
+ updatePassword
46290
+ } = useUserRepoV2();
46291
+ const { getRoleByName, addRole } = useRoleRepo();
46292
+ const { add: addMember } = useMemberRepo();
46293
+ const { getById: getOrgById } = useOrgRepo();
46294
+ const { getSiteById } = useSiteRepo();
46295
+ const {
46296
+ getVerificationById: _getVerificationById,
46297
+ updateVerificationStatusById: _updateVerificationStatusById
46298
+ } = useVerificationRepoV2();
46299
+ const { verify: _verify } = useVerificationServiceV2();
46300
+ const { createFile, deleteFileById } = useFileRepo();
46301
+ async function createUserBySignUp({
46302
+ id = "",
46303
+ name = ""
46304
+ }) {
46305
+ const session = import_node_server_utils222.useAtlas.getClient()?.startSession();
46306
+ session?.startTransaction();
46307
+ try {
46308
+ const signUp = await _getVerificationById(id);
46309
+ if (!signUp)
46310
+ throw new import_node_server_utils222.BadRequestError("Invalid sign up link.");
46311
+ if (signUp.status === "complete" /* COMPLETE */)
46312
+ throw new import_node_server_utils222.BadRequestError(
46313
+ "You have already an account created using this link."
46314
+ );
46315
+ const expired = signUp.expireAt < (/* @__PURE__ */ new Date()).toISOString();
46316
+ if (signUp.status === "expired" || expired)
46317
+ throw new import_node_server_utils222.BadRequestError("Sign up link expired.");
46318
+ const email = signUp.email;
46319
+ const _user = await _getUserByEmail(email);
46320
+ if (_user)
46321
+ throw new import_node_server_utils222.BadRequestError(`User already exists: ${email}.`);
46322
+ let org = null;
46323
+ if (signUp.metadata?.org) {
46324
+ org = await getOrgById(signUp.metadata.org);
46325
+ if (!org)
46326
+ signUp.metadata.org = "";
46327
+ }
46328
+ if (signUp.metadata?.siteId)
46329
+ await getSiteById(signUp.metadata?.siteId);
46330
+ const user = {
46331
+ email,
46332
+ password: signUp.metadata?.password,
46333
+ name,
46334
+ defaultOrg: org?._id?.toString() || ""
46335
+ };
46336
+ const userId = await _createUser(user, session);
46337
+ if (org?._id) {
46338
+ await addMember(
46339
+ {
46340
+ org: org?._id?.toString() || "",
46341
+ orgName: org?.name || "",
46342
+ user: userId.toString(),
46343
+ name,
46344
+ role: signUp.metadata?.role?.toString() || "",
46345
+ type: signUp.metadata?.app ?? "organization",
46346
+ siteId: signUp.metadata?.siteId?.toString() || "",
46347
+ siteName: signUp.metadata?.siteName || ""
46348
+ },
46349
+ session
46350
+ );
46351
+ }
46352
+ await _updateVerificationStatusById(
46353
+ id,
46354
+ "complete" /* COMPLETE */,
46355
+ session
46356
+ );
46357
+ await session?.commitTransaction();
46358
+ return userId;
46359
+ } catch (error) {
46360
+ await session?.abortTransaction();
46361
+ throw error;
46362
+ } finally {
46363
+ session?.endSession();
46364
+ }
46365
+ }
46366
+ async function resetPassword(id, newPassword, passwordConfirmation) {
46367
+ if (newPassword !== passwordConfirmation) {
46368
+ throw new import_node_server_utils222.BadRequestError("Passwords do not match.");
46369
+ }
46370
+ let hashedPassword;
46371
+ const session = import_node_server_utils222.useAtlas.getClient()?.startSession();
46372
+ session?.startTransaction();
46373
+ try {
46374
+ hashedPassword = await (0, import_node_server_utils222.hashPassword)(newPassword);
46375
+ } catch (error) {
46376
+ throw new import_node_server_utils222.InternalServerError(`Error hashing password: ${error}`);
46377
+ }
46378
+ try {
46379
+ const otpDoc = await _getVerificationById(id);
46380
+ if (!otpDoc) {
46381
+ throw new import_node_server_utils222.NotFoundError("You are using an invalid reset link.");
46382
+ }
46383
+ if (otpDoc.status === "complete" /* COMPLETE */) {
46384
+ throw new import_node_server_utils222.BadRequestError("This link has already been invalidated.");
46385
+ }
46386
+ const user = await _getUserByEmail(otpDoc.email);
46387
+ if (!user) {
46388
+ throw new import_node_server_utils222.NotFoundError("User not found.");
46389
+ }
46390
+ if (!user._id) {
46391
+ throw new import_node_server_utils222.InternalServerError("Invalid user ID.");
46392
+ }
46393
+ await Promise.all([
46394
+ _updateVerificationStatusById(id, "complete" /* COMPLETE */, session),
46395
+ _updatePasswordById(
46396
+ { _id: user._id.toString(), password: hashedPassword },
46397
+ session
46398
+ )
46399
+ ]);
46400
+ await session?.commitTransaction();
46401
+ return "Successfully reset password.";
46402
+ } catch (error) {
46403
+ await session?.abortTransaction();
46404
+ throw error;
46405
+ } finally {
46406
+ session?.endSession();
46407
+ }
46408
+ }
46409
+ const s3 = new import_node_server_utils222.useS3({
46410
+ accessKeyId: SPACES_ACCESS_KEY,
46411
+ secretAccessKey: SPACES_SECRET_KEY,
46412
+ endpoint: SPACES_ENDPOINT,
46413
+ region: SPACES_REGION,
46414
+ bucket: SPACES_BUCKET,
46415
+ forcePathStyle: false
46416
+ });
46417
+ async function updateUserProfile({
46418
+ file,
46419
+ user,
46420
+ previousProfile
46421
+ }) {
46422
+ const session = import_node_server_utils222.useAtlas.getClient()?.startSession();
46423
+ session?.startTransaction();
46424
+ const _file = {
46425
+ name: file.originalname,
46426
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
46427
+ };
46428
+ try {
46429
+ const id = await createFile(_file, session);
46430
+ await s3.uploadObject({
46431
+ key: id,
46432
+ body: file.buffer,
46433
+ contentType: file.mimetype
46434
+ });
46435
+ if (previousProfile) {
46436
+ await deleteFileById(previousProfile, session);
46437
+ await s3.deleteObject(previousProfile);
46438
+ }
46439
+ await _updateUserFieldById(
46440
+ { _id: user, field: "profile", value: id },
46441
+ session
46442
+ );
46443
+ await session?.commitTransaction();
46444
+ return id;
46445
+ } catch (error) {
46446
+ await session?.abortTransaction();
46447
+ throw error;
46448
+ } finally {
46449
+ session?.endSession();
46450
+ }
46451
+ }
46452
+ async function updatePasswordById(id, currentPassword, newPassword, passwordConfirmation) {
46453
+ let hashedPassword;
46454
+ const user = await getUserById(id);
46455
+ const isPasswordValid = await (0, import_node_server_utils222.comparePassword)(
46456
+ currentPassword,
46457
+ user.password
46458
+ );
46459
+ if (!isPasswordValid)
46460
+ throw new import_node_server_utils222.BadRequestError("Invalid current password.");
46461
+ if (newPassword !== passwordConfirmation)
46462
+ throw new import_node_server_utils222.BadRequestError("Passwords do not match.");
46463
+ try {
46464
+ hashedPassword = await (0, import_node_server_utils222.hashPassword)(newPassword);
46465
+ if (!hashedPassword)
46466
+ throw new import_node_server_utils222.InternalServerError("Error hashing password.");
46467
+ return await updatePassword({ _id: id, password: hashedPassword });
46468
+ } catch (error) {
46469
+ throw error;
46470
+ }
46471
+ }
46472
+ return {
46473
+ createUserBySignUp,
46474
+ resetPassword,
46475
+ updateUserProfile,
46476
+ updatePasswordById
46477
+ };
46478
+ }
46479
+
46020
46480
  // src/controllers/auth-v2.controller.ts
46021
46481
  function useAuthControllerV2() {
46022
46482
  const { signUp: _signUp } = useVerificationServiceV2();
46023
46483
  const { login: _login, logout: _logout } = useAuthServiceV2();
46484
+ const { resetPassword: _resetPassword } = useUserServiceV2();
46024
46485
  async function signUp(req, res, next) {
46025
46486
  try {
46026
46487
  const validation = import_joi127.default.object({
@@ -46034,8 +46495,8 @@ function useAuthControllerV2() {
46034
46495
  });
46035
46496
  if (error) {
46036
46497
  const messages = error.details.map((d) => d.message);
46037
- import_node_server_utils222.logger.log({ level: "error", message: messages.join(", ") });
46038
- next(new import_node_server_utils222.BadRequestError(messages.join(", ")));
46498
+ import_node_server_utils223.logger.log({ level: "error", message: messages.join(", ") });
46499
+ next(new import_node_server_utils223.BadRequestError(messages.join(", ")));
46039
46500
  return;
46040
46501
  }
46041
46502
  const { email, password, country, orgName } = value;
@@ -46051,7 +46512,7 @@ function useAuthControllerV2() {
46051
46512
  return;
46052
46513
  } catch (error) {
46053
46514
  console.log(error);
46054
- import_node_server_utils222.logger.log({ level: "error", message: error.message });
46515
+ import_node_server_utils223.logger.log({ level: "error", message: error.message });
46055
46516
  next(error);
46056
46517
  return;
46057
46518
  }
@@ -46069,8 +46530,8 @@ function useAuthControllerV2() {
46069
46530
  });
46070
46531
  if (error) {
46071
46532
  const messages = error.details.map((d) => d.message);
46072
- import_node_server_utils222.logger.log({ level: "error", message: messages.join(", ") });
46073
- next(new import_node_server_utils222.BadRequestError(messages.join(", ")));
46533
+ import_node_server_utils223.logger.log({ level: "error", message: messages.join(", ") });
46534
+ next(new import_node_server_utils223.BadRequestError(messages.join(", ")));
46074
46535
  return;
46075
46536
  }
46076
46537
  const session = await _login(value);
@@ -46082,7 +46543,7 @@ function useAuthControllerV2() {
46082
46543
  res.cookie("sid", session.sid, cookieOptions).cookie("user", session.user, cookieOptions).json(session);
46083
46544
  return;
46084
46545
  } catch (error) {
46085
- import_node_server_utils222.logger.log({ level: "error", message: error.message });
46546
+ import_node_server_utils223.logger.log({ level: "error", message: error.message });
46086
46547
  next(error);
46087
46548
  return;
46088
46549
  }
@@ -46090,7 +46551,7 @@ function useAuthControllerV2() {
46090
46551
  async function logout(req, res, next) {
46091
46552
  const sid = req.headers["authorization"] ?? "";
46092
46553
  if (!sid) {
46093
- next(new import_node_server_utils222.BadRequestError("Session ID is required"));
46554
+ next(new import_node_server_utils223.BadRequestError("Session ID is required"));
46094
46555
  return;
46095
46556
  }
46096
46557
  try {
@@ -46098,127 +46559,170 @@ function useAuthControllerV2() {
46098
46559
  res.json({ message: "Logged out successfully" });
46099
46560
  return;
46100
46561
  } catch (error) {
46101
- import_node_server_utils222.logger.log({ level: "error", message: error.message });
46562
+ import_node_server_utils223.logger.log({ level: "error", message: error.message });
46102
46563
  next(error);
46103
46564
  return;
46104
46565
  }
46105
46566
  }
46106
- return {
46107
- signUp,
46108
- login,
46109
- logout
46110
- };
46111
- }
46112
-
46113
- // src/services/user-v2.service.ts
46114
- var import_node_server_utils223 = require("@7365admin1/node-server-utils");
46115
- var import_multer2 = require("multer");
46116
- function useUserServiceV2() {
46117
- const { createUser: _createUser, getUserByEmail } = useUserRepoV2();
46118
- const { getRoleByName, addRole } = useRoleRepo();
46119
- const { add: addMember } = useMemberRepo();
46120
- const { getById: getOrgById } = useOrgRepo();
46121
- const { getSiteById } = useSiteRepo();
46122
- const {
46123
- getVerificationById: _getVerificationById,
46124
- updateVerificationStatusById: _updateVerificationStatusById
46125
- } = useVerificationRepoV2();
46126
- const { verify } = useVerificationService();
46127
- const { createFile, deleteFileById } = useFileRepo();
46128
- async function createUserBySignUp({
46129
- id = "",
46130
- name = ""
46131
- }) {
46132
- const session = import_node_server_utils223.useAtlas.getClient()?.startSession();
46133
- session?.startTransaction();
46567
+ async function resetPassword(req, res, next) {
46568
+ const validation = import_joi127.default.object({
46569
+ otp: import_joi127.default.string().hex().required(),
46570
+ newPassword: import_joi127.default.string().required().min(8),
46571
+ passwordConfirmation: import_joi127.default.string().required().min(8)
46572
+ });
46573
+ const { error, value } = validation.validate(req.body, {
46574
+ abortEarly: false
46575
+ });
46576
+ if (error) {
46577
+ const messages = error.details.map((d) => d.message);
46578
+ import_node_server_utils223.logger.log({ level: "error", message: messages.join(", ") });
46579
+ next(new import_node_server_utils223.BadRequestError(messages.join(", ")));
46580
+ return;
46581
+ }
46582
+ const { otp, newPassword, passwordConfirmation } = value;
46134
46583
  try {
46135
- const signUp = await _getVerificationById(id);
46136
- if (!signUp)
46137
- throw new import_node_server_utils223.BadRequestError("Invalid sign up link.");
46138
- if (signUp.status === "complete")
46139
- throw new import_node_server_utils223.BadRequestError(
46140
- "You have already an account created using this link."
46141
- );
46142
- const expired = signUp.expireAt < (/* @__PURE__ */ new Date()).toISOString();
46143
- if (signUp.status === "expired" || expired)
46144
- throw new import_node_server_utils223.BadRequestError("Sign up link expired.");
46145
- const email = signUp.email;
46146
- const _user = await getUserByEmail(email);
46147
- if (_user)
46148
- throw new import_node_server_utils223.BadRequestError(`User already exists: ${email}.`);
46149
- let org = null;
46150
- if (signUp.metadata?.org) {
46151
- org = await getOrgById(signUp.metadata.org);
46152
- if (!org)
46153
- signUp.metadata.org = "";
46154
- }
46155
- if (signUp.metadata?.siteId)
46156
- await getSiteById(signUp.metadata?.siteId);
46157
- const user = {
46158
- email,
46159
- password: signUp.metadata?.password,
46160
- name,
46161
- defaultOrg: org?._id?.toString() || ""
46162
- };
46163
- const userId = await _createUser(user, session);
46164
- if (org?._id) {
46165
- await addMember(
46166
- {
46167
- org: org?._id?.toString() || "",
46168
- orgName: org?.name || "",
46169
- user: userId.toString(),
46170
- name,
46171
- role: signUp.metadata?.role?.toString() || "",
46172
- type: signUp.metadata?.app ?? "organization",
46173
- siteId: signUp.metadata?.siteId?.toString() || "",
46174
- siteName: signUp.metadata?.siteName || ""
46175
- },
46176
- session
46177
- );
46178
- }
46179
- await _updateVerificationStatusById(
46180
- id,
46181
- "complete" /* COMPLETE */,
46182
- session
46584
+ const message = await _resetPassword(
46585
+ otp,
46586
+ newPassword,
46587
+ passwordConfirmation
46183
46588
  );
46184
- await session?.commitTransaction();
46185
- return userId;
46186
- } catch (error) {
46187
- await session?.abortTransaction();
46188
- throw error;
46189
- } finally {
46190
- session?.endSession();
46589
+ res.json({ message });
46590
+ return;
46591
+ } catch (error2) {
46592
+ import_node_server_utils223.logger.log({ level: "error", message: error2.message });
46593
+ next(error2);
46594
+ return;
46191
46595
  }
46192
46596
  }
46193
46597
  return {
46194
- createUserBySignUp
46598
+ signUp,
46599
+ login,
46600
+ logout,
46601
+ resetPassword
46195
46602
  };
46196
46603
  }
46197
46604
 
46198
46605
  // src/controllers/user-v2.controller.ts
46199
46606
  var import_joi128 = __toESM(require("joi"));
46607
+ var import_multer3 = require("multer");
46200
46608
  var import_node_server_utils224 = require("@7365admin1/node-server-utils");
46201
46609
  function useUserControllerV2() {
46202
- const { createUserBySignUp: _createUserBySignUp } = useUserServiceV2();
46610
+ const {
46611
+ updateBirthday: _updateBirthday,
46612
+ getUserById: _getUserById,
46613
+ getUserByEmail: _getUserByEmail,
46614
+ getUserById: _getById,
46615
+ getUsers: _getUsers,
46616
+ getUsersByOrgId: _getUsersByOrgId,
46617
+ updateUserFieldById: _updateUserFieldById
46618
+ } = useUserRepoV2();
46619
+ const { createUserBySignUp, updateUserProfile: _updateUserProfile, updatePasswordById: _updatePasswordById } = useUserServiceV2();
46620
+ function rejectValidation(error, next) {
46621
+ const message = error.details.map((d) => d.message).join(", ");
46622
+ import_node_server_utils224.logger.log({ level: "error", message });
46623
+ next(new import_node_server_utils224.BadRequestError(message));
46624
+ }
46625
+ async function getById(req, res, next) {
46626
+ const validation = import_joi128.default.string().hex().required();
46627
+ const _id = req.params.id;
46628
+ const { error, value } = validation.validate(_id);
46629
+ if (error) {
46630
+ import_node_server_utils224.logger.log({ level: "error", message: `${error.message}` });
46631
+ next(new import_node_server_utils224.BadRequestError(error.message));
46632
+ return;
46633
+ }
46634
+ try {
46635
+ const user = await _getById(value);
46636
+ res.json(user);
46637
+ return;
46638
+ } catch (error2) {
46639
+ import_node_server_utils224.logger.log({ level: "error", message: `${error2.message}` });
46640
+ next(error2);
46641
+ return;
46642
+ }
46643
+ }
46644
+ async function getByEmail(req, res, next) {
46645
+ const { error, value } = import_joi128.default.string().email().required().validate(req.params.email);
46646
+ if (error)
46647
+ return rejectValidation(error, next);
46648
+ try {
46649
+ const user = await _getUserByEmail(value);
46650
+ res.json(user);
46651
+ return;
46652
+ } catch (err) {
46653
+ import_node_server_utils224.logger.log({ level: "error", message: `${err.message}` });
46654
+ next(err);
46655
+ return;
46656
+ }
46657
+ }
46658
+ async function getUsers(req, res, next) {
46659
+ const { search = "", page = 1, limit = 10, sort = {}, type = "", status = "active" } = req.query;
46660
+ const { error, value } = import_joi128.default.object({
46661
+ search: import_joi128.default.string().optional().allow("", null),
46662
+ page: import_joi128.default.number().integer().min(1).allow("", null).default(1),
46663
+ limit: import_joi128.default.number().integer().min(1).allow("", null).default(10),
46664
+ sort: import_joi128.default.object().optional().allow("", null).default({}),
46665
+ type: import_joi128.default.string().optional().allow("", null).default(""),
46666
+ status: import_joi128.default.string().optional().allow("", null).default("active" /* ACTIVE */)
46667
+ }).validate({ search, page, limit, sort, type, status });
46668
+ if (error)
46669
+ return rejectValidation(error, next);
46670
+ try {
46671
+ const users = await _getUsers({
46672
+ search: value.search ?? "",
46673
+ page: value.page,
46674
+ limit: value.limit,
46675
+ sort: value.sort,
46676
+ type: value.type,
46677
+ status: value.status
46678
+ });
46679
+ res.json(users);
46680
+ return;
46681
+ } catch (err) {
46682
+ next(err);
46683
+ }
46684
+ }
46685
+ async function getUsersByOrgId(req, res, next) {
46686
+ const { search, page, status, organization } = req.query;
46687
+ const { error, value } = import_joi128.default.object({
46688
+ search: import_joi128.default.string().optional().allow("", null),
46689
+ page: import_joi128.default.number().integer().min(1).allow("", null).default(1),
46690
+ status: import_joi128.default.string().required(),
46691
+ organization: import_joi128.default.string().required()
46692
+ }).validate({ search, page, status, organization });
46693
+ if (error)
46694
+ return rejectValidation(error, next);
46695
+ try {
46696
+ res.json(
46697
+ await _getUsersByOrgId({
46698
+ search: value.search ?? "",
46699
+ page: value.page,
46700
+ status: value.status,
46701
+ organization: value.organization
46702
+ })
46703
+ );
46704
+ } catch (err) {
46705
+ next(err);
46706
+ }
46707
+ }
46203
46708
  async function createUserByVerification(req, res, next) {
46204
- const schema2 = import_joi128.default.object({
46205
- id: import_joi128.default.string().hex().length(24).required(),
46709
+ const allowedTypes = ["user-sign-up" /* USER_SIGN_UP */, "user-invite" /* USER_INVITE */];
46710
+ const validation = import_joi128.default.object({
46711
+ id: import_joi128.default.string().hex().required(),
46206
46712
  name: import_joi128.default.string().required(),
46207
- type: import_joi128.default.string().required().valid("user-sign-up" /* USER_SIGN_UP */, "user-invite" /* USER_INVITE */)
46208
- });
46209
- const { error, value } = schema2.validate({
46210
- id: req.params.id,
46211
- ...req.body
46713
+ password: import_joi128.default.string().required(),
46714
+ type: import_joi128.default.string().required().valid(...allowedTypes)
46212
46715
  });
46716
+ const id = req.params.id;
46717
+ const payload = { ...req.body };
46718
+ const { error, value } = validation.validate({ id, ...payload });
46213
46719
  if (error) {
46214
- const messages = error.details.map((d) => d.message).join(", ");
46215
- import_node_server_utils224.logger.log({ level: "error", message: messages });
46216
- next(new import_node_server_utils224.BadRequestError(messages));
46720
+ import_node_server_utils224.logger.log({ level: "error", message: `${error.message}` });
46721
+ next(new import_node_server_utils224.BadRequestError(error.message));
46217
46722
  return;
46218
46723
  }
46219
- const { id, name } = value;
46220
46724
  try {
46221
- await _createUserBySignUp({ id, name });
46725
+ await createUserBySignUp({ id: value.id, name: value.name });
46222
46726
  res.status(201).json({ message: "Successfully created account." });
46223
46727
  return;
46224
46728
  } catch (error2) {
@@ -46227,8 +46731,148 @@ function useUserControllerV2() {
46227
46731
  return;
46228
46732
  }
46229
46733
  }
46734
+ async function updateUserProfile(req, res, next) {
46735
+ if (!req.file) {
46736
+ next(new import_node_server_utils224.BadRequestError("File is required!"));
46737
+ return;
46738
+ }
46739
+ const validation = import_joi128.default.object({
46740
+ previousProfile: import_joi128.default.string().hex().optional().allow("", null)
46741
+ });
46742
+ const payload = { ...req.body };
46743
+ const { error, value } = validation.validate(payload);
46744
+ if (error) {
46745
+ import_node_server_utils224.logger.log({ level: "error", message: `${error.message}` });
46746
+ next(new import_node_server_utils224.BadRequestError(error.message));
46747
+ return;
46748
+ }
46749
+ const user = req.headers.user ?? "";
46750
+ try {
46751
+ await _updateUserProfile({
46752
+ file: req.file,
46753
+ user,
46754
+ ...value
46755
+ });
46756
+ res.json({ message: "Successfully updated profile picture." });
46757
+ return;
46758
+ } catch (error2) {
46759
+ import_node_server_utils224.logger.log({ level: "error", message: `${error2.message}` });
46760
+ next(error2);
46761
+ return;
46762
+ }
46763
+ }
46764
+ async function updateBirthday(req, res, next) {
46765
+ const MONTHS = [
46766
+ "January",
46767
+ "February",
46768
+ "March",
46769
+ "April",
46770
+ "May",
46771
+ "June",
46772
+ "July",
46773
+ "August",
46774
+ "September",
46775
+ "October",
46776
+ "November",
46777
+ "December"
46778
+ ];
46779
+ const validation = import_joi128.default.object({
46780
+ _id: import_joi128.default.string().hex().required(),
46781
+ month: import_joi128.default.string().valid(...MONTHS).required(),
46782
+ day: import_joi128.default.number().integer().min(1).max(31).required(),
46783
+ year: import_joi128.default.number().integer().min(1900).max((/* @__PURE__ */ new Date()).getFullYear()).required()
46784
+ });
46785
+ const _id = req.params.id;
46786
+ const payload = { ...req.body };
46787
+ const { error } = validation.validate({ _id, ...payload });
46788
+ if (error) {
46789
+ import_node_server_utils224.logger.log({ level: "error", message: `${error.message}` });
46790
+ next(new import_node_server_utils224.BadRequestError(error.message));
46791
+ return;
46792
+ }
46793
+ try {
46794
+ const message = await _updateBirthday({ _id, ...payload });
46795
+ res.json({ message });
46796
+ return;
46797
+ } catch (error2) {
46798
+ import_node_server_utils224.logger.log({ level: "error", message: `${error2.message}` });
46799
+ next(error2);
46800
+ return;
46801
+ }
46802
+ }
46803
+ async function updateUserFieldById(req, res, next) {
46804
+ const FIELDS = ["name", "email", "contact", "nric", "dateOfBirth", "profile", "gender", "defaultOrg"];
46805
+ const validation = import_joi128.default.object({
46806
+ _id: import_joi128.default.string().hex().required(),
46807
+ field: import_joi128.default.string().valid(...FIELDS).required(),
46808
+ value: import_joi128.default.when("field", {
46809
+ switch: [
46810
+ { is: "email", then: import_joi128.default.string().email().required() },
46811
+ { is: "defaultOrg", then: import_joi128.default.string().hex().required() }
46812
+ ],
46813
+ otherwise: import_joi128.default.string().required()
46814
+ })
46815
+ });
46816
+ const _id = req.params.id;
46817
+ const payload = { ...req.body };
46818
+ const { error } = validation.validate({ _id, ...payload });
46819
+ if (error) {
46820
+ import_node_server_utils224.logger.log({ level: "error", message: `${error.message}` });
46821
+ next(new import_node_server_utils224.BadRequestError(error.message));
46822
+ return;
46823
+ }
46824
+ try {
46825
+ const message = await _updateUserFieldById({ _id, ...payload });
46826
+ res.json({ message });
46827
+ return;
46828
+ } catch (error2) {
46829
+ import_node_server_utils224.logger.log({ level: "error", message: `${error2.message}` });
46830
+ next(error2);
46831
+ return;
46832
+ }
46833
+ }
46834
+ async function updatePasswordById(req, res, next) {
46835
+ const validation = import_joi128.default.object({
46836
+ _id: import_joi128.default.string().hex().required(),
46837
+ currentPassword: import_joi128.default.string().required().min(8),
46838
+ newPassword: import_joi128.default.string().required().min(8),
46839
+ passwordConfirmation: import_joi128.default.string().required().min(8)
46840
+ });
46841
+ const _id = req.params.id;
46842
+ const payload = { ...req.body };
46843
+ const { error } = validation.validate({
46844
+ _id,
46845
+ ...payload
46846
+ });
46847
+ if (error) {
46848
+ next(new import_node_server_utils224.BadRequestError(error.message));
46849
+ return;
46850
+ }
46851
+ const currentPassword = req.body.currentPassword ?? "";
46852
+ const newPassword = req.body.newPassword ?? "";
46853
+ const passwordConfirmation = req.body.passwordConfirmation ?? "";
46854
+ try {
46855
+ await _updatePasswordById(
46856
+ _id,
46857
+ currentPassword,
46858
+ newPassword,
46859
+ passwordConfirmation
46860
+ );
46861
+ res.json({ message: "Successfully updated password." });
46862
+ } catch (error2) {
46863
+ next(error2);
46864
+ }
46865
+ }
46230
46866
  return {
46231
- createUserByVerification
46867
+ getById,
46868
+ getByEmail,
46869
+ getUsersByOrgId,
46870
+ getUsers,
46871
+ createUserByVerification,
46872
+ updateUserProfile,
46873
+ updateBirthday,
46874
+ updateUserFieldById,
46875
+ updatePasswordById
46232
46876
  };
46233
46877
  }
46234
46878
  // Annotate the CommonJS export names for ESM import in node:
@@ -46371,6 +47015,7 @@ function useUserControllerV2() {
46371
47015
  occurrence_book_namespace_collection,
46372
47016
  orgSchema,
46373
47017
  overnight_parking_requests_namespace_collection,
47018
+ parseDahuaFind,
46374
47019
  pestDashboardCollection,
46375
47020
  poolDashboardCollection,
46376
47021
  promoCodeSchema,