@7365admin1/core 3.34.4-staging.16 → 3.34.4-staging.18

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.d.ts CHANGED
@@ -2763,6 +2763,7 @@ type TPerson = {
2763
2763
  deletedAt?: string | Date;
2764
2764
  plateNumbers?: string[];
2765
2765
  contacts?: string[];
2766
+ updatedBy?: string | ObjectId;
2766
2767
  };
2767
2768
  declare const PERSON_TYPES: readonly ["walk-in", "drop-off", "contractor", "delivery", "pick-up", "guest", "tenant", "resident"];
2768
2769
  type PersonType = (typeof PERSON_TYPES)[number];
@@ -2813,7 +2814,7 @@ type visitorPersonService = {
2813
2814
  type: visitorType;
2814
2815
  site: string | ObjectId;
2815
2816
  company?: string;
2816
- updatedBy?: string | ObjectId;
2817
+ updatedBy?: string | ObjectId | undefined;
2817
2818
  };
2818
2819
  type visitorPersonRepo = {
2819
2820
  nric: string;
@@ -2825,8 +2826,6 @@ type visitorPersonRepo = {
2825
2826
  site: string | ObjectId;
2826
2827
  companyName: string[];
2827
2828
  status: string;
2828
- createdAt: string | Date;
2829
- updatedAt: string | Date;
2830
2829
  createdBy?: string | ObjectId | undefined;
2831
2830
  updatedBy?: string | ObjectId | undefined;
2832
2831
  };
@@ -3155,7 +3154,7 @@ declare function usePersonRepo(): {
3155
3154
  getByUserId: (userId: string | ObjectId) => Promise<TPerson | null>;
3156
3155
  reviewResidentPerson: (_id: ObjectId | string, value: Partial<TPerson>, session?: ClientSession) => Promise<mongodb.UpdateResult<TPerson>>;
3157
3156
  addFromVisitor: (value: visitorPersonRepo, session?: ClientSession) => Promise<mongodb.InsertOneResult<TPerson>>;
3158
- findFirstOne: (query: Record<string, any>, session?: ClientSession) => Promise<mongodb.WithId<TPerson>[]>;
3157
+ findFirstTen: (query: Record<string, any>, session?: ClientSession) => Promise<mongodb.WithId<TPerson>[]>;
3159
3158
  };
3160
3159
 
3161
3160
  declare function usePersonController(): {
@@ -6105,8 +6104,8 @@ declare function useNfcPatrolLogRepo(): {
6105
6104
  date?: string | undefined;
6106
6105
  type?: "month" | undefined;
6107
6106
  route?: {
6108
- _id: ObjectId | string;
6109
- startTime: string;
6107
+ _id?: string | ObjectId | undefined;
6108
+ startTime?: string | undefined;
6110
6109
  } | undefined;
6111
6110
  }, session?: ClientSession) => Promise<{
6112
6111
  items: any[];
@@ -6137,7 +6136,7 @@ declare function useNfcPatrolLogService(): {
6137
6136
 
6138
6137
  declare function useNfcPatrolLogController(): {
6139
6138
  add: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6140
- getAllBySite: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6139
+ getAllBySite: (req: Request, res: Response, next: NextFunction) => Promise<void | Response<any, Record<string, any>>>;
6141
6140
  completeCheckpoint: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6142
6141
  getLog: (req: Request, res: Response, next: NextFunction) => Promise<void>;
6143
6142
  sign: (req: Request, res: Response, next: NextFunction) => Promise<void>;
package/dist/index.js CHANGED
@@ -25359,6 +25359,9 @@ function usePersonRepo() {
25359
25359
  throw new import_node_server_utils74.BadRequestError("Invalid person transaction ID format.");
25360
25360
  }
25361
25361
  value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
25362
+ if (value.updatedBy) {
25363
+ value.updatedBy = await convertObjectIdUtil2(value.updatedBy, "updatedBy");
25364
+ }
25362
25365
  try {
25363
25366
  const result = await collection.updateOne(
25364
25367
  { _id },
@@ -25851,10 +25854,10 @@ function usePersonRepo() {
25851
25854
  throw error;
25852
25855
  }
25853
25856
  }
25854
- async function findFirstOne(query, session) {
25857
+ async function findFirstTen(query, session) {
25855
25858
  try {
25856
25859
  query.site = await convertObjectIdUtil2(query.site, "site");
25857
- const data = await collection.find(query, { session }).limit(1).toArray();
25860
+ const data = await collection.find(query, { session }).limit(10).toArray();
25858
25861
  return data;
25859
25862
  } catch (error) {
25860
25863
  throw new import_node_server_utils74.InternalServerError("Failed to find many persons.");
@@ -25862,7 +25865,17 @@ function usePersonRepo() {
25862
25865
  }
25863
25866
  async function addFromVisitor(value, session) {
25864
25867
  value.site = await convertObjectIdUtil2(value.site, "site");
25865
- const res = await collection.insertOne(value, { session });
25868
+ if (value.updatedBy) {
25869
+ value.updatedBy = await convertObjectIdUtil2(value.updatedBy, "updatedBy");
25870
+ }
25871
+ if (value.createdBy) {
25872
+ value.createdBy = await convertObjectIdUtil2(value.createdBy, "createdBy");
25873
+ }
25874
+ const res = await collection.insertOne({
25875
+ ...value,
25876
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
25877
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
25878
+ }, { session });
25866
25879
  console.log("person.repo addFromVisitor res", res);
25867
25880
  return res;
25868
25881
  }
@@ -25886,7 +25899,7 @@ function usePersonRepo() {
25886
25899
  getByUserId,
25887
25900
  reviewResidentPerson,
25888
25901
  addFromVisitor,
25889
- findFirstOne
25902
+ findFirstTen
25890
25903
  };
25891
25904
  }
25892
25905
 
@@ -33807,7 +33820,7 @@ function usePersonService() {
33807
33820
  getByUserId: _getByUserId,
33808
33821
  reviewResidentPerson: _reviewResidentPerson,
33809
33822
  addFromVisitor: _addFromVisitor,
33810
- findFirstOne
33823
+ findFirstTen
33811
33824
  } = usePersonRepo();
33812
33825
  const { addPlateNumber: _addPlateNumber } = useDahuaService();
33813
33826
  const {
@@ -34197,43 +34210,116 @@ function usePersonService() {
34197
34210
  }
34198
34211
  }
34199
34212
  async function addUpdateFromVisitor(value, session) {
34213
+ value.type = value.type == "walk-in" ? "guest" : value.type;
34200
34214
  let updateId = null;
34215
+ let add2 = true;
34201
34216
  let set = {};
34202
- if (value?.nric) {
34203
- const existingPerson = await findFirstOne({ nric: value.nric, site: value.site }, session);
34204
- if (Array.isArray(existingPerson) && existingPerson.length > 0) {
34205
- updateId = existingPerson[0]._id;
34206
- if (value.contact && Array.isArray(existingPerson[0].contacts) && !existingPerson[0].contacts.includes(value.contact)) {
34207
- set = { contacts: [...existingPerson[0].contacts, value.contact] };
34217
+ const cleanInput = (str) => str.replace(/\s+/g, "");
34218
+ const cleanPhone = (str) => str.replace(/\D/g, "");
34219
+ const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
34220
+ const nric = value.nric ? cleanInput(value.nric) : "";
34221
+ const name = value.name?.trim();
34222
+ const contact = value.contact?.trim();
34223
+ const plateNumber = value.plateNumber ? cleanInput(value.plateNumber) : "";
34224
+ const email = value.email?.trim();
34225
+ const type = value.type?.trim();
34226
+ const company = value.company?.trim();
34227
+ const orConditions = [
34228
+ ...nric ? [{ nric: { $regex: `^${escapeRegex(nric)}$`, $options: "i" } }] : [],
34229
+ ...contact ? [{ contacts: { $regex: `^\\+?${cleanPhone(escapeRegex(contact))}$`, $options: "i" } }] : [],
34230
+ ...plateNumber ? [{ plateNumbers: { $regex: `^${escapeRegex(plateNumber)}$`, $options: "i" } }] : []
34231
+ ];
34232
+ const existingPerson2 = await findFirstTen(
34233
+ {
34234
+ type,
34235
+ site: value.site,
34236
+ ...orConditions.length > 0 && { $or: orConditions }
34237
+ },
34238
+ session
34239
+ );
34240
+ if (Array.isArray(existingPerson2) && existingPerson2.length > 0) {
34241
+ let matchedPerson = nric ? existingPerson2.find((person) => person.nric === nric) : null;
34242
+ if (matchedPerson) {
34243
+ add2 = false;
34244
+ updateId = matchedPerson._id;
34245
+ if (contact && Array.isArray(matchedPerson.contacts) && !matchedPerson.contacts.includes(contact)) {
34246
+ set = { contacts: [...matchedPerson.contacts, contact] };
34208
34247
  }
34209
- if (value.plateNumber && Array.isArray(existingPerson[0].plateNumbers) && !existingPerson[0].plateNumbers.includes(value.plateNumber)) {
34210
- set = { ...set, plateNumbers: [...existingPerson[0].plateNumbers, value.plateNumber] };
34248
+ if (plateNumber && Array.isArray(matchedPerson.plateNumbers) && !matchedPerson.plateNumbers.includes(plateNumber)) {
34249
+ set = { ...set, plateNumbers: [...matchedPerson.plateNumbers, plateNumber] };
34211
34250
  }
34212
- if (value.company && Array.isArray(existingPerson[0].companyName) && !existingPerson[0].companyName.includes(value.company)) {
34213
- set = { ...set, companyName: [...existingPerson[0].companyName, value.company] };
34251
+ if (company && Array.isArray(matchedPerson.companyName) && !matchedPerson.companyName.includes(company)) {
34252
+ set = { ...set, companyName: [...matchedPerson.companyName, company] };
34214
34253
  }
34254
+ if (name && name != matchedPerson.name) {
34255
+ set = { ...set, name };
34256
+ }
34257
+ if (email && email != matchedPerson.email) {
34258
+ set = { ...set, email };
34259
+ }
34260
+ } else {
34261
+ matchedPerson = contact ? existingPerson2.find((person) => Array.isArray(person.contacts) && person.contacts.includes(contact)) : null;
34215
34262
  }
34216
- } else {
34263
+ if (matchedPerson) {
34264
+ add2 = false;
34265
+ updateId = matchedPerson._id;
34266
+ if (nric && nric !== matchedPerson.nric) {
34267
+ set = { ...set, nric };
34268
+ }
34269
+ if (plateNumber && Array.isArray(matchedPerson.plateNumbers) && !matchedPerson.plateNumbers.includes(plateNumber)) {
34270
+ set = { ...set, plateNumbers: [...matchedPerson.plateNumbers, plateNumber] };
34271
+ }
34272
+ if (company && Array.isArray(matchedPerson.companyName) && !matchedPerson.companyName.includes(company)) {
34273
+ set = { ...set, companyName: [...matchedPerson.companyName, company] };
34274
+ }
34275
+ if (name && name !== matchedPerson.name) {
34276
+ set = { ...set, name };
34277
+ }
34278
+ if (email && email !== matchedPerson.email) {
34279
+ set = { ...set, email };
34280
+ }
34281
+ } else {
34282
+ matchedPerson = plateNumber ? existingPerson2.find((person) => Array.isArray(person.plateNumbers) && person.plateNumbers.includes(plateNumber)) : null;
34283
+ }
34284
+ if (matchedPerson && (contact && Array.isArray(matchedPerson.contacts) && !matchedPerson.contacts.includes(contact) && (nric && nric != matchedPerson.nric) || !nric && !contact)) {
34285
+ add2 = false;
34286
+ updateId = matchedPerson._id;
34287
+ if (nric && nric !== matchedPerson.nric) {
34288
+ set = { ...set, nric };
34289
+ }
34290
+ if (contact && Array.isArray(matchedPerson.contacts) && !matchedPerson.contacts.includes(contact)) {
34291
+ set = { contacts: [...matchedPerson.contacts, contact] };
34292
+ }
34293
+ if (company && Array.isArray(matchedPerson.companyName) && !matchedPerson.companyName.includes(company)) {
34294
+ set = { ...set, companyName: [...matchedPerson.companyName, company] };
34295
+ }
34296
+ if (name && name !== matchedPerson.name) {
34297
+ set = { ...set, name };
34298
+ }
34299
+ if (email && email !== matchedPerson.email) {
34300
+ set = { ...set, email };
34301
+ }
34302
+ }
34303
+ }
34304
+ if (add2) {
34217
34305
  const data = {
34218
34306
  nric: value.nric,
34219
34307
  name: value.name,
34220
34308
  contacts: value.contact ? [value.contact] : [],
34221
34309
  plateNumbers: value.plateNumber ? [value.plateNumber] : [],
34222
- type: value.type,
34310
+ type,
34223
34311
  email: value.email,
34224
34312
  site: value.site,
34225
34313
  status: "active",
34226
34314
  companyName: value.company ? [value.company] : [],
34227
34315
  createdBy: value.updatedBy,
34228
- updatedBy: value.updatedBy,
34229
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
34230
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
34316
+ updatedBy: value.updatedBy
34231
34317
  };
34232
- const res = await _addFromVisitor(data, session);
34318
+ const res_addFromVisitor = await _addFromVisitor(data, session);
34233
34319
  }
34234
34320
  if (updateId && Object.keys(set).length > 0) {
34235
34321
  set = { ...set, updatedBy: value.updatedBy, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
34236
- const updateRes = await _updateById(updateId, set, session);
34322
+ const res_updateById = await _updateById(updateId, set, session);
34237
34323
  }
34238
34324
  }
34239
34325
  return {
@@ -35533,8 +35619,9 @@ function useVisitorTransactionService() {
35533
35619
  value.unitName = unit?.name;
35534
35620
  }
35535
35621
  const { nric = "", name = "", contact = "", plateNumber = "", email = "", site = "", type = "guest", company, createdBy } = value;
35622
+ console.log("type", type);
35536
35623
  if (/^(guest|walk-in|contractor|delivery)$/.test(type)) {
35537
- const res = await addUpdateFromVisitor({
35624
+ await addUpdateFromVisitor({
35538
35625
  nric,
35539
35626
  name,
35540
35627
  contact,
@@ -58502,13 +58589,9 @@ function useNfcPatrolLogRepo() {
58502
58589
  };
58503
58590
  if (date) {
58504
58591
  if (type === "month") {
58505
- const [year, month] = date.split("-").map(Number);
58506
- const endDay = new Date(year, month, 0).getDate();
58507
58592
  query.date = {
58508
- $gte: `${year}-${String(month).padStart(2, "0")}-01`,
58509
- $lte: `${year}-${String(month).padStart(2, "0")}-${String(
58510
- endDay
58511
- ).padStart(2, "0")}`
58593
+ $gte: `${date}-01-01`,
58594
+ $lte: `${date}-12-31`
58512
58595
  };
58513
58596
  } else {
58514
58597
  query.date = date;
@@ -58829,49 +58912,52 @@ function useNfcPatrolLogController() {
58829
58912
  page: import_joi111.default.number().integer().min(1).default(1),
58830
58913
  limit: import_joi111.default.number().integer().min(1).max(100).default(10),
58831
58914
  site: import_joi111.default.string().length(24).hex().required(),
58832
- date: import_joi111.default.string().pattern(/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/).required().messages({
58833
- "string.pattern.base": "Date must be in YYYY-MM-DD format (e.g. 2026-07-17)"
58915
+ date: import_joi111.default.string().pattern(/^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?$/).optional().messages({
58916
+ "string.pattern.base": "Date must be YYYY or YYYY-MM or YYYY-MM-DD"
58834
58917
  }),
58835
58918
  type: import_joi111.default.string().valid("month").optional(),
58836
58919
  route: import_joi111.default.object({
58837
- _id: import_joi111.default.string().length(24).hex().required(),
58838
- startTime: import_joi111.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).required()
58839
- }).required()
58920
+ _id: import_joi111.default.string().length(24).hex().optional(),
58921
+ startTime: import_joi111.default.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().messages({
58922
+ "string.pattern.base": "startTime must be in HH:mm 24-hour format"
58923
+ })
58924
+ }).min(1).optional()
58840
58925
  });
58841
58926
  const query = {
58927
+ page: req.query.page,
58928
+ limit: req.query.limit,
58842
58929
  site: req.query.site,
58843
58930
  date: req.query.date,
58844
58931
  type: req.query.type,
58845
- route: {
58846
- _id: req.query["route._id"],
58847
- startTime: req.query["route.startTime"]
58848
- }
58932
+ route: req.query["route._id"] || req.query["route.startTime"] ? {
58933
+ ...req.query["route._id"] ? { _id: req.query["route._id"] } : {},
58934
+ ...req.query["route.startTime"] ? { startTime: req.query["route.startTime"] } : {}
58935
+ } : void 0
58849
58936
  };
58850
58937
  const { error, value } = validation.validate(query, {
58851
- abortEarly: false
58938
+ abortEarly: false,
58939
+ allowUnknown: true,
58940
+ stripUnknown: true
58852
58941
  });
58853
58942
  if (error) {
58854
- const messages = error.details.map((d) => d.message).join(", ");
58855
- import_node_server_utils200.logger.log({ level: "error", message: messages });
58856
- next(new import_node_server_utils200.BadRequestError(messages));
58857
- return;
58943
+ return next(
58944
+ new import_node_server_utils200.BadRequestError(
58945
+ error.details.map((d) => d.message).join(", ")
58946
+ )
58947
+ );
58858
58948
  }
58859
- const { page, limit, site, date, type, route } = value;
58860
58949
  try {
58861
58950
  const data = await _getAllBySite({
58862
- page,
58863
- limit,
58864
- site,
58865
- date,
58866
- type,
58867
- route
58951
+ page: value.page,
58952
+ limit: value.limit,
58953
+ site: value.site,
58954
+ date: value.date,
58955
+ type: value.type,
58956
+ route: value.route
58868
58957
  });
58869
- res.status(200).json(data);
58870
- return;
58958
+ return res.status(200).json(data);
58871
58959
  } catch (error2) {
58872
- import_node_server_utils200.logger.log({ level: "error", message: error2.message });
58873
- next(error2);
58874
- return;
58960
+ return next(error2);
58875
58961
  }
58876
58962
  }
58877
58963
  async function completeCheckpoint(req, res, next) {