@7365admin1/core 2.25.0 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -104,6 +104,7 @@ __export(src_exports, {
104
104
  MVehicle: () => MVehicle,
105
105
  MVehicleTransaction: () => MVehicleTransaction,
106
106
  MVerification: () => MVerification,
107
+ MVerificationV2: () => MVerificationV2,
107
108
  MVisitorTransaction: () => MVisitorTransaction,
108
109
  MWorkOrder: () => MWorkOrder,
109
110
  OrgNature: () => OrgNature,
@@ -112,6 +113,7 @@ __export(src_exports, {
112
113
  PERSON_TYPES: () => PERSON_TYPES,
113
114
  PMDashboardCollection: () => PMDashboardCollection,
114
115
  Period: () => Period,
116
+ PersonStatus: () => PersonStatus,
115
117
  PersonTypes: () => PersonTypes,
116
118
  SiteCategories: () => SiteCategories,
117
119
  SiteStatus: () => SiteStatus,
@@ -124,6 +126,7 @@ __export(src_exports, {
124
126
  VehicleSort: () => VehicleSort,
125
127
  VehicleStatus: () => VehicleStatus,
126
128
  VehicleType: () => VehicleType,
129
+ VerificationType: () => VerificationType,
127
130
  VisitorSort: () => VisitorSort,
128
131
  VisitorStatus: () => VisitorStatus,
129
132
  addressSchema: () => addressSchema,
@@ -248,6 +251,7 @@ __export(src_exports, {
248
251
  useAttendanceSettingsRepository: () => useAttendanceSettingsRepository,
249
252
  useAttendanceSettingsService: () => useAttendanceSettingsService,
250
253
  useAuthController: () => useAuthController,
254
+ useAuthControllerV2: () => useAuthControllerV2,
251
255
  useAuthService: () => useAuthService,
252
256
  useBuildingController: () => useBuildingController,
253
257
  useBuildingRepo: () => useBuildingRepo,
@@ -401,7 +405,9 @@ __export(src_exports, {
401
405
  useVehicleService: () => useVehicleService,
402
406
  useVerificationController: () => useVerificationController,
403
407
  useVerificationRepo: () => useVerificationRepo,
408
+ useVerificationRepoV2: () => useVerificationRepoV2,
404
409
  useVerificationService: () => useVerificationService,
410
+ useVerificationServiceV2: () => useVerificationServiceV2,
405
411
  useVisitorTransactionController: () => useVisitorTransactionController,
406
412
  useVisitorTransactionRepo: () => useVisitorTransactionRepo,
407
413
  useVisitorTransactionService: () => useVisitorTransactionService,
@@ -4518,7 +4524,9 @@ var siteSchema = import_joi9.default.object({
4518
4524
  category: import_joi9.default.string().valid(...Object.values(SiteCategories)).default("commercial" /* COMMERCIAL */),
4519
4525
  deliveryCompanyList: import_joi9.default.array().items(import_joi9.default.string()).optional().allow(null),
4520
4526
  isOpenGate: import_joi9.default.boolean().optional().default(false),
4521
- dahuaTimeExpiration: import_joi9.default.number().optional().allow(null)
4527
+ dahuaTimeExpiration: import_joi9.default.number().optional().allow(null),
4528
+ siteDocs: import_joi9.default.array().items(import_joi9.default.string().hex().length(24).allow(null, "")),
4529
+ unitDocs: import_joi9.default.array().items(import_joi9.default.string().hex().length(24).allow(null, ""))
4522
4530
  });
4523
4531
  var updateSiteSchema = import_joi9.default.object({
4524
4532
  _id: import_joi9.default.string().hex().length(24).required(),
@@ -4526,7 +4534,9 @@ var updateSiteSchema = import_joi9.default.object({
4526
4534
  metadata: metadataSchema3.optional(),
4527
4535
  deliveryCompanyList: import_joi9.default.array().items(import_joi9.default.string().trim()).optional().allow(null),
4528
4536
  isOpenGate: import_joi9.default.boolean().optional().allow(null),
4529
- dahuaTimeExpiration: import_joi9.default.number().optional().allow(null)
4537
+ dahuaTimeExpiration: import_joi9.default.number().optional().allow(null),
4538
+ siteDocs: import_joi9.default.array().items(import_joi9.default.string().hex().length(24).allow(null, "")),
4539
+ unitDocs: import_joi9.default.array().items(import_joi9.default.string().hex().length(24).allow(null, ""))
4530
4540
  });
4531
4541
  function MSite(value) {
4532
4542
  const { error } = siteSchema.validate(value);
@@ -4553,6 +4563,8 @@ function MSite(value) {
4553
4563
  deliveryCompanyList: value.deliveryCompanyList ?? [],
4554
4564
  isOpenGate: value.isOpenGate,
4555
4565
  dahuaTimeExpiration: value.dahuaTimeExpiration,
4566
+ siteDocs: value.siteDocs ?? [],
4567
+ unitDocs: value.unitDocs ?? [],
4556
4568
  updatedAt: value.updatedAt ?? "",
4557
4569
  deletedAt: value.deletedAt ?? ""
4558
4570
  };
@@ -8743,7 +8755,7 @@ var import_node_server_utils41 = require("@7365admin1/node-server-utils");
8743
8755
  var import_zod = require("zod");
8744
8756
  var import_mongodb25 = require("mongodb");
8745
8757
  var import_node_server_utils40 = require("@7365admin1/node-server-utils");
8746
- function toObjectId2(value) {
8758
+ function toObjectId3(value) {
8747
8759
  if (typeof value === "string") {
8748
8760
  if (!/^[a-fA-F0-9]{24}$/.test(value)) {
8749
8761
  throw new import_node_server_utils40.BadRequestError(`Invalid ObjectId format: ${value}`);
@@ -8795,7 +8807,7 @@ var TInvoice = import_zod.z.object({
8795
8807
  message: "Invalid ObjectId: Must be a 24-character hex string."
8796
8808
  }),
8797
8809
  import_zod.z.instanceof(import_mongodb25.ObjectId, { message: "Invalid ObjectId instance." })
8798
- ]).optional().transform((val) => val ? toObjectId2(val) : void 0),
8810
+ ]).optional().transform((val) => val ? toObjectId3(val) : void 0),
8799
8811
  invoiceNumber: import_zod.z.string({ required_error: "Invoice number is required." }),
8800
8812
  type: TInvoiceType.default("other"),
8801
8813
  amount: import_zod.z.number().min(0, { message: "Invoice amount must be at least 0." }),
@@ -12953,17 +12965,22 @@ var import_mongodb38 = require("mongodb");
12953
12965
  var import_node_server_utils66 = require("@7365admin1/node-server-utils");
12954
12966
  var import_joi35 = __toESM(require("joi"));
12955
12967
  var import_mongodb37 = require("mongodb");
12956
- var PersonTypes = /* @__PURE__ */ ((PersonTypes2) => {
12957
- PersonTypes2["WALK_IN"] = "walk-in";
12958
- PersonTypes2["DROP_OFF"] = "drop-off";
12959
- PersonTypes2["CONTRACTOR"] = "contractor";
12960
- PersonTypes2["DELIVERY"] = "delivery";
12961
- PersonTypes2["PICK_UP"] = "pick-up";
12962
- PersonTypes2["GUEST"] = "guest";
12963
- PersonTypes2["TENANT"] = "tenant";
12964
- PersonTypes2["RESIDENT"] = "resident";
12965
- return PersonTypes2;
12968
+ var PersonTypes = /* @__PURE__ */ ((PersonTypes3) => {
12969
+ PersonTypes3["WALK_IN"] = "walk-in";
12970
+ PersonTypes3["DROP_OFF"] = "drop-off";
12971
+ PersonTypes3["CONTRACTOR"] = "contractor";
12972
+ PersonTypes3["DELIVERY"] = "delivery";
12973
+ PersonTypes3["PICK_UP"] = "pick-up";
12974
+ PersonTypes3["GUEST"] = "guest";
12975
+ PersonTypes3["TENANT"] = "tenant";
12976
+ PersonTypes3["RESIDENT"] = "resident";
12977
+ return PersonTypes3;
12966
12978
  })(PersonTypes || {});
12979
+ var PersonStatus = /* @__PURE__ */ ((PersonStatus2) => {
12980
+ PersonStatus2["ACTIVE"] = "active";
12981
+ PersonStatus2["DELETED"] = "deleted";
12982
+ return PersonStatus2;
12983
+ })(PersonStatus || {});
12967
12984
  var PERSON_TYPES = [
12968
12985
  "walk-in",
12969
12986
  "drop-off",
@@ -13682,7 +13699,8 @@ var vehicleSchema = import_joi37.default.object({
13682
13699
  start: import_joi37.default.date().optional().allow("", null),
13683
13700
  end: import_joi37.default.date().optional().allow("", null),
13684
13701
  unitName: import_joi37.default.string().optional().allow("", null),
13685
- status: import_joi37.default.string().optional().valid(...Object.values(VehicleStatus)).allow("")
13702
+ status: import_joi37.default.string().optional().valid(...Object.values(VehicleStatus)).allow(""),
13703
+ peopleId: import_joi37.default.string().hex().length(24).optional().allow(null, "")
13686
13704
  });
13687
13705
  function MVehicle(value) {
13688
13706
  const { error } = vehicleSchema.validate(value);
@@ -13711,6 +13729,13 @@ function MVehicle(value) {
13711
13729
  throw new import_node_server_utils68.BadRequestError("Invalid building unit ID format.");
13712
13730
  }
13713
13731
  }
13732
+ if (value.peopleId) {
13733
+ try {
13734
+ value.peopleId = new import_mongodb40.ObjectId(value.peopleId);
13735
+ } catch (error2) {
13736
+ throw new import_node_server_utils68.BadRequestError("Invalid building unit ID format.");
13737
+ }
13738
+ }
13714
13739
  const createdAtDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
13715
13740
  const expiredDate = new Date(createdAtDate);
13716
13741
  expiredDate.setFullYear(expiredDate.getFullYear() + 10);
@@ -13735,6 +13760,7 @@ function MVehicle(value) {
13735
13760
  end: value.end ?? expiredAt,
13736
13761
  status: value.status ?? "active" /* ACTIVE */,
13737
13762
  unitName: value.unitName ?? "",
13763
+ peopleId: value.peopleId ?? "",
13738
13764
  createdAt,
13739
13765
  updatedAt: value.updatedAt ?? "",
13740
13766
  deletedAt: value.deletedAt ?? ""
@@ -14886,7 +14912,7 @@ function usePersonRepo() {
14886
14912
  }
14887
14913
  async function getPeopleByUnit({
14888
14914
  status = "active",
14889
- type,
14915
+ type = [],
14890
14916
  unit
14891
14917
  }, session) {
14892
14918
  const cacheKey = (0, import_node_server_utils70.makeCacheKey)(site_people_namespace_collection, {
@@ -14895,13 +14921,20 @@ function usePersonRepo() {
14895
14921
  type,
14896
14922
  key: "get-residents-by-unit"
14897
14923
  });
14924
+ const cacheData = await getCache(cacheKey);
14925
+ if (cacheData) {
14926
+ import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14927
+ return cacheData;
14928
+ }
14898
14929
  try {
14899
- const cacheData = await getCache(cacheKey);
14900
- if (cacheData) {
14901
- import_node_server_utils70.logger.info(`Cache hit for key: ${cacheKey}`);
14902
- return cacheData;
14903
- }
14904
- const data = await collection.find({ unit, status, ...type && { type } }).sort({ _id: -1 }).toArray();
14930
+ const query = {
14931
+ unit,
14932
+ status,
14933
+ ...Array.isArray(type) && type.length > 0 && {
14934
+ type: { $in: type }
14935
+ }
14936
+ };
14937
+ const data = await collection.find(query).sort({ _id: -1 }).toArray();
14905
14938
  setCache(cacheKey, data, 15 * 60).then(() => {
14906
14939
  import_node_server_utils70.logger.info(`Cache set for key: ${cacheKey}`);
14907
14940
  }).catch((err) => {
@@ -15043,13 +15076,14 @@ function usePersonRepo() {
15043
15076
  throw new import_node_server_utils70.InternalServerError("Failed to retrieve person by NRIC.");
15044
15077
  }
15045
15078
  }
15046
- async function pushVehicleByNRIC(nric, plate, session) {
15079
+ async function pushVehicleById(id, plate, session) {
15047
15080
  const { plateNumber, recNo } = plate;
15048
15081
  const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
15082
+ const _id = (0, import_node_server_utils70.toObjectId)(id);
15049
15083
  try {
15050
15084
  const updateExisting = await collection.updateOne(
15051
15085
  {
15052
- nric,
15086
+ _id,
15053
15087
  "plates.plateNumber": plateNumber
15054
15088
  },
15055
15089
  {
@@ -15062,7 +15096,7 @@ function usePersonRepo() {
15062
15096
  );
15063
15097
  if (updateExisting.matchedCount === 0) {
15064
15098
  await collection.updateOne(
15065
- { nric },
15099
+ { _id },
15066
15100
  {
15067
15101
  $push: {
15068
15102
  plates: {
@@ -15154,7 +15188,7 @@ function usePersonRepo() {
15154
15188
  getCompany,
15155
15189
  getPeopleByPlateNumber,
15156
15190
  getPeopleByNRIC,
15157
- pushVehicleByNRIC,
15191
+ pushVehicleById,
15158
15192
  pullVehicleByRecNo,
15159
15193
  getByUserId
15160
15194
  };
@@ -15185,7 +15219,7 @@ function useVehicleService() {
15185
15219
  } = useDahuaService();
15186
15220
  const { getAllCameraWithPassword: _getAllSiteCameras } = useSiteCameraRepo();
15187
15221
  const { getById: _getById } = useOrgRepo();
15188
- const { pushVehicleByNRIC: _pushVehicleByNRIC } = usePersonRepo();
15222
+ const { pushVehicleById: _pushVehicleById } = usePersonRepo();
15189
15223
  const { pullVehicleByRecNo: _pullVehicleByRecNo } = usePersonRepo();
15190
15224
  async function add(value) {
15191
15225
  const session = import_node_server_utils71.useAtlas.getClient()?.startSession();
@@ -15292,9 +15326,9 @@ function useVehicleService() {
15292
15326
  }
15293
15327
  const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
15294
15328
  vehicleValue.recNo = responseData.split("=")[1]?.trim();
15295
- if (value.nric && vehicleValue.recNo) {
15296
- await _pushVehicleByNRIC(
15297
- value.nric,
15329
+ if (value.peopleId && vehicleValue.recNo) {
15330
+ await _pushVehicleById(
15331
+ value.peopleId,
15298
15332
  {
15299
15333
  plateNumber,
15300
15334
  recNo: vehicleValue.recNo
@@ -15454,9 +15488,9 @@ function useVehicleService() {
15454
15488
  value.recNo = responseData.split("=")[1]?.trim();
15455
15489
  }
15456
15490
  value.status = "active" /* ACTIVE */;
15457
- if (vehicle.nric && value.recNo) {
15458
- await _pushVehicleByNRIC(
15459
- vehicle.nric,
15491
+ if (vehicle.peopleId && value.recNo) {
15492
+ await _pushVehicleById(
15493
+ vehicle.peopleId,
15460
15494
  {
15461
15495
  plateNumber: _plateNumber,
15462
15496
  recNo: value.recNo
@@ -15571,9 +15605,9 @@ function useVehicleService() {
15571
15605
  value.recNo = responseData.split("=")[1]?.trim();
15572
15606
  }
15573
15607
  value.status = "active" /* ACTIVE */;
15574
- if (vehicle.nric && value.recNo) {
15575
- await _pushVehicleByNRIC(
15576
- vehicle.nric,
15608
+ if (vehicle.peopleId && value.recNo) {
15609
+ await _pushVehicleById(
15610
+ vehicle.peopleId,
15577
15611
  {
15578
15612
  plateNumber: _plateNumber,
15579
15613
  recNo: value.recNo
@@ -15610,7 +15644,7 @@ function useVehicleService() {
15610
15644
  const _start = vehicle.start;
15611
15645
  const _end = vehicle.end;
15612
15646
  const _recNo = plate.recNo;
15613
- const _type = plate.type;
15647
+ const _type = value.type ? value.type : plate.type;
15614
15648
  const { name, plateNumber, start, end, recNo, type, unit, site, ...rest } = value;
15615
15649
  const startDahua = value.start ? formatDahuaDate(new Date(value.start)) : formatDahuaDate(new Date(_start));
15616
15650
  const endDahua = value.end ? formatDahuaDate(new Date(value.end)) : formatDahuaDate(new Date(_end));
@@ -15638,20 +15672,60 @@ function useVehicleService() {
15638
15672
  }
15639
15673
  for (const camera of siteCameras) {
15640
15674
  const { host, username, password } = camera;
15641
- const dahuaPayload = {
15642
- host,
15643
- username,
15644
- password,
15645
- plateNumber: plateNumber ? plateNumber : _plateNumber,
15646
- recno: _recNo,
15647
- mode: _type === "TrafficBlackList" /* TRAFFIC_BLACKLIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */,
15648
- start: startDahua,
15649
- end: endDahua,
15650
- owner: name ? name : _name
15651
- };
15652
- const dahuaResponse = await _updatePlateNumber(dahuaPayload);
15653
- if (dahuaResponse?.statusCode !== 200) {
15654
- throw new import_node_server_utils71.BadRequestError("Failed to update plate number to ANPR");
15675
+ if (value.type) {
15676
+ const removePlateNumber = {
15677
+ host,
15678
+ username,
15679
+ password,
15680
+ mode: plate.type === "blocklist" /* BLOCKLIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */,
15681
+ //whitelist or blocklist
15682
+ recno: _recNo
15683
+ };
15684
+ const responseForDeletion = await _removePlateNumber(
15685
+ removePlateNumber
15686
+ );
15687
+ if (responseForDeletion?.statusCode !== 200) {
15688
+ throw new import_node_server_utils71.BadRequestError(
15689
+ "Failed to delete plate number to ANPR"
15690
+ );
15691
+ }
15692
+ const dahuaPayload = {
15693
+ host,
15694
+ username,
15695
+ password,
15696
+ plateNumber: _plateNumber,
15697
+ mode: value.type === "blocklist" /* BLOCKLIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */,
15698
+ //whitelist or blocklist
15699
+ owner: _name,
15700
+ ...startDahua ? { start: startDahua } : {},
15701
+ ...endDahua ? { end: endDahua } : {}
15702
+ };
15703
+ const dahuaResponse = await _addPlateNumber(dahuaPayload);
15704
+ if (dahuaResponse?.statusCode !== 200) {
15705
+ throw new import_node_server_utils71.BadRequestError(
15706
+ "Failed to update plate number to ANPR"
15707
+ );
15708
+ }
15709
+ const responseData = dahuaResponse?.data?.toString("utf-8") ?? "";
15710
+ value.recNo = responseData.split("=")[1]?.trim();
15711
+ } else {
15712
+ const dahuaPayload = {
15713
+ host,
15714
+ username,
15715
+ password,
15716
+ plateNumber: plateNumber ? plateNumber : _plateNumber,
15717
+ recno: _recNo,
15718
+ mode: _type === "blocklist" /* BLOCKLIST */ ? "TrafficBlackList" /* TRAFFIC_BLACKLIST */ : "TrafficRedList" /* TRAFFIC_REDLIST */,
15719
+ start: startDahua,
15720
+ end: endDahua,
15721
+ owner: name ? name : _name
15722
+ };
15723
+ const dahuaResponse = await _updatePlateNumber(dahuaPayload);
15724
+ if (dahuaResponse?.statusCode !== 200) {
15725
+ throw new import_node_server_utils71.BadRequestError(
15726
+ "Failed to update plate number to ANPR"
15727
+ );
15728
+ }
15655
15729
  }
15656
15730
  }
15657
15731
  }
@@ -15663,7 +15737,9 @@ function useVehicleService() {
15663
15737
  ...end && { end },
15664
15738
  ...unit && {
15665
15739
  unit: typeof unit === "string" ? new import_mongodb43.ObjectId(unit) : unit
15666
- }
15740
+ },
15741
+ ...value.recNo && { recNo: value.recNo },
15742
+ ...type && { type: value.type }
15667
15743
  };
15668
15744
  await _updateVehicleById(_id, formattedValue, session);
15669
15745
  await session.commitTransaction();
@@ -19367,8 +19443,24 @@ function useCustomerSiteController() {
19367
19443
  var import_node_server_utils91 = require("@7365admin1/node-server-utils");
19368
19444
  var import_joi51 = __toESM(require("joi"));
19369
19445
  var import_mongodb50 = require("mongodb");
19446
+
19447
+ // src/models/base.model.ts
19448
+ var AppServiceType = /* @__PURE__ */ ((AppServiceType2) => {
19449
+ AppServiceType2["REAL_ESTATE_DEVELOPER"] = "real_estate_developer";
19450
+ AppServiceType2["PROPERTY_MANAGEMENT_AGENCY"] = "property_management_agency";
19451
+ AppServiceType2["SECURITY_AGENCY"] = "security_agency";
19452
+ AppServiceType2["CLEANING_SERVICES"] = "cleaning_services";
19453
+ AppServiceType2["MECHANICAL_ELECTRICAL_SERVICES"] = "mechanical_electrical_services";
19454
+ AppServiceType2["LANDSCAPING_SERVICES"] = "landscaping_services";
19455
+ AppServiceType2["PEST_CONTROL_SERVICES"] = "pest_control_services";
19456
+ AppServiceType2["POOL_MAINTENANCE_SERVICES"] = "pool_maintenance_services";
19457
+ return AppServiceType2;
19458
+ })(AppServiceType || {});
19459
+
19460
+ // src/models/attendance-settings.model.ts
19370
19461
  var attendanceSettingsSchema = import_joi51.default.object({
19371
19462
  site: import_joi51.default.string().hex().required(),
19463
+ serviceType: import_joi51.default.string().valid(...Object.values(AppServiceType)).required(),
19372
19464
  isLocationEnabled: import_joi51.default.boolean().required(),
19373
19465
  location: import_joi51.default.when("isLocationEnabled", {
19374
19466
  is: true,
@@ -19411,6 +19503,7 @@ function MAttendanceSettings(value) {
19411
19503
  }
19412
19504
  return {
19413
19505
  site: value.site,
19506
+ serviceType: value.serviceType,
19414
19507
  isLocationEnabled: value.isLocationEnabled,
19415
19508
  location: value.isLocationEnabled && value.location ? value.location : void 0,
19416
19509
  isGeofencingEnabled: value.isLocationEnabled ? value.isGeofencingEnabled ?? false : void 0,
@@ -19435,7 +19528,10 @@ function useAttendanceSettingsRepository() {
19435
19528
  const { delNamespace, setCache, getCache } = (0, import_node_server_utils92.useCache)(namespace_collection);
19436
19529
  async function createIndex() {
19437
19530
  try {
19438
- await collection.createIndexes([{ key: { site: 1 } }]);
19531
+ await collection.createIndexes([
19532
+ { key: { site: 1 } },
19533
+ { key: { serviceType: 1 } }
19534
+ ]);
19439
19535
  } catch (error) {
19440
19536
  throw new import_node_server_utils92.InternalServerError(
19441
19537
  "Failed to create index on attendance settings."
@@ -19459,15 +19555,16 @@ function useAttendanceSettingsRepository() {
19459
19555
  throw error;
19460
19556
  }
19461
19557
  }
19462
- async function getAttendanceSettingsBySite(site, session) {
19558
+ async function getAttendanceSettingsBySite(site, serviceType, session) {
19463
19559
  try {
19464
19560
  site = new import_mongodb51.ObjectId(site);
19465
19561
  } catch (error) {
19466
19562
  throw new import_node_server_utils92.BadRequestError("Invalid attendance settings site ID format.");
19467
19563
  }
19468
- const query = { site };
19564
+ const query = { site, serviceType };
19469
19565
  const cacheKey = (0, import_node_server_utils92.makeCacheKey)(namespace_collection, {
19470
- site: site.toString()
19566
+ site: site.toString(),
19567
+ serviceType
19471
19568
  });
19472
19569
  if (!session) {
19473
19570
  const cachedData = await getCache(cacheKey);
@@ -19539,8 +19636,8 @@ function useAttendanceSettingsRepository() {
19539
19636
  return {
19540
19637
  createIndex,
19541
19638
  createAttendanceSettings,
19542
- updateAttendanceSettings,
19543
- getAttendanceSettingsBySite
19639
+ getAttendanceSettingsBySite,
19640
+ updateAttendanceSettings
19544
19641
  };
19545
19642
  }
19546
19643
 
@@ -19551,9 +19648,9 @@ function useAttendanceSettingsService() {
19551
19648
  createAttendanceSettings,
19552
19649
  getAttendanceSettingsBySite: _getAttendanceSettingsBySite
19553
19650
  } = useAttendanceSettingsRepository();
19554
- async function getAttendanceSettingsBySite(site) {
19651
+ async function getAttendanceSettingsBySite(site, serviceType) {
19555
19652
  try {
19556
- let settings = await _getAttendanceSettingsBySite(site);
19653
+ let settings = await _getAttendanceSettingsBySite(site, serviceType);
19557
19654
  if (!settings) {
19558
19655
  import_node_server_utils93.logger.info(
19559
19656
  `No attendance settings found for site ${site}, creating default settings`
@@ -19564,12 +19661,13 @@ function useAttendanceSettingsService() {
19564
19661
  await createAttendanceSettings(
19565
19662
  {
19566
19663
  site,
19664
+ serviceType,
19567
19665
  isLocationEnabled: false
19568
19666
  },
19569
19667
  session
19570
19668
  );
19571
19669
  await session?.commitTransaction();
19572
- settings = await _getAttendanceSettingsBySite(site);
19670
+ settings = await _getAttendanceSettingsBySite(site, serviceType);
19573
19671
  } catch (error) {
19574
19672
  await session?.abortTransaction();
19575
19673
  throw error;
@@ -19593,16 +19691,21 @@ function useAttendanceSettingsController() {
19593
19691
  const { getAttendanceSettingsBySite: _getAttendanceSettingsBySite } = useAttendanceSettingsService();
19594
19692
  const { updateAttendanceSettings: _updateAttendanceSettings } = useAttendanceSettingsRepository();
19595
19693
  async function getAttendanceSettingsBySite(req, res, next) {
19596
- const validation = import_joi52.default.string().hex().required();
19597
- const site = req.params.site;
19598
- const { error } = validation.validate(site);
19694
+ const query = { ...req.query, ...req.params };
19695
+ const validation = import_joi52.default.object({
19696
+ site: import_joi52.default.string().hex().required(),
19697
+ serviceType: import_joi52.default.string().valid(...Object.values(AppServiceType)).required()
19698
+ });
19699
+ const { error } = validation.validate(query);
19599
19700
  if (error) {
19600
19701
  import_node_server_utils94.logger.log({ level: "error", message: error.message });
19601
19702
  next(new import_node_server_utils94.BadRequestError(error.message));
19602
19703
  return;
19603
19704
  }
19705
+ const site = req.params.site ?? "";
19706
+ const serviceType = req.query.serviceType ?? "";
19604
19707
  try {
19605
- const data = await _getAttendanceSettingsBySite(site);
19708
+ const data = await _getAttendanceSettingsBySite(site, serviceType);
19606
19709
  res.json(data);
19607
19710
  return;
19608
19711
  } catch (error2) {
@@ -19641,6 +19744,7 @@ var import_joi53 = __toESM(require("joi"));
19641
19744
  var import_mongodb52 = require("mongodb");
19642
19745
  var attendanceSchema = import_joi53.default.object({
19643
19746
  site: import_joi53.default.string().hex().required(),
19747
+ serviceType: import_joi53.default.string().valid(...Object.values(AppServiceType)).required(),
19644
19748
  checkIn: import_joi53.default.object({
19645
19749
  timestamp: import_joi53.default.date().required(),
19646
19750
  location: import_joi53.default.object({
@@ -19673,6 +19777,7 @@ function MAttendance(value) {
19673
19777
  }
19674
19778
  return {
19675
19779
  site: value.site,
19780
+ serviceType: value.serviceType,
19676
19781
  checkIn: value.checkIn,
19677
19782
  checkOut: null,
19678
19783
  user: value.user,
@@ -19697,6 +19802,7 @@ function useAttendanceRepository() {
19697
19802
  try {
19698
19803
  await collection.createIndexes([
19699
19804
  { key: { site: 1 } },
19805
+ { key: { serviceType: 1 } },
19700
19806
  { key: { user: 1 } }
19701
19807
  ]);
19702
19808
  } catch (error) {
@@ -19724,13 +19830,15 @@ function useAttendanceRepository() {
19724
19830
  page = 1,
19725
19831
  limit = 10,
19726
19832
  search = "",
19727
- site
19833
+ site,
19834
+ serviceType
19728
19835
  }) {
19729
19836
  page = page > 0 ? page - 1 : 0;
19730
- const query = {};
19837
+ const query = { serviceType };
19731
19838
  const cacheOptions = {
19732
19839
  page,
19733
- limit
19840
+ limit,
19841
+ serviceType
19734
19842
  };
19735
19843
  try {
19736
19844
  site = new import_mongodb53.ObjectId(site);
@@ -20103,7 +20211,11 @@ function useAttendanceService() {
20103
20211
  const session = import_node_server_utils97.useAtlas.getClient()?.startSession();
20104
20212
  try {
20105
20213
  session?.startTransaction();
20106
- const setting = await getAttendanceSettingsBySite(value.site, session);
20214
+ const setting = await getAttendanceSettingsBySite(
20215
+ value.site,
20216
+ value.serviceType,
20217
+ session
20218
+ );
20107
20219
  if (setting?.isLocationEnabled && setting?.isGeofencingEnabled) {
20108
20220
  if (!setting.location || !value.checkIn.location) {
20109
20221
  throw new import_node_server_utils97.BadRequestError("Location data is required for check-in.");
@@ -20150,6 +20262,7 @@ function useAttendanceService() {
20150
20262
  const attendance = await getRawAttendanceById(_id, session);
20151
20263
  const setting = await getAttendanceSettingsBySite(
20152
20264
  attendance.site,
20265
+ attendance.serviceType,
20153
20266
  session
20154
20267
  );
20155
20268
  if (setting?.isLocationEnabled && setting?.isGeofencingEnabled) {
@@ -20235,7 +20348,8 @@ function useAttendanceController() {
20235
20348
  page: import_joi54.default.number().min(1).optional().allow("", null),
20236
20349
  limit: import_joi54.default.number().min(1).optional().allow("", null),
20237
20350
  search: import_joi54.default.string().optional().allow("", null),
20238
- site: import_joi54.default.string().hex().required()
20351
+ site: import_joi54.default.string().hex().required(),
20352
+ serviceType: import_joi54.default.string().valid(...Object.values(AppServiceType)).required()
20239
20353
  });
20240
20354
  const { error } = validation.validate(query);
20241
20355
  if (error) {
@@ -20247,12 +20361,14 @@ function useAttendanceController() {
20247
20361
  const limit = parseInt(req.query.limit) ?? 10;
20248
20362
  const search = req.query.search ?? "";
20249
20363
  const site = req.params.site ?? "";
20364
+ const serviceType = req.query.serviceType ?? "";
20250
20365
  try {
20251
20366
  const data = await _getAllAttendances({
20252
20367
  page,
20253
20368
  limit,
20254
20369
  search,
20255
- site
20370
+ site,
20371
+ serviceType
20256
20372
  });
20257
20373
  res.json(data);
20258
20374
  return;
@@ -21669,20 +21785,37 @@ function usePersonController() {
21669
21785
  }
21670
21786
  }
21671
21787
  async function getPeopleByUnit(req, res, next) {
21672
- const schema2 = import_joi58.default.object({
21673
- unit: import_joi58.default.string().required(),
21674
- type: import_joi58.default.string().optional(),
21675
- status: import_joi58.default.string().optional()
21676
- });
21677
- const { unit } = req.params;
21678
- const { type, status } = req.query;
21679
- const { error } = schema2.validate({ status, type, unit });
21680
- if (error) {
21681
- import_node_server_utils105.logger.log({ level: "error", message: error.message });
21682
- next(new import_node_server_utils105.BadRequestError(error.message));
21683
- return;
21684
- }
21685
- try {
21788
+ const PERSON_TYPES3 = Object.values(PersonTypes);
21789
+ console.log(req.query);
21790
+ try {
21791
+ const schema2 = import_joi58.default.object({
21792
+ unit: import_joi58.default.string().required(),
21793
+ type: import_joi58.default.string().optional().allow("", null).custom((value2, helpers) => {
21794
+ if (!value2)
21795
+ return ["resident" /* RESIDENT */];
21796
+ const parsed = value2.split(",").map((v) => v.trim()).filter(Boolean);
21797
+ for (const t of parsed) {
21798
+ if (!PERSON_TYPES3.includes(t)) {
21799
+ return helpers.error("any.only");
21800
+ }
21801
+ }
21802
+ return parsed;
21803
+ }).messages({
21804
+ "any.only": `Type must be one of: ${PERSON_TYPES3.join(", ")}`
21805
+ }),
21806
+ status: import_joi58.default.string().valid(...Object.values(PersonStatus)).optional().default("active" /* ACTIVE */)
21807
+ });
21808
+ const { error, value } = schema2.validate(
21809
+ { unit: req.params.unit, ...req.query },
21810
+ { abortEarly: false }
21811
+ );
21812
+ if (error) {
21813
+ const messages = error.details.map((d) => d.message).join(", ");
21814
+ import_node_server_utils105.logger.log({ level: "error", message: messages });
21815
+ next(new import_node_server_utils105.BadRequestError(messages));
21816
+ return;
21817
+ }
21818
+ const { unit, type, status } = value;
21686
21819
  const data = await _getPeopleByUnit({
21687
21820
  status,
21688
21821
  type,
@@ -21690,9 +21823,9 @@ function usePersonController() {
21690
21823
  });
21691
21824
  res.json(data);
21692
21825
  return;
21693
- } catch (error2) {
21694
- import_node_server_utils105.logger.log({ level: "error", message: error2.message });
21695
- next(error2);
21826
+ } catch (error) {
21827
+ import_node_server_utils105.logger.log({ level: "error", message: error.message });
21828
+ next(error);
21696
21829
  return;
21697
21830
  }
21698
21831
  }
@@ -28151,7 +28284,7 @@ function useSiteBillingConfigurationController() {
28151
28284
  (acc, [key, value2]) => ({ ...acc, [key]: value2 }),
28152
28285
  {}
28153
28286
  );
28154
- req.body.createdBy = cookies?.["user"].toString() ?? "";
28287
+ req.body.createdBy = cookies?.["user"] ? cookies["user"].toString() : req.body.createdBy;
28155
28288
  const data = { ...req.body };
28156
28289
  const { error, value } = schemaBillingConfiguration.validate(data);
28157
28290
  if (error) {
@@ -35216,7 +35349,7 @@ function useStatementOfAccountController() {
35216
35349
  (acc, [key, value]) => ({ ...acc, [key]: value }),
35217
35350
  {}
35218
35351
  );
35219
- req.body.createdBy = cookies?.["user"].toString() ?? "";
35352
+ req.body.createdBy = cookies?.["user"] ? cookies["user"].toString() : req.body.createdBy;
35220
35353
  const data = { ...req.body };
35221
35354
  const validation = import_joi93.default.object({
35222
35355
  dateFrom: import_joi93.default.string().required(),
@@ -44004,7 +44137,6 @@ var import_node_server_utils213 = require("@7365admin1/node-server-utils");
44004
44137
  var import_mongodb116 = require("mongodb");
44005
44138
  var import_moment_timezone5 = __toESM(require("moment-timezone"));
44006
44139
  async function manpowerEvents(io) {
44007
- console.log("Manpower events initialized");
44008
44140
  let intervalId = null;
44009
44141
  let activeConnections = 0;
44010
44142
  const { getAttendanceDataCount: _getAttendanceDataCount } = useHrmLabsAttendanceSrvc();
@@ -44822,6 +44954,227 @@ function useRedDotPaymentController() {
44822
44954
  getMerchantDetailsById
44823
44955
  };
44824
44956
  }
44957
+
44958
+ // src/models/verification-v2.model.ts
44959
+ var import_node_server_utils216 = require("@7365admin1/node-server-utils");
44960
+ var import_mongodb121 = require("mongodb");
44961
+ var VerificationType = /* @__PURE__ */ ((VerificationType2) => {
44962
+ VerificationType2["USER_SIGN_UP"] = "user-sign-up";
44963
+ VerificationType2["FORGET_PASSWORD"] = "forget-password";
44964
+ VerificationType2["USER_INVITE"] = "user-invite";
44965
+ VerificationType2["MEMBER_INVITE"] = "member-invite";
44966
+ return VerificationType2;
44967
+ })(VerificationType || {});
44968
+ var MVerificationV2 = class {
44969
+ constructor(value) {
44970
+ this._id = value._id ?? new import_mongodb121.ObjectId();
44971
+ this.type = value.type ?? "";
44972
+ this.email = value.email ?? "";
44973
+ if (value.metadata?.role) {
44974
+ try {
44975
+ value.metadata.role = new import_mongodb121.ObjectId(value.metadata.role);
44976
+ } catch (error) {
44977
+ throw new import_node_server_utils216.BadRequestError("Invalid role ID format.");
44978
+ }
44979
+ }
44980
+ if (value.metadata?.org) {
44981
+ try {
44982
+ value.metadata.org = new import_mongodb121.ObjectId(value.metadata.org);
44983
+ } catch (error) {
44984
+ throw new import_node_server_utils216.BadRequestError("Invalid org ID format.");
44985
+ }
44986
+ }
44987
+ if (value.metadata?.siteId) {
44988
+ try {
44989
+ value.metadata.siteId = new import_mongodb121.ObjectId(value.metadata.siteId);
44990
+ } catch (error) {
44991
+ throw new import_node_server_utils216.BadRequestError("Invalid site ID format.");
44992
+ }
44993
+ }
44994
+ if (value.metadata?.serviceProviderOrgId) {
44995
+ try {
44996
+ value.metadata.serviceProviderOrgId = new import_mongodb121.ObjectId(
44997
+ value.metadata.serviceProviderOrgId
44998
+ );
44999
+ } catch (error) {
45000
+ throw new import_node_server_utils216.BadRequestError("Invalid service provider ID format.");
45001
+ }
45002
+ }
45003
+ this.metadata = { ...value.metadata };
45004
+ this.status = value.status ?? "pending";
45005
+ this.createdAt = value.createdAt ?? /* @__PURE__ */ new Date();
45006
+ this.updatedAt = value.updatedAt ?? null;
45007
+ this.expireAt = value.expireAt ?? new Date(Date.now() + 3600 * 1e3);
45008
+ }
45009
+ };
45010
+
45011
+ // src/repositories/verification-v2.repo.ts
45012
+ var import_node_server_utils217 = require("@7365admin1/node-server-utils");
45013
+ function useVerificationRepoV2() {
45014
+ const db = import_node_server_utils217.useAtlas.getDb();
45015
+ if (!db) {
45016
+ throw new import_node_server_utils217.InternalServerError("Unable to connect to server.");
45017
+ }
45018
+ const namespace_collection = "verifications";
45019
+ const collection = db.collection(namespace_collection);
45020
+ async function createIndex() {
45021
+ try {
45022
+ await collection.createIndex([
45023
+ { email: 1 },
45024
+ { type: 1 },
45025
+ { status: 1 },
45026
+ { "metadata.org": 1 }
45027
+ ]);
45028
+ } catch (error) {
45029
+ throw new import_node_server_utils217.InternalServerError("Failed to create index.");
45030
+ }
45031
+ }
45032
+ async function createTextIndex() {
45033
+ try {
45034
+ await collection.createIndex({
45035
+ email: "text"
45036
+ });
45037
+ } catch (error) {
45038
+ throw new import_node_server_utils217.InternalServerError("Failed to create text index on email.");
45039
+ }
45040
+ }
45041
+ const { delNamespace, setCache, getCache, delCache } = (0, import_node_server_utils217.useCache)(namespace_collection);
45042
+ async function add(value, session) {
45043
+ value = new MVerificationV2(value);
45044
+ try {
45045
+ const res = await collection.insertOne(value, { session });
45046
+ delNamespace().then(() => {
45047
+ import_node_server_utils217.logger.info(`Cache cleared for namespace: ${namespace_collection}`);
45048
+ }).catch((err) => {
45049
+ import_node_server_utils217.logger.error(
45050
+ `Failed to clear cache for namespace: ${namespace_collection}`,
45051
+ err
45052
+ );
45053
+ });
45054
+ return res.insertedId;
45055
+ } catch (error) {
45056
+ import_node_server_utils217.logger.log({
45057
+ level: "info",
45058
+ message: String(error)
45059
+ });
45060
+ throw new import_node_server_utils217.InternalServerError("Server internal error.");
45061
+ }
45062
+ }
45063
+ return {
45064
+ createIndex,
45065
+ createTextIndex,
45066
+ add
45067
+ };
45068
+ }
45069
+
45070
+ // src/services/verification-v2.service.ts
45071
+ var import_node_server_utils218 = require("@7365admin1/node-server-utils");
45072
+ function useVerificationServiceV2() {
45073
+ const MailerConfig = {
45074
+ host: MAILER_TRANSPORT_HOST,
45075
+ port: MAILER_TRANSPORT_PORT,
45076
+ secure: MAILER_TRANSPORT_SECURE,
45077
+ email: MAILER_EMAIL,
45078
+ password: MAILER_PASSWORD
45079
+ };
45080
+ const mailer = new import_node_server_utils218.useMailer(MailerConfig);
45081
+ const { add } = useVerificationRepoV2();
45082
+ const { getUserByEmail } = useUserRepo();
45083
+ async function signUp({
45084
+ email,
45085
+ metadata
45086
+ }) {
45087
+ try {
45088
+ const user = await getUserByEmail(email);
45089
+ if (user) {
45090
+ throw new import_node_server_utils218.BadRequestError(
45091
+ `Email ${email} is already registered, please login to continue.`
45092
+ );
45093
+ }
45094
+ metadata.password = await (0, import_node_server_utils218.hashPassword)(metadata.password);
45095
+ const value = {
45096
+ type: "user-sign-up" /* USER_SIGN_UP */,
45097
+ email,
45098
+ metadata,
45099
+ expireAt: new Date((/* @__PURE__ */ new Date()).getTime() + 5 * 60 * 1e3).toISOString(),
45100
+ // 5mins from now
45101
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
45102
+ };
45103
+ const res = await add(value);
45104
+ const dir = __dirname;
45105
+ const filePath = (0, import_node_server_utils218.getDirectory)(dir, "./public/handlebars/sign-up");
45106
+ const emailContent = (0, import_node_server_utils218.compileHandlebar)({
45107
+ context: {
45108
+ email,
45109
+ validity: "5 minutes",
45110
+ link: `${APP_MAIN}/sign-up/${res}`
45111
+ },
45112
+ filePath
45113
+ });
45114
+ mailer.sendMail({
45115
+ to: email,
45116
+ subject: "Sign Up Verification",
45117
+ html: emailContent,
45118
+ sender: "iService365"
45119
+ }).catch((error) => {
45120
+ import_node_server_utils218.logger.log({
45121
+ level: "error",
45122
+ message: `Error sending user invite email: ${error}`
45123
+ });
45124
+ });
45125
+ return res;
45126
+ } catch (error) {
45127
+ throw error;
45128
+ }
45129
+ }
45130
+ return {
45131
+ signUp
45132
+ };
45133
+ }
45134
+
45135
+ // src/controllers/auth-v2.controller.ts
45136
+ var import_joi125 = __toESM(require("joi"));
45137
+ var import_node_server_utils219 = require("@7365admin1/node-server-utils");
45138
+ function useAuthControllerV2() {
45139
+ const { signUp: _signUp } = useVerificationServiceV2();
45140
+ async function signUp(req, res, next) {
45141
+ const validation = import_joi125.default.object({
45142
+ email: import_joi125.default.string().email().lowercase().trim().required(),
45143
+ password: import_joi125.default.string().trim().required(),
45144
+ country: import_joi125.default.string().min(3).required(),
45145
+ orgName: import_joi125.default.string().min(1).required()
45146
+ });
45147
+ const { error, value } = validation.validate(req.body, {
45148
+ abortEarly: false
45149
+ });
45150
+ if (error) {
45151
+ const messages = error.details.map((d) => d.message);
45152
+ import_node_server_utils219.logger.log({ level: "error", message: messages.join(", ") });
45153
+ next(new import_node_server_utils219.BadRequestError(messages.join(", ")));
45154
+ return;
45155
+ }
45156
+ const { email, password, country, orgName } = value;
45157
+ try {
45158
+ const message = await _signUp({
45159
+ email,
45160
+ metadata: {
45161
+ password,
45162
+ country,
45163
+ orgName
45164
+ }
45165
+ });
45166
+ res.json({ message });
45167
+ return;
45168
+ } catch (error2) {
45169
+ import_node_server_utils219.logger.log({ level: "error", message: error2.message });
45170
+ next(error2);
45171
+ return;
45172
+ }
45173
+ }
45174
+ return {
45175
+ signUp
45176
+ };
45177
+ }
44825
45178
  // Annotate the CommonJS export names for ESM import in node:
44826
45179
  0 && (module.exports = {
44827
45180
  ANPRMode,
@@ -44898,6 +45251,7 @@ function useRedDotPaymentController() {
44898
45251
  MVehicle,
44899
45252
  MVehicleTransaction,
44900
45253
  MVerification,
45254
+ MVerificationV2,
44901
45255
  MVisitorTransaction,
44902
45256
  MWorkOrder,
44903
45257
  OrgNature,
@@ -44906,6 +45260,7 @@ function useRedDotPaymentController() {
44906
45260
  PERSON_TYPES,
44907
45261
  PMDashboardCollection,
44908
45262
  Period,
45263
+ PersonStatus,
44909
45264
  PersonTypes,
44910
45265
  SiteCategories,
44911
45266
  SiteStatus,
@@ -44918,6 +45273,7 @@ function useRedDotPaymentController() {
44918
45273
  VehicleSort,
44919
45274
  VehicleStatus,
44920
45275
  VehicleType,
45276
+ VerificationType,
44921
45277
  VisitorSort,
44922
45278
  VisitorStatus,
44923
45279
  addressSchema,
@@ -45042,6 +45398,7 @@ function useRedDotPaymentController() {
45042
45398
  useAttendanceSettingsRepository,
45043
45399
  useAttendanceSettingsService,
45044
45400
  useAuthController,
45401
+ useAuthControllerV2,
45045
45402
  useAuthService,
45046
45403
  useBuildingController,
45047
45404
  useBuildingRepo,
@@ -45195,7 +45552,9 @@ function useRedDotPaymentController() {
45195
45552
  useVehicleService,
45196
45553
  useVerificationController,
45197
45554
  useVerificationRepo,
45555
+ useVerificationRepoV2,
45198
45556
  useVerificationService,
45557
+ useVerificationServiceV2,
45199
45558
  useVisitorTransactionController,
45200
45559
  useVisitorTransactionRepo,
45201
45560
  useVisitorTransactionService,