@7365admin1/core 3.8.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -537,13 +537,13 @@ var require_logger = __commonJS({
537
537
  "use strict";
538
538
  exports.__esModule = true;
539
539
  var _utils = require_utils();
540
- var logger197 = {
540
+ var logger200 = {
541
541
  methodMap: ["debug", "info", "warn", "error"],
542
542
  level: "info",
543
543
  // Maps a given level value to the `methodMap` indexes above.
544
544
  lookupLevel: function lookupLevel(level) {
545
545
  if (typeof level === "string") {
546
- var levelMap = _utils.indexOf(logger197.methodMap, level.toLowerCase());
546
+ var levelMap = _utils.indexOf(logger200.methodMap, level.toLowerCase());
547
547
  if (levelMap >= 0) {
548
548
  level = levelMap;
549
549
  } else {
@@ -554,9 +554,9 @@ var require_logger = __commonJS({
554
554
  },
555
555
  // Can be overridden in the host environment
556
556
  log: function log(level) {
557
- level = logger197.lookupLevel(level);
558
- if (typeof console !== "undefined" && logger197.lookupLevel(logger197.level) <= level) {
559
- var method = logger197.methodMap[level];
557
+ level = logger200.lookupLevel(level);
558
+ if (typeof console !== "undefined" && logger200.lookupLevel(logger200.level) <= level) {
559
+ var method = logger200.methodMap[level];
560
560
  if (!console[method]) {
561
561
  method = "log";
562
562
  }
@@ -567,7 +567,7 @@ var require_logger = __commonJS({
567
567
  }
568
568
  }
569
569
  };
570
- exports["default"] = logger197;
570
+ exports["default"] = logger200;
571
571
  module.exports = exports["default"];
572
572
  }
573
573
  });
@@ -10822,7 +10822,8 @@ var metadataSchema3 = Joi9.object({
10822
10822
  guardPosts: Joi9.number().optional(),
10823
10823
  gracePeriod: Joi9.number().optional(),
10824
10824
  incidentCounter: Joi9.number().optional(),
10825
- incidentLogo: Joi9.string().optional().allow("", null)
10825
+ incidentLogo: Joi9.string().optional().allow("", null),
10826
+ services: Joi9.array().items(Joi9.object().unknown(true)).optional()
10826
10827
  });
10827
10828
  var updateAddressSchema = Joi9.object({
10828
10829
  line1: Joi9.string().min(3).allow("", null),
@@ -10852,7 +10853,8 @@ var allowedFieldsSite = [
10852
10853
  "metadata.guardPosts",
10853
10854
  "metadata.gracePeriod",
10854
10855
  "metadata.incidentCounter",
10855
- "metadata.incidentLogo"
10856
+ "metadata.incidentLogo",
10857
+ "metadata.services"
10856
10858
  ];
10857
10859
  var siteSchema = Joi9.object({
10858
10860
  name: Joi9.string().required(),
@@ -11746,9 +11748,7 @@ function useVerificationRepoV2() {
11746
11748
  }
11747
11749
  );
11748
11750
  } catch (error) {
11749
- throw new InternalServerError11(
11750
- "Failed to retrieve verification."
11751
- );
11751
+ throw new InternalServerError11("Failed to retrieve verification.");
11752
11752
  }
11753
11753
  }
11754
11754
  async function updateVerificationCodeById(_id, verificationCode, expireAt, session) {
@@ -11766,9 +11766,7 @@ function useVerificationRepoV2() {
11766
11766
  { session }
11767
11767
  );
11768
11768
  } catch (error) {
11769
- throw new InternalServerError11(
11770
- "Failed to update verification code."
11771
- );
11769
+ throw new InternalServerError11("Failed to update verification code.");
11772
11770
  }
11773
11771
  }
11774
11772
  return {
@@ -20787,12 +20785,20 @@ var schemaVisitorTransaction = Joi37.object({
20787
20785
  nric: Joi37.string().optional().allow(null, ""),
20788
20786
  visitorPass: Joi37.array().items(
20789
20787
  Joi37.object({
20790
- keyId: Joi37.string().hex().length(24).required()
20788
+ keyId: Joi37.string().hex().length(24).required(),
20789
+ receivedDate: Joi37.date().optional().allow(null),
20790
+ status: Joi37.string().optional().allow(null, ""),
20791
+ lastUpdate: Joi37.date().optional().allow(null),
20792
+ remarks: Joi37.string().optional().allow(null, "")
20791
20793
  })
20792
20794
  ).optional().allow(null),
20793
20795
  passKeys: Joi37.array().items(
20794
20796
  Joi37.object({
20795
- keyId: Joi37.string().hex().length(24).required()
20797
+ keyId: Joi37.string().hex().length(24).required(),
20798
+ receivedDate: Joi37.date().optional().allow(null),
20799
+ status: Joi37.string().optional().allow(null, ""),
20800
+ lastUpdate: Joi37.date().optional().allow(null),
20801
+ remarks: Joi37.string().optional().allow(null, "")
20796
20802
  })
20797
20803
  ).optional().allow(null),
20798
20804
  contact: Joi37.string().optional().allow(null, "")
@@ -20809,19 +20815,28 @@ var schemaVisitorTransaction = Joi37.object({
20809
20815
  numberOfPassengers: Joi37.number().integer().optional().allow(null, ""),
20810
20816
  visitorPass: Joi37.array().items(
20811
20817
  Joi37.object({
20812
- keyId: Joi37.string().hex().length(24).allow(null, "")
20818
+ keyId: Joi37.string().hex().length(24).allow(null, ""),
20819
+ receivedDate: Joi37.date().optional().allow(null),
20820
+ status: Joi37.string().optional().allow(null, ""),
20821
+ lastUpdate: Joi37.date().optional().allow(null),
20822
+ remarks: Joi37.string().optional().allow(null, "")
20813
20823
  })
20814
20824
  ).optional().allow(null),
20815
20825
  passKeys: Joi37.array().items(
20816
20826
  Joi37.object({
20817
- keyId: Joi37.string().hex().length(24).allow(null, "")
20827
+ keyId: Joi37.string().hex().length(24).allow(null, ""),
20828
+ receivedDate: Joi37.date().optional().allow(null),
20829
+ status: Joi37.string().optional().allow(null, ""),
20830
+ lastUpdate: Joi37.date().optional().allow(null),
20831
+ remarks: Joi37.string().optional().allow(null, "")
20818
20832
  })
20819
20833
  ).optional().allow(null),
20820
20834
  checkInRemarks: Joi37.string().optional().allow("", null),
20821
20835
  checkOutRemarks: Joi37.string().optional().allow("", null),
20822
20836
  expectedCheckIn: Joi37.string().isoDate().optional(),
20823
20837
  purpose: Joi37.string().optional().allow(null, ""),
20824
- inviterId: Joi37.any().optional().allow(null, "")
20838
+ inviterId: Joi37.any().optional().allow(null, ""),
20839
+ createdBy: Joi37.string().hex().length(24).optional().allow(null, "")
20825
20840
  });
20826
20841
  var schemaUpdateVisTrans = Joi37.object({
20827
20842
  _id: Joi37.string().hex().length(24).required(),
@@ -20941,22 +20956,22 @@ function MVisitorTransaction(value) {
20941
20956
  throw new Error("Invalid type for manualCheckout key.");
20942
20957
  }
20943
20958
  }
20944
- if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0) {
20959
+ if (Array.isArray(value.visitorPass)) {
20945
20960
  value.visitorPass = value.visitorPass.map((v) => {
20946
- if (typeof v === "string")
20947
- return { keyId: new ObjectId39(v) };
20948
- if (v?.keyId && typeof v.keyId === "string") {
20949
- return { keyId: new ObjectId39(v.keyId) };
20961
+ try {
20962
+ v.keyId = new ObjectId39(v.keyId);
20963
+ } catch (error2) {
20964
+ throw new Error("Invalid VisitorPass ID.");
20950
20965
  }
20951
20966
  return v;
20952
20967
  });
20953
20968
  }
20954
- if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0) {
20969
+ if (Array.isArray(value.passKeys)) {
20955
20970
  value.passKeys = value.passKeys.map((p) => {
20956
- if (typeof p === "string")
20957
- return { keyId: new ObjectId39(p) };
20958
- if (p?.keyId && typeof p.keyId === "string") {
20959
- return { keyId: new ObjectId39(p.keyId) };
20971
+ try {
20972
+ p.keyId = new ObjectId39(p.keyId);
20973
+ } catch (error2) {
20974
+ throw new Error("Invalid PassKey ID.");
20960
20975
  }
20961
20976
  return p;
20962
20977
  });
@@ -21651,9 +21666,57 @@ function useVisitorTransactionRepo() {
21651
21666
  }
21652
21667
  }
21653
21668
  async function resendEmailInvitedResident(visitorId, updatedBy) {
21654
- const updatedDocument = await collection.findOne({
21655
- _id: await convertObjectIdUtil(visitorId)
21656
- });
21669
+ const pipeline = [
21670
+ { $match: { _id: await convertObjectIdUtil(visitorId) } },
21671
+ {
21672
+ $lookup: {
21673
+ from: "buildings",
21674
+ localField: "block",
21675
+ foreignField: "_id",
21676
+ as: "blockDetails"
21677
+ }
21678
+ },
21679
+ {
21680
+ $addFields: {
21681
+ blockName: {
21682
+ $ifNull: [
21683
+ { $arrayElemAt: ["$blockDetails.name", 0] },
21684
+ "Unknown"
21685
+ ]
21686
+ }
21687
+ }
21688
+ },
21689
+ {
21690
+ $project: {
21691
+ blockDetails: 0
21692
+ }
21693
+ },
21694
+ {
21695
+ $lookup: {
21696
+ from: "building-levels",
21697
+ localField: "level",
21698
+ foreignField: "_id",
21699
+ as: "levelDetails"
21700
+ }
21701
+ },
21702
+ {
21703
+ $addFields: {
21704
+ levelName: {
21705
+ $ifNull: [
21706
+ { $arrayElemAt: ["$levelDetails.name", 0] },
21707
+ "Unknown"
21708
+ ]
21709
+ }
21710
+ }
21711
+ },
21712
+ {
21713
+ $project: {
21714
+ levelDetails: 0
21715
+ }
21716
+ }
21717
+ ];
21718
+ const results = await collection.aggregate(pipeline).toArray();
21719
+ const updatedDocument = results[0] || null;
21657
21720
  if (!updatedDocument?.email)
21658
21721
  return;
21659
21722
  if (!updatedDocument?._id)
@@ -21668,7 +21731,7 @@ function useVisitorTransactionRepo() {
21668
21731
  name: `${updatedDocument?.name}`,
21669
21732
  plateNumber: updatedDocument?.plateNumber,
21670
21733
  nric: updatedDocument?.nric,
21671
- address: `${updatedDocument?.block} ${updatedDocument?.level} ${updatedDocument?.unitName}`,
21734
+ address: `${updatedDocument?.blockName} ${updatedDocument?.levelName} ${updatedDocument?.unitName}`,
21672
21735
  contactNumber: updatedDocument?.contact ? updatedDocument?.contact : "N/A",
21673
21736
  email: updatedDocument?.email ? updatedDocument?.email : "N/A",
21674
21737
  duration: updatedDocument?.duration ? updatedDocument?.duration : "N/A",
@@ -27615,7 +27678,7 @@ function useBuildingRepo() {
27615
27678
  try {
27616
27679
  await collection.createIndexes([
27617
27680
  { key: { name: "text" }, name: "text-index" },
27618
- { key: { name: 1 }, unique: true, name: "unique-name-index" },
27681
+ // { key: { name: 1 }, unique: true, name: "unique-name-index" },
27619
27682
  { key: { site: 1 } },
27620
27683
  { key: { createdAt: 1 } },
27621
27684
  {
@@ -28307,11 +28370,6 @@ function useBuildingLevelRepo() {
28307
28370
  try {
28308
28371
  await collection.createIndexes([
28309
28372
  // Ensure name is unique per blockId
28310
- {
28311
- key: { blockId: 1, name: 1 },
28312
- unique: true,
28313
- name: "unique_name_per_blockId"
28314
- },
28315
28373
  // Other useful indexes
28316
28374
  { key: { site: 1 }, name: "idx_site" },
28317
28375
  { key: { blockId: 1 }, name: "idx_blockId" },
@@ -28572,7 +28630,11 @@ function useBuildingLevelRepo() {
28572
28630
  const res = await collection.bulkWrite(operations, { session });
28573
28631
  delCachedData();
28574
28632
  return {
28575
- insertedIds: res.insertedIds
28633
+ insertedIds: res.insertedIds,
28634
+ levels: levels.map((l, i) => ({
28635
+ _id: res.insertedIds[i],
28636
+ name: l.name
28637
+ }))
28576
28638
  };
28577
28639
  } catch (error) {
28578
28640
  logger63.log({
@@ -28856,8 +28918,8 @@ function useBuildingService() {
28856
28918
  const name = row.name;
28857
28919
  const rawLevel = row.level?.toString().trim();
28858
28920
  const rawUnit = row.unit?.toString().trim();
28859
- const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null : `Lvl${rawLevel}`;
28860
- const normalizedUnit = /^(na|n\/a)$/i.test(rawUnit) ? null : `Unit ${rawUnit}`;
28921
+ const normalizedLevel = /^(na|n\/a)$/i.test(rawLevel) ? null : rawLevel;
28922
+ const normalizedUnit = /^(na|n\/a)$/i.test(rawUnit) ? null : rawUnit;
28861
28923
  if (!blockMap.has(block)) {
28862
28924
  blockMap.set(block, { name, levels: [], unitsByLevel: /* @__PURE__ */ new Map() });
28863
28925
  }
@@ -28878,57 +28940,76 @@ function useBuildingService() {
28878
28940
  }
28879
28941
  }
28880
28942
  }
28881
- const buildingPayloads = Array.from(blockMap.entries()).map(
28882
- ([block, { name, levels }]) => ({
28943
+ const buildingPayloads = [];
28944
+ const buildingUnitPayloads = [];
28945
+ for (const [
28946
+ block,
28947
+ { name, levels, unitsByLevel }
28948
+ ] of blockMap.entries()) {
28949
+ const buildingId = new ObjectId53();
28950
+ const levelsPayload = (levels ?? []).map((levelName) => ({
28951
+ blockId: buildingId.toString(),
28952
+ site: site.toString(),
28953
+ name: levelName,
28954
+ status: "active" /* ACTIVE */,
28955
+ createdAt: /* @__PURE__ */ new Date(),
28956
+ updatedAt: null,
28957
+ deletedAt: null
28958
+ }));
28959
+ let insertedLevels;
28960
+ if (levelsPayload.length > 0) {
28961
+ insertedLevels = await _bulkWriteLevels(levelsPayload, session);
28962
+ }
28963
+ const levelNameToId = /* @__PURE__ */ new Map();
28964
+ if (insertedLevels) {
28965
+ insertedLevels.levels.forEach((lvl) => {
28966
+ levelNameToId.set(lvl.name, lvl._id);
28967
+ });
28968
+ }
28969
+ const buildingPayload = {
28970
+ _id: buildingId,
28883
28971
  site,
28884
28972
  block,
28885
28973
  name,
28886
- levels
28887
- })
28888
- );
28889
- const blockToBuildingId = /* @__PURE__ */ new Map();
28890
- for (const buildingPayload of buildingPayloads) {
28891
- const result = await _add(buildingPayload);
28892
- blockToBuildingId.set(buildingPayload.block, result);
28893
- }
28894
- const buildingUnitPayloads = [];
28895
- Array.from(blockMap.entries()).forEach(
28896
- ([block, { name, unitsByLevel }]) => {
28897
- const buildingId = blockToBuildingId.get(block);
28898
- Array.from(unitsByLevel.entries()).forEach(([level, units]) => {
28899
- units.forEach((unit) => {
28900
- buildingUnitPayloads.push({
28901
- site,
28902
- name: unit,
28903
- building: buildingId.toString(),
28904
- buildingName: name,
28905
- block,
28906
- level,
28907
- category: "",
28908
- status: "active" /* ACTIVE */,
28909
- buildingUnitFiles: [],
28910
- owner: "",
28911
- ownerName: "",
28912
- companyName: "",
28913
- companyRegistrationNumber: "",
28914
- billing: [],
28915
- unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null,
28916
- createdAt: /* @__PURE__ */ new Date(),
28917
- updatedAt: "",
28918
- deletedAt: ""
28919
- });
28974
+ levels: insertedLevels ? Object.values(insertedLevels.insertedIds) : []
28975
+ };
28976
+ const buildingResult = await _add(buildingPayload, session);
28977
+ Array.from(unitsByLevel.entries()).forEach(([levelName, units]) => {
28978
+ const levelId = levelNameToId.get(levelName);
28979
+ units.forEach((unit) => {
28980
+ buildingUnitPayloads.push({
28981
+ site: new ObjectId53(site),
28982
+ name: unit,
28983
+ building: buildingId,
28984
+ // already an ObjectId
28985
+ buildingName: name,
28986
+ block,
28987
+ level: levelId,
28988
+ // ✅ use ObjectId instead of string
28989
+ category: "",
28990
+ status: "active" /* ACTIVE */,
28991
+ buildingUnitFiles: [],
28992
+ owner: "",
28993
+ ownerName: "",
28994
+ companyName: "",
28995
+ companyRegistrationNumber: "",
28996
+ billing: [],
28997
+ unitNumber: parseInt(unit.replace("Unit ", ""), 10) || null,
28998
+ createdAt: /* @__PURE__ */ new Date(),
28999
+ updatedAt: "",
29000
+ deletedAt: ""
28920
29001
  });
28921
29002
  });
28922
- }
28923
- );
29003
+ });
29004
+ }
28924
29005
  await _bulkAddBuildingUnits(buildingUnitPayloads);
28925
- await session?.commitTransaction();
29006
+ await session.commitTransaction();
28926
29007
  return { buildingPayloads, buildingUnitPayloads };
28927
29008
  } catch (error) {
28928
- await session?.abortTransaction();
29009
+ await session.abortTransaction();
28929
29010
  throw error;
28930
29011
  } finally {
28931
- session?.endSession();
29012
+ session.endSession();
28932
29013
  }
28933
29014
  }
28934
29015
  return {
@@ -29199,9 +29280,9 @@ function useBuildingController() {
29199
29280
  const lowerName = originalname.toLowerCase();
29200
29281
  const rowSchema = Joi46.object({
29201
29282
  block: Joi46.number().integer().min(0).required(),
29202
- level: Joi46.string().optional().allow(null, ""),
29203
- unit: Joi46.string().optional().allow(null, ""),
29204
- category: Joi46.string().trim().required(),
29283
+ level: Joi46.alternatives().try(Joi46.string(), Joi46.number()).custom((value) => String(value)).optional().allow(null, ""),
29284
+ unit: Joi46.alternatives().try(Joi46.string(), Joi46.number()).custom((value) => String(value)).optional().allow(null, ""),
29285
+ category: Joi46.string().trim().optional().allow(null, ""),
29205
29286
  name: Joi46.string().trim().optional().allow(null, ""),
29206
29287
  email: Joi46.string().email().lowercase().optional().allow(null, ""),
29207
29288
  phoneNumber: Joi46.string().trim().optional().allow(null, "")
@@ -29215,11 +29296,9 @@ function useBuildingController() {
29215
29296
  { abortEarly: false, convert: true }
29216
29297
  );
29217
29298
  if (queryError) {
29218
- next(
29219
- new BadRequestError84(
29220
- queryError.details.map((d) => d.message).join(", ")
29221
- )
29222
- );
29299
+ const messages = queryError.details.map((d) => d.message).join(", ");
29300
+ logger65.log({ level: "error", message: messages });
29301
+ next(new BadRequestError84(messages));
29223
29302
  return;
29224
29303
  }
29225
29304
  const { site, org } = queryValue;
@@ -29254,11 +29333,11 @@ function useBuildingController() {
29254
29333
  } else if (lowerName.endsWith(".csv")) {
29255
29334
  rows = await new Promise((resolve, reject) => {
29256
29335
  const parsed = [];
29257
- fs2.createReadStream(path5).pipe(csv()).on("headers", (headers) => {
29258
- headers = headers.map(
29259
- (h) => h.trim().replace(/\(.*\)/, "").trim()
29260
- );
29261
- }).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
29336
+ fs2.createReadStream(path5).pipe(
29337
+ csv({
29338
+ mapHeaders: ({ header }) => header.trim().replace(/\(.*\)/, "").trim()
29339
+ })
29340
+ ).on("data", (row) => parsed.push(row)).on("end", () => resolve(parsed)).on("error", reject);
29262
29341
  });
29263
29342
  } else {
29264
29343
  next(
@@ -29276,6 +29355,7 @@ function useBuildingController() {
29276
29355
  if (error) {
29277
29356
  invalidRows.push({
29278
29357
  row: index + 2,
29358
+ // +2 because header is row 1
29279
29359
  data: row,
29280
29360
  errors: error.details.map((d) => d.message)
29281
29361
  });
@@ -29297,6 +29377,7 @@ function useBuildingController() {
29297
29377
  fs2.unlink(path5, () => {
29298
29378
  });
29299
29379
  } catch (error) {
29380
+ console.log(error);
29300
29381
  logger65.log({ level: "error", message: error.message });
29301
29382
  next(error);
29302
29383
  }
@@ -33271,17 +33352,13 @@ var KeyRepo = class {
33271
33352
  }
33272
33353
  }
33273
33354
  static async updateKeyById(keyId, key, site, session, isChild) {
33274
- try {
33275
- keyId = new ObjectId61(keyId);
33276
- if (site)
33277
- site = new ObjectId61(site);
33278
- if (key.updatedBy)
33279
- key.updatedBy = await convertObjectIdUtil(key.updatedBy);
33280
- if (!key.status)
33281
- delete key.status;
33282
- } catch (error) {
33283
- return Promise.reject("Invalid key id");
33284
- }
33355
+ keyId = await convertObjectIdUtil2(keyId, "keyId");
33356
+ if (site)
33357
+ site = await convertObjectIdUtil2(site, "Site");
33358
+ if (key.updatedBy)
33359
+ key.updatedBy = await convertObjectIdUtil2(key.updatedBy, "Updated By");
33360
+ if (!key.status)
33361
+ delete key.status;
33285
33362
  try {
33286
33363
  key.updatedAt = /* @__PURE__ */ new Date();
33287
33364
  const query = { _id: keyId, ...site && { site } };
@@ -33294,6 +33371,7 @@ var KeyRepo = class {
33294
33371
  { session }
33295
33372
  );
33296
33373
  let setKeys = [];
33374
+ console.log("updateKeyById result", result);
33297
33375
  if (result.modifiedCount > 0) {
33298
33376
  const updatedDocs = await this.collection().find(find).toArray();
33299
33377
  if (Array.isArray(updatedDocs) && updatedDocs.length > 0) {
@@ -33308,10 +33386,12 @@ var KeyRepo = class {
33308
33386
  await this.collectionDynamic("keys-histories").insertMany(setKeys, {
33309
33387
  session
33310
33388
  });
33389
+ } else {
33390
+ throw new Error("Failed Updating Keys");
33311
33391
  }
33312
33392
  return result;
33313
33393
  } catch (error) {
33314
- console.log(error);
33394
+ throw new Error(error);
33315
33395
  }
33316
33396
  }
33317
33397
  static async deleteKeyById(_id, session) {
@@ -33461,7 +33541,7 @@ async function send(userIds, title, body, data, isForMAMobileApp = false, appSlu
33461
33541
  if (isForMAMobileApp) {
33462
33542
  tokens = await PushTokenRepo.findTokensByUserIds(userIds, appSlug);
33463
33543
  } else {
33464
- tokens = await PushTokenRepo.findTokensByUserIds(userIds);
33544
+ tokens = await PushTokenRepo.findTokensByUserIds(userIds, appSlug);
33465
33545
  }
33466
33546
  if (!tokens.length)
33467
33547
  return;
@@ -33509,6 +33589,37 @@ var NotificationService = class {
33509
33589
  "iservice365-resident-mobile-app"
33510
33590
  );
33511
33591
  }
33592
+ static async onlineFormRequestStatusUpdated(payload) {
33593
+ let screen = "";
33594
+ let params = {};
33595
+ if (payload.status === "pending" || payload.status === "resubmission") {
33596
+ screen = "/(user)/(online-forms)/form-fill";
33597
+ params = {
33598
+ id: payload.onlineFormId.toString(),
33599
+ submissionStatus: payload.status ?? ""
33600
+ };
33601
+ } else {
33602
+ screen = "/(user)/(online-forms)/submission-detail";
33603
+ params = {
33604
+ id: payload.onlineFormId.toString(),
33605
+ status: payload.status ?? ""
33606
+ };
33607
+ }
33608
+ await send(
33609
+ toStringArray(payload.to),
33610
+ "Online Form",
33611
+ `Your online form has been updated to ${payload.status}.`,
33612
+ {
33613
+ onlineFormId: payload.onlineFormId.toString(),
33614
+ status: payload.status,
33615
+ module: "onlineForm",
33616
+ screen,
33617
+ params: JSON.stringify(params)
33618
+ },
33619
+ false,
33620
+ "iservice365-resident-mobile-app"
33621
+ );
33622
+ }
33512
33623
  static async bulletinBoardCreatedForMA(payload) {
33513
33624
  await send(
33514
33625
  toStringArray(payload.to),
@@ -33751,51 +33862,51 @@ function useVisitorTransactionService() {
33751
33862
  for (let i = 0; i < value.members.length; i += chunkSize) {
33752
33863
  const chunk = value.members.slice(i, i + chunkSize);
33753
33864
  for (const member of chunk) {
33754
- await KeyRepo.checkPassKeyAvailability(
33755
- member.visitorPass,
33756
- member.passKeys
33757
- );
33758
- if (member.visitorPass && Array.isArray(member.visitorPass) && member.visitorPass.length > 0) {
33759
- for (const vp of member.visitorPass) {
33760
- try {
33761
- const updatePayload = { status: "In Use" /* IN_USE */ };
33762
- const visitorPassId = typeof vp === "string" || vp instanceof ObjectId62 ? vp : vp.keyId;
33763
- if (!visitorPassId)
33764
- value.visitorPass = [];
33765
- await KeyRepo.updateKeyById(
33766
- visitorPassId,
33767
- updatePayload,
33768
- value.site
33769
- );
33770
- } catch (error) {
33771
- throw error;
33772
- }
33865
+ await KeyRepo.checkPassKeyAvailability(member.visitorPass, member.passKeys);
33866
+ if (Array.isArray(member.visitorPass)) {
33867
+ for (const item of member.visitorPass) {
33868
+ console.log("Type of keyId:", typeof item.keyId);
33869
+ console.log("item visitorPass", item);
33870
+ await KeyRepo.updateKeyById(
33871
+ item.keyId,
33872
+ {
33873
+ status: "In Use" /* IN_USE */,
33874
+ updatedBy: value.createdBy
33875
+ },
33876
+ value.site,
33877
+ session
33878
+ );
33879
+ item.receivedDate = /* @__PURE__ */ new Date();
33880
+ item.status = "Not Returned" /* NOT_RETURNED */;
33881
+ item.lastUpdate = null;
33882
+ item.remarks = "";
33773
33883
  }
33774
33884
  }
33775
- if (member.passKeys && Array.isArray(member.passKeys) && member.passKeys.length > 0) {
33776
- for (const pk of member.passKeys) {
33777
- try {
33778
- const updatePayload = { status: "In Use" /* IN_USE */ };
33779
- const passKeyId = typeof pk === "string" || pk instanceof ObjectId62 ? pk : pk.keyId;
33780
- if (!passKeyId)
33781
- value.passKeys = [];
33782
- await KeyRepo.updateKeyById(
33783
- passKeyId,
33784
- updatePayload,
33785
- value.site
33786
- );
33787
- } catch (error) {
33788
- throw error;
33789
- }
33885
+ if (Array.isArray(member.passKeys)) {
33886
+ for (const item of member.passKeys) {
33887
+ await KeyRepo.updateKeyById(
33888
+ item.keyId,
33889
+ {
33890
+ status: "In Use" /* IN_USE */,
33891
+ updatedBy: value.createdBy
33892
+ },
33893
+ value.site,
33894
+ session
33895
+ );
33896
+ item.receivedDate = /* @__PURE__ */ new Date();
33897
+ item.status = "Not Returned" /* NOT_RETURNED */;
33898
+ item.lastUpdate = null;
33899
+ item.remarks = "";
33790
33900
  }
33791
33901
  }
33792
33902
  }
33793
33903
  await Promise.all(
33794
33904
  chunk.map((member) => {
33795
- const { visitorPass, passKeys } = member;
33905
+ const clonedMember = structuredClone(member);
33906
+ const { visitorPass, passKeys } = clonedMember;
33796
33907
  return _add(
33797
33908
  {
33798
- ...member,
33909
+ ...clonedMember,
33799
33910
  block,
33800
33911
  level,
33801
33912
  unit,
@@ -33842,184 +33953,184 @@ function useVisitorTransactionService() {
33842
33953
  throw new BadRequestError100("This plate number is blocklisted");
33843
33954
  }
33844
33955
  await KeyRepo.checkPassKeyAvailability(value.visitorPass, value.passKeys);
33845
- if (value.visitorPass && Array.isArray(value.visitorPass) && value.visitorPass.length > 0 && value.visitorPass) {
33956
+ if (Array.isArray(value.visitorPass)) {
33957
+ for (const item of value.visitorPass) {
33958
+ await KeyRepo.updateKeyById(
33959
+ item.keyId,
33960
+ {
33961
+ status: "In Use" /* IN_USE */,
33962
+ updatedBy: value.createdBy
33963
+ },
33964
+ value.site,
33965
+ session
33966
+ );
33967
+ item.receivedDate = /* @__PURE__ */ new Date();
33968
+ item.status = "Not Returned" /* NOT_RETURNED */;
33969
+ item.lastUpdate = null;
33970
+ item.remarks = "";
33971
+ }
33972
+ }
33973
+ if (Array.isArray(value.passKeys)) {
33974
+ for (const item of value.passKeys) {
33975
+ await KeyRepo.updateKeyById(
33976
+ item.keyId,
33977
+ {
33978
+ status: "In Use" /* IN_USE */,
33979
+ updatedBy: value.createdBy
33980
+ },
33981
+ value.site,
33982
+ session
33983
+ );
33984
+ item.receivedDate = /* @__PURE__ */ new Date();
33985
+ item.status = "Not Returned" /* NOT_RETURNED */;
33986
+ item.lastUpdate = null;
33987
+ item.remarks = "";
33988
+ }
33989
+ }
33990
+ const result = await _add(value, session);
33991
+ await session?.commitTransaction();
33992
+ let openBarrier = null;
33993
+ const isOpenBarrier = allowedPersonTypes.includes(value?.type) || camera?.ANPRSwitches?.openBarrierPickUpDropOff == true;
33994
+ if (isOpenBarrier && value.plateNumber && host && username && password) {
33995
+ try {
33996
+ logger80.info(`Attempting to open barrier at host: ${host}`);
33997
+ openBarrier = await _openBarrier({
33998
+ host,
33999
+ username,
34000
+ password,
34001
+ plateNumber: value?.plateNumber
34002
+ });
34003
+ logger80.info(`Barrier command sent successfully to ${host}`, {
34004
+ response: openBarrier
34005
+ });
34006
+ } catch (error) {
34007
+ logger80.error(
34008
+ `Failed to open barrier at host ${host}. Critical system error:`,
34009
+ error
34010
+ );
34011
+ openBarrier = { success: false, error: error?.message };
34012
+ }
34013
+ }
34014
+ console.log("Open barrier response:", openBarrier);
34015
+ return result;
34016
+ } catch (error) {
34017
+ await session?.abortTransaction();
34018
+ throw error;
34019
+ } finally {
34020
+ session?.endSession();
34021
+ }
34022
+ }
34023
+ async function updateVisitorTransactionById(id, value) {
34024
+ const session = useAtlas50.getClient()?.startSession();
34025
+ session?.startTransaction();
34026
+ try {
34027
+ let camera;
34028
+ let host;
34029
+ let username;
34030
+ let password;
34031
+ if (value.site && value.plateNumber) {
34032
+ try {
34033
+ camera = await _getVisitorsInBySite(value.site);
34034
+ if (!camera) {
34035
+ logger80.warn(`No camera document found for site: ${value.site}`);
34036
+ }
34037
+ } catch (error) {
34038
+ logger80.error(
34039
+ `Error _getVisitorsInBySite camera for site ${value.site}:`,
34040
+ error
34041
+ );
34042
+ }
34043
+ }
34044
+ if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
34045
+ host = camera.host;
34046
+ username = camera.username;
34047
+ password = camera.password;
34048
+ const blacklist = "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
34049
+ const _plateNumber = value.plateNumber;
34050
+ const dahuaBlocklistQuery = {
34051
+ host,
34052
+ username,
34053
+ password,
34054
+ plateNumber: _plateNumber,
34055
+ mode: blacklist
34056
+ };
34057
+ const isBlocklistedRaw = await _getPlateNumber(dahuaBlocklistQuery);
34058
+ const rawString = isBlocklistedRaw?.toString?.("utf-8") ?? String(isBlocklistedRaw);
34059
+ const foundMatch = rawString.match(/found=(\d+)/);
34060
+ const found = foundMatch ? Number(foundMatch[1]) : 0;
34061
+ if (found === 1)
34062
+ throw new BadRequestError100("This plate number is blocklisted");
34063
+ }
34064
+ if (Array.isArray(value.visitorPass) && value.visitorPass.length > 0) {
34065
+ const keptVisitorPass = [];
33846
34066
  for (const vp of value.visitorPass) {
33847
- try {
33848
- const updatePayload = { status: "In Use" /* IN_USE */ };
33849
- const visitorPassId = typeof vp === "string" || vp instanceof ObjectId62 ? vp : vp.keyId;
33850
- if (!visitorPassId)
33851
- value.visitorPass = [];
33852
- await KeyRepo.updateKeyById(
33853
- visitorPassId,
33854
- updatePayload,
33855
- value.site
33856
- );
33857
- } catch (error) {
33858
- throw error;
34067
+ const updatePayload = {
34068
+ ...vp.status && { status: vp.status },
34069
+ ...vp.remarks && { remarks: vp.remarks }
34070
+ };
34071
+ const visitorPassId = typeof vp === "string" || vp instanceof ObjectId62 ? vp : vp.keyId;
34072
+ await KeyRepo.updateKeyById(
34073
+ visitorPassId,
34074
+ updatePayload,
34075
+ value.site
34076
+ );
34077
+ if (typeof vp !== "string" && !(vp instanceof ObjectId62)) {
34078
+ keptVisitorPass.push({
34079
+ keyId: new ObjectId62(visitorPassId)
34080
+ });
33859
34081
  }
33860
34082
  }
34083
+ value.visitorPass = keptVisitorPass;
33861
34084
  }
33862
34085
  if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0) {
34086
+ const keptPassKeys = [];
33863
34087
  for (const pk of value.passKeys) {
33864
34088
  try {
33865
- const updatePayload = { status: "In Use" /* IN_USE */ };
34089
+ const updatePayload = {
34090
+ ...pk.status && { status: pk.status },
34091
+ ...pk.remarks && { remarks: pk.remarks }
34092
+ };
33866
34093
  const passKeyId = typeof pk === "string" || pk instanceof ObjectId62 ? pk : pk.keyId;
33867
- if (!passKeyId)
33868
- value.passKeys = [];
33869
34094
  await KeyRepo.updateKeyById(
33870
34095
  passKeyId,
33871
34096
  updatePayload,
33872
34097
  value.site
33873
34098
  );
34099
+ if (typeof pk !== "string" && !(pk instanceof ObjectId62)) {
34100
+ keptPassKeys.push({
34101
+ keyId: new ObjectId62(passKeyId)
34102
+ });
34103
+ }
33874
34104
  } catch (error) {
33875
34105
  throw error;
33876
34106
  }
33877
34107
  }
34108
+ value.passKeys = keptPassKeys;
33878
34109
  }
33879
- const result = await _add(value, session);
33880
- await session?.commitTransaction();
33881
- let openBarrier = null;
33882
- const isOpenBarrier = allowedPersonTypes.includes(value?.type) || camera?.ANPRSwitches?.openBarrierPickUpDropOff == true;
33883
- if (isOpenBarrier && value.plateNumber && host && username && password) {
33884
- try {
33885
- logger80.info(`Attempting to open barrier at host: ${host}`);
33886
- openBarrier = await _openBarrier({
33887
- host,
33888
- username,
33889
- password,
33890
- plateNumber: value?.plateNumber
33891
- });
33892
- logger80.info(`Barrier command sent successfully to ${host}`, {
33893
- response: openBarrier
33894
- });
33895
- } catch (error) {
33896
- logger80.error(
33897
- `Failed to open barrier at host ${host}. Critical system error:`,
33898
- error
33899
- );
33900
- openBarrier = { success: false, error: error?.message };
33901
- }
33902
- }
33903
- console.log("Open barrier response:", openBarrier);
33904
- return result;
33905
- } catch (error) {
33906
- await session?.abortTransaction();
33907
- throw error;
33908
- } finally {
33909
- session?.endSession();
33910
- }
33911
- }
33912
- async function updateVisitorTransactionById(id, value) {
33913
- const session = useAtlas50.getClient()?.startSession();
33914
- session?.startTransaction();
33915
- try {
33916
- let camera;
33917
- let host;
33918
- let username;
33919
- let password;
33920
- if (value.site && value.plateNumber) {
33921
- try {
33922
- camera = await _getVisitorsInBySite(value.site);
33923
- if (!camera) {
33924
- logger80.warn(`No camera document found for site: ${value.site}`);
33925
- }
33926
- } catch (error) {
33927
- logger80.error(
33928
- `Error _getVisitorsInBySite camera for site ${value.site}:`,
33929
- error
33930
- );
33931
- }
33932
- }
33933
- if (camera && value.plateNumber && camera.host && camera.username && camera.password) {
33934
- host = camera.host;
33935
- username = camera.username;
33936
- password = camera.password;
33937
- const blacklist = "TrafficBlackList" /* TRAFFIC_BLACKLIST */;
33938
- const _plateNumber = value.plateNumber;
33939
- const dahuaBlocklistQuery = {
33940
- host,
33941
- username,
33942
- password,
33943
- plateNumber: _plateNumber,
33944
- mode: blacklist
33945
- };
33946
- const isBlocklistedRaw = await _getPlateNumber(dahuaBlocklistQuery);
33947
- const rawString = isBlocklistedRaw?.toString?.("utf-8") ?? String(isBlocklistedRaw);
33948
- const foundMatch = rawString.match(/found=(\d+)/);
33949
- const found = foundMatch ? Number(foundMatch[1]) : 0;
33950
- if (found === 1)
33951
- throw new BadRequestError100("This plate number is blocklisted");
33952
- }
33953
- if (Array.isArray(value.visitorPass) && value.visitorPass.length > 0) {
33954
- const keptVisitorPass = [];
33955
- for (const vp of value.visitorPass) {
33956
- const updatePayload = {
33957
- ...vp.status && { status: vp.status },
33958
- ...vp.remarks && { remarks: vp.remarks }
33959
- };
33960
- const visitorPassId = typeof vp === "string" || vp instanceof ObjectId62 ? vp : vp.keyId;
33961
- await KeyRepo.updateKeyById(
33962
- visitorPassId,
33963
- updatePayload,
33964
- value.site
33965
- );
33966
- if (typeof vp !== "string" && !(vp instanceof ObjectId62)) {
33967
- keptVisitorPass.push({
33968
- keyId: new ObjectId62(visitorPassId)
33969
- });
33970
- }
33971
- }
33972
- value.visitorPass = keptVisitorPass;
33973
- }
33974
- if (value.passKeys && Array.isArray(value.passKeys) && value.passKeys.length > 0) {
33975
- const keptPassKeys = [];
33976
- for (const pk of value.passKeys) {
33977
- try {
33978
- const updatePayload = {
33979
- ...pk.status && { status: pk.status },
33980
- ...pk.remarks && { remarks: pk.remarks }
33981
- };
33982
- const passKeyId = typeof pk === "string" || pk instanceof ObjectId62 ? pk : pk.keyId;
33983
- await KeyRepo.updateKeyById(
33984
- passKeyId,
33985
- updatePayload,
33986
- value.site
33987
- );
33988
- if (typeof pk !== "string" && !(pk instanceof ObjectId62)) {
33989
- keptPassKeys.push({
33990
- keyId: new ObjectId62(passKeyId)
33991
- });
33992
- }
33993
- } catch (error) {
33994
- throw error;
33995
- }
33996
- }
33997
- value.passKeys = keptPassKeys;
33998
- }
33999
- if (value.checkIn) {
34000
- const parsed = new Date(value.checkIn);
34001
- value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
34002
- }
34003
- if (value.checkOut) {
34004
- const parsed = new Date(value.checkOut);
34005
- value.checkOut = isNaN(parsed.getTime()) ? null : parsed;
34006
- }
34007
- if (value.site) {
34008
- value.site = typeof value.site === "string" ? new ObjectId62(value.site) : value.site;
34009
- }
34010
- if (value.unit) {
34011
- value.unit = typeof value.unit === "string" ? new ObjectId62(value.unit) : value.unit;
34012
- const unit = await _getUnitById(value.unit);
34013
- value.unitName = unit?.name;
34014
- }
34015
- await _updateVisitorTansactionById(id, value, session);
34016
- const allowedPersonTypes = [
34017
- "contractor" /* CONTRACTOR */,
34018
- "walk-in" /* WALK_IN */,
34019
- "guest" /* GUEST */,
34020
- "delivery" /* DELIVERY */
34021
- // PersonTypes.PICK_UP,
34022
- ];
34110
+ if (value.checkIn) {
34111
+ const parsed = new Date(value.checkIn);
34112
+ value.checkIn = isNaN(parsed.getTime()) ? null : parsed;
34113
+ }
34114
+ if (value.checkOut) {
34115
+ const parsed = new Date(value.checkOut);
34116
+ value.checkOut = isNaN(parsed.getTime()) ? null : parsed;
34117
+ }
34118
+ if (value.site) {
34119
+ value.site = typeof value.site === "string" ? new ObjectId62(value.site) : value.site;
34120
+ }
34121
+ if (value.unit) {
34122
+ value.unit = typeof value.unit === "string" ? new ObjectId62(value.unit) : value.unit;
34123
+ const unit = await _getUnitById(value.unit);
34124
+ value.unitName = unit?.name;
34125
+ }
34126
+ await _updateVisitorTansactionById(id, value, session);
34127
+ const allowedPersonTypes = [
34128
+ "contractor" /* CONTRACTOR */,
34129
+ "walk-in" /* WALK_IN */,
34130
+ "guest" /* GUEST */,
34131
+ "delivery" /* DELIVERY */
34132
+ // PersonTypes.PICK_UP,
34133
+ ];
34023
34134
  let openBarrier = null;
34024
34135
  const isOpenBarrier = allowedPersonTypes.includes(value?.type) || camera?.ANPRSwitches?.openBarrierPickUpDropOff == true;
34025
34136
  if (isOpenBarrier && value.plateNumber && host && username && password) {
@@ -34156,9 +34267,9 @@ function useVisitorTransactionService() {
34156
34267
  value.checkIn = null;
34157
34268
  const payload = {
34158
34269
  ...value,
34159
- block: inviter?.block,
34160
- level: inviter?.level,
34161
- unit: inviter?.unit,
34270
+ block: inviter?.block?.toString(),
34271
+ level: inviter?.level?.toString(),
34272
+ unit: inviter?.unit?.toString(),
34162
34273
  unitName: unit?.name,
34163
34274
  org: inviter?.org.toString(),
34164
34275
  site: inviter?.site.toString(),
@@ -34254,7 +34365,8 @@ function useVisitorTransactionController() {
34254
34365
  } = useVisitorTransactionRepo();
34255
34366
  async function add(req, res, next) {
34256
34367
  try {
34257
- const { error, value } = schemaVisitorTransaction.validate(req.body, {
34368
+ const { companyName, firstName, lastName, ...restData } = req.body;
34369
+ const { error, value } = schemaVisitorTransaction.validate(restData, {
34258
34370
  abortEarly: false
34259
34371
  });
34260
34372
  if (error) {
@@ -34486,8 +34598,11 @@ function useVisitorTransactionController() {
34486
34598
  return;
34487
34599
  } catch (error2) {
34488
34600
  logger81.log({ level: "error", message: error2.message });
34489
- next(error2);
34490
- return;
34601
+ if (error2?.message) {
34602
+ next(new BadRequestError101(error2?.message));
34603
+ } else {
34604
+ next(error2);
34605
+ }
34491
34606
  }
34492
34607
  }
34493
34608
  async function changeVisitorTransactionKeysById(req, res, next) {
@@ -57827,7 +57942,8 @@ function useNewDashboardRepo() {
57827
57942
  site,
57828
57943
  serviceType,
57829
57944
  page = 1,
57830
- limit = 10
57945
+ limit = 10,
57946
+ period = "today" /* TODAY */
57831
57947
  }) {
57832
57948
  page = page > 0 ? page - 1 : 0;
57833
57949
  const cacheOptions = { serviceType, page, limit };
@@ -57837,9 +57953,7 @@ function useNewDashboardRepo() {
57837
57953
  } catch {
57838
57954
  throw new BadRequestError182("Invalid site ID format.");
57839
57955
  }
57840
- const todayStart = moment2.tz("Asia/Singapore").startOf("day").toDate();
57841
- const todayEnd = moment2.tz("Asia/Singapore").endOf("day").toDate();
57842
- const todayRange = { $gte: todayStart, $lte: todayEnd };
57956
+ const todayRange = getDateRange(period);
57843
57957
  try {
57844
57958
  const [items, countResult] = await Promise.all([
57845
57959
  areaChecklistCollection.aggregate([
@@ -57915,7 +58029,8 @@ function useNewDashboardRepo() {
57915
58029
  site,
57916
58030
  serviceType,
57917
58031
  page = 1,
57918
- limit = 10
58032
+ limit = 10,
58033
+ period = "today" /* TODAY */
57919
58034
  }) {
57920
58035
  page = page > 0 ? page - 1 : 0;
57921
58036
  const cacheOptions = { serviceType, page, limit };
@@ -57925,8 +58040,9 @@ function useNewDashboardRepo() {
57925
58040
  } catch {
57926
58041
  throw new BadRequestError182("Invalid site ID format.");
57927
58042
  }
57928
- const todayStart = moment2.tz("Asia/Singapore").startOf("day").toDate();
57929
- const todayEnd = moment2.tz("Asia/Singapore").endOf("day").toDate();
58043
+ const periodRange = getDateRange(period);
58044
+ const todayStart = periodRange.$gte;
58045
+ const todayEnd = periodRange.$lte;
57930
58046
  const todayStartStr = todayStart.toISOString();
57931
58047
  const todayEndStr = todayEnd.toISOString();
57932
58048
  try {
@@ -58043,7 +58159,8 @@ function useNewDashboardRepo() {
58043
58159
  site,
58044
58160
  serviceType,
58045
58161
  page = 1,
58046
- limit = 10
58162
+ limit = 10,
58163
+ period = "today" /* TODAY */
58047
58164
  }) {
58048
58165
  page = page > 0 ? page - 1 : 0;
58049
58166
  const cacheOptions = { serviceType, page, limit };
@@ -58054,10 +58171,14 @@ function useNewDashboardRepo() {
58054
58171
  throw new BadRequestError182("Invalid site ID format.");
58055
58172
  }
58056
58173
  const workOrderService = workOrderServiceMap[serviceType] ?? serviceType;
58174
+ const matchQuery = { site, service: workOrderService };
58175
+ if (period) {
58176
+ matchQuery.createdAt = getDateRange(period);
58177
+ }
58057
58178
  try {
58058
58179
  const [items, length] = await Promise.all([
58059
58180
  feedbackCollection.aggregate([
58060
- { $match: { site, service: workOrderService } },
58181
+ { $match: matchQuery },
58061
58182
  { $sort: { createdAt: -1, _id: -1 } },
58062
58183
  {
58063
58184
  $lookup: {
@@ -58080,7 +58201,7 @@ function useNewDashboardRepo() {
58080
58201
  { $skip: page * limit },
58081
58202
  { $limit: limit }
58082
58203
  ]).toArray(),
58083
- feedbackCollection.countDocuments({ site, service: workOrderService })
58204
+ feedbackCollection.countDocuments(matchQuery)
58084
58205
  ]);
58085
58206
  const data = paginate51(items, page, limit, length);
58086
58207
  return data;
@@ -58240,6 +58361,7 @@ function useNewDashboardController() {
58240
58361
  const validation = Joi112.object({
58241
58362
  site: Joi112.string().hex().required(),
58242
58363
  serviceType: Joi112.string().valid(...Object.values(AppServiceType)).required(),
58364
+ period: Joi112.string().valid(...Object.values(Period)).default("today" /* TODAY */),
58243
58365
  page: Joi112.number().min(1).optional().allow("", null),
58244
58366
  limit: Joi112.number().min(1).optional().allow("", null)
58245
58367
  });
@@ -58251,12 +58373,14 @@ function useNewDashboardController() {
58251
58373
  }
58252
58374
  const site = req.params.site;
58253
58375
  const serviceType = req.params.serviceType;
58376
+ const period = req.query.period;
58254
58377
  const page = parseInt(req.query.page) ?? 1;
58255
58378
  const limit = parseInt(req.query.limit) ?? 10;
58256
58379
  try {
58257
58380
  const data = await _getServiceTodayTaskSchedule({
58258
58381
  site,
58259
58382
  serviceType,
58383
+ period,
58260
58384
  page,
58261
58385
  limit
58262
58386
  });
@@ -58273,6 +58397,7 @@ function useNewDashboardController() {
58273
58397
  const validation = Joi112.object({
58274
58398
  site: Joi112.string().hex().required(),
58275
58399
  serviceType: Joi112.string().valid(...Object.values(AppServiceType)).required(),
58400
+ period: Joi112.string().valid(...Object.values(Period)).default("today" /* TODAY */),
58276
58401
  page: Joi112.number().min(1).optional().allow("", null),
58277
58402
  limit: Joi112.number().min(1).optional().allow("", null)
58278
58403
  });
@@ -58284,12 +58409,14 @@ function useNewDashboardController() {
58284
58409
  }
58285
58410
  const site = req.params.site;
58286
58411
  const serviceType = req.params.serviceType;
58412
+ const period = req.query.period;
58287
58413
  const page = parseInt(req.query.page) ?? 1;
58288
58414
  const limit = parseInt(req.query.limit) ?? 10;
58289
58415
  try {
58290
58416
  const data = await _getServiceStaffAttendance({
58291
58417
  site,
58292
58418
  serviceType,
58419
+ period,
58293
58420
  page,
58294
58421
  limit
58295
58422
  });
@@ -58306,6 +58433,7 @@ function useNewDashboardController() {
58306
58433
  const validation = Joi112.object({
58307
58434
  site: Joi112.string().hex().required(),
58308
58435
  serviceType: Joi112.string().valid(...Object.values(AppServiceType)).required(),
58436
+ period: Joi112.string().valid(...Object.values(Period)).default("today" /* TODAY */),
58309
58437
  page: Joi112.number().min(1).optional().allow("", null),
58310
58438
  limit: Joi112.number().min(1).optional().allow("", null)
58311
58439
  });
@@ -58317,12 +58445,14 @@ function useNewDashboardController() {
58317
58445
  }
58318
58446
  const site = req.params.site;
58319
58447
  const serviceType = req.params.serviceType;
58448
+ const period = req.query.period;
58320
58449
  const page = parseInt(req.query.page) ?? 1;
58321
58450
  const limit = parseInt(req.query.limit) ?? 10;
58322
58451
  try {
58323
58452
  const data = await _getServiceRecentFeedbacks({
58324
58453
  site,
58325
58454
  serviceType,
58455
+ period,
58326
58456
  page,
58327
58457
  limit
58328
58458
  });
@@ -66391,10 +66521,6 @@ function useChatPrelovedRepo() {
66391
66521
  return { add, updateById, deleteById };
66392
66522
  }
66393
66523
 
66394
- // src/controllers/chat-preloved.controller.ts
66395
- import { BadRequestError as BadRequestError222, logger as logger192 } from "@7365admin1/node-server-utils";
66396
- import Joi143 from "joi";
66397
-
66398
66524
  // src/services/chat-preloved.service.ts
66399
66525
  import { BadRequestError as BadRequestError221, InternalServerError as InternalServerError81, useAtlas as useAtlas126 } from "@7365admin1/node-server-utils";
66400
66526
 
@@ -66725,6 +66851,8 @@ function useChatPrelovedService() {
66725
66851
  }
66726
66852
 
66727
66853
  // src/controllers/chat-preloved.controller.ts
66854
+ import { BadRequestError as BadRequestError222, logger as logger192 } from "@7365admin1/node-server-utils";
66855
+ import Joi143 from "joi";
66728
66856
  function useChatPrelovedController() {
66729
66857
  const { add: _add } = useChatPrelovedService();
66730
66858
  const { updateById: _updateById, deleteById: _deleteById } = useChatPrelovedRepo();
@@ -66904,58 +67032,230 @@ function useChannelPrelovedController() {
66904
67032
  return { add, getChannel, getChatLists, getChannelMessages };
66905
67033
  }
66906
67034
 
66907
- // src/models/online-forms-v2.model.ts
67035
+ // src/models/bid-preloved.model.ts
66908
67036
  import Joi145 from "joi";
66909
67037
  import { ObjectId as ObjectId149 } from "mongodb";
67038
+ var BidType = /* @__PURE__ */ ((BidType2) => {
67039
+ BidType2["BID"] = "bid";
67040
+ BidType2["RESERVE"] = "reserve";
67041
+ return BidType2;
67042
+ })(BidType || {});
67043
+ var BidStatus = /* @__PURE__ */ ((BidStatus3) => {
67044
+ BidStatus3["PENDING"] = "pending";
67045
+ BidStatus3["ACCEPTED"] = "accepted";
67046
+ BidStatus3["RESERVED"] = "reserved";
67047
+ BidStatus3["CANCELLED"] = "cancelled";
67048
+ return BidStatus3;
67049
+ })(BidStatus || {});
67050
+ var schemaBidPreloved = Joi145.object({
67051
+ type: Joi145.string().valid(...Object.values(BidType)).required(),
67052
+ postId: Joi145.string().hex().length(24).required(),
67053
+ price: Joi145.when("type", {
67054
+ is: "bid" /* BID */,
67055
+ then: Joi145.number().required(),
67056
+ otherwise: Joi145.number().optional().allow(null)
67057
+ }),
67058
+ message: Joi145.string().optional().allow("", null),
67059
+ buyerId: Joi145.string().hex().length(24).optional().allow("", null),
67060
+ status: Joi145.string().valid(...Object.values(BidStatus)).optional().default("pending" /* PENDING */)
67061
+ });
67062
+ var schemaUpdateBidPreloved = Joi145.object({
67063
+ status: Joi145.string().valid(...Object.values(BidStatus)).required()
67064
+ });
67065
+ function MBidPreloved(value) {
67066
+ const { error } = schemaBidPreloved.validate(value);
67067
+ if (error)
67068
+ throw new Error(error.details[0].message);
67069
+ if (value.postId && typeof value.postId === "string")
67070
+ value.postId = new ObjectId149(value.postId);
67071
+ if (value.buyerId && typeof value.buyerId === "string")
67072
+ value.buyerId = new ObjectId149(value.buyerId);
67073
+ return {
67074
+ _id: new ObjectId149(),
67075
+ price: value.price ?? null,
67076
+ message: value.message ?? "",
67077
+ status: value.status ?? "pending" /* PENDING */,
67078
+ type: value.type,
67079
+ postId: value.postId,
67080
+ buyerId: value.buyerId ?? null,
67081
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
67082
+ updatedAt: null
67083
+ };
67084
+ }
67085
+
67086
+ // src/repositories/bid-preloved.repo.ts
67087
+ import {
67088
+ InternalServerError as InternalServerError82,
67089
+ NotFoundError as NotFoundError61,
67090
+ useAtlas as useAtlas127
67091
+ } from "@7365admin1/node-server-utils";
67092
+ import { ObjectId as ObjectId150 } from "mongodb";
67093
+ function useBidPrelovedRepo() {
67094
+ const db = useAtlas127.getDb();
67095
+ if (!db)
67096
+ throw new InternalServerError82("Unable to connect to server.");
67097
+ const collection = db.collection("bid-preloved");
67098
+ async function add(value, session) {
67099
+ try {
67100
+ const doc = MBidPreloved(value);
67101
+ const res = await collection.insertOne(doc, { session });
67102
+ return res.insertedId;
67103
+ } catch (error) {
67104
+ throw error;
67105
+ }
67106
+ }
67107
+ async function updateStatus(_id, status) {
67108
+ const objectId2 = typeof _id === "string" ? new ObjectId150(_id) : _id;
67109
+ const existing = await collection.findOne({ _id: objectId2 });
67110
+ if (!existing)
67111
+ throw new NotFoundError61("Bid not found.");
67112
+ const res = await collection.updateOne(
67113
+ { _id: objectId2 },
67114
+ { $set: { status, updatedAt: (/* @__PURE__ */ new Date()).toISOString() } }
67115
+ );
67116
+ if (res.modifiedCount === 0)
67117
+ throw new InternalServerError82("Unable to update bid.");
67118
+ return "Bid updated successfully.";
67119
+ }
67120
+ async function getById(_id) {
67121
+ if (typeof _id === "string")
67122
+ _id = new ObjectId150(_id);
67123
+ const result = await collection.findOne({ _id });
67124
+ if (!result)
67125
+ throw new NotFoundError61("Bid not found.");
67126
+ return result;
67127
+ }
67128
+ return { add, getById, updateStatus };
67129
+ }
67130
+
67131
+ // src/controllers/bid-preloved.controller.ts
67132
+ import { BadRequestError as BadRequestError224, logger as logger194 } from "@7365admin1/node-server-utils";
67133
+ import Joi146 from "joi";
67134
+ function useBidPrelovedController() {
67135
+ const {
67136
+ add: _add,
67137
+ getById: _getById,
67138
+ updateStatus: _updateStatus
67139
+ } = useBidPrelovedRepo();
67140
+ async function add(req, res, next) {
67141
+ const { error, value } = schemaBidPreloved.validate(req.body, {
67142
+ abortEarly: false
67143
+ });
67144
+ if (error) {
67145
+ const messages = error.details.map((d) => d.message).join(", ");
67146
+ logger194.log({ level: "error", message: messages });
67147
+ next(new BadRequestError224(messages));
67148
+ return;
67149
+ }
67150
+ try {
67151
+ const data = await _add(value);
67152
+ res.status(201).json(data);
67153
+ } catch (error2) {
67154
+ logger194.log({ level: "error", message: error2.message });
67155
+ next(error2);
67156
+ }
67157
+ }
67158
+ async function updateStatus(req, res, next) {
67159
+ const paramsSchema = Joi146.object({
67160
+ id: Joi146.string().hex().length(24).required()
67161
+ });
67162
+ const { error: paramError, value: params } = paramsSchema.validate(
67163
+ req.params
67164
+ );
67165
+ if (paramError) {
67166
+ logger194.log({ level: "error", message: paramError.message });
67167
+ next(new BadRequestError224(paramError.message));
67168
+ return;
67169
+ }
67170
+ const { error: bodyError, value: body } = schemaUpdateBidPreloved.validate(
67171
+ req.body
67172
+ );
67173
+ if (bodyError) {
67174
+ logger194.log({ level: "error", message: bodyError.message });
67175
+ next(new BadRequestError224(bodyError.message));
67176
+ return;
67177
+ }
67178
+ try {
67179
+ const data = await _updateStatus(params.id, body.status);
67180
+ res.status(200).json(data);
67181
+ } catch (error) {
67182
+ logger194.log({ level: "error", message: error.message });
67183
+ next(error);
67184
+ }
67185
+ }
67186
+ async function getById(req, res, next) {
67187
+ const paramsSchema = Joi146.object({
67188
+ id: Joi146.string().hex().length(24).required()
67189
+ });
67190
+ const { error, value: params } = paramsSchema.validate(req.params);
67191
+ if (error) {
67192
+ logger194.log({ level: "error", message: error.message });
67193
+ next(new BadRequestError224(error.message));
67194
+ return;
67195
+ }
67196
+ try {
67197
+ const data = await _getById(params.id);
67198
+ res.status(200).json(data);
67199
+ } catch (error2) {
67200
+ logger194.log({ level: "error", message: error2.message });
67201
+ next(error2);
67202
+ }
67203
+ }
67204
+ return { add, getById, updateStatus };
67205
+ }
67206
+
67207
+ // src/models/online-forms-v2.model.ts
67208
+ import Joi147 from "joi";
67209
+ import { ObjectId as ObjectId151 } from "mongodb";
66910
67210
  var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
66911
67211
  FormEntryStatus2["ACTIVE"] = "active";
66912
67212
  FormEntryStatus2["INACTIVE"] = "inactive";
66913
67213
  FormEntryStatus2["DELETED"] = "deleted";
66914
67214
  return FormEntryStatus2;
66915
67215
  })(FormEntryStatus || {});
66916
- var schemaFormEntry = Joi145.object({
66917
- _id: Joi145.string().hex().optional().allow("", null),
66918
- formType: Joi145.string().required(),
66919
- block: Joi145.string().optional().allow(null, ""),
66920
- level: Joi145.string().optional().allow(null, ""),
66921
- unit: Joi145.string().optional().allow(null, ""),
66922
- name: Joi145.string().optional().allow(null, ""),
66923
- phoneNumber: Joi145.string().optional().allow(null, ""),
66924
- createdBy: Joi145.string().required(),
66925
- fields: Joi145.object().pattern(
66926
- Joi145.string(),
66927
- Joi145.alternatives().try(
66928
- Joi145.string(),
66929
- Joi145.number(),
66930
- Joi145.boolean(),
66931
- Joi145.valid(null)
67216
+ var schemaFormEntry = Joi147.object({
67217
+ _id: Joi147.string().hex().optional().allow("", null),
67218
+ formType: Joi147.string().required(),
67219
+ block: Joi147.string().optional().allow(null, ""),
67220
+ level: Joi147.string().optional().allow(null, ""),
67221
+ unit: Joi147.string().optional().allow(null, ""),
67222
+ name: Joi147.string().optional().allow(null, ""),
67223
+ phoneNumber: Joi147.string().optional().allow(null, ""),
67224
+ createdBy: Joi147.string().required(),
67225
+ fields: Joi147.object().pattern(
67226
+ Joi147.string(),
67227
+ Joi147.alternatives().try(
67228
+ Joi147.string(),
67229
+ Joi147.number(),
67230
+ Joi147.boolean(),
67231
+ Joi147.valid(null)
66932
67232
  )
66933
67233
  ).required(),
66934
- status: Joi145.string().optional().allow("", null),
66935
- org: Joi145.string().hex().optional().allow("", null),
66936
- site: Joi145.string().hex().optional().allow("", null),
66937
- createdAt: Joi145.date().optional().allow("", null),
66938
- updatedAt: Joi145.date().optional().allow("", null),
66939
- deletedAt: Joi145.date().optional().allow("", null)
67234
+ status: Joi147.string().optional().allow("", null),
67235
+ org: Joi147.string().hex().optional().allow("", null),
67236
+ site: Joi147.string().hex().optional().allow("", null),
67237
+ createdAt: Joi147.date().optional().allow("", null),
67238
+ updatedAt: Joi147.date().optional().allow("", null),
67239
+ deletedAt: Joi147.date().optional().allow("", null)
66940
67240
  });
66941
- var schemaUpdateFormEntry = Joi145.object({
66942
- _id: Joi145.string().hex().required(),
66943
- formType: Joi145.string().optional().allow("", null),
66944
- block: Joi145.string().optional().allow(null, ""),
66945
- level: Joi145.string().optional().allow(null, ""),
66946
- unit: Joi145.string().optional().allow(null, ""),
66947
- fields: Joi145.object().pattern(
66948
- Joi145.string(),
66949
- Joi145.alternatives().try(
66950
- Joi145.string(),
66951
- Joi145.number(),
66952
- Joi145.boolean(),
66953
- Joi145.valid(null)
67241
+ var schemaUpdateFormEntry = Joi147.object({
67242
+ _id: Joi147.string().hex().required(),
67243
+ formType: Joi147.string().optional().allow("", null),
67244
+ block: Joi147.string().optional().allow(null, ""),
67245
+ level: Joi147.string().optional().allow(null, ""),
67246
+ unit: Joi147.string().optional().allow(null, ""),
67247
+ fields: Joi147.object().pattern(
67248
+ Joi147.string(),
67249
+ Joi147.alternatives().try(
67250
+ Joi147.string(),
67251
+ Joi147.number(),
67252
+ Joi147.boolean(),
67253
+ Joi147.valid(null)
66954
67254
  )
66955
67255
  ).optional(),
66956
- status: Joi145.string().optional().allow("", null),
66957
- updatedAt: Joi145.date().optional().allow("", null),
66958
- deletedAt: Joi145.date().optional().allow("", null)
67256
+ status: Joi147.string().optional().allow("", null),
67257
+ updatedAt: Joi147.date().optional().allow("", null),
67258
+ deletedAt: Joi147.date().optional().allow("", null)
66959
67259
  });
66960
67260
  function MFormEntry(value) {
66961
67261
  const { error } = schemaFormEntry.validate(value);
@@ -66964,21 +67264,21 @@ function MFormEntry(value) {
66964
67264
  }
66965
67265
  if (value._id && typeof value._id === "string") {
66966
67266
  try {
66967
- value._id = new ObjectId149(value._id);
67267
+ value._id = new ObjectId151(value._id);
66968
67268
  } catch {
66969
67269
  throw new Error("Invalid ID.");
66970
67270
  }
66971
67271
  }
66972
67272
  if (value.org && typeof value.org === "string") {
66973
67273
  try {
66974
- value.org = new ObjectId149(value.org);
67274
+ value.org = new ObjectId151(value.org);
66975
67275
  } catch {
66976
67276
  throw new Error("Invalid org ID.");
66977
67277
  }
66978
67278
  }
66979
67279
  if (value.site && typeof value.site === "string") {
66980
67280
  try {
66981
- value.site = new ObjectId149(value.site);
67281
+ value.site = new ObjectId151(value.site);
66982
67282
  } catch {
66983
67283
  throw new Error("Invalid site ID.");
66984
67284
  }
@@ -67000,67 +67300,68 @@ function MFormEntry(value) {
67000
67300
  deletedAt: value.deletedAt ?? null
67001
67301
  };
67002
67302
  }
67003
- var residentFormEntry = Joi145.object({
67004
- _id: Joi145.string().hex().optional().allow("", null),
67005
- typeOfForm: Joi145.string().optional().allow("", null),
67006
- unitNumber: Joi145.string().optional().allow(null, ""),
67007
- fields: Joi145.object().pattern(
67008
- Joi145.string(),
67009
- Joi145.alternatives().try(
67010
- Joi145.string(),
67011
- Joi145.number(),
67012
- Joi145.boolean(),
67013
- Joi145.valid(null)
67303
+ var residentFormEntry = Joi147.object({
67304
+ _id: Joi147.string().hex().optional().allow("", null),
67305
+ typeOfForm: Joi147.string().optional().allow("", null),
67306
+ unitNumber: Joi147.string().optional().allow(null, ""),
67307
+ fields: Joi147.object().pattern(
67308
+ Joi147.string(),
67309
+ Joi147.alternatives().try(
67310
+ Joi147.string(),
67311
+ Joi147.number(),
67312
+ Joi147.boolean(),
67313
+ Joi147.valid(null)
67014
67314
  )
67015
67315
  ).optional().allow(null, ""),
67016
- status: Joi145.string().optional().allow("", null),
67017
- org: Joi145.string().hex().optional().allow("", null),
67018
- site: Joi145.string().hex().optional().allow("", null),
67019
- userId: Joi145.string().hex().optional().allow("", null),
67020
- createdAt: Joi145.date().optional().allow("", null),
67021
- updatedAt: Joi145.date().optional().allow("", null),
67022
- deletedAt: Joi145.date().optional().allow("", null),
67023
- remarks: Joi145.string().optional().allow("", null),
67024
- managementValues: Joi145.object().pattern(
67025
- Joi145.string(),
67026
- Joi145.alternatives().try(
67027
- Joi145.string(),
67028
- Joi145.number(),
67029
- Joi145.boolean(),
67030
- Joi145.valid(null)
67316
+ status: Joi147.string().optional().allow("", null),
67317
+ org: Joi147.string().hex().optional().allow("", null),
67318
+ site: Joi147.string().hex().optional().allow("", null),
67319
+ userId: Joi147.string().hex().optional().allow("", null),
67320
+ createdAt: Joi147.date().optional().allow("", null),
67321
+ updatedAt: Joi147.date().optional().allow("", null),
67322
+ deletedAt: Joi147.date().optional().allow("", null),
67323
+ remarks: Joi147.string().optional().allow("", null),
67324
+ managementValues: Joi147.object().pattern(
67325
+ Joi147.string(),
67326
+ Joi147.alternatives().try(
67327
+ Joi147.string(),
67328
+ Joi147.number(),
67329
+ Joi147.boolean(),
67330
+ Joi147.valid(null)
67031
67331
  )
67032
67332
  ).optional().allow(null, "")
67033
67333
  });
67034
67334
 
67035
67335
  // src/repositories/online-forms-v2.repository.ts
67036
67336
  import {
67037
- BadRequestError as BadRequestError224,
67038
- InternalServerError as InternalServerError82,
67039
- logger as logger194,
67337
+ BadRequestError as BadRequestError225,
67338
+ InternalServerError as InternalServerError83,
67339
+ logger as logger195,
67040
67340
  makeCacheKey as makeCacheKey65,
67041
- NotFoundError as NotFoundError61,
67341
+ NotFoundError as NotFoundError62,
67042
67342
  paginate as paginate64,
67043
- useAtlas as useAtlas127,
67343
+ useAtlas as useAtlas128,
67044
67344
  useCache as useCache69
67045
67345
  } from "@7365admin1/node-server-utils";
67046
- import { ObjectId as ObjectId150 } from "mongodb";
67346
+ import { ObjectId as ObjectId152 } from "mongodb";
67047
67347
  var online_forms_namespace_collection = "online-forms";
67048
67348
  function useFormEntryRepo() {
67049
- const db = useAtlas127.getDb();
67349
+ const db = useAtlas128.getDb();
67050
67350
  if (!db) {
67051
- throw new InternalServerError82("Unable to connect to server.");
67351
+ throw new InternalServerError83("Unable to connect to server.");
67052
67352
  }
67053
67353
  const collection = db.collection(online_forms_namespace_collection);
67054
67354
  const { delNamespace, getCache, setCache } = useCache69(
67055
67355
  online_forms_namespace_collection
67056
67356
  );
67357
+ const { getUserById } = useUserRepo();
67057
67358
  async function createTextIndex() {
67058
67359
  try {
67059
67360
  await collection.createIndex({
67060
67361
  name: "text"
67061
67362
  });
67062
67363
  } catch (error) {
67063
- throw new InternalServerError82(
67364
+ throw new InternalServerError83(
67064
67365
  "Failed to create text index on online form."
67065
67366
  );
67066
67367
  }
@@ -67070,11 +67371,11 @@ function useFormEntryRepo() {
67070
67371
  value = MFormEntry(value);
67071
67372
  const res = await collection.insertOne(value, { session });
67072
67373
  delNamespace().then(() => {
67073
- logger194.info(
67374
+ logger195.info(
67074
67375
  `Cache cleared for namespace: ${online_forms_namespace_collection}`
67075
67376
  );
67076
67377
  }).catch((err) => {
67077
- logger194.error(
67378
+ logger195.error(
67078
67379
  `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
67079
67380
  err
67080
67381
  );
@@ -67083,7 +67384,7 @@ function useFormEntryRepo() {
67083
67384
  } catch (error) {
67084
67385
  const isDuplicated = error.message.includes("duplicate");
67085
67386
  if (isDuplicated) {
67086
- throw new BadRequestError224("Online Form already exists.");
67387
+ throw new BadRequestError225("Online Form already exists.");
67087
67388
  }
67088
67389
  throw error;
67089
67390
  }
@@ -67099,8 +67400,8 @@ function useFormEntryRepo() {
67099
67400
  }) {
67100
67401
  page = page > 0 ? page - 1 : 0;
67101
67402
  sort = Object.keys(sort).length > 0 ? sort : { _id: -1 };
67102
- site = new ObjectId150(site);
67103
- org = new ObjectId150(org);
67403
+ site = new ObjectId152(site);
67404
+ org = new ObjectId152(org);
67104
67405
  const cacheOptions = {
67105
67406
  page,
67106
67407
  limit,
@@ -67126,7 +67427,7 @@ function useFormEntryRepo() {
67126
67427
  );
67127
67428
  const cachedData = await getCache(cacheKey);
67128
67429
  if (cachedData) {
67129
- logger194.info(`Cache hit for key: ${cacheKey}`);
67430
+ logger195.info(`Cache hit for key: ${cacheKey}`);
67130
67431
  return cachedData;
67131
67432
  }
67132
67433
  try {
@@ -67155,9 +67456,9 @@ function useFormEntryRepo() {
67155
67456
  const length = await collection.countDocuments(query);
67156
67457
  const data = paginate64(items, page, limit, length);
67157
67458
  setCache(cacheKey, data, 15 * 60).then(() => {
67158
- logger194.info(`Cache set for key: ${cacheKey}`);
67459
+ logger195.info(`Cache set for key: ${cacheKey}`);
67159
67460
  }).catch((err) => {
67160
- logger194.error(`Failed to set cache for key: ${cacheKey}`, err);
67461
+ logger195.error(`Failed to set cache for key: ${cacheKey}`, err);
67161
67462
  });
67162
67463
  return data;
67163
67464
  } catch (error) {
@@ -67168,24 +67469,24 @@ function useFormEntryRepo() {
67168
67469
  const cacheKey = makeCacheKey65(online_forms_namespace_collection, { _id });
67169
67470
  const cachedData = await getCache(cacheKey);
67170
67471
  if (cachedData) {
67171
- logger194.info(`Cache hit for key: ${cacheKey}`);
67472
+ logger195.info(`Cache hit for key: ${cacheKey}`);
67172
67473
  return cachedData;
67173
67474
  }
67174
67475
  try {
67175
- _id = new ObjectId150(_id);
67476
+ _id = new ObjectId152(_id);
67176
67477
  } catch (error) {
67177
- throw new BadRequestError224("Invalid online form ID format.");
67478
+ throw new BadRequestError225("Invalid online form ID format.");
67178
67479
  }
67179
67480
  const query = { _id, status: { $ne: "deleted" } };
67180
67481
  try {
67181
67482
  const [data] = await collection.aggregate([{ $match: query }]).toArray();
67182
67483
  if (!data) {
67183
- throw new NotFoundError61("Document not found.");
67484
+ throw new NotFoundError62("Document not found.");
67184
67485
  }
67185
67486
  setCache(cacheKey, data, 15 * 60).then(() => {
67186
- logger194.info(`Cache set for key: ${cacheKey}`);
67487
+ logger195.info(`Cache set for key: ${cacheKey}`);
67187
67488
  }).catch((err) => {
67188
- logger194.error(`Failed to set cache for key: ${cacheKey}`, err);
67489
+ logger195.error(`Failed to set cache for key: ${cacheKey}`, err);
67189
67490
  });
67190
67491
  return data;
67191
67492
  } catch (error) {
@@ -67194,9 +67495,9 @@ function useFormEntryRepo() {
67194
67495
  }
67195
67496
  async function updateFormEntryById(_id, value) {
67196
67497
  try {
67197
- _id = new ObjectId150(_id);
67498
+ _id = new ObjectId152(_id);
67198
67499
  } catch (error) {
67199
- throw new BadRequestError224("Invalid online form ID format.");
67500
+ throw new BadRequestError225("Invalid online form ID format.");
67200
67501
  }
67201
67502
  try {
67202
67503
  const updateValue = {
@@ -67205,14 +67506,34 @@ function useFormEntryRepo() {
67205
67506
  };
67206
67507
  const res = await collection.updateOne({ _id }, { $set: updateValue });
67207
67508
  if (res.modifiedCount === 0) {
67208
- throw new InternalServerError82("Unable to update online form.");
67209
- }
67509
+ throw new InternalServerError83("Unable to update online form.");
67510
+ }
67511
+ const onlineFormRequest = await collection.findOne({ _id });
67512
+ if (!onlineFormRequest) {
67513
+ throw new NotFoundError62("Online form not found.");
67514
+ }
67515
+ const user = await getUserById(onlineFormRequest.userId.toString());
67516
+ if (!user || !user._id) {
67517
+ throw new NotFoundError62("User not found.");
67518
+ }
67519
+ const userId = user._id.toString();
67520
+ await NotificationService.onlineFormRequestStatusUpdated({
67521
+ to: userId,
67522
+ onlineFormId: onlineFormRequest._id,
67523
+ // typeOfForm: onlineFormRequest.typeOfForm,
67524
+ // unitNumber: onlineFormRequest.unitNumber,
67525
+ status: onlineFormRequest.status
67526
+ // createdAt: onlineFormRequest.createdAt ?? "",
67527
+ // fields: onlineFormRequest.fields ?? {},
67528
+ // remarks: onlineFormRequest.remarks ?? "",
67529
+ // managementValuesJson: onlineFormRequest.managementValues ?? {},
67530
+ });
67210
67531
  delNamespace().then(() => {
67211
- logger194.info(
67532
+ logger195.info(
67212
67533
  `Cache cleared for namespace: ${online_forms_namespace_collection}`
67213
67534
  );
67214
67535
  }).catch((err) => {
67215
- logger194.error(
67536
+ logger195.error(
67216
67537
  `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
67217
67538
  err
67218
67539
  );
@@ -67224,9 +67545,9 @@ function useFormEntryRepo() {
67224
67545
  }
67225
67546
  async function deleteOnlineFormById(_id, session) {
67226
67547
  try {
67227
- _id = new ObjectId150(_id);
67548
+ _id = new ObjectId152(_id);
67228
67549
  } catch (error) {
67229
- throw new BadRequestError224("Invalid online form ID format.");
67550
+ throw new BadRequestError225("Invalid online form ID format.");
67230
67551
  }
67231
67552
  try {
67232
67553
  const updateValue = {
@@ -67240,12 +67561,14 @@ function useFormEntryRepo() {
67240
67561
  { session }
67241
67562
  );
67242
67563
  if (res.modifiedCount === 0) {
67243
- throw new InternalServerError82("Unable to delete online form.");
67564
+ throw new InternalServerError83("Unable to delete online form.");
67244
67565
  }
67245
67566
  delNamespace().then(() => {
67246
- logger194.info(`Cache cleared for namespace: ${online_forms_namespace_collection}`);
67567
+ logger195.info(
67568
+ `Cache cleared for namespace: ${online_forms_namespace_collection}`
67569
+ );
67247
67570
  }).catch((err) => {
67248
- logger194.error(
67571
+ logger195.error(
67249
67572
  `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
67250
67573
  err
67251
67574
  );
@@ -67257,16 +67580,16 @@ function useFormEntryRepo() {
67257
67580
  }
67258
67581
  async function addResidentForm(value, session) {
67259
67582
  try {
67260
- value.site = new ObjectId150(value.site);
67261
- value.org = new ObjectId150(value.org);
67262
- value.userId = new ObjectId150(value.userId);
67583
+ value.site = new ObjectId152(value.site);
67584
+ value.org = new ObjectId152(value.org);
67585
+ value.userId = new ObjectId152(value.userId);
67263
67586
  const res = await collection.insertOne(value, { session });
67264
67587
  delNamespace().then(() => {
67265
- logger194.info(
67588
+ logger195.info(
67266
67589
  `Cache cleared for namespace: ${online_forms_namespace_collection}`
67267
67590
  );
67268
67591
  }).catch((err) => {
67269
- logger194.error(
67592
+ logger195.error(
67270
67593
  `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
67271
67594
  err
67272
67595
  );
@@ -67275,16 +67598,20 @@ function useFormEntryRepo() {
67275
67598
  } catch (error) {
67276
67599
  const isDuplicated = error.message.includes("duplicate");
67277
67600
  if (isDuplicated) {
67278
- throw new BadRequestError224("Online Form already exists.");
67601
+ throw new BadRequestError225("Online Form already exists.");
67279
67602
  }
67280
67603
  throw error;
67281
67604
  }
67282
67605
  }
67283
- async function residentForm({ userId, site, org }) {
67606
+ async function residentForm({
67607
+ userId,
67608
+ site,
67609
+ org
67610
+ }) {
67284
67611
  try {
67285
- const user = new ObjectId150(userId);
67286
- const siteId = new ObjectId150(site);
67287
- const orgId = new ObjectId150(org);
67612
+ const user = new ObjectId152(userId);
67613
+ const siteId = new ObjectId152(site);
67614
+ const orgId = new ObjectId152(org);
67288
67615
  const res = await collection.aggregate([
67289
67616
  {
67290
67617
  $match: {
@@ -67312,8 +67639,8 @@ function useFormEntryRepo() {
67312
67639
  }
67313
67640
 
67314
67641
  // src/controllers/online-forms-v2.controller.ts
67315
- import { BadRequestError as BadRequestError225, logger as logger195 } from "@7365admin1/node-server-utils";
67316
- import Joi146 from "joi";
67642
+ import { BadRequestError as BadRequestError226, logger as logger196 } from "@7365admin1/node-server-utils";
67643
+ import Joi148 from "joi";
67317
67644
  import ExcelJS3 from "exceljs";
67318
67645
  import fs6 from "fs";
67319
67646
  function useFormEntryController() {
@@ -67339,14 +67666,14 @@ function useFormEntryController() {
67339
67666
  async function uploadFormEntrys(req, res, next) {
67340
67667
  try {
67341
67668
  if (!req.file) {
67342
- next(new BadRequestError225("Excel file is required."));
67669
+ next(new BadRequestError226("Excel file is required."));
67343
67670
  return;
67344
67671
  }
67345
67672
  const workbook = new ExcelJS3.Workbook();
67346
67673
  await workbook.xlsx.readFile(req.file.path);
67347
67674
  const worksheet = workbook.worksheets[0];
67348
67675
  if (!worksheet) {
67349
- next(new BadRequestError225("No worksheet found in uploaded Excel file."));
67676
+ next(new BadRequestError226("No worksheet found in uploaded Excel file."));
67350
67677
  return;
67351
67678
  }
67352
67679
  const headerRow = worksheet.getRow(1);
@@ -67374,8 +67701,8 @@ function useFormEntryController() {
67374
67701
  });
67375
67702
  if (error) {
67376
67703
  const messages = error.details.map((d) => d.message).join(", ");
67377
- logger195.log({ level: "error", message: messages });
67378
- next(new BadRequestError225(messages));
67704
+ logger196.log({ level: "error", message: messages });
67705
+ next(new BadRequestError226(messages));
67379
67706
  return;
67380
67707
  }
67381
67708
  const result = await _add(value);
@@ -67383,25 +67710,25 @@ function useFormEntryController() {
67383
67710
  fs6.unlink(req.file.path, () => {
67384
67711
  });
67385
67712
  } catch (error) {
67386
- logger195.log({ level: "error", message: error.message });
67713
+ logger196.log({ level: "error", message: error.message });
67387
67714
  next(error);
67388
67715
  }
67389
67716
  }
67390
67717
  async function getAll(req, res, next) {
67391
67718
  try {
67392
- const schema2 = Joi146.object({
67393
- search: Joi146.string().optional().allow("", null),
67394
- page: Joi146.number().integer().min(1).allow("", null).default(1),
67395
- limit: Joi146.number().integer().min(1).max(100).allow("", null).default(10),
67396
- status: Joi146.string().optional().allow(null, ""),
67397
- org: Joi146.string().hex().optional().allow("", null),
67398
- site: Joi146.string().hex().optional().allow("", null)
67719
+ const schema2 = Joi148.object({
67720
+ search: Joi148.string().optional().allow("", null),
67721
+ page: Joi148.number().integer().min(1).allow("", null).default(1),
67722
+ limit: Joi148.number().integer().min(1).max(100).allow("", null).default(10),
67723
+ status: Joi148.string().optional().allow(null, ""),
67724
+ org: Joi148.string().hex().optional().allow("", null),
67725
+ site: Joi148.string().hex().optional().allow("", null)
67399
67726
  });
67400
67727
  const { error, value } = schema2.validate(req.query);
67401
67728
  if (error) {
67402
67729
  const messages = error.details.map((d) => d.message).join(", ");
67403
- logger195.log({ level: "error", message: messages });
67404
- next(new BadRequestError225(messages));
67730
+ logger196.log({ level: "error", message: messages });
67731
+ next(new BadRequestError226(messages));
67405
67732
  return;
67406
67733
  }
67407
67734
  const { search, page, limit, status, org, site } = value;
@@ -67409,21 +67736,21 @@ function useFormEntryController() {
67409
67736
  res.json(data);
67410
67737
  return;
67411
67738
  } catch (error) {
67412
- logger195.log({ level: "error", message: error.message });
67739
+ logger196.log({ level: "error", message: error.message });
67413
67740
  next(error);
67414
67741
  return;
67415
67742
  }
67416
67743
  }
67417
67744
  async function getFormEntryById(req, res, next) {
67418
67745
  try {
67419
- const schema2 = Joi146.object({
67420
- _id: Joi146.string().hex().length(24).required()
67746
+ const schema2 = Joi148.object({
67747
+ _id: Joi148.string().hex().length(24).required()
67421
67748
  });
67422
67749
  const { error, value } = schema2.validate({ _id: req.params.id });
67423
67750
  if (error) {
67424
67751
  const messages = error.details.map((d) => d.message).join(", ");
67425
- logger195.log({ level: "error", message: messages });
67426
- next(new BadRequestError225(messages));
67752
+ logger196.log({ level: "error", message: messages });
67753
+ next(new BadRequestError226(messages));
67427
67754
  return;
67428
67755
  }
67429
67756
  const { _id } = value;
@@ -67431,7 +67758,7 @@ function useFormEntryController() {
67431
67758
  res.json(data);
67432
67759
  return;
67433
67760
  } catch (error) {
67434
- logger195.log({ level: "error", message: error.message });
67761
+ logger196.log({ level: "error", message: error.message });
67435
67762
  next(error);
67436
67763
  return;
67437
67764
  }
@@ -67444,8 +67771,8 @@ function useFormEntryController() {
67444
67771
  });
67445
67772
  if (error) {
67446
67773
  const messages = error.details.map((d) => d.message).join(", ");
67447
- logger195.log({ level: "error", message: messages });
67448
- next(new BadRequestError225(messages));
67774
+ logger196.log({ level: "error", message: messages });
67775
+ next(new BadRequestError226(messages));
67449
67776
  return;
67450
67777
  }
67451
67778
  const { _id, ...rest } = value;
@@ -67453,26 +67780,26 @@ function useFormEntryController() {
67453
67780
  res.json({ message: "Successfully updated online form." });
67454
67781
  return;
67455
67782
  } catch (error) {
67456
- logger195.log({ level: "error", message: error.message });
67783
+ logger196.log({ level: "error", message: error.message });
67457
67784
  next(error);
67458
67785
  return;
67459
67786
  }
67460
67787
  }
67461
67788
  async function deleteFormEntryById(req, res, next) {
67462
67789
  try {
67463
- const validation = Joi146.string().hex().required();
67790
+ const validation = Joi148.string().hex().required();
67464
67791
  const _id = req.params.id;
67465
67792
  const { error } = validation.validate(_id);
67466
67793
  if (error) {
67467
- logger195.log({ level: "error", message: error.message });
67468
- next(new BadRequestError225(error.message));
67794
+ logger196.log({ level: "error", message: error.message });
67795
+ next(new BadRequestError226(error.message));
67469
67796
  return;
67470
67797
  }
67471
67798
  await _deleteOnlineFormById(_id);
67472
67799
  res.json({ message: "Successfully deleted online form." });
67473
67800
  return;
67474
67801
  } catch (error) {
67475
- logger195.log({ level: "error", message: error.message });
67802
+ logger196.log({ level: "error", message: error.message });
67476
67803
  next(error);
67477
67804
  return;
67478
67805
  }
@@ -67489,8 +67816,8 @@ function useFormEntryController() {
67489
67816
  });
67490
67817
  if (error) {
67491
67818
  const messages = error.details.map((d) => d.message).join(", ");
67492
- logger195.log({ level: "error", message: messages });
67493
- next(new BadRequestError225(messages));
67819
+ logger196.log({ level: "error", message: messages });
67820
+ next(new BadRequestError226(messages));
67494
67821
  return;
67495
67822
  }
67496
67823
  try {
@@ -67498,7 +67825,7 @@ function useFormEntryController() {
67498
67825
  res.status(201).json({ message: data });
67499
67826
  return;
67500
67827
  } catch (error2) {
67501
- logger195.log({ level: "error", message: error2.message });
67828
+ logger196.log({ level: "error", message: error2.message });
67502
67829
  next(error2);
67503
67830
  return;
67504
67831
  }
@@ -67510,8 +67837,8 @@ function useFormEntryController() {
67510
67837
  });
67511
67838
  if (error) {
67512
67839
  const messages = error.details.map((d) => d.message).join(", ");
67513
- logger195.log({ level: "error", message: messages });
67514
- next(new BadRequestError225(messages));
67840
+ logger196.log({ level: "error", message: messages });
67841
+ next(new BadRequestError226(messages));
67515
67842
  return;
67516
67843
  }
67517
67844
  try {
@@ -67519,7 +67846,7 @@ function useFormEntryController() {
67519
67846
  res.status(201).json({ message: data });
67520
67847
  return;
67521
67848
  } catch (error2) {
67522
- logger195.log({ level: "error", message: error2.message });
67849
+ logger196.log({ level: "error", message: error2.message });
67523
67850
  next(error2);
67524
67851
  return;
67525
67852
  }
@@ -67527,22 +67854,22 @@ function useFormEntryController() {
67527
67854
  async function residentForm(req, res, next) {
67528
67855
  try {
67529
67856
  const { site, userId, org } = req.query;
67530
- const residentFormPayload = Joi146.object({
67531
- org: Joi146.string().hex().required(),
67532
- site: Joi146.string().hex().required(),
67533
- userId: Joi146.string().hex().required()
67857
+ const residentFormPayload = Joi148.object({
67858
+ org: Joi148.string().hex().required(),
67859
+ site: Joi148.string().hex().required(),
67860
+ userId: Joi148.string().hex().required()
67534
67861
  });
67535
67862
  const { error } = residentFormPayload.validate({ site, userId, org }, { abortEarly: true });
67536
67863
  if (error) {
67537
67864
  const messages = error.details.map((d) => d.message).join(", ");
67538
- logger195.log({ level: "error", message: messages });
67539
- next(new BadRequestError225(messages));
67865
+ logger196.log({ level: "error", message: messages });
67866
+ next(new BadRequestError226(messages));
67540
67867
  return;
67541
67868
  }
67542
67869
  const result = await _residentForm({ userId, site, org });
67543
67870
  res.json(result);
67544
67871
  } catch (error) {
67545
- logger195.log({ level: "error", message: error.message });
67872
+ logger196.log({ level: "error", message: error.message });
67546
67873
  next(error);
67547
67874
  return;
67548
67875
  }
@@ -67560,11 +67887,11 @@ function useFormEntryController() {
67560
67887
  }
67561
67888
 
67562
67889
  // src/services/building-level.service.ts
67563
- import { useAtlas as useAtlas128 } from "@7365admin1/node-server-utils";
67890
+ import { useAtlas as useAtlas129 } from "@7365admin1/node-server-utils";
67564
67891
  function useBuildingLevelService() {
67565
67892
  const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelRepo();
67566
67893
  async function add(value) {
67567
- const session = useAtlas128.getClient()?.startSession();
67894
+ const session = useAtlas129.getClient()?.startSession();
67568
67895
  try {
67569
67896
  session?.startTransaction();
67570
67897
  await _add(value, session);
@@ -67578,7 +67905,7 @@ function useBuildingLevelService() {
67578
67905
  }
67579
67906
  }
67580
67907
  async function updateLevelById(_id, value) {
67581
- const session = useAtlas128.getClient()?.startSession();
67908
+ const session = useAtlas129.getClient()?.startSession();
67582
67909
  try {
67583
67910
  session?.startTransaction();
67584
67911
  await _updateLevelById(_id, value, session);
@@ -67598,8 +67925,8 @@ function useBuildingLevelService() {
67598
67925
  }
67599
67926
 
67600
67927
  // src/controllers/building-level.controller.ts
67601
- import { BadRequestError as BadRequestError226, logger as logger196 } from "@7365admin1/node-server-utils";
67602
- import Joi147 from "joi";
67928
+ import { BadRequestError as BadRequestError227, logger as logger197 } from "@7365admin1/node-server-utils";
67929
+ import Joi149 from "joi";
67603
67930
  function useBuildingLevelController() {
67604
67931
  const { add: _add, updateLevelById: _updateLevelById } = useBuildingLevelService();
67605
67932
  const {
@@ -67616,8 +67943,8 @@ function useBuildingLevelController() {
67616
67943
  });
67617
67944
  if (error) {
67618
67945
  const messages = error.details.map((d) => d.message).join(", ");
67619
- logger196.log({ level: "error", message: messages });
67620
- next(new BadRequestError226(messages));
67946
+ logger197.log({ level: "error", message: messages });
67947
+ next(new BadRequestError227(messages));
67621
67948
  return;
67622
67949
  }
67623
67950
  const result = await _add(value);
@@ -67628,20 +67955,20 @@ function useBuildingLevelController() {
67628
67955
  }
67629
67956
  async function getAll(req, res, next) {
67630
67957
  try {
67631
- const validation = Joi147.object({
67632
- page: Joi147.number().min(1).optional().default(1),
67633
- limit: Joi147.number().min(1).optional().default(20),
67634
- search: Joi147.string().optional().allow("", null),
67635
- site: Joi147.string().hex().length(24).optional().allow("", null),
67636
- status: Joi147.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
67958
+ const validation = Joi149.object({
67959
+ page: Joi149.number().min(1).optional().default(1),
67960
+ limit: Joi149.number().min(1).optional().default(20),
67961
+ search: Joi149.string().optional().allow("", null),
67962
+ site: Joi149.string().hex().length(24).optional().allow("", null),
67963
+ status: Joi149.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
67637
67964
  });
67638
67965
  const { error, value } = validation.validate(req.query, {
67639
67966
  abortEarly: false
67640
67967
  });
67641
67968
  if (error) {
67642
67969
  const messages = error.details.map((d) => d.message);
67643
- logger196.log({ level: "error", message: messages.join(", ") });
67644
- next(new BadRequestError226(messages.join(", ")));
67970
+ logger197.log({ level: "error", message: messages.join(", ") });
67971
+ next(new BadRequestError227(messages.join(", ")));
67645
67972
  return;
67646
67973
  }
67647
67974
  const { page, limit, status, site, search } = value;
@@ -67660,14 +67987,14 @@ function useBuildingLevelController() {
67660
67987
  }
67661
67988
  async function getById(req, res, next) {
67662
67989
  try {
67663
- const schema2 = Joi147.object({
67664
- id: Joi147.string().hex().length(24).required()
67990
+ const schema2 = Joi149.object({
67991
+ id: Joi149.string().hex().length(24).required()
67665
67992
  });
67666
67993
  const { error, value } = schema2.validate({ id: req.params.id });
67667
67994
  if (error) {
67668
67995
  const messages = error.details.map((d) => d.message);
67669
- logger196.log({ level: "error", message: messages.join(", ") });
67670
- next(new BadRequestError226(messages.join(", ")));
67996
+ logger197.log({ level: "error", message: messages.join(", ") });
67997
+ next(new BadRequestError227(messages.join(", ")));
67671
67998
  return;
67672
67999
  }
67673
68000
  const { id } = value;
@@ -67686,8 +68013,8 @@ function useBuildingLevelController() {
67686
68013
  });
67687
68014
  if (error) {
67688
68015
  const messages = error.details.map((d) => d.message);
67689
- logger196.log({ level: "error", message: messages.join(", ") });
67690
- next(new BadRequestError226(messages.join(", ")));
68016
+ logger197.log({ level: "error", message: messages.join(", ") });
68017
+ next(new BadRequestError227(messages.join(", ")));
67691
68018
  return;
67692
68019
  }
67693
68020
  const { _id, ...rest } = value;
@@ -67699,14 +68026,14 @@ function useBuildingLevelController() {
67699
68026
  }
67700
68027
  async function deleteById(req, res, next) {
67701
68028
  try {
67702
- const schema2 = Joi147.object({
67703
- id: Joi147.string().hex().required()
68029
+ const schema2 = Joi149.object({
68030
+ id: Joi149.string().hex().required()
67704
68031
  });
67705
68032
  const { error, value } = schema2.validate({ id: req.params.id });
67706
68033
  if (error) {
67707
68034
  const messages = error.details.map((d) => d.message);
67708
- logger196.log({ level: "error", message: messages.join(", ") });
67709
- next(new BadRequestError226(messages.join(", ")));
68035
+ logger197.log({ level: "error", message: messages.join(", ") });
68036
+ next(new BadRequestError227(messages.join(", ")));
67710
68037
  return;
67711
68038
  }
67712
68039
  const { id } = value;
@@ -67719,19 +68046,19 @@ function useBuildingLevelController() {
67719
68046
  }
67720
68047
  async function batchUpdateByIds(req, res, next) {
67721
68048
  try {
67722
- const schema2 = Joi147.array().items(
67723
- Joi147.object({
67724
- _id: Joi147.string().hex().length(24).required(),
67725
- value: Joi147.object({
67726
- name: Joi147.string().optional().allow("", null)
68049
+ const schema2 = Joi149.array().items(
68050
+ Joi149.object({
68051
+ _id: Joi149.string().hex().length(24).required(),
68052
+ value: Joi149.object({
68053
+ name: Joi149.string().optional().allow("", null)
67727
68054
  }).required()
67728
68055
  })
67729
68056
  );
67730
68057
  const { error, value } = schema2.validate(req.body);
67731
68058
  if (error) {
67732
68059
  const messages = error.details.map((d) => d.message);
67733
- logger196.log({ level: "error", message: messages.join(", ") });
67734
- next(new BadRequestError226(messages.join(", ")));
68060
+ logger197.log({ level: "error", message: messages.join(", ") });
68061
+ next(new BadRequestError227(messages.join(", ")));
67735
68062
  return;
67736
68063
  }
67737
68064
  const updates = value.map((item) => ({
@@ -67746,9 +68073,9 @@ function useBuildingLevelController() {
67746
68073
  }
67747
68074
  async function getBuildingLevelList(req, res, next) {
67748
68075
  try {
67749
- const schema2 = Joi147.object({
67750
- site: Joi147.string().hex().length(24).required(),
67751
- block: Joi147.string().hex().length(24).required()
68076
+ const schema2 = Joi149.object({
68077
+ site: Joi149.string().hex().length(24).required(),
68078
+ block: Joi149.string().hex().length(24).required()
67752
68079
  });
67753
68080
  const { error, value } = schema2.validate({
67754
68081
  site: req.params.siteId,
@@ -67756,8 +68083,8 @@ function useBuildingLevelController() {
67756
68083
  });
67757
68084
  if (error) {
67758
68085
  const messages = error.details.map((d) => d.message).join(", ");
67759
- logger196.log({ level: "error", message: messages });
67760
- next(new BadRequestError226(messages));
68086
+ logger197.log({ level: "error", message: messages });
68087
+ next(new BadRequestError227(messages));
67761
68088
  return;
67762
68089
  }
67763
68090
  const { site, block } = value;
@@ -67778,10 +68105,1363 @@ function useBuildingLevelController() {
67778
68105
  getBuildingLevelList
67779
68106
  };
67780
68107
  }
68108
+
68109
+ // src/models/hid-amico.model.ts
68110
+ import { BadRequestError as BadRequestError228, logger as logger198 } from "@7365admin1/node-server-utils";
68111
+ import { ObjectId as ObjectId153 } from "mongodb";
68112
+ import Joi150 from "joi";
68113
+ function canReadObjectId(value) {
68114
+ if (value instanceof ObjectId153)
68115
+ return true;
68116
+ if (typeof value === "string")
68117
+ return ObjectId153.isValid(value);
68118
+ if (value && typeof value === "object") {
68119
+ const candidate = value;
68120
+ if (canReadObjectId(candidate._id) || canReadObjectId(candidate.$oid))
68121
+ return true;
68122
+ if (typeof candidate.toHexString === "function" && ObjectId153.isValid(candidate.toHexString()))
68123
+ return true;
68124
+ if (typeof candidate.toString === "function") {
68125
+ const text = candidate.toString();
68126
+ return text !== "[object Object]" && ObjectId153.isValid(text);
68127
+ }
68128
+ }
68129
+ return false;
68130
+ }
68131
+ function toObjectId23(value, label = "ID") {
68132
+ if (value instanceof ObjectId153)
68133
+ return value;
68134
+ if (typeof value === "string" && ObjectId153.isValid(value))
68135
+ return new ObjectId153(value);
68136
+ if (value && typeof value === "object") {
68137
+ const candidate = value;
68138
+ if (candidate._id)
68139
+ return toObjectId23(candidate._id, label);
68140
+ if (candidate.$oid)
68141
+ return toObjectId23(candidate.$oid, label);
68142
+ if (typeof candidate.toHexString === "function")
68143
+ return toObjectId23(candidate.toHexString(), label);
68144
+ if (typeof candidate.toString === "function") {
68145
+ const text = candidate.toString();
68146
+ if (text !== "[object Object]")
68147
+ return toObjectId23(text, label);
68148
+ }
68149
+ }
68150
+ throw new BadRequestError228(`Invalid ${label} format`);
68151
+ }
68152
+ var objectIdSchema2 = Joi150.custom((value, helpers) => canReadObjectId(value) ? value : helpers.error("any.invalid"), "ObjectId").messages({
68153
+ "any.invalid": "{{#label}} must be a valid ObjectId"
68154
+ });
68155
+ var schemaHidAmicoReader = Joi150.object({
68156
+ _id: objectIdSchema2.optional(),
68157
+ site: objectIdSchema2.required(),
68158
+ name: Joi150.string().trim().required(),
68159
+ baseUrl: Joi150.string().uri({ scheme: ["http", "https"] }).required(),
68160
+ username: Joi150.string().trim().required(),
68161
+ password: Joi150.string().required(),
68162
+ location: Joi150.string().allow(null, "").optional(),
68163
+ deviceId: Joi150.string().allow(null, "").optional(),
68164
+ monitorPath: Joi150.string().allow(null, "").optional(),
68165
+ enabled: Joi150.boolean().optional(),
68166
+ status: Joi150.string().valid("active", "inactive", "deleted", "offline").optional(),
68167
+ lastSeenAt: Joi150.date().optional(),
68168
+ lastSyncAt: Joi150.date().optional(),
68169
+ lastSyncStatus: Joi150.string().valid("idle", "running", "completed", "failed").optional(),
68170
+ lastSyncMessage: Joi150.string().allow(null, "").optional(),
68171
+ createdAt: Joi150.date().optional(),
68172
+ updatedAt: Joi150.date().optional(),
68173
+ deletedAt: Joi150.date().optional()
68174
+ });
68175
+ var schemaUpdateHidAmicoReader = Joi150.object({
68176
+ site: objectIdSchema2.optional(),
68177
+ name: Joi150.string().trim().optional(),
68178
+ baseUrl: Joi150.string().uri({ scheme: ["http", "https"] }).optional(),
68179
+ username: Joi150.string().trim().optional(),
68180
+ password: Joi150.string().allow(null, "").optional(),
68181
+ location: Joi150.string().allow(null, "").optional(),
68182
+ deviceId: Joi150.string().allow(null, "").optional(),
68183
+ monitorPath: Joi150.string().allow(null, "").optional(),
68184
+ enabled: Joi150.boolean().optional(),
68185
+ status: Joi150.string().valid("active", "inactive", "deleted", "offline").optional(),
68186
+ lastSeenAt: Joi150.date().optional(),
68187
+ lastSyncAt: Joi150.date().optional(),
68188
+ lastSyncStatus: Joi150.string().valid("idle", "running", "completed", "failed").optional(),
68189
+ lastSyncMessage: Joi150.string().allow(null, "").optional(),
68190
+ deletedAt: Joi150.date().optional()
68191
+ });
68192
+ var schemaHidAmicoEvent = Joi150.object({
68193
+ _id: objectIdSchema2.optional(),
68194
+ reader: objectIdSchema2.required(),
68195
+ site: objectIdSchema2.optional(),
68196
+ type: Joi150.string().required(),
68197
+ payload: Joi150.object().unknown(true).required(),
68198
+ status: Joi150.string().valid("received", "processed", "failed").optional(),
68199
+ createdAt: Joi150.date().optional()
68200
+ });
68201
+ var schemaHidAmicoIdentity = Joi150.object({
68202
+ _id: objectIdSchema2.optional(),
68203
+ reader: objectIdSchema2.required(),
68204
+ site: objectIdSchema2.required(),
68205
+ hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
68206
+ registration: Joi150.string().optional().allow(null, ""),
68207
+ cardNo: Joi150.string().optional().allow(null, ""),
68208
+ person: objectIdSchema2.optional().allow(null, ""),
68209
+ user: objectIdSchema2.optional().allow(null, ""),
68210
+ member: objectIdSchema2.optional().allow(null, ""),
68211
+ visitor: objectIdSchema2.optional().allow(null, ""),
68212
+ type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").required(),
68213
+ status: Joi150.string().valid("active", "inactive", "deleted").optional(),
68214
+ metadata: Joi150.object().unknown(true).optional(),
68215
+ createdAt: Joi150.date().optional(),
68216
+ updatedAt: Joi150.date().optional(),
68217
+ deletedAt: Joi150.date().optional()
68218
+ }).or("hidUserId", "registration", "cardNo");
68219
+ var schemaCreateHidAmicoIdentity = Joi150.object({
68220
+ site: objectIdSchema2.optional(),
68221
+ hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
68222
+ registration: Joi150.string().optional().allow(null, ""),
68223
+ cardNo: Joi150.string().optional().allow(null, ""),
68224
+ person: objectIdSchema2.optional().allow(null, ""),
68225
+ user: objectIdSchema2.optional().allow(null, ""),
68226
+ member: objectIdSchema2.optional().allow(null, ""),
68227
+ visitor: objectIdSchema2.optional().allow(null, ""),
68228
+ type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").required(),
68229
+ status: Joi150.string().valid("active", "inactive", "deleted").optional(),
68230
+ metadata: Joi150.object().unknown(true).optional()
68231
+ }).or("hidUserId", "registration", "cardNo");
68232
+ var schemaUpdateHidAmicoIdentity = Joi150.object({
68233
+ hidUserId: Joi150.alternatives(Joi150.string(), Joi150.number()).optional().allow(null, ""),
68234
+ registration: Joi150.string().optional().allow(null, ""),
68235
+ cardNo: Joi150.string().optional().allow(null, ""),
68236
+ person: objectIdSchema2.optional().allow(null, ""),
68237
+ user: objectIdSchema2.optional().allow(null, ""),
68238
+ member: objectIdSchema2.optional().allow(null, ""),
68239
+ visitor: objectIdSchema2.optional().allow(null, ""),
68240
+ type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").optional(),
68241
+ status: Joi150.string().valid("active", "inactive", "deleted").optional(),
68242
+ metadata: Joi150.object().unknown(true).optional(),
68243
+ deletedAt: Joi150.date().optional()
68244
+ });
68245
+ var schemaHidAmicoReaderIdParams = Joi150.object({
68246
+ readerId: Joi150.string().hex().length(24).required()
68247
+ });
68248
+ var schemaHidAmicoUserImageParams = Joi150.object({
68249
+ readerId: Joi150.string().hex().length(24).required(),
68250
+ hidUserId: Joi150.alternatives().try(Joi150.string(), Joi150.number()).required()
68251
+ });
68252
+ var schemaHidAmicoIdentityIdParams = Joi150.object({
68253
+ identityId: Joi150.string().hex().length(24).required()
68254
+ });
68255
+ var schemaHidAmicoReaderListQuery = Joi150.object({
68256
+ site: Joi150.string().hex().length(24).optional(),
68257
+ page: Joi150.number().min(1).optional(),
68258
+ limit: Joi150.number().min(1).optional()
68259
+ });
68260
+ var schemaHidAmicoLogQuery = Joi150.object({
68261
+ page: Joi150.number().min(1).optional(),
68262
+ limit: Joi150.number().min(1).optional(),
68263
+ type: Joi150.string().optional()
68264
+ });
68265
+ var schemaHidAmicoIdentityQuery = Joi150.object({
68266
+ page: Joi150.number().min(1).optional(),
68267
+ limit: Joi150.number().min(1).optional(),
68268
+ type: Joi150.string().valid("resident", "staff", "contractor", "visitor", "admin", "unknown").optional(),
68269
+ status: Joi150.string().valid("active", "inactive", "deleted").optional(),
68270
+ search: Joi150.string().allow("").optional()
68271
+ });
68272
+ var schemaHidAmicoSync = Joi150.object({
68273
+ objects: Joi150.array().items(
68274
+ Joi150.object({
68275
+ object: Joi150.string().required(),
68276
+ values: Joi150.array().items(Joi150.object().unknown(true)).required()
68277
+ }).unknown(true)
68278
+ ).optional(),
68279
+ users: Joi150.array().items(Joi150.object().unknown(true)).optional(),
68280
+ cards: Joi150.array().items(Joi150.object().unknown(true)).optional(),
68281
+ qrcodes: Joi150.array().items(Joi150.object().unknown(true)).optional(),
68282
+ pins: Joi150.array().items(Joi150.object().unknown(true)).optional()
68283
+ }).unknown(true);
68284
+ var schemaHidAmicoExecuteActions = Joi150.object({
68285
+ actions: Joi150.array().items(Joi150.object().unknown(true)).min(1).required()
68286
+ }).unknown(true);
68287
+ var schemaHidAmicoConfiguration = Joi150.object().pattern(Joi150.string(), Joi150.array().items(Joi150.string())).min(1).unknown(true);
68288
+ var schemaHidAmicoSetConfiguration = Joi150.object().unknown(true);
68289
+ var schemaHidAmicoObjectOperation = Joi150.object({
68290
+ operation: Joi150.string().valid("load", "create", "modify", "destroy").required(),
68291
+ object: Joi150.string().required(),
68292
+ values: Joi150.alternatives().try(
68293
+ Joi150.array().items(Joi150.object().unknown(true)),
68294
+ Joi150.object().unknown(true)
68295
+ ).optional(),
68296
+ where: Joi150.object().unknown(true).optional(),
68297
+ fields: Joi150.array().items(Joi150.string()).optional(),
68298
+ order: Joi150.array().items(Joi150.string()).optional(),
68299
+ limit: Joi150.number().integer().min(1).optional(),
68300
+ offset: Joi150.number().integer().min(0).optional()
68301
+ }).unknown(true);
68302
+ var schemaHidAmicoNotificationParams = Joi150.object({
68303
+ readerId: Joi150.string().hex().length(24).required(),
68304
+ type: Joi150.string().valid(
68305
+ "dao",
68306
+ "template",
68307
+ "user_image",
68308
+ "card",
68309
+ "pin",
68310
+ "password",
68311
+ "operation_mode",
68312
+ "door",
68313
+ "secbox",
68314
+ "access_photo",
68315
+ "new_user_identified",
68316
+ "push_result"
68317
+ ).required()
68318
+ });
68319
+ function MHidAmicoReader(value) {
68320
+ const { error } = schemaHidAmicoReader.validate(value);
68321
+ if (error) {
68322
+ logger198.info(`HID Amico reader: ${error.message}`);
68323
+ throw new BadRequestError228(error.message);
68324
+ }
68325
+ return {
68326
+ _id: value._id ? toObjectId23(value._id, "reader ID") : new ObjectId153(),
68327
+ site: toObjectId23(value.site, "site ID"),
68328
+ name: value.name,
68329
+ baseUrl: value.baseUrl.replace(/\/+$/, ""),
68330
+ username: value.username,
68331
+ password: value.password,
68332
+ location: value.location ?? "",
68333
+ deviceId: value.deviceId ?? "",
68334
+ monitorPath: value.monitorPath ?? "api/notifications",
68335
+ enabled: value.enabled ?? true,
68336
+ status: value.status ?? "active",
68337
+ lastSeenAt: value.lastSeenAt ?? "",
68338
+ lastSyncAt: value.lastSyncAt ?? "",
68339
+ lastSyncStatus: value.lastSyncStatus ?? "idle",
68340
+ lastSyncMessage: value.lastSyncMessage ?? "",
68341
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
68342
+ updatedAt: value.updatedAt ?? /* @__PURE__ */ new Date(),
68343
+ deletedAt: value.deletedAt ?? ""
68344
+ };
68345
+ }
68346
+ function MHidAmicoEvent(value) {
68347
+ const { error } = schemaHidAmicoEvent.validate(value);
68348
+ if (error) {
68349
+ logger198.info(`HID Amico event: ${error.message}`);
68350
+ throw new BadRequestError228(error.message);
68351
+ }
68352
+ return {
68353
+ _id: value._id ? toObjectId23(value._id, "event ID") : new ObjectId153(),
68354
+ reader: toObjectId23(value.reader, "reader ID"),
68355
+ site: value.site ? toObjectId23(value.site, "site ID") : void 0,
68356
+ type: value.type,
68357
+ payload: value.payload,
68358
+ status: value.status ?? "received",
68359
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date()
68360
+ };
68361
+ }
68362
+ function optionalObjectId(value) {
68363
+ return value ? toObjectId23(value) : void 0;
68364
+ }
68365
+ function MHidAmicoIdentity(value) {
68366
+ const { error } = schemaHidAmicoIdentity.validate(value);
68367
+ if (error) {
68368
+ logger198.info(`HID Amico identity: ${error.message}`);
68369
+ throw new BadRequestError228(error.message);
68370
+ }
68371
+ return {
68372
+ _id: value._id ? toObjectId23(value._id, "identity ID") : new ObjectId153(),
68373
+ reader: toObjectId23(value.reader, "reader ID"),
68374
+ site: toObjectId23(value.site, "site ID"),
68375
+ hidUserId: value.hidUserId === void 0 || value.hidUserId === null ? "" : String(value.hidUserId),
68376
+ registration: value.registration ?? "",
68377
+ cardNo: value.cardNo ?? "",
68378
+ person: optionalObjectId(value.person),
68379
+ user: optionalObjectId(value.user),
68380
+ member: optionalObjectId(value.member),
68381
+ visitor: optionalObjectId(value.visitor),
68382
+ type: value.type,
68383
+ status: value.status ?? "active",
68384
+ metadata: value.metadata ?? {},
68385
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
68386
+ updatedAt: value.updatedAt ?? /* @__PURE__ */ new Date(),
68387
+ deletedAt: value.deletedAt ?? ""
68388
+ };
68389
+ }
68390
+
68391
+ // src/repositories/hid-amico.repo.ts
68392
+ import {
68393
+ BadRequestError as BadRequestError229,
68394
+ InternalServerError as InternalServerError84,
68395
+ logger as logger199,
68396
+ paginate as paginate65,
68397
+ useAtlas as useAtlas130
68398
+ } from "@7365admin1/node-server-utils";
68399
+ import { ObjectId as ObjectId154 } from "mongodb";
68400
+ function useHidAmicoRepo() {
68401
+ function db() {
68402
+ const instance = useAtlas130.getDb();
68403
+ if (!instance) {
68404
+ throw new InternalServerError84("Unable to connect to server.");
68405
+ }
68406
+ return instance;
68407
+ }
68408
+ function readers() {
68409
+ return db().collection("hid-amico-readers");
68410
+ }
68411
+ function events() {
68412
+ return db().collection("hid-amico-events");
68413
+ }
68414
+ function identities() {
68415
+ return db().collection("hid-amico-identities");
68416
+ }
68417
+ function toId(id, label = "ID") {
68418
+ try {
68419
+ return new ObjectId154(id);
68420
+ } catch {
68421
+ throw new BadRequestError229(`Invalid ${label} format`);
68422
+ }
68423
+ }
68424
+ function hideSecret(reader) {
68425
+ if (!reader) {
68426
+ return reader;
68427
+ }
68428
+ const { password, ...safeReader } = reader;
68429
+ const status = safeReader.lastSyncStatus === "failed" && safeReader.status === "active" ? "offline" : safeReader.status;
68430
+ return {
68431
+ ...safeReader,
68432
+ status,
68433
+ passwordSet: Boolean(password)
68434
+ };
68435
+ }
68436
+ function escapeRegex(value) {
68437
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
68438
+ }
68439
+ function buildIdentityKeyQuery(value) {
68440
+ const or = [];
68441
+ if (value.hidUserId !== void 0 && value.hidUserId !== null && String(value.hidUserId) !== "") {
68442
+ or.push({ hidUserId: String(value.hidUserId) });
68443
+ }
68444
+ if (value.registration) {
68445
+ or.push({ registration: value.registration });
68446
+ }
68447
+ if (value.cardNo) {
68448
+ or.push({ cardNo: value.cardNo });
68449
+ }
68450
+ return or;
68451
+ }
68452
+ async function createIndexes() {
68453
+ try {
68454
+ await Promise.all([
68455
+ readers().createIndex({ site: 1, status: 1 }),
68456
+ readers().createIndex(
68457
+ { site: 1, baseUrl: 1 },
68458
+ { unique: true, partialFilterExpression: { status: "active" } }
68459
+ ),
68460
+ readers().createIndex({ deviceId: 1 }),
68461
+ events().createIndex({ reader: 1, createdAt: -1 }),
68462
+ events().createIndex({ site: 1, createdAt: -1 }),
68463
+ events().createIndex({ type: 1, createdAt: -1 }),
68464
+ identities().createIndex({ reader: 1, status: 1 }),
68465
+ identities().createIndex({ site: 1, status: 1 }),
68466
+ identities().createIndex({ reader: 1, hidUserId: 1 }),
68467
+ identities().createIndex({ reader: 1, registration: 1 }),
68468
+ identities().createIndex({ reader: 1, cardNo: 1 })
68469
+ ]);
68470
+ return "HID Amico indexes created.";
68471
+ } catch (error) {
68472
+ logger199.error(error.message);
68473
+ throw new Error("Failed to create HID Amico indexes.");
68474
+ }
68475
+ }
68476
+ async function add(value, session) {
68477
+ try {
68478
+ const doc = MHidAmicoReader(value);
68479
+ await readers().insertOne(doc, { session });
68480
+ return hideSecret(doc);
68481
+ } catch (error) {
68482
+ if (error.message?.includes("duplicate")) {
68483
+ throw new BadRequestError229("HID Amico reader already exists for this site and URL.");
68484
+ }
68485
+ throw error;
68486
+ }
68487
+ }
68488
+ async function list(value) {
68489
+ const page = value.page ? value.page - 1 : 0;
68490
+ const limit = value.limit || 10;
68491
+ const query = { status: { $ne: "deleted" } };
68492
+ if (value.site) {
68493
+ query.site = toId(value.site, "site ID");
68494
+ }
68495
+ const items = await readers().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
68496
+ const total = await readers().countDocuments(query);
68497
+ return paginate65(items.map(hideSecret), page, limit, total);
68498
+ }
68499
+ async function getById(id, options = {}) {
68500
+ const _id = toId(id, "reader ID");
68501
+ const reader = await readers().findOne(
68502
+ { _id, status: { $ne: "deleted" } }
68503
+ );
68504
+ if (!reader) {
68505
+ throw new BadRequestError229("HID Amico reader not found.");
68506
+ }
68507
+ return options.includePassword ? reader : hideSecret(reader);
68508
+ }
68509
+ async function updateById(id, value, session) {
68510
+ const { error } = schemaUpdateHidAmicoReader.validate(value);
68511
+ if (error) {
68512
+ throw new BadRequestError229(error.message);
68513
+ }
68514
+ const _id = toId(id, "reader ID");
68515
+ const payload = {
68516
+ ...value,
68517
+ updatedAt: /* @__PURE__ */ new Date()
68518
+ };
68519
+ if (payload.site) {
68520
+ payload.site = toId(payload.site, "site ID");
68521
+ }
68522
+ if (payload.baseUrl) {
68523
+ payload.baseUrl = payload.baseUrl.replace(/\/+$/, "");
68524
+ }
68525
+ const updated = await readers().findOneAndUpdate(
68526
+ { _id, status: { $ne: "deleted" } },
68527
+ { $set: payload },
68528
+ { returnDocument: "after", session }
68529
+ );
68530
+ if (!updated) {
68531
+ throw new BadRequestError229("HID Amico reader not found.");
68532
+ }
68533
+ return hideSecret(updated);
68534
+ }
68535
+ async function markDeleted(id, session) {
68536
+ return updateById(
68537
+ id,
68538
+ {
68539
+ status: "deleted",
68540
+ enabled: false,
68541
+ deletedAt: /* @__PURE__ */ new Date()
68542
+ },
68543
+ session
68544
+ );
68545
+ }
68546
+ async function addEvent(value, session) {
68547
+ const event = MHidAmicoEvent(value);
68548
+ await events().insertOne(event, { session });
68549
+ return event;
68550
+ }
68551
+ async function listEvents(value) {
68552
+ const page = value.page ? value.page - 1 : 0;
68553
+ const limit = value.limit || 20;
68554
+ const query = { reader: toId(value.reader, "reader ID") };
68555
+ if (value.type) {
68556
+ query.type = value.type;
68557
+ }
68558
+ const items = await events().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
68559
+ const total = await events().countDocuments(query);
68560
+ return paginate65(items, page, limit, total);
68561
+ }
68562
+ async function addIdentity(value, session) {
68563
+ try {
68564
+ const identity = MHidAmicoIdentity(value);
68565
+ const existing = await findExistingIdentity({
68566
+ reader: identity.reader,
68567
+ hidUserId: identity.hidUserId,
68568
+ registration: identity.registration,
68569
+ cardNo: identity.cardNo
68570
+ });
68571
+ if (existing) {
68572
+ throw new BadRequestError229("HID Amico identity already exists for this reader.");
68573
+ }
68574
+ await identities().insertOne(identity, { session });
68575
+ return identity;
68576
+ } catch (error) {
68577
+ if (error instanceof BadRequestError229) {
68578
+ throw error;
68579
+ }
68580
+ if (error.message?.includes("duplicate")) {
68581
+ throw new BadRequestError229("HID Amico identity already exists for this reader.");
68582
+ }
68583
+ throw error;
68584
+ }
68585
+ }
68586
+ async function listIdentities(value) {
68587
+ const page = value.page ? value.page - 1 : 0;
68588
+ const limit = value.limit || 20;
68589
+ const query = {
68590
+ reader: toId(value.reader, "reader ID"),
68591
+ status: value.status || { $ne: "deleted" }
68592
+ };
68593
+ if (value.type) {
68594
+ query.type = value.type;
68595
+ }
68596
+ if (value.search) {
68597
+ const search = escapeRegex(value.search);
68598
+ query.$or = [
68599
+ { hidUserId: { $regex: search, $options: "i" } },
68600
+ { registration: { $regex: search, $options: "i" } },
68601
+ { cardNo: { $regex: search, $options: "i" } }
68602
+ ];
68603
+ }
68604
+ const items = await identities().find(query).sort({ createdAt: -1 }).skip(page * limit).limit(limit).toArray();
68605
+ const total = await identities().countDocuments(query);
68606
+ return paginate65(items, page, limit, total);
68607
+ }
68608
+ async function updateIdentity(id, value, session) {
68609
+ const { error } = schemaUpdateHidAmicoIdentity.validate(value);
68610
+ if (error) {
68611
+ throw new BadRequestError229(error.message);
68612
+ }
68613
+ const payload = {
68614
+ ...value,
68615
+ updatedAt: /* @__PURE__ */ new Date()
68616
+ };
68617
+ const unsetPayload = {};
68618
+ ["person", "user", "member", "visitor"].forEach((field) => {
68619
+ if (payload[field]) {
68620
+ payload[field] = toId(payload[field], `${field} ID`);
68621
+ }
68622
+ if (payload[field] === "" || payload[field] === null) {
68623
+ delete payload[field];
68624
+ unsetPayload[field] = "";
68625
+ }
68626
+ });
68627
+ if (payload.hidUserId !== void 0 && payload.hidUserId !== null) {
68628
+ payload.hidUserId = String(payload.hidUserId);
68629
+ }
68630
+ const updated = await identities().findOneAndUpdate(
68631
+ { _id: toId(id, "identity ID"), status: { $ne: "deleted" } },
68632
+ {
68633
+ $set: payload,
68634
+ ...Object.keys(unsetPayload).length ? { $unset: unsetPayload } : {}
68635
+ },
68636
+ { returnDocument: "after", session }
68637
+ );
68638
+ if (!updated) {
68639
+ throw new BadRequestError229("HID Amico identity not found.");
68640
+ }
68641
+ return updated;
68642
+ }
68643
+ async function deleteIdentity(id, session) {
68644
+ return updateIdentity(
68645
+ id,
68646
+ {
68647
+ status: "deleted",
68648
+ deletedAt: /* @__PURE__ */ new Date()
68649
+ },
68650
+ session
68651
+ );
68652
+ }
68653
+ async function findIdentity(value) {
68654
+ const or = buildIdentityKeyQuery(value);
68655
+ if (!or.length) {
68656
+ return null;
68657
+ }
68658
+ return identities().findOne({
68659
+ reader: toId(value.reader, "reader ID"),
68660
+ status: "active",
68661
+ $or: or
68662
+ });
68663
+ }
68664
+ async function findExistingIdentity(value) {
68665
+ const or = buildIdentityKeyQuery(value);
68666
+ if (!or.length) {
68667
+ return null;
68668
+ }
68669
+ return identities().findOne({
68670
+ reader: toId(value.reader, "reader ID"),
68671
+ status: { $ne: "deleted" },
68672
+ $or: or
68673
+ });
68674
+ }
68675
+ return {
68676
+ createIndexes,
68677
+ add,
68678
+ list,
68679
+ getById,
68680
+ updateById,
68681
+ markDeleted,
68682
+ addEvent,
68683
+ listEvents,
68684
+ addIdentity,
68685
+ listIdentities,
68686
+ updateIdentity,
68687
+ deleteIdentity,
68688
+ findIdentity,
68689
+ findExistingIdentity
68690
+ };
68691
+ }
68692
+
68693
+ // src/services/hid-amico.service.ts
68694
+ import crypto5 from "crypto";
68695
+ import axios4 from "axios";
68696
+ import { BadRequestError as BadRequestError230 } from "@7365admin1/node-server-utils";
68697
+ var PASSWORD_PREFIX = "v1";
68698
+ function getSecretKey() {
68699
+ const secret = process.env.HID_AMICO_SECRET || process.env.ACCESS_TOKEN_SECRET || "iservice365-hid-amico";
68700
+ return crypto5.createHash("sha256").update(secret).digest();
68701
+ }
68702
+ function encryptSecret(value) {
68703
+ const iv = crypto5.randomBytes(12);
68704
+ const cipher = crypto5.createCipheriv("aes-256-gcm", getSecretKey(), iv);
68705
+ const encrypted = Buffer.concat([cipher.update(value, "utf8"), cipher.final()]);
68706
+ const tag = cipher.getAuthTag();
68707
+ return [PASSWORD_PREFIX, iv.toString("hex"), tag.toString("hex"), encrypted.toString("hex")].join(":");
68708
+ }
68709
+ function decryptSecret(value) {
68710
+ if (!value?.startsWith(`${PASSWORD_PREFIX}:`)) {
68711
+ return value;
68712
+ }
68713
+ const [, ivHex, tagHex, encryptedHex] = value.split(":");
68714
+ const decipher = crypto5.createDecipheriv("aes-256-gcm", getSecretKey(), Buffer.from(ivHex, "hex"));
68715
+ decipher.setAuthTag(Buffer.from(tagHex, "hex"));
68716
+ return Buffer.concat([
68717
+ decipher.update(Buffer.from(encryptedHex, "hex")),
68718
+ decipher.final()
68719
+ ]).toString("utf8");
68720
+ }
68721
+ function formatHidResponse(data) {
68722
+ if (data === void 0 || data === null) {
68723
+ return "";
68724
+ }
68725
+ const text = typeof data === "string" ? data : JSON.stringify(data);
68726
+ return text.length > 300 ? `${text.slice(0, 300)}...` : text;
68727
+ }
68728
+ function sanitizeHidPath(path5) {
68729
+ return path5.replace(/([?&]session=)[^&]+/i, "$1<redacted>");
68730
+ }
68731
+ function toHidRequestError(error, path5) {
68732
+ if (axios4.isAxiosError(error)) {
68733
+ const status = error.response?.status;
68734
+ const payload = formatHidResponse(error.response?.data);
68735
+ const detail = [
68736
+ `HID Amico request failed: ${sanitizeHidPath(path5)}`,
68737
+ status ? `status ${status}` : "",
68738
+ payload ? `response ${payload}` : error.message
68739
+ ].filter(Boolean).join(" - ");
68740
+ return new BadRequestError230(detail);
68741
+ }
68742
+ return error;
68743
+ }
68744
+ var HidAmicoClient = class {
68745
+ constructor(reader) {
68746
+ this.reader = reader;
68747
+ this.session = "";
68748
+ this.http = axios4.create({
68749
+ baseURL: reader.baseUrl.replace(/\/+$/, ""),
68750
+ timeout: 15e3,
68751
+ headers: { "Content-Type": "application/json" }
68752
+ });
68753
+ }
68754
+ async post(path5, body) {
68755
+ try {
68756
+ return await this.http.post(path5, body);
68757
+ } catch (error) {
68758
+ throw toHidRequestError(error, path5);
68759
+ }
68760
+ }
68761
+ async get(path5, responseType = "json") {
68762
+ try {
68763
+ return await this.http.get(path5, { responseType });
68764
+ } catch (error) {
68765
+ throw toHidRequestError(error, path5);
68766
+ }
68767
+ }
68768
+ url(path5) {
68769
+ const normalizedPath = path5.startsWith("/") ? path5 : `/${path5}`;
68770
+ if (!this.session) {
68771
+ return normalizedPath;
68772
+ }
68773
+ const separator = normalizedPath.includes("?") ? "&" : "?";
68774
+ return `${normalizedPath}${separator}session=${encodeURIComponent(this.session)}`;
68775
+ }
68776
+ async login() {
68777
+ const res = await this.post("/hidlogin.fcgi", {
68778
+ login: this.reader.username,
68779
+ password: decryptSecret(this.reader.password)
68780
+ });
68781
+ if (!res.data?.session) {
68782
+ throw new BadRequestError230("HID Amico login failed: missing session.");
68783
+ }
68784
+ this.session = res.data.session;
68785
+ return this.session;
68786
+ }
68787
+ async sessionIsValid() {
68788
+ if (!this.session) {
68789
+ await this.login();
68790
+ }
68791
+ const res = await this.post(this.url("/session_is_valid.fcgi"), {});
68792
+ return Boolean(res.data?.session_is_valid ?? res.data?.valid ?? true);
68793
+ }
68794
+ async getUserImage(hidUserId) {
68795
+ if (!this.session) {
68796
+ await this.login();
68797
+ }
68798
+ const path5 = this.url(`/user_get_image.fcgi?user_id=${encodeURIComponent(String(hidUserId))}`);
68799
+ const res = await this.get(path5, "arraybuffer");
68800
+ const contentType = String(res.headers?.["content-type"] || "");
68801
+ const buffer = Buffer.from(res.data);
68802
+ if (contentType.includes("application/json")) {
68803
+ const payload = JSON.parse(buffer.toString("utf8"));
68804
+ const image = payload.image || payload.photo || payload.data?.image || payload.data?.photo;
68805
+ if (!image) {
68806
+ throw new BadRequestError230("HID Amico user image response did not include an image.");
68807
+ }
68808
+ return {
68809
+ contentType: payload.contentType || payload.mimeType || "image/jpeg",
68810
+ base64: String(image).replace(/^data:image\/[a-zA-Z0-9.+-]+;base64,/, "")
68811
+ };
68812
+ }
68813
+ return {
68814
+ contentType: contentType || "image/jpeg",
68815
+ base64: buffer.toString("base64")
68816
+ };
68817
+ }
68818
+ async logout() {
68819
+ if (!this.session) {
68820
+ return;
68821
+ }
68822
+ const logoutUrl = this.url("/logout.fcgi");
68823
+ try {
68824
+ this.session = "";
68825
+ await this.post(logoutUrl, {});
68826
+ } catch {
68827
+ this.session = "";
68828
+ }
68829
+ }
68830
+ async createObjects(batch) {
68831
+ if (!this.session) {
68832
+ await this.login();
68833
+ }
68834
+ const res = await this.post(this.url("/create_objects.fcgi"), {
68835
+ object: batch.object,
68836
+ values: batch.values
68837
+ });
68838
+ return res.data;
68839
+ }
68840
+ async loadObjects(query) {
68841
+ if (!this.session) {
68842
+ await this.login();
68843
+ }
68844
+ const res = await this.post(this.url("/load_objects.fcgi"), query);
68845
+ return res.data;
68846
+ }
68847
+ async modifyObjects(payload) {
68848
+ if (!this.session) {
68849
+ await this.login();
68850
+ }
68851
+ const res = await this.post(this.url("/modify_objects.fcgi"), payload);
68852
+ return res.data;
68853
+ }
68854
+ async destroyObjects(payload) {
68855
+ if (!this.session) {
68856
+ await this.login();
68857
+ }
68858
+ const res = await this.post(this.url("/destroy_objects.fcgi"), payload);
68859
+ return res.data;
68860
+ }
68861
+ async doorState() {
68862
+ if (!this.session) {
68863
+ await this.login();
68864
+ }
68865
+ const res = await this.post(this.url("/door_state.fcgi"), {});
68866
+ return res.data;
68867
+ }
68868
+ async executeActions(actions) {
68869
+ if (!this.session) {
68870
+ await this.login();
68871
+ }
68872
+ const res = await this.post(this.url("/execute_actions.fcgi"), { actions });
68873
+ return res.data;
68874
+ }
68875
+ async getConfiguration(payload) {
68876
+ if (!this.session) {
68877
+ await this.login();
68878
+ }
68879
+ const res = await this.post(this.url("/get_configuration.fcgi"), payload);
68880
+ return res.data;
68881
+ }
68882
+ async setConfiguration(payload) {
68883
+ if (!this.session) {
68884
+ await this.login();
68885
+ }
68886
+ const res = await this.post(this.url("/set_configuration.fcgi"), payload);
68887
+ return res.data;
68888
+ }
68889
+ };
68890
+ function normalizeBatches(payload) {
68891
+ if (Array.isArray(payload?.objects)) {
68892
+ return payload.objects.filter((batch) => batch?.object && Array.isArray(batch?.values));
68893
+ }
68894
+ const batches = [];
68895
+ const mappings = [
68896
+ ["users", "users"],
68897
+ ["cards", "cards"],
68898
+ ["qrcodes", "qrcodes"],
68899
+ ["pins", "pins"]
68900
+ ];
68901
+ mappings.forEach(([key, object]) => {
68902
+ if (Array.isArray(payload?.[key]) && payload[key].length) {
68903
+ batches.push({ object, values: payload[key] });
68904
+ }
68905
+ });
68906
+ return batches;
68907
+ }
68908
+ function firstValue(payload, keys) {
68909
+ for (const key of keys) {
68910
+ const value = payload?.[key];
68911
+ if (value !== void 0 && value !== null && value !== "") {
68912
+ return value;
68913
+ }
68914
+ }
68915
+ return void 0;
68916
+ }
68917
+ function extractIdentityKeys(payload) {
68918
+ const nested = payload?.user || payload?.person || payload?.data || {};
68919
+ const merged = { ...payload, ...nested };
68920
+ return {
68921
+ hidUserId: firstValue(merged, ["hidUserId", "hid_user_id", "user_id", "userId", "id", "user"]),
68922
+ registration: firstValue(merged, ["registration", "register", "employeeNo", "staffNo", "memberNo"]),
68923
+ cardNo: firstValue(merged, ["cardNo", "card_no", "card", "cardNumber", "value"])
68924
+ };
68925
+ }
68926
+ function useHidAmicoService() {
68927
+ const repo = useHidAmicoRepo();
68928
+ async function getActiveReader(id) {
68929
+ const reader = await repo.getById(id, { includePassword: true });
68930
+ if (reader.enabled === false || reader.status === "inactive" || reader.status === "deleted") {
68931
+ throw new BadRequestError230("HID Amico reader is not active.");
68932
+ }
68933
+ return reader;
68934
+ }
68935
+ async function createReader(value) {
68936
+ return repo.add({
68937
+ ...value,
68938
+ baseUrl: value.baseUrl.replace(/\/+$/, ""),
68939
+ password: encryptSecret(value.password)
68940
+ });
68941
+ }
68942
+ async function updateReader(id, value) {
68943
+ const payload = { ...value };
68944
+ if (payload.password) {
68945
+ payload.password = encryptSecret(payload.password);
68946
+ } else {
68947
+ delete payload.password;
68948
+ }
68949
+ return repo.updateById(id, payload);
68950
+ }
68951
+ async function listReaders(value) {
68952
+ return repo.list(value);
68953
+ }
68954
+ async function deleteReader(id) {
68955
+ return repo.markDeleted(id);
68956
+ }
68957
+ async function testReader(id) {
68958
+ const reader = await repo.getById(id, { includePassword: true });
68959
+ const client = new HidAmicoClient(reader);
68960
+ try {
68961
+ await client.login();
68962
+ const valid = await client.sessionIsValid();
68963
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date(), lastSyncMessage: "Connection test succeeded." });
68964
+ await repo.addEvent({ reader: id, site: reader.site, type: "test", payload: { valid } });
68965
+ return { valid, message: "HID Amico connection test succeeded." };
68966
+ } catch (error) {
68967
+ await repo.updateById(id, {
68968
+ status: "offline",
68969
+ lastSyncAt: /* @__PURE__ */ new Date(),
68970
+ lastSyncStatus: "failed",
68971
+ lastSyncMessage: error.message
68972
+ });
68973
+ await repo.addEvent({ reader: id, site: reader.site, type: "test_failed", payload: { message: error.message } });
68974
+ throw error;
68975
+ } finally {
68976
+ await client.logout();
68977
+ }
68978
+ }
68979
+ async function syncReader(id, payload) {
68980
+ const reader = await getActiveReader(id);
68981
+ const batches = normalizeBatches(payload);
68982
+ const client = new HidAmicoClient(reader);
68983
+ const results = [];
68984
+ await repo.updateById(id, { lastSyncStatus: "running", lastSyncMessage: "Sync started." });
68985
+ try {
68986
+ await client.login();
68987
+ for (const batch of batches) {
68988
+ const result = await client.createObjects(batch);
68989
+ results.push({ object: batch.object, count: batch.values.length, result });
68990
+ }
68991
+ const message = batches.length ? `Synced ${batches.length} HID object batch(es).` : "HID reader session verified. No sync payload was supplied.";
68992
+ await repo.updateById(id, {
68993
+ lastSeenAt: /* @__PURE__ */ new Date(),
68994
+ lastSyncAt: /* @__PURE__ */ new Date(),
68995
+ lastSyncStatus: "completed",
68996
+ lastSyncMessage: message
68997
+ });
68998
+ await repo.addEvent({ reader: id, site: reader.site, type: "sync", payload: { message, results } });
68999
+ return { message, results };
69000
+ } catch (error) {
69001
+ await repo.updateById(id, {
69002
+ status: "offline",
69003
+ lastSyncAt: /* @__PURE__ */ new Date(),
69004
+ lastSyncStatus: "failed",
69005
+ lastSyncMessage: error.message
69006
+ });
69007
+ await repo.addEvent({ reader: id, site: reader.site, type: "sync_failed", payload: { message: error.message } });
69008
+ throw error;
69009
+ } finally {
69010
+ await client.logout();
69011
+ }
69012
+ }
69013
+ async function receiveNotification(readerId, type, payload) {
69014
+ const reader = await repo.getById(readerId);
69015
+ const identityKeys = extractIdentityKeys(payload);
69016
+ const identity = await repo.findIdentity({
69017
+ reader: readerId,
69018
+ ...identityKeys
69019
+ });
69020
+ const enrichedPayload = identity ? {
69021
+ ...payload,
69022
+ identity: {
69023
+ _id: identity._id,
69024
+ type: identity.type,
69025
+ hidUserId: identity.hidUserId,
69026
+ registration: identity.registration,
69027
+ cardNo: identity.cardNo,
69028
+ person: identity.person,
69029
+ user: identity.user,
69030
+ member: identity.member,
69031
+ visitor: identity.visitor
69032
+ }
69033
+ } : {
69034
+ ...payload,
69035
+ identity: null,
69036
+ identityLookup: identityKeys
69037
+ };
69038
+ await repo.updateById(readerId, { lastSeenAt: /* @__PURE__ */ new Date() });
69039
+ return repo.addEvent({
69040
+ reader: readerId,
69041
+ site: reader.site,
69042
+ type,
69043
+ payload: enrichedPayload,
69044
+ status: identity ? "processed" : "received"
69045
+ });
69046
+ }
69047
+ async function listLogs(value) {
69048
+ return repo.listEvents(value);
69049
+ }
69050
+ async function listIdentities(value) {
69051
+ return repo.listIdentities(value);
69052
+ }
69053
+ async function createIdentity(readerId, value) {
69054
+ const reader = await repo.getById(readerId);
69055
+ return repo.addIdentity({
69056
+ ...value,
69057
+ reader: readerId,
69058
+ site: value.site || reader?.site?.toString()
69059
+ });
69060
+ }
69061
+ async function updateIdentity(identityId, value) {
69062
+ return repo.updateIdentity(identityId, value);
69063
+ }
69064
+ async function deleteIdentity(identityId) {
69065
+ return repo.deleteIdentity(identityId);
69066
+ }
69067
+ async function runObjectOperation(id, operation, payload) {
69068
+ const reader = await getActiveReader(id);
69069
+ const client = new HidAmicoClient(reader);
69070
+ try {
69071
+ await client.login();
69072
+ let result;
69073
+ if (operation === "load") {
69074
+ result = await client.loadObjects(payload);
69075
+ } else if (operation === "create") {
69076
+ result = await client.createObjects(payload);
69077
+ } else if (operation === "modify") {
69078
+ result = await client.modifyObjects(payload);
69079
+ } else {
69080
+ result = await client.destroyObjects(payload);
69081
+ }
69082
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
69083
+ await repo.addEvent({ reader: id, site: reader.site, type: `objects_${operation}`, payload: { request: payload, result } });
69084
+ return result;
69085
+ } catch (error) {
69086
+ await repo.addEvent({ reader: id, site: reader.site, type: `objects_${operation}_failed`, payload: { request: payload, message: error.message } });
69087
+ throw error;
69088
+ } finally {
69089
+ await client.logout();
69090
+ }
69091
+ }
69092
+ async function getUserImage(readerId, hidUserId) {
69093
+ const reader = await getActiveReader(readerId);
69094
+ const client = new HidAmicoClient(reader);
69095
+ try {
69096
+ await client.login();
69097
+ return await client.getUserImage(hidUserId);
69098
+ } finally {
69099
+ await client.logout();
69100
+ }
69101
+ }
69102
+ async function getDoorState(id) {
69103
+ const reader = await getActiveReader(id);
69104
+ const client = new HidAmicoClient(reader);
69105
+ try {
69106
+ await client.login();
69107
+ const state = await client.doorState();
69108
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
69109
+ await repo.addEvent({ reader: id, site: reader.site, type: "door_state", payload: state });
69110
+ return state;
69111
+ } finally {
69112
+ await client.logout();
69113
+ }
69114
+ }
69115
+ async function executeActions(id, actions) {
69116
+ const reader = await getActiveReader(id);
69117
+ const client = new HidAmicoClient(reader);
69118
+ try {
69119
+ await client.login();
69120
+ const result = await client.executeActions(actions);
69121
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
69122
+ await repo.addEvent({ reader: id, site: reader.site, type: "execute_actions", payload: { actions, result } });
69123
+ return result;
69124
+ } catch (error) {
69125
+ await repo.addEvent({ reader: id, site: reader.site, type: "execute_actions_failed", payload: { actions, message: error.message } });
69126
+ throw error;
69127
+ } finally {
69128
+ await client.logout();
69129
+ }
69130
+ }
69131
+ async function getConfiguration(id, payload) {
69132
+ const reader = await getActiveReader(id);
69133
+ const client = new HidAmicoClient(reader);
69134
+ try {
69135
+ await client.login();
69136
+ const result = await client.getConfiguration(payload);
69137
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
69138
+ await repo.addEvent({ reader: id, site: reader.site, type: "configuration", payload: { request: payload, result } });
69139
+ return result;
69140
+ } catch (error) {
69141
+ await repo.addEvent({ reader: id, site: reader.site, type: "configuration_failed", payload: { request: payload, message: error.message } });
69142
+ throw error;
69143
+ } finally {
69144
+ await client.logout();
69145
+ }
69146
+ }
69147
+ async function setConfiguration(id, payload) {
69148
+ const reader = await getActiveReader(id);
69149
+ const client = new HidAmicoClient(reader);
69150
+ try {
69151
+ await client.login();
69152
+ const result = await client.setConfiguration(payload);
69153
+ await repo.updateById(id, { lastSeenAt: /* @__PURE__ */ new Date() });
69154
+ await repo.addEvent({ reader: id, site: reader.site, type: "set_configuration", payload: { request: payload, result } });
69155
+ return result;
69156
+ } catch (error) {
69157
+ await repo.addEvent({ reader: id, site: reader.site, type: "set_configuration_failed", payload: { request: payload, message: error.message } });
69158
+ throw error;
69159
+ } finally {
69160
+ await client.logout();
69161
+ }
69162
+ }
69163
+ return {
69164
+ listReaders,
69165
+ createReader,
69166
+ updateReader,
69167
+ deleteReader,
69168
+ testReader,
69169
+ syncReader,
69170
+ receiveNotification,
69171
+ listLogs,
69172
+ listIdentities,
69173
+ createIdentity,
69174
+ updateIdentity,
69175
+ deleteIdentity,
69176
+ runObjectOperation,
69177
+ getUserImage,
69178
+ getDoorState,
69179
+ executeActions,
69180
+ getConfiguration,
69181
+ setConfiguration
69182
+ };
69183
+ }
69184
+
69185
+ // src/controllers/hid-amico.controller.ts
69186
+ import { BadRequestError as BadRequestError231 } from "@7365admin1/node-server-utils";
69187
+ function useHidAmicoController() {
69188
+ const service = useHidAmicoService();
69189
+ async function listReaders(req, res, next) {
69190
+ const { error, value } = schemaHidAmicoReaderListQuery.validate(req.query);
69191
+ if (error) {
69192
+ next(new BadRequestError231(error.message));
69193
+ return;
69194
+ }
69195
+ try {
69196
+ res.json(await service.listReaders(value));
69197
+ } catch (error2) {
69198
+ next(error2);
69199
+ }
69200
+ }
69201
+ async function createReader(req, res, next) {
69202
+ const { error, value } = schemaHidAmicoReader.validate(req.body);
69203
+ if (error) {
69204
+ next(new BadRequestError231(error.message));
69205
+ return;
69206
+ }
69207
+ try {
69208
+ res.status(201).json({ data: await service.createReader(value) });
69209
+ } catch (error2) {
69210
+ next(error2);
69211
+ }
69212
+ }
69213
+ async function updateReader(req, res, next) {
69214
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69215
+ const body = schemaUpdateHidAmicoReader.validate(req.body);
69216
+ if (params.error || body.error) {
69217
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69218
+ return;
69219
+ }
69220
+ try {
69221
+ res.json({ data: await service.updateReader(params.value.readerId, body.value) });
69222
+ } catch (error) {
69223
+ next(error);
69224
+ }
69225
+ }
69226
+ async function deleteReader(req, res, next) {
69227
+ const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
69228
+ if (error) {
69229
+ next(new BadRequestError231(error.message));
69230
+ return;
69231
+ }
69232
+ try {
69233
+ res.json({ data: await service.deleteReader(value.readerId), message: "HID Amico reader deleted." });
69234
+ } catch (error2) {
69235
+ next(error2);
69236
+ }
69237
+ }
69238
+ async function testReader(req, res, next) {
69239
+ const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
69240
+ if (error) {
69241
+ next(new BadRequestError231(error.message));
69242
+ return;
69243
+ }
69244
+ try {
69245
+ res.json({ data: await service.testReader(value.readerId) });
69246
+ } catch (error2) {
69247
+ next(error2);
69248
+ }
69249
+ }
69250
+ async function syncReader(req, res, next) {
69251
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69252
+ const body = schemaHidAmicoSync.validate(req.body ?? {});
69253
+ if (params.error || body.error) {
69254
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69255
+ return;
69256
+ }
69257
+ try {
69258
+ res.json({ data: await service.syncReader(params.value.readerId, body.value) });
69259
+ } catch (error) {
69260
+ next(error);
69261
+ }
69262
+ }
69263
+ async function listLogs(req, res, next) {
69264
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69265
+ const query = schemaHidAmicoLogQuery.validate(req.query);
69266
+ if (params.error || query.error) {
69267
+ next(new BadRequestError231(params.error?.message || query.error?.message));
69268
+ return;
69269
+ }
69270
+ try {
69271
+ res.json(await service.listLogs({ reader: params.value.readerId, ...query.value }));
69272
+ } catch (error) {
69273
+ next(error);
69274
+ }
69275
+ }
69276
+ async function listIdentities(req, res, next) {
69277
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69278
+ const query = schemaHidAmicoIdentityQuery.validate(req.query);
69279
+ if (params.error || query.error) {
69280
+ next(new BadRequestError231(params.error?.message || query.error?.message));
69281
+ return;
69282
+ }
69283
+ try {
69284
+ res.json(await service.listIdentities({ reader: params.value.readerId, ...query.value }));
69285
+ } catch (error) {
69286
+ next(error);
69287
+ }
69288
+ }
69289
+ async function createIdentity(req, res, next) {
69290
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69291
+ if (params.error) {
69292
+ next(new BadRequestError231(params.error.message));
69293
+ return;
69294
+ }
69295
+ try {
69296
+ const body = schemaCreateHidAmicoIdentity.validate(req.body);
69297
+ if (body.error) {
69298
+ next(new BadRequestError231(body.error.message));
69299
+ return;
69300
+ }
69301
+ res.status(201).json({ data: await service.createIdentity(params.value.readerId, body.value) });
69302
+ } catch (error) {
69303
+ next(error);
69304
+ }
69305
+ }
69306
+ async function updateIdentity(req, res, next) {
69307
+ const params = schemaHidAmicoIdentityIdParams.validate(req.params);
69308
+ const body = schemaUpdateHidAmicoIdentity.validate(req.body ?? {});
69309
+ if (params.error || body.error) {
69310
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69311
+ return;
69312
+ }
69313
+ try {
69314
+ res.json({ data: await service.updateIdentity(params.value.identityId, body.value) });
69315
+ } catch (error) {
69316
+ next(error);
69317
+ }
69318
+ }
69319
+ async function deleteIdentity(req, res, next) {
69320
+ const { error, value } = schemaHidAmicoIdentityIdParams.validate(req.params);
69321
+ if (error) {
69322
+ next(new BadRequestError231(error.message));
69323
+ return;
69324
+ }
69325
+ try {
69326
+ res.json({ data: await service.deleteIdentity(value.identityId), message: "HID Amico identity deleted." });
69327
+ } catch (error2) {
69328
+ next(error2);
69329
+ }
69330
+ }
69331
+ async function receiveNotification(req, res, next) {
69332
+ const validation = schemaHidAmicoNotificationParams.validate(req.params);
69333
+ if (validation.error) {
69334
+ next(new BadRequestError231(validation.error.message));
69335
+ return;
69336
+ }
69337
+ try {
69338
+ const event = await service.receiveNotification(
69339
+ validation.value.readerId,
69340
+ validation.value.type,
69341
+ req.body ?? {}
69342
+ );
69343
+ res.status(202).json({ data: event });
69344
+ } catch (error) {
69345
+ next(error);
69346
+ }
69347
+ }
69348
+ async function getDoorState(req, res, next) {
69349
+ const { error, value } = schemaHidAmicoReaderIdParams.validate(req.params);
69350
+ if (error) {
69351
+ next(new BadRequestError231(error.message));
69352
+ return;
69353
+ }
69354
+ try {
69355
+ res.json({ data: await service.getDoorState(value.readerId) });
69356
+ } catch (error2) {
69357
+ next(error2);
69358
+ }
69359
+ }
69360
+ async function getUserImage(req, res, next) {
69361
+ const { error, value } = schemaHidAmicoUserImageParams.validate(req.params);
69362
+ if (error) {
69363
+ next(new BadRequestError231(error.message));
69364
+ return;
69365
+ }
69366
+ try {
69367
+ const image = await service.getUserImage(value.readerId, value.hidUserId);
69368
+ res.json({ data: image });
69369
+ } catch (error2) {
69370
+ next(error2);
69371
+ }
69372
+ }
69373
+ async function executeActions(req, res, next) {
69374
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69375
+ const body = schemaHidAmicoExecuteActions.validate(req.body ?? {});
69376
+ if (params.error || body.error) {
69377
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69378
+ return;
69379
+ }
69380
+ try {
69381
+ res.json({ data: await service.executeActions(params.value.readerId, body.value.actions) });
69382
+ } catch (error) {
69383
+ next(error);
69384
+ }
69385
+ }
69386
+ async function getConfiguration(req, res, next) {
69387
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69388
+ const body = schemaHidAmicoConfiguration.validate(req.body ?? {});
69389
+ if (params.error || body.error) {
69390
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69391
+ return;
69392
+ }
69393
+ try {
69394
+ res.json({ data: await service.getConfiguration(params.value.readerId, body.value) });
69395
+ } catch (error) {
69396
+ next(error);
69397
+ }
69398
+ }
69399
+ async function setConfiguration(req, res, next) {
69400
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69401
+ const body = schemaHidAmicoSetConfiguration.validate(req.body ?? {});
69402
+ if (params.error || body.error) {
69403
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69404
+ return;
69405
+ }
69406
+ try {
69407
+ res.json({ data: await service.setConfiguration(params.value.readerId, body.value) });
69408
+ } catch (error) {
69409
+ next(error);
69410
+ }
69411
+ }
69412
+ async function runObjectOperation(req, res, next) {
69413
+ const params = schemaHidAmicoReaderIdParams.validate(req.params);
69414
+ const body = schemaHidAmicoObjectOperation.validate(req.body ?? {});
69415
+ if (params.error || body.error) {
69416
+ next(new BadRequestError231(params.error?.message || body.error?.message));
69417
+ return;
69418
+ }
69419
+ const { operation, ...payload } = body.value;
69420
+ if (operation === "create" && !Array.isArray(payload.values)) {
69421
+ next(new BadRequestError231("values array is required for HID object create operations."));
69422
+ return;
69423
+ }
69424
+ if (operation === "modify" && (!payload.values || Array.isArray(payload.values) || !payload.where)) {
69425
+ next(new BadRequestError231("values object and where are required for HID object modify operations."));
69426
+ return;
69427
+ }
69428
+ if (operation === "destroy" && !payload.where) {
69429
+ next(new BadRequestError231("where is required for HID object destroy operations."));
69430
+ return;
69431
+ }
69432
+ try {
69433
+ res.json({ data: await service.runObjectOperation(params.value.readerId, operation, payload) });
69434
+ } catch (error) {
69435
+ next(error);
69436
+ }
69437
+ }
69438
+ return {
69439
+ listReaders,
69440
+ createReader,
69441
+ updateReader,
69442
+ deleteReader,
69443
+ testReader,
69444
+ syncReader,
69445
+ listLogs,
69446
+ listIdentities,
69447
+ createIdentity,
69448
+ updateIdentity,
69449
+ deleteIdentity,
69450
+ receiveNotification,
69451
+ getUserImage,
69452
+ getDoorState,
69453
+ executeActions,
69454
+ getConfiguration,
69455
+ setConfiguration,
69456
+ runObjectOperation
69457
+ };
69458
+ }
67781
69459
  export {
67782
69460
  ANPRMode,
67783
69461
  AccessTypeProps,
67784
69462
  AppServiceType,
69463
+ BidStatus,
69464
+ BidType,
67785
69465
  BuildingLevelStatus,
67786
69466
  BuildingStatus,
67787
69467
  BulletinOrder,
@@ -67813,6 +69493,7 @@ export {
67813
69493
  MAddress,
67814
69494
  MAttendance,
67815
69495
  MAttendanceSettings,
69496
+ MBidPreloved,
67816
69497
  MBillingConfiguration,
67817
69498
  MBillingItem,
67818
69499
  MBuilding,
@@ -67833,6 +69514,9 @@ export {
67833
69514
  MFile,
67834
69515
  MFormEntry,
67835
69516
  MGuestManagement,
69517
+ MHidAmicoEvent,
69518
+ MHidAmicoIdentity,
69519
+ MHidAmicoReader,
67836
69520
  MIncidentReport,
67837
69521
  MManpowerDesignations,
67838
69522
  MManpowerMonitoring,
@@ -67952,6 +69636,7 @@ export {
67952
69636
  schema,
67953
69637
  schemaApprovedBy,
67954
69638
  schemaApprover,
69639
+ schemaBidPreloved,
67955
69640
  schemaBilling,
67956
69641
  schemaBillingConfiguration,
67957
69642
  schemaBillingItem,
@@ -67964,6 +69649,7 @@ export {
67964
69649
  schemaCategoryPreloved,
67965
69650
  schemaChannelPreloved,
67966
69651
  schemaChatPreloved,
69652
+ schemaCreateHidAmicoIdentity,
67967
69653
  schemaCustomerSite,
67968
69654
  schemaDocumentManagement,
67969
69655
  schemaEntryPassSettings,
@@ -67971,6 +69657,21 @@ export {
67971
69657
  schemaFiles,
67972
69658
  schemaFormEntry,
67973
69659
  schemaGuestManagement,
69660
+ schemaHidAmicoConfiguration,
69661
+ schemaHidAmicoEvent,
69662
+ schemaHidAmicoExecuteActions,
69663
+ schemaHidAmicoIdentity,
69664
+ schemaHidAmicoIdentityIdParams,
69665
+ schemaHidAmicoIdentityQuery,
69666
+ schemaHidAmicoLogQuery,
69667
+ schemaHidAmicoNotificationParams,
69668
+ schemaHidAmicoObjectOperation,
69669
+ schemaHidAmicoReader,
69670
+ schemaHidAmicoReaderIdParams,
69671
+ schemaHidAmicoReaderListQuery,
69672
+ schemaHidAmicoSetConfiguration,
69673
+ schemaHidAmicoSync,
69674
+ schemaHidAmicoUserImageParams,
67974
69675
  schemaIncidentReport,
67975
69676
  schemaMultipleDocumentManagement,
67976
69677
  schemaNfcPatrolLog,
@@ -67998,6 +69699,7 @@ export {
67998
69699
  schemaStatementOfAccount,
67999
69700
  schemaSubcategoryPreloved,
68000
69701
  schemaUnitBilling,
69702
+ schemaUpdateBidPreloved,
68001
69703
  schemaUpdateBuildingLevel,
68002
69704
  schemaUpdateBulletinBoard,
68003
69705
  schemaUpdateBulletinVideo,
@@ -68008,6 +69710,8 @@ export {
68008
69710
  schemaUpdateEventManagement,
68009
69711
  schemaUpdateFormEntry,
68010
69712
  schemaUpdateGuestManagement,
69713
+ schemaUpdateHidAmicoIdentity,
69714
+ schemaUpdateHidAmicoReader,
68011
69715
  schemaUpdateIncidentReport,
68012
69716
  schemaUpdateOccurrenceBook,
68013
69717
  schemaUpdateOccurrenceEntry,
@@ -68053,6 +69757,8 @@ export {
68053
69757
  useAuthControllerV2,
68054
69758
  useAuthService,
68055
69759
  useAuthServiceV2,
69760
+ useBidPrelovedController,
69761
+ useBidPrelovedRepo,
68056
69762
  useBuildingController,
68057
69763
  useBuildingLevelController,
68058
69764
  useBuildingLevelRepo,
@@ -68075,6 +69781,7 @@ export {
68075
69781
  useChatController,
68076
69782
  useChatPrelovedController,
68077
69783
  useChatPrelovedRepo,
69784
+ useChatPrelovedService,
68078
69785
  useChatRepo,
68079
69786
  useCounterModel,
68080
69787
  useCounterRepo,
@@ -68105,6 +69812,9 @@ export {
68105
69812
  useGuestManagementController,
68106
69813
  useGuestManagementRepo,
68107
69814
  useGuestManagementService,
69815
+ useHidAmicoController,
69816
+ useHidAmicoRepo,
69817
+ useHidAmicoService,
68108
69818
  useHrmLabsAttendanceCtrl,
68109
69819
  useHrmLabsAttendanceSrvc,
68110
69820
  useIncidentReportController,