@7365admin1/core 2.65.0 → 2.67.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
@@ -125,7 +125,15 @@ var userSchema = Joi2.object({
125
125
  email: Joi2.string().email().required(),
126
126
  password: Joi2.string().min(8).required(),
127
127
  name: Joi2.string().required(),
128
- defaultOrg: Joi2.string().hex().optional().allow("", null)
128
+ defaultOrg: Joi2.string().hex().optional().allow("", null),
129
+ status: Joi2.string().optional().allow("", null),
130
+ block: Joi2.number().optional().allow(null),
131
+ level: Joi2.string().optional().allow("", null),
132
+ type: Joi2.string().optional().allow("", null),
133
+ unitName: Joi2.string().optional().allow("", null),
134
+ contact: Joi2.string().optional().allow("", null),
135
+ site: Joi2.string().hex().optional().allow("", null),
136
+ unitId: Joi2.string().hex().optional().allow("", null)
129
137
  });
130
138
  function MUser(value) {
131
139
  const { error } = userSchema.validate(value);
@@ -139,12 +147,33 @@ function MUser(value) {
139
147
  throw new BadRequestError2("Invalid default org ID format.");
140
148
  }
141
149
  }
150
+ if (value.site && typeof value.site === "string") {
151
+ try {
152
+ value.site = new ObjectId(value.site);
153
+ } catch {
154
+ throw new BadRequestError2("Invalid site ID format.");
155
+ }
156
+ }
157
+ if (value.unitId && typeof value.unitId === "string") {
158
+ try {
159
+ value.unitId = new ObjectId(value.unitId);
160
+ } catch {
161
+ throw new BadRequestError2("Invalid unit ID format.");
162
+ }
163
+ }
142
164
  return {
143
165
  email: value.email,
144
166
  password: value.password,
145
167
  name: value.name ?? "",
146
168
  defaultOrg: value.defaultOrg ?? "",
147
- status: "active" /* ACTIVE */,
169
+ status: value.status ?? "active" /* ACTIVE */,
170
+ block: value.block ?? null,
171
+ level: value.level ?? "",
172
+ type: value.type ?? "",
173
+ unitName: value.unitName ?? "",
174
+ contact: value.contact ?? "",
175
+ site: value.site ?? "",
176
+ unitId: value.unitId ?? "",
148
177
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
149
178
  updatedAt: value.updatedAt ?? "",
150
179
  deletedAt: value.deletedAt ?? ""
@@ -4182,7 +4211,7 @@ function useOrgRepo() {
4182
4211
  }
4183
4212
  async function createUniqueIndex() {
4184
4213
  try {
4185
- await collection.createIndex({ email: 1 }, { unique: true });
4214
+ await collection.createIndex({ email: 1 });
4186
4215
  } catch (error) {
4187
4216
  throw new InternalServerError9("Failed to create unique index on name.");
4188
4217
  }
@@ -4372,6 +4401,29 @@ function useOrgRepo() {
4372
4401
  throw error;
4373
4402
  }
4374
4403
  }
4404
+ async function getOrgsByEmail(email) {
4405
+ const cacheKey = makeCacheKey8(namespace_collection, {
4406
+ email
4407
+ });
4408
+ const cachedData = await getCache(cacheKey);
4409
+ if (cachedData) {
4410
+ logger10.info(`Cache hit for key: ${cacheKey}`);
4411
+ return cachedData;
4412
+ }
4413
+ try {
4414
+ const data = await collection.find({
4415
+ email
4416
+ }).toArray();
4417
+ setCache(cacheKey, data, 15 * 60).then(() => {
4418
+ logger10.info(`Cache set for key: ${cacheKey}`);
4419
+ }).catch((err) => {
4420
+ logger10.error(`Failed to set cache for key: ${cacheKey}`, err);
4421
+ });
4422
+ return data;
4423
+ } catch (error) {
4424
+ throw error;
4425
+ }
4426
+ }
4375
4427
  async function updateFieldById({
4376
4428
  _id,
4377
4429
  field,
@@ -4474,7 +4526,8 @@ function useOrgRepo() {
4474
4526
  getByEmail,
4475
4527
  updateFieldById,
4476
4528
  updateStatusById,
4477
- deleteById
4529
+ deleteById,
4530
+ getOrgsByEmail
4478
4531
  };
4479
4532
  }
4480
4533
 
@@ -5497,7 +5550,6 @@ function useVerificationService() {
5497
5550
  await getSiteById(metadata.siteId);
5498
5551
  }
5499
5552
  const verificationIds = [];
5500
- const invitedApps = [];
5501
5553
  for (const app of apps) {
5502
5554
  await useVerificationRepo().findOne({
5503
5555
  type,
@@ -5520,34 +5572,32 @@ function useVerificationService() {
5520
5572
  };
5521
5573
  const createdId = await add(value);
5522
5574
  verificationIds.push(createdId.toString());
5523
- invitedApps.push(app);
5575
+ const link = `${APP_MAIN}/verify/invitation/${createdId}`;
5576
+ const emailContent = compileHandlebar({
5577
+ context: {
5578
+ email,
5579
+ validity: VERIFICATION_USER_INVITE_DURATION,
5580
+ link,
5581
+ hasPropertyManagement: app === "property_management_agency",
5582
+ hasSecurity: app === "security_agency",
5583
+ hasCleaning: app === "cleaning_services",
5584
+ hasMechanical: app === "mechanical_electrical_services",
5585
+ hasLandscape: app === "landscaping_services",
5586
+ hasPestControl: app === "pest_control_services",
5587
+ hasPoolMaintenance: app === "pool_maintenance_services"
5588
+ },
5589
+ filePath: getDirectory(
5590
+ __dirname,
5591
+ "./public/handlebars/user-invite"
5592
+ )
5593
+ });
5594
+ await mailer.sendMail({
5595
+ to: email,
5596
+ subject: "User Invite",
5597
+ html: emailContent,
5598
+ sender: "iService365"
5599
+ });
5524
5600
  }
5525
- const link = `${APP_MAIN}/verify/invitation/${verificationIds[0]}`;
5526
- const appsSet = new Set(invitedApps);
5527
- const emailContent = compileHandlebar({
5528
- context: {
5529
- email,
5530
- validity: VERIFICATION_USER_INVITE_DURATION,
5531
- link,
5532
- hasPropertyManagement: appsSet.has("property_management_agency"),
5533
- hasSecurity: appsSet.has("security_agency"),
5534
- hasCleaning: appsSet.has("cleaning_services"),
5535
- hasMechanical: appsSet.has("mechanical_electrical_services"),
5536
- hasLandscape: appsSet.has("landscaping_services"),
5537
- hasPestControl: appsSet.has("pest_control_services"),
5538
- hasPoolMaintenance: appsSet.has("pool_maintenance_services")
5539
- },
5540
- filePath: getDirectory(
5541
- __dirname,
5542
- "./public/handlebars/user-invite"
5543
- )
5544
- });
5545
- await mailer.sendMail({
5546
- to: email,
5547
- subject: "User Invite",
5548
- html: emailContent,
5549
- sender: "iService365"
5550
- });
5551
5601
  return verificationIds;
5552
5602
  }
5553
5603
  async function createSimpleMemberInvite({
@@ -8042,7 +8092,7 @@ function useVerificationController() {
8042
8092
  siteId: Joi16.string().hex().optional().allow("", null),
8043
8093
  siteName: Joi16.string().optional().allow("", null)
8044
8094
  });
8045
- const { error } = validation.validate(payload);
8095
+ const { error, value } = validation.validate(payload);
8046
8096
  if (error) {
8047
8097
  logger22.log({
8048
8098
  level: "error",
@@ -8051,15 +8101,17 @@ function useVerificationController() {
8051
8101
  next(new BadRequestError31(error.message));
8052
8102
  return;
8053
8103
  }
8054
- const email = req.body.email ?? "";
8055
- const app = req.body.app ?? [];
8056
- const role = req.body.role ?? "";
8057
- const name = req.body.name ?? "";
8058
- const org = req.body.org ?? "";
8059
- const siteId = req.body.siteId ?? "";
8060
- const siteName = req.body.siteName ?? "";
8061
8104
  try {
8062
- await _createSimpleUserInvite({
8105
+ const {
8106
+ email,
8107
+ app,
8108
+ role,
8109
+ name,
8110
+ org,
8111
+ siteId,
8112
+ siteName
8113
+ } = value;
8114
+ const verificationIds = await _createSimpleUserInvite({
8063
8115
  email,
8064
8116
  metadata: {
8065
8117
  app,
@@ -8071,7 +8123,9 @@ function useVerificationController() {
8071
8123
  }
8072
8124
  });
8073
8125
  res.status(201).json({
8074
- message: "Successfully invited user."
8126
+ message: "Successfully invited user.",
8127
+ totalInvites: verificationIds.length,
8128
+ verificationIds
8075
8129
  });
8076
8130
  return;
8077
8131
  } catch (error2) {
@@ -8531,7 +8585,8 @@ function useOrgController() {
8531
8585
  getByEmail: _getByEmail,
8532
8586
  getAll: _getAll,
8533
8587
  add: _add,
8534
- update: _update
8588
+ update: _update,
8589
+ getOrgsByEmail: _getOrgsByEmail
8535
8590
  } = useOrgRepo();
8536
8591
  async function add(req, res, next) {
8537
8592
  const validation = Joi18.object({
@@ -8715,6 +8770,30 @@ function useOrgController() {
8715
8770
  return;
8716
8771
  }
8717
8772
  }
8773
+ async function getOrgsByEmail(req, res, next) {
8774
+ const validation = Joi18.object({
8775
+ email: Joi18.string().email().required()
8776
+ });
8777
+ const query = {
8778
+ email: req.params.email
8779
+ };
8780
+ const { error } = validation.validate(query);
8781
+ if (error) {
8782
+ logger25.log({ level: "error", message: error.message });
8783
+ next(new BadRequestError33(error.message));
8784
+ return;
8785
+ }
8786
+ const email = req.params.email;
8787
+ try {
8788
+ const data = await _getOrgsByEmail(email);
8789
+ res.json(data);
8790
+ return;
8791
+ } catch (error2) {
8792
+ logger25.log({ level: "error", message: error2.message });
8793
+ next(error2);
8794
+ return;
8795
+ }
8796
+ }
8718
8797
  async function update(req, res, next) {
8719
8798
  const validation = Joi18.object({
8720
8799
  name: Joi18.string().optional(),
@@ -8748,7 +8827,8 @@ function useOrgController() {
8748
8827
  getByName,
8749
8828
  getById,
8750
8829
  getByEmail,
8751
- update
8830
+ update,
8831
+ getOrgsByEmail
8752
8832
  };
8753
8833
  }
8754
8834
 
@@ -26552,7 +26632,14 @@ function usePersonService() {
26552
26632
  password: hashedPassword,
26553
26633
  name: value.name,
26554
26634
  status: value.platform == "mobile" ? "pending" : "active",
26555
- defaultOrg: value.org?.toString() || ""
26635
+ defaultOrg: value.org?.toString() || "",
26636
+ block: value.block,
26637
+ level: value.level,
26638
+ type: value.type,
26639
+ unitName: value.unitName,
26640
+ contact: value.contact,
26641
+ site: value.site?.toString() || "",
26642
+ unitId: value.unit?.toString() || ""
26556
26643
  };
26557
26644
  const userId = await addUser(user, session);
26558
26645
  value.user = userId.toString();
@@ -31283,26 +31370,31 @@ var schemaDocumentManagement = Joi74.object({
31283
31370
  _id: Joi74.string().hex().optional().allow("", null),
31284
31371
  name: Joi74.string().required(),
31285
31372
  type: Joi74.string().optional().allow("", null),
31286
- attachment: Joi74.string().required(),
31287
- status: Joi74.string().required(),
31288
- createdBy: Joi74.string().hex().required(),
31373
+ attachment: Joi74.when("isFolder", { is: true, then: Joi74.forbidden(), otherwise: Joi74.string().optional().allow("", null) }),
31374
+ remarks: Joi74.string().optional().allow("", null),
31375
+ isFolder: Joi74.boolean().optional().default(false),
31289
31376
  org: Joi74.string().hex().optional().allow("", null),
31290
31377
  site: Joi74.string().hex().optional().allow("", null),
31378
+ parentId: Joi74.string().hex().optional().allow("", null),
31379
+ createdBy: Joi74.string().hex().required(),
31291
31380
  updatedBy: Joi74.string().hex().optional().allow("", null),
31292
31381
  createdAt: Joi74.date().optional().allow("", null),
31293
- updatedAt: Joi74.date().optional().allow("", null)
31382
+ updatedAt: Joi74.date().optional().allow("", null),
31383
+ status: Joi74.string().optional().allow("", null).default("active")
31294
31384
  });
31295
31385
  var schemaUpdateDocumentManagement = Joi74.object({
31296
31386
  _id: Joi74.string().hex().required(),
31297
31387
  name: Joi74.string().optional().allow("", null),
31298
31388
  type: Joi74.string().optional().allow("", null),
31299
- attachment: Joi74.string().optional(),
31300
- status: Joi74.string().optional().allow("", null),
31389
+ attachment: Joi74.when("isFolder", { is: true, then: Joi74.forbidden(), otherwise: Joi74.string().optional().allow("", null) }),
31390
+ remarks: Joi74.string().optional().allow("", null),
31391
+ isFolder: Joi74.boolean().optional(),
31301
31392
  org: Joi74.string().hex().optional().allow("", null),
31302
31393
  site: Joi74.string().hex().optional().allow("", null),
31394
+ parentId: Joi74.string().hex().optional().allow("", null),
31303
31395
  updatedBy: Joi74.string().hex().optional().allow("", null),
31304
- createdAt: Joi74.date().optional().allow("", null),
31305
- updatedAt: Joi74.date().optional().allow("", null)
31396
+ updatedAt: Joi74.date().optional().allow("", null),
31397
+ status: Joi74.string().optional().allow("", null)
31306
31398
  });
31307
31399
  function MDocumentManagement(value) {
31308
31400
  const { error } = schemaDocumentManagement.validate(value);
@@ -31330,18 +31422,31 @@ function MDocumentManagement(value) {
31330
31422
  throw new Error("Invalid site ID.");
31331
31423
  }
31332
31424
  }
31425
+ if (value.parentId && typeof value.parentId === "string") {
31426
+ try {
31427
+ value.parentId = new ObjectId76(value.parentId);
31428
+ } catch (error2) {
31429
+ throw new Error("Invalid parentId.");
31430
+ }
31431
+ }
31432
+ if (value.isFolder) {
31433
+ value.attachment = void 0;
31434
+ }
31333
31435
  return {
31334
31436
  _id: value._id,
31335
31437
  name: value.name,
31336
31438
  type: value.type,
31337
31439
  attachment: value.attachment,
31338
- status: value.status,
31440
+ remarks: value.remarks ?? "",
31441
+ isFolder: value.isFolder ?? false,
31339
31442
  org: value.org,
31340
31443
  site: value.site,
31444
+ ...value.parentId ? { parentId: value.parentId } : {},
31341
31445
  createdBy: value.createdBy,
31342
31446
  updatedBy: value.updatedBy,
31343
31447
  createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
31344
- updatedAt: value.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
31448
+ updatedAt: value.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
31449
+ status: value.status ?? "active"
31345
31450
  };
31346
31451
  }
31347
31452
 
@@ -31365,11 +31470,22 @@ function useDocumentManagementRepo() {
31365
31470
  const namespace_collection = "documents";
31366
31471
  const collection = db.collection(namespace_collection);
31367
31472
  const { delNamespace, getCache, setCache } = useCache40(namespace_collection);
31473
+ async function createIndex() {
31474
+ try {
31475
+ await collection.createIndexes([
31476
+ { key: { site: 1 } },
31477
+ { key: { isFolder: 1 } },
31478
+ { key: { parentId: 1 } }
31479
+ ]);
31480
+ } catch (error) {
31481
+ throw new InternalServerError41("Failed to create index on document.");
31482
+ }
31483
+ }
31368
31484
  async function createTextIndex() {
31369
31485
  try {
31370
31486
  await collection.createIndex({
31371
31487
  name: "text",
31372
- type: "text"
31488
+ remarks: "text"
31373
31489
  });
31374
31490
  } catch (error) {
31375
31491
  throw new InternalServerError41("Failed to create text index on document.");
@@ -31403,7 +31519,8 @@ function useDocumentManagementRepo() {
31403
31519
  sort = {},
31404
31520
  status = "active",
31405
31521
  org = "",
31406
- site = ""
31522
+ site = "",
31523
+ parentId = ""
31407
31524
  }) {
31408
31525
  page = page > 0 ? page - 1 : 0;
31409
31526
  try {
@@ -31422,14 +31539,24 @@ function useDocumentManagementRepo() {
31422
31539
  const query = {
31423
31540
  ...status ? { $and: [{ status }, { status: { $ne: "deleted" } }] } : { status: { $ne: "deleted" } }
31424
31541
  };
31425
- if (site) {
31426
- query.site = site;
31427
- cacheOptions.site = site;
31542
+ if (org) {
31543
+ query.org = new ObjectId77(org);
31544
+ cacheOptions.org = org.toString();
31545
+ }
31546
+ if (parentId) {
31547
+ try {
31548
+ query.parentId = new ObjectId77(parentId);
31549
+ cacheOptions.parentId = parentId.toString();
31550
+ } catch (error) {
31551
+ throw new BadRequestError124("Invalid parentId format.");
31552
+ }
31553
+ } else {
31554
+ query.parentId = { $in: [null, ""] };
31428
31555
  }
31429
31556
  if (search) {
31430
31557
  query.$or = [
31431
31558
  { name: { $regex: search, $options: "i" } },
31432
- { type: { $regex: search, $options: "i" } }
31559
+ { remarks: { $regex: search, $options: "i" } }
31433
31560
  ];
31434
31561
  cacheOptions.search = search;
31435
31562
  }
@@ -31451,6 +31578,9 @@ function useDocumentManagementRepo() {
31451
31578
  type: 1,
31452
31579
  status: 1,
31453
31580
  attachment: 1,
31581
+ parentId: 1,
31582
+ isFolder: 1,
31583
+ remarks: 1,
31454
31584
  createdAt: 1,
31455
31585
  updatedAt: 1
31456
31586
  }
@@ -31622,6 +31752,7 @@ function useDocumentManagementRepo() {
31622
31752
  }
31623
31753
  }
31624
31754
  return {
31755
+ createIndex,
31625
31756
  createTextIndex,
31626
31757
  add,
31627
31758
  getAll,
@@ -31639,7 +31770,7 @@ import {
31639
31770
  NotFoundError as NotFoundError29
31640
31771
  } from "@7365admin1/node-server-utils";
31641
31772
  function useDocumentManagementService() {
31642
- const { add: _add, getAll: _getAll } = useDocumentManagementRepo();
31773
+ const { add: _add } = useDocumentManagementRepo();
31643
31774
  const { updateStatusById } = useFileRepo();
31644
31775
  async function createDocument(value) {
31645
31776
  const session = useAtlas65.getClient()?.startSession();
@@ -31669,32 +31800,8 @@ function useDocumentManagementService() {
31669
31800
  session?.endSession();
31670
31801
  }
31671
31802
  }
31672
- async function getDocuments({
31673
- search,
31674
- page,
31675
- limit,
31676
- sort,
31677
- status,
31678
- org,
31679
- site
31680
- }) {
31681
- try {
31682
- return await _getAll({
31683
- search,
31684
- page,
31685
- limit,
31686
- sort,
31687
- status,
31688
- org,
31689
- site
31690
- });
31691
- } catch (error) {
31692
- throw error;
31693
- }
31694
- }
31695
31803
  return {
31696
- createDocument,
31697
- getDocuments
31804
+ createDocument
31698
31805
  };
31699
31806
  }
31700
31807
 
@@ -31702,8 +31809,9 @@ function useDocumentManagementService() {
31702
31809
  import { BadRequestError as BadRequestError126, logger as logger104 } from "@7365admin1/node-server-utils";
31703
31810
  import Joi75 from "joi";
31704
31811
  function useDocumentManagementController() {
31705
- const { createDocument: _add, getDocuments: _getDocuments } = useDocumentManagementService();
31812
+ const { createDocument: _add } = useDocumentManagementService();
31706
31813
  const {
31814
+ getAll: _getDocuments,
31707
31815
  getDocumentById: _getDocumentById,
31708
31816
  updateDocumentById: _updateDocumentById,
31709
31817
  deleteDocumentById: _deleteDocumentById,
@@ -31721,8 +31829,12 @@ function useDocumentManagementController() {
31721
31829
  createdBy = req.body.createdBy;
31722
31830
  }
31723
31831
  const payload = { ...req.body, createdBy };
31724
- if (payload.attachment.length > 0) {
31832
+ if (payload.isFolder) {
31833
+ delete payload.attachment;
31834
+ } else if (Array.isArray(payload.attachment)) {
31725
31835
  payload.attachment = payload.attachment[0];
31836
+ } else if (!payload.attachment) {
31837
+ payload.attachment = "";
31726
31838
  }
31727
31839
  const { error } = schemaDocumentManagement.validate(payload, {
31728
31840
  abortEarly: false
@@ -31750,7 +31862,8 @@ function useDocumentManagementController() {
31750
31862
  limit: Joi75.number().integer().min(1).max(100).allow("", null).default(10),
31751
31863
  status: Joi75.string().required(),
31752
31864
  org: Joi75.string().hex().optional().allow("", null),
31753
- site: Joi75.string().hex().optional().allow("", null)
31865
+ site: Joi75.string().hex().optional().allow("", null),
31866
+ parentId: Joi75.string().hex().optional().allow("", null)
31754
31867
  });
31755
31868
  const query = { ...req.query };
31756
31869
  query.status = req.query.status;
@@ -31766,6 +31879,7 @@ function useDocumentManagementController() {
31766
31879
  const status = req.query.status ?? "active";
31767
31880
  const org = req.query.org ?? "";
31768
31881
  const site = req.query.site ?? "";
31882
+ const parentId = req.query.parentId ?? "";
31769
31883
  try {
31770
31884
  const data = await _getDocuments({
31771
31885
  search,
@@ -31773,7 +31887,8 @@ function useDocumentManagementController() {
31773
31887
  limit,
31774
31888
  status,
31775
31889
  org,
31776
- site
31890
+ site,
31891
+ parentId
31777
31892
  });
31778
31893
  res.json(data);
31779
31894
  return;
@@ -31829,8 +31944,12 @@ function useDocumentManagementController() {
31829
31944
  }
31830
31945
  const _id = req.params.id;
31831
31946
  const payload = { ...req.body, updatedBy };
31832
- if (payload.attachment.length > 0) {
31947
+ if (payload.isFolder) {
31948
+ delete payload.attachment;
31949
+ } else if (Array.isArray(payload.attachment)) {
31833
31950
  payload.attachment = payload.attachment[0];
31951
+ } else if (!payload.attachment) {
31952
+ payload.attachment = "";
31834
31953
  }
31835
31954
  const { error } = validation.validate({ _id, ...payload });
31836
31955
  if (error) {
@@ -36340,10 +36459,42 @@ function UseAccessManagementRepo() {
36340
36459
  },
36341
36460
  {
36342
36461
  $facet: {
36343
- available_physical: [{ $match: { assignedUnit: { $eq: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
36344
- available_non_physical: [{ $match: { assignedUnit: { $eq: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }],
36345
- assigned_physical: [{ $match: { assignedUnit: { $ne: null }, type: "NFC" /* NFC */ } }, { $count: "count" }],
36346
- assigned_non_physical: [{ $match: { assignedUnit: { $ne: null }, type: "QRCODE" /* QR */ } }, { $count: "count" }]
36462
+ available_physical: [
36463
+ {
36464
+ $match: {
36465
+ assignedUnit: { $eq: null },
36466
+ type: "NFC" /* NFC */
36467
+ }
36468
+ },
36469
+ { $count: "count" }
36470
+ ],
36471
+ available_non_physical: [
36472
+ {
36473
+ $match: {
36474
+ assignedUnit: { $eq: null },
36475
+ type: "QRCODE" /* QR */
36476
+ }
36477
+ },
36478
+ { $count: "count" }
36479
+ ],
36480
+ assigned_physical: [
36481
+ {
36482
+ $match: {
36483
+ assignedUnit: { $ne: null },
36484
+ type: "NFC" /* NFC */
36485
+ }
36486
+ },
36487
+ { $count: "count" }
36488
+ ],
36489
+ assigned_non_physical: [
36490
+ {
36491
+ $match: {
36492
+ assignedUnit: { $ne: null },
36493
+ type: "QRCODE" /* QR */
36494
+ }
36495
+ },
36496
+ { $count: "count" }
36497
+ ]
36347
36498
  }
36348
36499
  }
36349
36500
  ]).toArray();
@@ -36428,16 +36579,35 @@ function UseAccessManagementRepo() {
36428
36579
  case terms.length >= 3:
36429
36580
  return {
36430
36581
  $and: [
36431
- { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
36432
- { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } },
36433
- { $expr: { $eq: [{ $toLower: "$level.units.name" }, getAfterSecondSlash(search)] } }
36582
+ {
36583
+ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
36584
+ },
36585
+ {
36586
+ $expr: {
36587
+ $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
36588
+ }
36589
+ },
36590
+ {
36591
+ $expr: {
36592
+ $eq: [
36593
+ { $toLower: "$level.units.name" },
36594
+ getAfterSecondSlash(search)
36595
+ ]
36596
+ }
36597
+ }
36434
36598
  ]
36435
36599
  };
36436
36600
  case terms.length === 2:
36437
36601
  return {
36438
36602
  $and: [
36439
- { $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] } },
36440
- { $expr: { $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()] } }
36603
+ {
36604
+ $expr: { $eq: [{ $toLower: "$name" }, terms[0].toLowerCase()] }
36605
+ },
36606
+ {
36607
+ $expr: {
36608
+ $eq: [{ $toLower: "$level.level" }, terms[1].toLowerCase()]
36609
+ }
36610
+ }
36441
36611
  ]
36442
36612
  };
36443
36613
  default:
@@ -36465,220 +36635,386 @@ function UseAccessManagementRepo() {
36465
36635
  site
36466
36636
  };
36467
36637
  const searchQuery = buildSearchQuery(search);
36468
- const result = await collectionName("buildings").aggregate([
36469
- // ✅ Match early with index-friendly query
36470
- {
36471
- $match: {
36472
- ...defaultQuery,
36473
- status: { $eq: "active" }
36474
- }
36475
- },
36476
- // ✅ Only project needed fields before heavy lookups
36477
- {
36478
- $project: {
36479
- _id: 1,
36480
- name: 1,
36481
- site: 1,
36482
- block: 1
36483
- }
36484
- },
36485
- // ✅ Use localField/foreignField for better index usage
36486
- {
36487
- $lookup: {
36488
- from: "building-levels",
36489
- localField: "_id",
36490
- foreignField: "block",
36491
- pipeline: [
36492
- { $match: { status: { $ne: "deleted" } } },
36493
- {
36494
- $lookup: {
36495
- from: "building-units",
36496
- localField: "_id",
36497
- foreignField: "level",
36498
- pipeline: [
36499
- { $match: { status: { $ne: "deleted" }, site } },
36500
- { $project: { _id: 1, name: 1 } }
36501
- ],
36502
- as: "units"
36503
- }
36504
- },
36505
- {
36506
- $match: { "units.0": { $exists: true } }
36507
- },
36508
- {
36509
- $project: {
36510
- _id: 1,
36511
- level: 1,
36512
- units: 1
36638
+ const result = await collectionName("buildings").aggregate(
36639
+ [
36640
+ // ✅ Match early with index-friendly query
36641
+ {
36642
+ $match: {
36643
+ ...defaultQuery,
36644
+ status: { $eq: "active" }
36645
+ }
36646
+ },
36647
+ // ✅ Only project needed fields before heavy lookups
36648
+ {
36649
+ $project: {
36650
+ _id: 1,
36651
+ name: 1,
36652
+ site: 1,
36653
+ block: 1
36654
+ }
36655
+ },
36656
+ // ✅ Use localField/foreignField for better index usage
36657
+ {
36658
+ $lookup: {
36659
+ from: "building-levels",
36660
+ localField: "_id",
36661
+ foreignField: "block",
36662
+ pipeline: [
36663
+ { $match: { status: { $ne: "deleted" } } },
36664
+ {
36665
+ $lookup: {
36666
+ from: "building-units",
36667
+ localField: "_id",
36668
+ foreignField: "level",
36669
+ pipeline: [
36670
+ { $match: { status: { $ne: "deleted" }, site } },
36671
+ { $project: { _id: 1, name: 1 } }
36672
+ ],
36673
+ as: "units"
36674
+ }
36675
+ },
36676
+ {
36677
+ $match: { "units.0": { $exists: true } }
36678
+ },
36679
+ {
36680
+ $project: {
36681
+ _id: 1,
36682
+ level: 1,
36683
+ units: 1
36684
+ }
36513
36685
  }
36514
- }
36515
- ],
36516
- as: "level"
36517
- }
36518
- },
36519
- // ✅ Filter out buildings with no levels early
36520
- {
36521
- $match: { "level.0": { $exists: true } }
36522
- },
36523
- // ✅ Unwind to flatten the hierarchy
36524
- {
36525
- $unwind: {
36526
- path: "$level",
36527
- preserveNullAndEmptyArrays: false
36528
- }
36529
- },
36530
- {
36531
- $unwind: {
36532
- path: "$level.units",
36533
- preserveNullAndEmptyArrays: false
36534
- }
36535
- },
36536
- // // Groups by unit _id and keeps only the first occurrence
36537
- // {
36538
- // $group: {
36539
- // _id: "$level.units._id",
36540
- // doc: { $first: "$$ROOT" },
36541
- // },
36542
- // },
36543
- // {
36544
- // $replaceRoot: { newRoot: "$doc" },
36545
- // },
36546
- // ✅ Apply search filter
36547
- {
36548
- $match: {
36549
- ...searchQuery
36550
- }
36551
- },
36552
- {
36553
- $facet: {
36554
- totalCount: [{ $count: "count" }],
36555
- items: [
36556
- // Sort BEFORE skip/limit for correct pagination
36557
- { $skip: page * limit },
36558
- { $limit: limit },
36559
- // ✅ Users lookup - optimized with index hint
36560
- {
36561
- $lookup: {
36562
- from: "users",
36563
- let: { unit: "$level.units._id" },
36564
- pipeline: [
36565
- {
36566
- $match: {
36567
- $expr: { $eq: ["$unitNumber", "$$unit"] },
36568
- residentType: "House/Unit Owner"
36686
+ ],
36687
+ as: "level"
36688
+ }
36689
+ },
36690
+ // ✅ Filter out buildings with no levels early
36691
+ {
36692
+ $match: { "level.0": { $exists: true } }
36693
+ },
36694
+ // ✅ Unwind to flatten the hierarchy
36695
+ {
36696
+ $unwind: {
36697
+ path: "$level",
36698
+ preserveNullAndEmptyArrays: false
36699
+ }
36700
+ },
36701
+ {
36702
+ $unwind: {
36703
+ path: "$level.units",
36704
+ preserveNullAndEmptyArrays: false
36705
+ }
36706
+ },
36707
+ // // Groups by unit _id and keeps only the first occurrence
36708
+ // {
36709
+ // $group: {
36710
+ // _id: "$level.units._id",
36711
+ // doc: { $first: "$$ROOT" },
36712
+ // },
36713
+ // },
36714
+ // {
36715
+ // $replaceRoot: { newRoot: "$doc" },
36716
+ // },
36717
+ // ✅ Apply search filter
36718
+ {
36719
+ $match: {
36720
+ ...searchQuery
36721
+ }
36722
+ },
36723
+ {
36724
+ $facet: {
36725
+ totalCount: [{ $count: "count" }],
36726
+ items: [
36727
+ // ✅ Sort BEFORE skip/limit for correct pagination
36728
+ { $skip: page * limit },
36729
+ { $limit: limit },
36730
+ // Users lookup - optimized with index hint
36731
+ {
36732
+ $lookup: {
36733
+ from: "users",
36734
+ let: { unit: "$level.units._id" },
36735
+ pipeline: [
36736
+ {
36737
+ $match: {
36738
+ $expr: { $eq: ["$unitNumber", "$$unit"] },
36739
+ residentType: "House/Unit Owner"
36740
+ }
36741
+ },
36742
+ { $limit: 1 },
36743
+ { $project: { _id: 1, givenName: 1, surname: 1 } }
36744
+ ],
36745
+ as: "unitOwner"
36746
+ }
36747
+ },
36748
+ // ✅ Access card lookup - optimized query
36749
+ {
36750
+ $lookup: {
36751
+ from: "access-cards",
36752
+ let: { unit: "$level.units._id" },
36753
+ pipeline: [
36754
+ {
36755
+ $match: {
36756
+ $expr: {
36757
+ $in: [
36758
+ "$$unit",
36759
+ {
36760
+ $cond: [
36761
+ { $isArray: "$assignedUnit" },
36762
+ "$assignedUnit",
36763
+ ["$assignedUnit"]
36764
+ ]
36765
+ }
36766
+ ]
36767
+ },
36768
+ userType
36769
+ }
36770
+ },
36771
+ {
36772
+ $project: {
36773
+ _id: 1,
36774
+ userId: 1,
36775
+ type: 1,
36776
+ cardNo: 1,
36777
+ isActivated: 1,
36778
+ replacementStatus: 1
36779
+ }
36780
+ }
36781
+ ],
36782
+ as: "accessCards"
36783
+ }
36784
+ },
36785
+ // ✅ Compute all card categorization and counts in ONE stage
36786
+ {
36787
+ $addFields: {
36788
+ f_Available: {
36789
+ $filter: {
36790
+ input: "$accessCards",
36791
+ as: "card",
36792
+ cond: {
36793
+ $and: [
36794
+ { $eq: ["$$card.userId", null] },
36795
+ { $eq: ["$$card.isActivated", true] }
36796
+ ]
36797
+ }
36569
36798
  }
36570
36799
  },
36571
- { $limit: 1 },
36572
- { $project: { _id: 1, givenName: 1, surname: 1 } }
36573
- ],
36574
- as: "unitOwner"
36575
- }
36576
- },
36577
- // Access card lookup - optimized query
36578
- {
36579
- $lookup: {
36580
- from: "access-cards",
36581
- let: { unit: "$level.units._id" },
36582
- pipeline: [
36583
- {
36584
- $match: {
36585
- $expr: {
36586
- $in: [
36587
- "$$unit",
36588
- { $cond: [{ $isArray: "$assignedUnit" }, "$assignedUnit", ["$assignedUnit"]] }
36800
+ f_Assigned: {
36801
+ $filter: {
36802
+ input: "$accessCards",
36803
+ as: "card",
36804
+ cond: {
36805
+ $and: [
36806
+ { $ne: ["$$card.userId", null] },
36807
+ { $eq: ["$$card.isActivated", true] }
36589
36808
  ]
36590
- },
36591
- userType
36809
+ }
36592
36810
  }
36593
36811
  },
36594
- { $project: { _id: 1, userId: 1, type: 1, cardNo: 1, isActivated: 1, replacementStatus: 1 } }
36595
- ],
36596
- as: "accessCards"
36597
- }
36598
- },
36599
- // ✅ Compute all card categorization and counts in ONE stage
36600
- {
36601
- $addFields: {
36602
- f_Available: {
36603
- $filter: {
36604
- input: "$accessCards",
36605
- as: "card",
36606
- cond: { $and: [{ $eq: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
36607
- }
36608
- },
36609
- f_Assigned: {
36610
- $filter: {
36611
- input: "$accessCards",
36612
- as: "card",
36613
- cond: { $and: [{ $ne: ["$$card.userId", null] }, { $eq: ["$$card.isActivated", true] }] }
36614
- }
36615
- },
36616
- f_replaced: {
36617
- $filter: {
36618
- input: "$accessCards",
36619
- as: "card",
36620
- cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $ne: ["$$card.replacementStatus", null] }] }
36621
- }
36622
- },
36623
- f_deleted: {
36624
- $filter: {
36625
- input: "$accessCards",
36626
- as: "card",
36627
- cond: { $and: [{ $eq: ["$$card.isActivated", false] }, { $eq: ["$$card.replacementStatus", null] }] }
36812
+ f_replaced: {
36813
+ $filter: {
36814
+ input: "$accessCards",
36815
+ as: "card",
36816
+ cond: {
36817
+ $and: [
36818
+ { $eq: ["$$card.isActivated", false] },
36819
+ { $ne: ["$$card.replacementStatus", null] }
36820
+ ]
36821
+ }
36822
+ }
36823
+ },
36824
+ f_deleted: {
36825
+ $filter: {
36826
+ input: "$accessCards",
36827
+ as: "card",
36828
+ cond: {
36829
+ $and: [
36830
+ { $eq: ["$$card.isActivated", false] },
36831
+ { $eq: ["$$card.replacementStatus", null] }
36832
+ ]
36833
+ }
36834
+ }
36628
36835
  }
36629
36836
  }
36630
- }
36631
- },
36632
- // ✅ Final projection with all computed fields
36633
- {
36634
- $project: {
36635
- _id: "$level.units._id",
36636
- name: "$level.units.name",
36637
- level: { _id: "$level._id", level: "$level.level" },
36638
- block: { _id: "$_id", name: "$name", block: "$block" },
36639
- site: "$site",
36640
- unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
36641
- available: {
36642
- physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36643
- non_physical: { $filter: { input: "$f_Available", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36644
- },
36645
- assigned: {
36646
- physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36647
- non_physical: { $filter: { input: "$f_Assigned", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36648
- },
36649
- cardCounts: {
36837
+ },
36838
+ // ✅ Final projection with all computed fields
36839
+ {
36840
+ $project: {
36841
+ _id: "$level.units._id",
36842
+ name: "$level.units.name",
36843
+ level: { _id: "$level._id", level: "$level.level" },
36844
+ block: { _id: "$_id", name: "$name", block: "$block" },
36845
+ site: "$site",
36846
+ unit_owner: { $arrayElemAt: ["$unitOwner", 0] },
36650
36847
  available: {
36651
- physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36652
- non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36848
+ physical: {
36849
+ $filter: {
36850
+ input: "$f_Available",
36851
+ as: "c",
36852
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36853
+ }
36854
+ },
36855
+ non_physical: {
36856
+ $filter: {
36857
+ input: "$f_Available",
36858
+ as: "c",
36859
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36860
+ }
36861
+ }
36653
36862
  },
36654
36863
  assigned: {
36655
- physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36656
- non_physical: { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36864
+ physical: {
36865
+ $filter: {
36866
+ input: "$f_Assigned",
36867
+ as: "c",
36868
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36869
+ }
36870
+ },
36871
+ non_physical: {
36872
+ $filter: {
36873
+ input: "$f_Assigned",
36874
+ as: "c",
36875
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36876
+ }
36877
+ }
36878
+ },
36879
+ cardCounts: {
36880
+ available: {
36881
+ physical: {
36882
+ $size: {
36883
+ $filter: {
36884
+ input: { $ifNull: ["$f_Available", []] },
36885
+ as: "c",
36886
+ cond: {
36887
+ $eq: ["$$c.type", "NFC" /* NFC */]
36888
+ }
36889
+ }
36890
+ }
36891
+ },
36892
+ non_physical: {
36893
+ $size: {
36894
+ $filter: {
36895
+ input: { $ifNull: ["$f_Available", []] },
36896
+ as: "c",
36897
+ cond: {
36898
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36899
+ }
36900
+ }
36901
+ }
36902
+ }
36903
+ },
36904
+ assigned: {
36905
+ physical: {
36906
+ $size: {
36907
+ $filter: {
36908
+ input: { $ifNull: ["$f_Assigned", []] },
36909
+ as: "c",
36910
+ cond: {
36911
+ $eq: ["$$c.type", "NFC" /* NFC */]
36912
+ }
36913
+ }
36914
+ }
36915
+ },
36916
+ non_physical: {
36917
+ $size: {
36918
+ $filter: {
36919
+ input: { $ifNull: ["$f_Assigned", []] },
36920
+ as: "c",
36921
+ cond: {
36922
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36923
+ }
36924
+ }
36925
+ }
36926
+ }
36927
+ }
36928
+ },
36929
+ replaced: {
36930
+ physical: {
36931
+ $filter: {
36932
+ input: "$f_replaced",
36933
+ as: "c",
36934
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36935
+ }
36936
+ },
36937
+ non_physical: {
36938
+ $filter: {
36939
+ input: "$f_replaced",
36940
+ as: "c",
36941
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36942
+ }
36943
+ }
36944
+ },
36945
+ deleted: {
36946
+ physical: {
36947
+ $filter: {
36948
+ input: "$f_deleted",
36949
+ as: "c",
36950
+ cond: { $eq: ["$$c.type", "NFC" /* NFC */] }
36951
+ }
36952
+ },
36953
+ non_physical: {
36954
+ $filter: {
36955
+ input: "$f_deleted",
36956
+ as: "c",
36957
+ cond: { $eq: ["$$c.type", "QRCODE" /* QR */] }
36958
+ }
36959
+ }
36960
+ },
36961
+ totalCardCount: {
36962
+ $add: [
36963
+ {
36964
+ $size: {
36965
+ $filter: {
36966
+ input: { $ifNull: ["$f_Available", []] },
36967
+ as: "c",
36968
+ cond: {
36969
+ $eq: ["$$c.type", "NFC" /* NFC */]
36970
+ }
36971
+ }
36972
+ }
36973
+ },
36974
+ {
36975
+ $size: {
36976
+ $filter: {
36977
+ input: { $ifNull: ["$f_Available", []] },
36978
+ as: "c",
36979
+ cond: {
36980
+ $eq: ["$$c.type", "QRCODE" /* QR */]
36981
+ }
36982
+ }
36983
+ }
36984
+ },
36985
+ {
36986
+ $size: {
36987
+ $filter: {
36988
+ input: { $ifNull: ["$f_Assigned", []] },
36989
+ as: "c",
36990
+ cond: {
36991
+ $eq: ["$$c.type", "NFC" /* NFC */]
36992
+ }
36993
+ }
36994
+ }
36995
+ },
36996
+ {
36997
+ $size: {
36998
+ $filter: {
36999
+ input: { $ifNull: ["$f_Assigned", []] },
37000
+ as: "c",
37001
+ cond: {
37002
+ $eq: ["$$c.type", "QRCODE" /* QR */]
37003
+ }
37004
+ }
37005
+ }
37006
+ }
37007
+ ]
36657
37008
  }
36658
- },
36659
- replaced: {
36660
- physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36661
- non_physical: { $filter: { input: "$f_replaced", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36662
- },
36663
- deleted: {
36664
- physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } },
36665
- non_physical: { $filter: { input: "$f_deleted", as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } }
36666
- },
36667
- totalCardCount: {
36668
- $add: [
36669
- { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36670
- { $size: { $filter: { input: { $ifNull: ["$f_Available", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } },
36671
- { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "NFC" /* NFC */] } } } },
36672
- { $size: { $filter: { input: { $ifNull: ["$f_Assigned", []] }, as: "c", cond: { $eq: ["$$c.type", "QRCODE" /* QR */] } } } }
36673
- ]
36674
37009
  }
36675
- }
36676
- },
36677
- { $sort: { totalCardCount: -1 } }
36678
- ]
37010
+ },
37011
+ { $sort: { totalCardCount: -1 } }
37012
+ ]
37013
+ }
36679
37014
  }
36680
- }
36681
- ], { allowDiskUse: true }).toArray();
37015
+ ],
37016
+ { allowDiskUse: true }
37017
+ ).toArray();
36682
37018
  const totalCount = result[0]?.totalCount?.[0]?.count ?? 0;
36683
37019
  const items = result[0]?.items ?? [];
36684
37020
  const paginatedResult = paginate39(items, page, limit, totalCount);
@@ -36697,157 +37033,162 @@ function UseAccessManagementRepo() {
36697
37033
  site: { $in: [site] }
36698
37034
  };
36699
37035
  const searchQuery = buildSearchQuery(search);
36700
- const result = await collectionName("buildings").aggregate([
36701
- // ✅ Match early with index-friendly query
36702
- {
36703
- $match: {
36704
- ...query,
36705
- status: { $ne: "deleted" }
36706
- }
36707
- },
36708
- // ✅ Only project needed fields before heavy lookups
36709
- {
36710
- $project: {
36711
- _id: 1,
36712
- name: 1,
36713
- site: 1
36714
- }
36715
- },
36716
- // ✅ Use localField/foreignField for better index usage
36717
- {
36718
- $lookup: {
36719
- from: "building-levels",
36720
- localField: "_id",
36721
- foreignField: "block",
36722
- pipeline: [
36723
- { $match: { status: { $ne: "deleted" } } },
36724
- {
36725
- $lookup: {
36726
- from: "building-units",
36727
- localField: "_id",
36728
- foreignField: "level",
36729
- pipeline: [
36730
- { $match: { status: { $ne: "deleted" } } },
36731
- { $project: { _id: 1, name: 1 } },
36732
- {
36733
- $lookup: {
36734
- from: "access-cards",
36735
- localField: "_id",
36736
- foreignField: "assignedUnit",
36737
- pipeline: [
36738
- {
36739
- $match: {
36740
- isActivated: true,
36741
- userType,
36742
- type
36743
- }
36744
- },
36745
- {
36746
- $group: {
36747
- _id: null,
36748
- accessLevels: { $addToSet: "$accessLevel" },
36749
- liftAccessLevels: { $addToSet: "$liftAccessLevel" },
36750
- doorNames: { $addToSet: "$doorName" },
36751
- liftNames: { $addToSet: "$liftName" },
36752
- cards: {
36753
- $push: {
36754
- _id: "$_id",
36755
- cardNo: "$cardNo",
36756
- accessLevel: "$accessLevel",
36757
- liftAccessLevel: "$liftAccessLevel",
36758
- doorName: "$doorName",
36759
- liftName: "$liftName"
37036
+ const result = await collectionName("buildings").aggregate(
37037
+ [
37038
+ // ✅ Match early with index-friendly query
37039
+ {
37040
+ $match: {
37041
+ ...query,
37042
+ status: { $ne: "deleted" }
37043
+ }
37044
+ },
37045
+ // ✅ Only project needed fields before heavy lookups
37046
+ {
37047
+ $project: {
37048
+ _id: 1,
37049
+ name: 1,
37050
+ site: 1
37051
+ }
37052
+ },
37053
+ // ✅ Use localField/foreignField for better index usage
37054
+ {
37055
+ $lookup: {
37056
+ from: "building-levels",
37057
+ localField: "_id",
37058
+ foreignField: "block",
37059
+ pipeline: [
37060
+ { $match: { status: { $ne: "deleted" } } },
37061
+ {
37062
+ $lookup: {
37063
+ from: "building-units",
37064
+ localField: "_id",
37065
+ foreignField: "level",
37066
+ pipeline: [
37067
+ { $match: { status: { $ne: "deleted" } } },
37068
+ { $project: { _id: 1, name: 1 } },
37069
+ {
37070
+ $lookup: {
37071
+ from: "access-cards",
37072
+ localField: "_id",
37073
+ foreignField: "assignedUnit",
37074
+ pipeline: [
37075
+ {
37076
+ $match: {
37077
+ isActivated: true,
37078
+ userType,
37079
+ type
37080
+ }
37081
+ },
37082
+ {
37083
+ $group: {
37084
+ _id: null,
37085
+ accessLevels: { $addToSet: "$accessLevel" },
37086
+ liftAccessLevels: {
37087
+ $addToSet: "$liftAccessLevel"
37088
+ },
37089
+ doorNames: { $addToSet: "$doorName" },
37090
+ liftNames: { $addToSet: "$liftName" },
37091
+ cards: {
37092
+ $push: {
37093
+ _id: "$_id",
37094
+ cardNo: "$cardNo",
37095
+ accessLevel: "$accessLevel",
37096
+ liftAccessLevel: "$liftAccessLevel",
37097
+ doorName: "$doorName",
37098
+ liftName: "$liftName"
37099
+ }
36760
37100
  }
36761
37101
  }
37102
+ },
37103
+ {
37104
+ $project: {
37105
+ _id: 0,
37106
+ accessCardCount: {
37107
+ $size: "$cards"
37108
+ },
37109
+ accessLevels: 1,
37110
+ liftAccessLevels: 1,
37111
+ doorNames: 1,
37112
+ liftNames: 1
37113
+ }
36762
37114
  }
36763
- },
36764
- {
36765
- $project: {
36766
- _id: 0,
36767
- accessCardCount: {
36768
- $size: "$cards"
36769
- },
36770
- accessLevels: 1,
36771
- liftAccessLevels: 1,
36772
- doorNames: 1,
36773
- liftNames: 1
36774
- }
36775
- }
36776
- ],
36777
- as: "fAccessCards"
36778
- }
36779
- },
36780
- {
36781
- $match: {
36782
- "fAccessCards.0": { $exists: true }
37115
+ ],
37116
+ as: "fAccessCards"
37117
+ }
37118
+ },
37119
+ {
37120
+ $match: {
37121
+ "fAccessCards.0": { $exists: true }
37122
+ }
36783
37123
  }
36784
- }
36785
- ],
36786
- as: "units"
36787
- }
36788
- },
36789
- {
36790
- $match: { "units.0": { $exists: true } }
36791
- },
36792
- {
36793
- $project: {
36794
- _id: 1,
36795
- level: 1,
36796
- units: 1
37124
+ ],
37125
+ as: "units"
37126
+ }
37127
+ },
37128
+ {
37129
+ $match: { "units.0": { $exists: true } }
37130
+ },
37131
+ {
37132
+ $project: {
37133
+ _id: 1,
37134
+ level: 1,
37135
+ units: 1
37136
+ }
36797
37137
  }
36798
- }
36799
- ],
36800
- as: "level"
36801
- }
36802
- },
36803
- // ✅ Filter out buildings with no levels early
36804
- {
36805
- $match: { "level.0": { $exists: true } }
36806
- },
36807
- // ✅ Unwind to flatten the hierarchy
36808
- {
36809
- $unwind: {
36810
- path: "$level",
36811
- preserveNullAndEmptyArrays: false
36812
- }
36813
- },
36814
- {
36815
- $unwind: {
36816
- path: "$level.units",
36817
- preserveNullAndEmptyArrays: false
36818
- }
36819
- },
36820
- {
36821
- $unwind: {
36822
- path: "$level.units.fAccessCards",
36823
- preserveNullAndEmptyArrays: false
36824
- }
36825
- },
36826
- // // Groups by unit _id and keeps only the first occurrence
36827
- {
36828
- $group: {
36829
- _id: "$level.units._id",
36830
- doc: { $first: "$$ROOT" }
36831
- }
36832
- },
36833
- {
36834
- $replaceRoot: { newRoot: "$doc" }
36835
- },
36836
- // ✅ Apply search filter
36837
- {
36838
- $match: {
36839
- ...searchQuery
36840
- }
36841
- },
36842
- {
36843
- $project: {
36844
- name: 1,
36845
- "level.level": 1,
36846
- "level.units.name": 1,
36847
- "level.units.fAccessCards": 1
37138
+ ],
37139
+ as: "level"
37140
+ }
37141
+ },
37142
+ // ✅ Filter out buildings with no levels early
37143
+ {
37144
+ $match: { "level.0": { $exists: true } }
37145
+ },
37146
+ // ✅ Unwind to flatten the hierarchy
37147
+ {
37148
+ $unwind: {
37149
+ path: "$level",
37150
+ preserveNullAndEmptyArrays: false
37151
+ }
37152
+ },
37153
+ {
37154
+ $unwind: {
37155
+ path: "$level.units",
37156
+ preserveNullAndEmptyArrays: false
37157
+ }
37158
+ },
37159
+ {
37160
+ $unwind: {
37161
+ path: "$level.units.fAccessCards",
37162
+ preserveNullAndEmptyArrays: false
37163
+ }
37164
+ },
37165
+ // // Groups by unit _id and keeps only the first occurrence
37166
+ {
37167
+ $group: {
37168
+ _id: "$level.units._id",
37169
+ doc: { $first: "$$ROOT" }
37170
+ }
37171
+ },
37172
+ {
37173
+ $replaceRoot: { newRoot: "$doc" }
37174
+ },
37175
+ // ✅ Apply search filter
37176
+ {
37177
+ $match: {
37178
+ ...searchQuery
37179
+ }
37180
+ },
37181
+ {
37182
+ $project: {
37183
+ name: 1,
37184
+ "level.level": 1,
37185
+ "level.units.name": 1,
37186
+ "level.units.fAccessCards": 1
37187
+ }
36848
37188
  }
36849
- }
36850
- ], { allowDiskUse: true }).toArray();
37189
+ ],
37190
+ { allowDiskUse: true }
37191
+ ).toArray();
36851
37192
  return result;
36852
37193
  } catch (error) {
36853
37194
  throw new Error(error.message);
@@ -36858,8 +37199,12 @@ function UseAccessManagementRepo() {
36858
37199
  try {
36859
37200
  session?.startTransaction();
36860
37201
  const { userId, cardId, site } = params;
36861
- const allUserId = await Promise.all(userId.map(async (id) => new ObjectId90(id)));
36862
- const allCardId = await Promise.all(cardId.map(async (id) => new ObjectId90(id)));
37202
+ const allUserId = await Promise.all(
37203
+ userId.map(async (id) => new ObjectId90(id))
37204
+ );
37205
+ const allCardId = await Promise.all(
37206
+ cardId.map(async (id) => new ObjectId90(id))
37207
+ );
36863
37208
  const siteId = new ObjectId90(site);
36864
37209
  const result = await collection().updateMany(
36865
37210
  {
@@ -36902,16 +37247,19 @@ function UseAccessManagementRepo() {
36902
37247
  liftAccessLevel,
36903
37248
  isActivated: true
36904
37249
  };
36905
- const result = await collection().aggregate([
36906
- {
36907
- $match: query
36908
- },
36909
- {
36910
- $facet: {
36911
- counts: [{ $count: "count" }]
37250
+ const result = await collection().aggregate(
37251
+ [
37252
+ {
37253
+ $match: query
37254
+ },
37255
+ {
37256
+ $facet: {
37257
+ counts: [{ $count: "count" }]
37258
+ }
36912
37259
  }
36913
- }
36914
- ], { allowDiskUse: true }).toArray();
37260
+ ],
37261
+ { allowDiskUse: true }
37262
+ ).toArray();
36915
37263
  return result;
36916
37264
  } catch (error) {
36917
37265
  throw new Error(error.message);
@@ -36945,7 +37293,9 @@ function UseAccessManagementRepo() {
36945
37293
  availableCardNo.push(num);
36946
37294
  num++;
36947
37295
  }
36948
- const cardNumbers = availableCardNo.map((no) => no.toString().padStart(10, "0"));
37296
+ const cardNumbers = availableCardNo.map(
37297
+ (no) => no.toString().padStart(10, "0")
37298
+ );
36949
37299
  const accessCards = [];
36950
37300
  const convertedUnits = unit.map((obj) => new ObjectId90(obj));
36951
37301
  for (let j = 0; j < (unit.length > 0 ? unit.length : quantity); j++) {
@@ -37005,10 +37355,18 @@ function UseAccessManagementRepo() {
37005
37355
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
37006
37356
  accessGroup: ag
37007
37357
  };
37008
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
37358
+ return readTemplate(
37359
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
37360
+ { ...command }
37361
+ );
37009
37362
  }).flat();
37010
- const response = await sendCommand(commands.join("").toString(), params.acm_url);
37011
- const result = await parseStringPromise2(response, { explicitArray: false });
37363
+ const response = await sendCommand(
37364
+ commands.join("").toString(),
37365
+ params.acm_url
37366
+ );
37367
+ const result = await parseStringPromise2(response, {
37368
+ explicitArray: false
37369
+ });
37012
37370
  if (result && result.RESULT.$.STCODE !== "0") {
37013
37371
  throw new Error("Command failed, server error.");
37014
37372
  }
@@ -37042,7 +37400,11 @@ function UseAccessManagementRepo() {
37042
37400
  } else {
37043
37401
  updateFields.isActivated = true;
37044
37402
  }
37045
- const res = await collection().updateOne({ _id: card._id }, { $set: updateFields }, { session });
37403
+ const res = await collection().updateOne(
37404
+ { _id: card._id },
37405
+ { $set: updateFields },
37406
+ { session }
37407
+ );
37046
37408
  results.push({ nfcId: nfc._id, modifiedCount: res.modifiedCount });
37047
37409
  }
37048
37410
  }
@@ -37069,8 +37431,20 @@ function UseAccessManagementRepo() {
37069
37431
  assignedUnit: null,
37070
37432
  userId: null,
37071
37433
  $or: [
37072
- { $and: [{ doorName: { $ne: null } }, { doorName: { $ne: "" } }, { accessLevel: { $ne: null } }] },
37073
- { $and: [{ liftName: { $ne: null } }, { liftName: { $ne: "" } }, { liftAccessLevel: { $ne: null } }] }
37434
+ {
37435
+ $and: [
37436
+ { doorName: { $ne: null } },
37437
+ { doorName: { $ne: "" } },
37438
+ { accessLevel: { $ne: null } }
37439
+ ]
37440
+ },
37441
+ {
37442
+ $and: [
37443
+ { liftName: { $ne: null } },
37444
+ { liftName: { $ne: "" } },
37445
+ { liftAccessLevel: { $ne: null } }
37446
+ ]
37447
+ }
37074
37448
  ]
37075
37449
  }
37076
37450
  },
@@ -37084,7 +37458,13 @@ function UseAccessManagementRepo() {
37084
37458
  accessLevels: {
37085
37459
  $addToSet: {
37086
37460
  $cond: [
37087
- { $and: [{ $ne: ["$doorName", null] }, { $ne: ["$doorName", ""] }, { $ne: ["$accessLevel", null] }] },
37461
+ {
37462
+ $and: [
37463
+ { $ne: ["$doorName", null] },
37464
+ { $ne: ["$doorName", ""] },
37465
+ { $ne: ["$accessLevel", null] }
37466
+ ]
37467
+ },
37088
37468
  { name: "$doorName", no: "$accessLevel" },
37089
37469
  "$$REMOVE"
37090
37470
  ]
@@ -37093,7 +37473,13 @@ function UseAccessManagementRepo() {
37093
37473
  liftAccessLevels: {
37094
37474
  $addToSet: {
37095
37475
  $cond: [
37096
- { $and: [{ $ne: ["$liftName", null] }, { $ne: ["$liftName", ""] }, { $ne: ["$liftAccessLevel", null] }] },
37476
+ {
37477
+ $and: [
37478
+ { $ne: ["$liftName", null] },
37479
+ { $ne: ["$liftName", ""] },
37480
+ { $ne: ["$liftAccessLevel", null] }
37481
+ ]
37482
+ },
37097
37483
  { name: "$liftName", no: "$liftAccessLevel" },
37098
37484
  "$$REMOVE"
37099
37485
  ]
@@ -37129,7 +37515,14 @@ function UseAccessManagementRepo() {
37129
37515
  const sessionResult = await Promise.all([
37130
37516
  await collection().findOneAndUpdate(
37131
37517
  { _id: id },
37132
- { $set: { remarks, replacementStatus: "Complete", requestDate: /* @__PURE__ */ new Date(), isActivated: false } },
37518
+ {
37519
+ $set: {
37520
+ remarks,
37521
+ replacementStatus: "Complete",
37522
+ requestDate: /* @__PURE__ */ new Date(),
37523
+ isActivated: false
37524
+ }
37525
+ },
37133
37526
  { returnDocument: "after", session }
37134
37527
  ),
37135
37528
  await collection().findOneAndUpdate(
@@ -37161,7 +37554,10 @@ function UseAccessManagementRepo() {
37161
37554
  isActivated: true
37162
37555
  };
37163
37556
  if (search) {
37164
- query.$or = [{ accessLevel: { $regex: search, $options: "i" } }, { cardNo: { $regex: search, $options: "i" } }];
37557
+ query.$or = [
37558
+ { accessLevel: { $regex: search, $options: "i" } },
37559
+ { cardNo: { $regex: search, $options: "i" } }
37560
+ ];
37165
37561
  }
37166
37562
  if (type) {
37167
37563
  query.userType = type;
@@ -37186,14 +37582,22 @@ function UseAccessManagementRepo() {
37186
37582
  {
37187
37583
  $addFields: {
37188
37584
  extractedCardNo: {
37189
- $substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
37585
+ $substr: [
37586
+ "$cardNo",
37587
+ { $subtract: [{ $strLenCP: "$cardNo" }, 5] },
37588
+ 5
37589
+ ]
37190
37590
  }
37191
37591
  }
37192
37592
  },
37193
37593
  {
37194
37594
  $facet: {
37195
37595
  totalCount: [{ $count: "count" }],
37196
- items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
37596
+ items: [
37597
+ { $sort: { _id: -1 } },
37598
+ { $skip: page * limit },
37599
+ { $limit: limit }
37600
+ ]
37197
37601
  }
37198
37602
  }
37199
37603
  ]).toArray();
@@ -37224,145 +37628,151 @@ function UseAccessManagementRepo() {
37224
37628
  query.replacementStatus = statusFilter;
37225
37629
  }
37226
37630
  if (dateFrom && dateTo) {
37227
- query.requestDate = { $gte: new Date(dateFrom), $lte: new Date(dateTo) };
37631
+ query.requestDate = {
37632
+ $gte: new Date(dateFrom),
37633
+ $lte: new Date(dateTo)
37634
+ };
37228
37635
  } else if (dateFrom) {
37229
37636
  query.requestDate = { $gte: new Date(dateFrom) };
37230
37637
  } else if (dateTo) {
37231
37638
  query.requestDate = { $lte: new Date(dateTo) };
37232
37639
  }
37233
- const res = await collection().aggregate([
37234
- {
37235
- $match: { ...query }
37236
- },
37237
- {
37238
- $lookup: {
37239
- from: "building-units",
37240
- let: { unit: "$assignedUnit" },
37241
- pipeline: [
37242
- {
37243
- $match: {
37244
- $expr: {
37245
- $eq: ["$_id", "$$unit"]
37640
+ const res = await collection().aggregate(
37641
+ [
37642
+ {
37643
+ $match: { ...query }
37644
+ },
37645
+ {
37646
+ $lookup: {
37647
+ from: "building-units",
37648
+ let: { unit: "$assignedUnit" },
37649
+ pipeline: [
37650
+ {
37651
+ $match: {
37652
+ $expr: {
37653
+ $eq: ["$_id", "$$unit"]
37654
+ }
37246
37655
  }
37247
- }
37248
- },
37249
- {
37250
- $project: {
37251
- _id: 1,
37252
- name: 1,
37253
- level: 1
37254
- }
37255
- }
37256
- ],
37257
- as: "unit"
37258
- }
37259
- },
37260
- {
37261
- $unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
37262
- },
37263
- {
37264
- $lookup: {
37265
- from: "building-levels",
37266
- let: { level: "$unit.level" },
37267
- pipeline: [
37268
- {
37269
- $match: {
37270
- $expr: {
37271
- $eq: ["$_id", "$$level"]
37656
+ },
37657
+ {
37658
+ $project: {
37659
+ _id: 1,
37660
+ name: 1,
37661
+ level: 1
37272
37662
  }
37273
37663
  }
37274
- },
37275
- {
37276
- $project: {
37277
- _id: 1,
37278
- level: 1,
37279
- block: 1
37280
- }
37281
- }
37282
- ],
37283
- as: "level"
37284
- }
37285
- },
37286
- {
37287
- $unwind: { path: "$level", preserveNullAndEmptyArrays: true }
37288
- },
37289
- {
37290
- $lookup: {
37291
- from: "buildings",
37292
- let: { block: "$level.block" },
37293
- pipeline: [
37294
- {
37295
- $match: {
37296
- $expr: {
37297
- $eq: ["$_id", "$$block"]
37664
+ ],
37665
+ as: "unit"
37666
+ }
37667
+ },
37668
+ {
37669
+ $unwind: { path: "$unit", preserveNullAndEmptyArrays: true }
37670
+ },
37671
+ {
37672
+ $lookup: {
37673
+ from: "building-levels",
37674
+ let: { level: "$unit.level" },
37675
+ pipeline: [
37676
+ {
37677
+ $match: {
37678
+ $expr: {
37679
+ $eq: ["$_id", "$$level"]
37680
+ }
37681
+ }
37682
+ },
37683
+ {
37684
+ $project: {
37685
+ _id: 1,
37686
+ level: 1,
37687
+ block: 1
37298
37688
  }
37299
37689
  }
37300
- },
37301
- {
37302
- $project: {
37303
- _id: 1,
37304
- name: 1
37305
- }
37306
- }
37307
- ],
37308
- as: "building"
37309
- }
37310
- },
37311
- {
37312
- $unwind: { path: "$building", preserveNullAndEmptyArrays: true }
37313
- },
37314
- {
37315
- $lookup: {
37316
- from: "users",
37317
- let: { id: "$userId" },
37318
- pipeline: [
37319
- {
37320
- $match: {
37321
- $expr: {
37322
- $eq: ["$_id", "$$id"]
37690
+ ],
37691
+ as: "level"
37692
+ }
37693
+ },
37694
+ {
37695
+ $unwind: { path: "$level", preserveNullAndEmptyArrays: true }
37696
+ },
37697
+ {
37698
+ $lookup: {
37699
+ from: "buildings",
37700
+ let: { block: "$level.block" },
37701
+ pipeline: [
37702
+ {
37703
+ $match: {
37704
+ $expr: {
37705
+ $eq: ["$_id", "$$block"]
37706
+ }
37707
+ }
37708
+ },
37709
+ {
37710
+ $project: {
37711
+ _id: 1,
37712
+ name: 1
37323
37713
  }
37324
37714
  }
37325
- },
37326
- {
37327
- $project: {
37328
- givenName: 1,
37329
- surname: 1
37715
+ ],
37716
+ as: "building"
37717
+ }
37718
+ },
37719
+ {
37720
+ $unwind: { path: "$building", preserveNullAndEmptyArrays: true }
37721
+ },
37722
+ {
37723
+ $lookup: {
37724
+ from: "users",
37725
+ let: { id: "$userId" },
37726
+ pipeline: [
37727
+ {
37728
+ $match: {
37729
+ $expr: {
37730
+ $eq: ["$_id", "$$id"]
37731
+ }
37732
+ }
37733
+ },
37734
+ {
37735
+ $project: {
37736
+ givenName: 1,
37737
+ surname: 1
37738
+ }
37330
37739
  }
37331
- }
37332
- ],
37333
- as: "user"
37334
- }
37335
- },
37336
- {
37337
- $unwind: { path: "$user", preserveNullAndEmptyArrays: true }
37338
- },
37339
- {
37340
- $match: { ...searchQuery }
37341
- },
37342
- {
37343
- $facet: {
37344
- data: [
37345
- { $skip: page * limit },
37346
- { $limit: limit },
37347
- {
37348
- $project: {
37349
- _id: 1,
37350
- cardNo: 1,
37351
- accessLevel: 1,
37352
- liftAccessLevel: 1,
37353
- replacementStatus: 1,
37354
- remarks: 1,
37355
- block: "$building.name",
37356
- level: "$level.level",
37357
- unit: "$unit.name",
37358
- user: "$user"
37740
+ ],
37741
+ as: "user"
37742
+ }
37743
+ },
37744
+ {
37745
+ $unwind: { path: "$user", preserveNullAndEmptyArrays: true }
37746
+ },
37747
+ {
37748
+ $match: { ...searchQuery }
37749
+ },
37750
+ {
37751
+ $facet: {
37752
+ data: [
37753
+ { $skip: page * limit },
37754
+ { $limit: limit },
37755
+ {
37756
+ $project: {
37757
+ _id: 1,
37758
+ cardNo: 1,
37759
+ accessLevel: 1,
37760
+ liftAccessLevel: 1,
37761
+ replacementStatus: 1,
37762
+ remarks: 1,
37763
+ block: "$building.name",
37764
+ level: "$level.level",
37765
+ unit: "$unit.name",
37766
+ user: "$user"
37767
+ }
37359
37768
  }
37360
- }
37361
- ],
37362
- totalCount: [{ $count: "count" }]
37769
+ ],
37770
+ totalCount: [{ $count: "count" }]
37771
+ }
37363
37772
  }
37364
- }
37365
- ], { allowDiskUse: true }).toArray();
37773
+ ],
37774
+ { allowDiskUse: true }
37775
+ ).toArray();
37366
37776
  const count = res[0]?.totalCount[0] ? res[0].totalCount[0].count : 0;
37367
37777
  const pagination = paginate39(res[0].data, page, limit, count);
37368
37778
  return pagination;
@@ -37374,7 +37784,10 @@ function UseAccessManagementRepo() {
37374
37784
  try {
37375
37785
  const { site } = params;
37376
37786
  const siteId = new ObjectId90(site);
37377
- const res = await collectionName("entrypass-settings").findOne({ site: siteId }, { allowDiskUse: true });
37787
+ const res = await collectionName("entrypass-settings").findOne(
37788
+ { site: siteId },
37789
+ { allowDiskUse: true }
37790
+ );
37378
37791
  return res;
37379
37792
  } catch (error) {
37380
37793
  throw new Error(error.message);
@@ -37384,13 +37797,19 @@ function UseAccessManagementRepo() {
37384
37797
  const session = useAtlas76.getClient()?.startSession();
37385
37798
  try {
37386
37799
  const { dataJson, site } = params;
37387
- const rawItems = JSON.parse(dataJson).filter((_, index) => index !== -1);
37800
+ const rawItems = JSON.parse(dataJson).filter(
37801
+ (_, index) => index !== -1
37802
+ );
37388
37803
  const items = await Promise.all(
37389
37804
  rawItems.map(async (item) => {
37390
37805
  const date = new Date(item["startDate (format MM/DD/YYYY)"]);
37391
37806
  const endDate = new Date(date.setFullYear(date.getFullYear() + 10));
37392
- const cardNumber = String(Number(item["cardNo (number 0-65535 ex. 301)"] || 0)).padStart(6, "0");
37393
- const facilityCode = String(Number(item["facilityCode (number 0-255 ex. 11)"] || 0)).padStart(4, "0");
37807
+ const cardNumber = String(
37808
+ Number(item["cardNo (number 0-65535 ex. 301)"] || 0)
37809
+ ).padStart(6, "0");
37810
+ const facilityCode = String(
37811
+ Number(item["facilityCode (number 0-255 ex. 11)"] || 0)
37812
+ ).padStart(4, "0");
37394
37813
  const pin = item["pin (number 6 digits only)"] ? item["pin (number 6 digits only)"].toString().padStart(6, "0") : "123456";
37395
37814
  const match = item["accessLevel (number ex. 1)"];
37396
37815
  const accessLevel = match ? match : null;
@@ -37421,7 +37840,10 @@ function UseAccessManagementRepo() {
37421
37840
  });
37422
37841
  })
37423
37842
  );
37424
- const result = await collection().insertMany(items, { session, ordered: false });
37843
+ const result = await collection().insertMany(items, {
37844
+ session,
37845
+ ordered: false
37846
+ });
37425
37847
  const mapping = items.map((item, i) => ({
37426
37848
  cardNo: item.cardNo,
37427
37849
  insertedId: result.insertedIds[i]
@@ -37436,8 +37858,19 @@ function UseAccessManagementRepo() {
37436
37858
  let isAborted = false;
37437
37859
  try {
37438
37860
  await session?.startTransaction();
37439
- const { units, quantity, type, site, userType, accessLevel, liftAccessLevel } = params;
37440
- const [convertedUnits, convertedSite] = await Promise.all([Promise.all(units.map((id) => new ObjectId90(id))), new ObjectId90(site)]);
37861
+ const {
37862
+ units,
37863
+ quantity,
37864
+ type,
37865
+ site,
37866
+ userType,
37867
+ accessLevel,
37868
+ liftAccessLevel
37869
+ } = params;
37870
+ const [convertedUnits, convertedSite] = await Promise.all([
37871
+ Promise.all(units.map((id) => new ObjectId90(id))),
37872
+ new ObjectId90(site)
37873
+ ]);
37441
37874
  const totalRequired = quantity * convertedUnits.length;
37442
37875
  const availableCards = await collection().find({
37443
37876
  assignedUnit: null,
@@ -37457,16 +37890,18 @@ function UseAccessManagementRepo() {
37457
37890
  message: `Insufficient ${type} access cards. Need ${totalRequired}, but only ${availableCards.length} available.`
37458
37891
  };
37459
37892
  }
37460
- const bulkUpdates = availableCards.map((card, index) => ({
37461
- updateOne: {
37462
- filter: { _id: card._id },
37463
- update: {
37464
- $set: {
37465
- assignedUnit: convertedUnits[Math.floor(index / quantity)]
37893
+ const bulkUpdates = availableCards.map(
37894
+ (card, index) => ({
37895
+ updateOne: {
37896
+ filter: { _id: card._id },
37897
+ update: {
37898
+ $set: {
37899
+ assignedUnit: convertedUnits[Math.floor(index / quantity)]
37900
+ }
37466
37901
  }
37467
37902
  }
37468
- }
37469
- }));
37903
+ })
37904
+ );
37470
37905
  await collection().bulkWrite(bulkUpdates, { session });
37471
37906
  await session?.commitTransaction();
37472
37907
  return {
@@ -37487,7 +37922,18 @@ function UseAccessManagementRepo() {
37487
37922
  try {
37488
37923
  const { cardId, remarks } = params;
37489
37924
  const id = new ObjectId90(cardId);
37490
- const result = await collection().findOneAndUpdate({ _id: id }, { $set: { isActivated: false, updatedAt: /* @__PURE__ */ new Date(), remarks, requestDate: /* @__PURE__ */ new Date() } }, { returnDocument: "after" });
37925
+ const result = await collection().findOneAndUpdate(
37926
+ { _id: id },
37927
+ {
37928
+ $set: {
37929
+ isActivated: false,
37930
+ updatedAt: /* @__PURE__ */ new Date(),
37931
+ remarks,
37932
+ requestDate: /* @__PURE__ */ new Date()
37933
+ }
37934
+ },
37935
+ { returnDocument: "after" }
37936
+ );
37491
37937
  return result;
37492
37938
  } catch (error) {
37493
37939
  throw new Error(error.message);
@@ -37548,7 +37994,13 @@ function UseAccessManagementRepo() {
37548
37994
  const { site, payload } = params;
37549
37995
  const id = new ObjectId90(site);
37550
37996
  const highestCardNo = await collection().aggregate([
37551
- { $match: { site: id, type: "NFC" /* NFC */, userType: "Visitor/Resident" /* DEFAULT */ } },
37997
+ {
37998
+ $match: {
37999
+ site: id,
38000
+ type: "NFC" /* NFC */,
38001
+ userType: "Visitor/Resident" /* DEFAULT */
38002
+ }
38003
+ },
37552
38004
  {
37553
38005
  $addFields: {
37554
38006
  qrTagCardNoNumeric: { $toInt: "$qrTagCardNo" }
@@ -37568,14 +38020,19 @@ function UseAccessManagementRepo() {
37568
38020
  if (highestCardNo.length > 0) {
37569
38021
  start = highestCardNo[0].qrTagCardNoNumeric || 0;
37570
38022
  }
37571
- const nextCardNumbers = Array.from({ length: payload.length }, (_, i) => String(start + i + 1).padStart(5, "0"));
38023
+ const nextCardNumbers = Array.from(
38024
+ { length: payload.length },
38025
+ (_, i) => String(start + i + 1).padStart(5, "0")
38026
+ );
37572
38027
  const bulkOps = await Promise.all(
37573
38028
  payload.map(async (doc, index) => {
37574
38029
  const id2 = new ObjectId90(doc._id);
37575
38030
  return {
37576
38031
  updateOne: {
37577
38032
  filter: { _id: id2 },
37578
- update: { $set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] } }
38033
+ update: {
38034
+ $set: { qrTag: doc.qrTag, qrTagCardNo: nextCardNumbers[index] }
38035
+ }
37579
38036
  }
37580
38037
  };
37581
38038
  })
@@ -37617,7 +38074,11 @@ function UseAccessManagementRepo() {
37617
38074
  {
37618
38075
  $addFields: {
37619
38076
  extractedCardNo: {
37620
- $substr: ["$cardNo", { $subtract: [{ $strLenCP: "$cardNo" }, 5] }, 5]
38077
+ $substr: [
38078
+ "$cardNo",
38079
+ { $subtract: [{ $strLenCP: "$cardNo" }, 5] },
38080
+ 5
38081
+ ]
37621
38082
  }
37622
38083
  }
37623
38084
  },
@@ -37655,7 +38116,11 @@ function UseAccessManagementRepo() {
37655
38116
  },
37656
38117
  {
37657
38118
  $facet: {
37658
- items: [{ $skip: page * limit }, { $limit: limit }, { $project: { cardNo: 1 } }],
38119
+ items: [
38120
+ { $skip: page * limit },
38121
+ { $limit: limit },
38122
+ { $project: { cardNo: 1 } }
38123
+ ],
37659
38124
  totalCounts: [{ $count: "count" }]
37660
38125
  }
37661
38126
  }
@@ -37666,7 +38131,9 @@ function UseAccessManagementRepo() {
37666
38131
  _id: unitId
37667
38132
  }
37668
38133
  },
37669
- { $project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 } },
38134
+ {
38135
+ $project: { _id: 1, name: 1, buildingName: 1, block: 1, level: 1 }
38136
+ },
37670
38137
  {
37671
38138
  $lookup: {
37672
38139
  from: "building-levels",
@@ -37754,7 +38221,18 @@ function UseAccessManagementRepo() {
37754
38221
  items: [
37755
38222
  { $skip: 0 },
37756
38223
  { $limit: 1 },
37757
- { $project: { _id: -1, accessLevel: 1, accessGroup: 1, userType: 1, doorName: 1, liftName: 1, liftAccessLevel: 1, isLiftCard: 1 } }
38224
+ {
38225
+ $project: {
38226
+ _id: -1,
38227
+ accessLevel: 1,
38228
+ accessGroup: 1,
38229
+ userType: 1,
38230
+ doorName: 1,
38231
+ liftName: 1,
38232
+ liftAccessLevel: 1,
38233
+ isLiftCard: 1
38234
+ }
38235
+ }
37758
38236
  ]
37759
38237
  }
37760
38238
  }
@@ -37803,13 +38281,25 @@ function UseAccessManagementRepo() {
37803
38281
  cardsToAttach = [...cardsId];
37804
38282
  } else if (type === "NFC" /* NFC */) {
37805
38283
  if (nfcCards && nfcCards.length > 0) {
37806
- const objectIds = nfcCards.map((card) => new ObjectId90(card._id));
38284
+ const objectIds = nfcCards.map(
38285
+ (card) => new ObjectId90(card._id)
38286
+ );
37807
38287
  cards = await collection().find({ _id: { $in: objectIds } }).toArray();
37808
- const nfcList = objectIds.map((card) => ({ _id: card, status: "In use", updatedAt: /* @__PURE__ */ new Date() }));
38288
+ const nfcList = objectIds.map((card) => ({
38289
+ _id: card,
38290
+ status: "In use",
38291
+ updatedAt: /* @__PURE__ */ new Date()
38292
+ }));
37809
38293
  cardsToAttach = [...nfcList];
37810
38294
  }
37811
38295
  }
37812
- const result = await collectionName("visitor.transactions").findOneAndUpdate({ _id: visitorId }, { $push: { cards: cardsToAttach } }, { session, returnDocument: "after" });
38296
+ const result = await collectionName(
38297
+ "visitor.transactions"
38298
+ ).findOneAndUpdate(
38299
+ { _id: visitorId },
38300
+ { $push: { cards: cardsToAttach } },
38301
+ { session, returnDocument: "after" }
38302
+ );
37813
38303
  const updatedVisitor = result?._id;
37814
38304
  const assignCards = cards.map((card) => card._id);
37815
38305
  if (assignCards.length > 0) {
@@ -37865,10 +38355,18 @@ function UseAccessManagementRepo() {
37865
38355
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
37866
38356
  accessGroup: ag
37867
38357
  };
37868
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
38358
+ return readTemplate(
38359
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
38360
+ { ...command }
38361
+ );
37869
38362
  }).flat();
37870
- const response = await sendCommand(commands.join("").toString(), acm_url);
37871
- serverResult = await parseStringPromise2(response, { explicitArray: false });
38363
+ const response = await sendCommand(
38364
+ commands.join("").toString(),
38365
+ acm_url
38366
+ );
38367
+ serverResult = await parseStringPromise2(response, {
38368
+ explicitArray: false
38369
+ });
37872
38370
  if (result && serverResult.RESULT.$.STCODE !== "0") {
37873
38371
  throw new Error("Command failed, server error.");
37874
38372
  }
@@ -37917,7 +38415,10 @@ function UseAccessManagementRepo() {
37917
38415
  try {
37918
38416
  await session?.startTransaction();
37919
38417
  const userId = new ObjectId90(params.userId);
37920
- const result = await collection().updateMany({ userId }, { $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } });
38418
+ const result = await collection().updateMany(
38419
+ { userId },
38420
+ { $set: { userId: null, status: "Available", updatedAt: /* @__PURE__ */ new Date() } }
38421
+ );
37921
38422
  await session?.commitTransaction();
37922
38423
  return result;
37923
38424
  } catch (error) {
@@ -37961,7 +38462,15 @@ function UseAccessManagementRepo() {
37961
38462
  foreignField: "level",
37962
38463
  pipeline: [
37963
38464
  { $match: { status: { $ne: "deleted" } } },
37964
- { $project: { _id: 1, name: 1, buildingName: 1, level: 1, block: 1 } }
38465
+ {
38466
+ $project: {
38467
+ _id: 1,
38468
+ name: 1,
38469
+ buildingName: 1,
38470
+ level: 1,
38471
+ block: 1
38472
+ }
38473
+ }
37965
38474
  ],
37966
38475
  as: "units"
37967
38476
  }
@@ -37982,11 +38491,20 @@ function UseAccessManagementRepo() {
37982
38491
  throw new Error(error.message);
37983
38492
  }
37984
38493
  }
37985
- async function getTransactionsRepo({ page = 1, limit = 10, site, cardNo, url }) {
38494
+ async function getTransactionsRepo({
38495
+ page = 1,
38496
+ limit = 10,
38497
+ site,
38498
+ cardNo,
38499
+ url
38500
+ }) {
37986
38501
  page = page ? page - 1 : 0;
37987
38502
  site = new ObjectId90(site);
37988
38503
  try {
37989
- let index = await collectionName("access-card-transactions").findOne({}, { sort: { index: -1 } });
38504
+ let index = await collectionName("access-card-transactions").findOne(
38505
+ {},
38506
+ { sort: { index: -1 } }
38507
+ );
37990
38508
  index = index ? index.index : 0;
37991
38509
  const response = await getTransactions(index, url);
37992
38510
  if (response && Array.isArray(response.items) && response.items.length > 0) {
@@ -37995,7 +38513,9 @@ function UseAccessManagementRepo() {
37995
38513
  data: JSON.parse(item.data),
37996
38514
  timestamp: item.timestamp
37997
38515
  }));
37998
- result2 = result2.filter((item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== "");
38516
+ result2 = result2.filter(
38517
+ (item) => item.data.Event.ETYPE === "0" && item.data.Event.CARDNO !== ""
38518
+ );
37999
38519
  if (result2.length > 0) {
38000
38520
  const transactions = result2.map(
38001
38521
  (item) => new MAccessCardTransaction({
@@ -38006,11 +38526,16 @@ function UseAccessManagementRepo() {
38006
38526
  accessType: item.data.Event.DEVNAME,
38007
38527
  accessStatus: item.data.Event.TRCODE,
38008
38528
  description: item.data.Event.TRDESC,
38009
- accessTime: entryPassDate(item.data.Event.TRDATE, item.data.Event.TRTIME),
38529
+ accessTime: entryPassDate(
38530
+ item.data.Event.TRDATE,
38531
+ item.data.Event.TRTIME
38532
+ ),
38010
38533
  createdAt: /* @__PURE__ */ new Date()
38011
38534
  })
38012
38535
  );
38013
- await collectionName("access-card-transactions").insertMany(transactions);
38536
+ await collectionName("access-card-transactions").insertMany(
38537
+ transactions
38538
+ );
38014
38539
  }
38015
38540
  }
38016
38541
  const result = await collectionName("access-card-transactions").aggregate([
@@ -38081,7 +38606,11 @@ function UseAccessManagementRepo() {
38081
38606
  {
38082
38607
  $facet: {
38083
38608
  totalCount: [{ $count: "count" }],
38084
- items: [{ $sort: { _id: -1 } }, { $skip: page * limit }, { $limit: limit }]
38609
+ items: [
38610
+ { $sort: { _id: -1 } },
38611
+ { $skip: page * limit },
38612
+ { $limit: limit }
38613
+ ]
38085
38614
  }
38086
38615
  }
38087
38616
  ]).toArray();
@@ -38104,7 +38633,9 @@ function UseAccessManagementRepo() {
38104
38633
  if (assignees.length < 1) {
38105
38634
  throw new Error("No user to Assign.");
38106
38635
  }
38107
- assignees = assignees.map((data) => new ObjectId90(data));
38636
+ assignees = assignees.map(
38637
+ (data) => new ObjectId90(data)
38638
+ );
38108
38639
  unit = new ObjectId90(unit);
38109
38640
  let availableCards = [];
38110
38641
  let update = [];
@@ -38114,7 +38645,18 @@ function UseAccessManagementRepo() {
38114
38645
  $match: {
38115
38646
  $expr: {
38116
38647
  $and: [
38117
- { $eq: ["$assignedUnit", unit] },
38648
+ {
38649
+ $in: [
38650
+ unit,
38651
+ {
38652
+ $cond: [
38653
+ { $isArray: "$assignedUnit" },
38654
+ "$assignedUnit",
38655
+ ["$assignedUnit"]
38656
+ ]
38657
+ }
38658
+ ]
38659
+ },
38118
38660
  { $eq: ["$userId", null] },
38119
38661
  { $eq: ["$type", type] },
38120
38662
  { $eq: ["$isActivated", true] }
@@ -38131,7 +38673,10 @@ function UseAccessManagementRepo() {
38131
38673
  card.staffNo = userId.toString().slice(-10);
38132
38674
  return card;
38133
38675
  });
38134
- update = availableCards.slice(0, assignees.length).map((card, index) => ({ _id: card._id, userId: new ObjectId90(assignees[index]) }));
38676
+ update = availableCards.slice(0, assignees.length).map((card, index) => ({
38677
+ _id: card._id,
38678
+ userId: new ObjectId90(assignees[index])
38679
+ }));
38135
38680
  const commands = cards.map((item, index) => {
38136
38681
  let ag = null;
38137
38682
  if (item.accessGroup !== void 0) {
@@ -38161,16 +38706,27 @@ function UseAccessManagementRepo() {
38161
38706
  liftAccessEndDate: formatEntryPassDate(item.liftAccessEndDate) || "19770510",
38162
38707
  accessGroup: ag
38163
38708
  };
38164
- return readTemplate(`${item.accessLevel !== null ? "add-card" : "add-card-lift"}`, { ...command });
38709
+ return readTemplate(
38710
+ `${item.accessLevel !== null ? "add-card" : "add-card-lift"}`,
38711
+ { ...command }
38712
+ );
38165
38713
  }).flat();
38166
38714
  const response = await sendCommand(commands.join("").toString(), acm_url);
38167
- const result = await parseStringPromise2(response, { explicitArray: false });
38715
+ const result = await parseStringPromise2(response, {
38716
+ explicitArray: false
38717
+ });
38168
38718
  console.log("status code", result.RESULT.$.STCODE);
38169
38719
  if (result && result.RESULT.$.STCODE !== "0") {
38170
38720
  throw new Error("Command failed, server error.");
38171
38721
  }
38172
38722
  for (const { _id, userId } of update) {
38173
- await collection().updateOne({ _id }, { $set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` } }, { session });
38723
+ await collection().updateOne(
38724
+ { _id },
38725
+ {
38726
+ $set: { userId, staffNo: `STAFF-${userId.toString().slice(-10)}` }
38727
+ },
38728
+ { session }
38729
+ );
38174
38730
  }
38175
38731
  await session?.commitTransaction();
38176
38732
  return "Cards assigned successfully.";
@@ -38186,7 +38742,11 @@ function UseAccessManagementRepo() {
38186
38742
  try {
38187
38743
  session?.startTransaction();
38188
38744
  const id = new ObjectId90(userId);
38189
- await collection().updateMany({ userId: id }, { $set: { userId: null, status: "Available" } }, { session });
38745
+ await collection().updateMany(
38746
+ { userId: id },
38747
+ { $set: { userId: null, status: "Available" } },
38748
+ { session }
38749
+ );
38190
38750
  session?.commitTransaction();
38191
38751
  return "Successful Checkout";
38192
38752
  } catch (error) {
@@ -38196,7 +38756,11 @@ function UseAccessManagementRepo() {
38196
38756
  await session?.endSession();
38197
38757
  }
38198
38758
  }
38199
- async function uploadTemplateRepo({ site, id, name }) {
38759
+ async function uploadTemplateRepo({
38760
+ site,
38761
+ id,
38762
+ name
38763
+ }) {
38200
38764
  site = new ObjectId90(site);
38201
38765
  id = new ObjectId90(id);
38202
38766
  try {
@@ -38209,6 +38773,46 @@ function UseAccessManagementRepo() {
38209
38773
  throw new Error(error.message);
38210
38774
  }
38211
38775
  }
38776
+ async function getResidentsRepo({
38777
+ orgId,
38778
+ siteId,
38779
+ unitId
38780
+ }) {
38781
+ try {
38782
+ orgId = new ObjectId90(orgId);
38783
+ siteId = new ObjectId90(siteId);
38784
+ unitId = new ObjectId90(unitId);
38785
+ const result = await collectionName("users").aggregate([
38786
+ {
38787
+ $match: {
38788
+ $expr: {
38789
+ $and: [
38790
+ { $eq: ["$defaultOrg", orgId] },
38791
+ { $eq: ["$site", siteId] },
38792
+ { $eq: ["$unitId", unitId] }
38793
+ ]
38794
+ }
38795
+ }
38796
+ },
38797
+ {
38798
+ $project: {
38799
+ _id: 1,
38800
+ email: 1,
38801
+ unitName: 1,
38802
+ type: 1,
38803
+ status: 1,
38804
+ name: 1,
38805
+ defaultOrg: 1,
38806
+ site: 1,
38807
+ unitId: 1
38808
+ }
38809
+ }
38810
+ ]).toArray();
38811
+ return result;
38812
+ } catch (error) {
38813
+ throw new Error(error.message);
38814
+ }
38815
+ }
38212
38816
  return {
38213
38817
  createIndexes,
38214
38818
  createIndexForEntrypass,
@@ -38244,7 +38848,8 @@ function UseAccessManagementRepo() {
38244
38848
  getTransactionsRepo,
38245
38849
  assignMultipleCardsRepo,
38246
38850
  visitorCheckoutRepo,
38247
- uploadTemplateRepo
38851
+ uploadTemplateRepo,
38852
+ getResidentsRepo
38248
38853
  };
38249
38854
  }
38250
38855
 
@@ -38288,7 +38893,8 @@ function useAccessManagementSvc() {
38288
38893
  getTransactionsRepo,
38289
38894
  assignMultipleCardsRepo,
38290
38895
  visitorCheckoutRepo,
38291
- uploadTemplateRepo
38896
+ uploadTemplateRepo,
38897
+ getResidentsRepo
38292
38898
  } = UseAccessManagementRepo();
38293
38899
  const addPhysicalCardSvc = async (payload) => {
38294
38900
  try {
@@ -38580,17 +39186,39 @@ function useAccessManagementSvc() {
38580
39186
  throw new Error(err.message);
38581
39187
  }
38582
39188
  };
38583
- const getTransactionsSvc = async ({ page, limit, site, cardNo, url }) => {
39189
+ const getTransactionsSvc = async ({
39190
+ page,
39191
+ limit,
39192
+ site,
39193
+ cardNo,
39194
+ url
39195
+ }) => {
38584
39196
  try {
38585
- const response = await getTransactionsRepo({ page, limit, site, cardNo, url });
39197
+ const response = await getTransactionsRepo({
39198
+ page,
39199
+ limit,
39200
+ site,
39201
+ cardNo,
39202
+ url
39203
+ });
38586
39204
  return response;
38587
39205
  } catch (err) {
38588
39206
  throw new Error(err.message);
38589
39207
  }
38590
39208
  };
38591
- const assignMultipleCardsSvc = async ({ assignees, unit, type, acm_url }) => {
39209
+ const assignMultipleCardsSvc = async ({
39210
+ assignees,
39211
+ unit,
39212
+ type,
39213
+ acm_url
39214
+ }) => {
38592
39215
  try {
38593
- const response = await assignMultipleCardsRepo({ assignees, unit, type, acm_url });
39216
+ const response = await assignMultipleCardsRepo({
39217
+ assignees,
39218
+ unit,
39219
+ type,
39220
+ acm_url
39221
+ });
38594
39222
  return response;
38595
39223
  } catch (err) {
38596
39224
  throw new Error(err.message);
@@ -38604,7 +39232,11 @@ function useAccessManagementSvc() {
38604
39232
  throw new Error(err.message);
38605
39233
  }
38606
39234
  };
38607
- const uploadTemplateSvc = async ({ site, id, name }) => {
39235
+ const uploadTemplateSvc = async ({
39236
+ site,
39237
+ id,
39238
+ name
39239
+ }) => {
38608
39240
  try {
38609
39241
  const response = await uploadTemplateRepo({ site, id, name });
38610
39242
  return response;
@@ -38612,6 +39244,18 @@ function useAccessManagementSvc() {
38612
39244
  throw new Error(err.message);
38613
39245
  }
38614
39246
  };
39247
+ const getResidentsSvc = async ({
39248
+ orgId,
39249
+ siteId,
39250
+ unitId
39251
+ }) => {
39252
+ try {
39253
+ const response = await getResidentsRepo({ orgId, siteId, unitId });
39254
+ return response;
39255
+ } catch (err) {
39256
+ throw new Error(err.message);
39257
+ }
39258
+ };
38615
39259
  return {
38616
39260
  addPhysicalCardSvc,
38617
39261
  addNonPhysicalCardSvc,
@@ -38650,7 +39294,8 @@ function useAccessManagementSvc() {
38650
39294
  getTransactionsSvc,
38651
39295
  assignMultipleCardsSvc,
38652
39296
  visitorCheckoutSvc,
38653
- uploadTemplateSvc
39297
+ uploadTemplateSvc,
39298
+ getResidentsSvc
38654
39299
  };
38655
39300
  }
38656
39301
 
@@ -38694,7 +39339,8 @@ function useAccessManagementController() {
38694
39339
  getTransactionsSvc,
38695
39340
  assignMultipleCardsSvc,
38696
39341
  visitorCheckoutSvc,
38697
- uploadTemplateSvc
39342
+ uploadTemplateSvc,
39343
+ getResidentsSvc
38698
39344
  } = useAccessManagementSvc();
38699
39345
  const addPhysicalCard = async (req, res) => {
38700
39346
  try {
@@ -38943,11 +39589,25 @@ function useAccessManagementController() {
38943
39589
  search: Joi86.string().optional().allow("", null),
38944
39590
  userType: Joi86.string().required()
38945
39591
  });
38946
- const { error } = schema2.validate({ page, limit, site, organization, search, userType });
39592
+ const { error } = schema2.validate({
39593
+ page,
39594
+ limit,
39595
+ site,
39596
+ organization,
39597
+ search,
39598
+ userType
39599
+ });
38947
39600
  if (error) {
38948
39601
  return res.status(400).json({ message: error.message });
38949
39602
  }
38950
- const result = await userTypeAccessCardsSvc({ page, limit, search, site, organization, userType });
39603
+ const result = await userTypeAccessCardsSvc({
39604
+ page,
39605
+ limit,
39606
+ search,
39607
+ site,
39608
+ organization,
39609
+ userType
39610
+ });
38951
39611
  return res.status(200).json({ message: "Success", data: result });
38952
39612
  } catch (error) {
38953
39613
  return res.status(500).json({
@@ -38958,7 +39618,12 @@ function useAccessManagementController() {
38958
39618
  };
38959
39619
  const assignedAccessCards = async (req, res) => {
38960
39620
  try {
38961
- const { site, userType, type, search = "" } = req.query;
39621
+ const {
39622
+ site,
39623
+ userType,
39624
+ type,
39625
+ search = ""
39626
+ } = req.query;
38962
39627
  const schema2 = Joi86.object({
38963
39628
  site: Joi86.string().hex().required(),
38964
39629
  userType: Joi86.string().required(),
@@ -38969,7 +39634,12 @@ function useAccessManagementController() {
38969
39634
  if (error) {
38970
39635
  return res.status(400).json({ message: error.message });
38971
39636
  }
38972
- const result = await assignedAccessCardsSvc({ site, userType, type, search });
39637
+ const result = await assignedAccessCardsSvc({
39638
+ site,
39639
+ userType,
39640
+ type,
39641
+ search
39642
+ });
38973
39643
  return res.status(200).json({ message: "Success", data: result });
38974
39644
  } catch (error) {
38975
39645
  return res.status(500).json({
@@ -39015,11 +39685,23 @@ function useAccessManagementController() {
39015
39685
  userType: Joi86.string().valid(...Object.values(EAccessCardUserTypes)).required(),
39016
39686
  type: Joi86.string().valid(...Object.values(EAccessCardTypes)).required()
39017
39687
  });
39018
- const { error } = schema2.validate({ accessLevel, liftAccessLevel, site, userType, type });
39688
+ const { error } = schema2.validate({
39689
+ accessLevel,
39690
+ liftAccessLevel,
39691
+ site,
39692
+ userType,
39693
+ type
39694
+ });
39019
39695
  if (error) {
39020
39696
  return res.status(400).json({ message: error.message });
39021
39697
  }
39022
- const result = await accessandLiftCardsSvc({ accessLevel, liftAccessLevel, site, userType, type });
39698
+ const result = await accessandLiftCardsSvc({
39699
+ accessLevel,
39700
+ liftAccessLevel,
39701
+ site,
39702
+ userType,
39703
+ type
39704
+ });
39023
39705
  return res.status(200).json({ message: "Success", data: result });
39024
39706
  } catch (error) {
39025
39707
  return res.status(500).json({
@@ -39106,11 +39788,23 @@ function useAccessManagementController() {
39106
39788
  issuedCardId: Joi86.string().required(),
39107
39789
  userId: Joi86.string().hex().required()
39108
39790
  });
39109
- const { error } = schema2.validate({ cardId, remarks, unitId, issuedCardId, userId });
39791
+ const { error } = schema2.validate({
39792
+ cardId,
39793
+ remarks,
39794
+ unitId,
39795
+ issuedCardId,
39796
+ userId
39797
+ });
39110
39798
  if (error) {
39111
39799
  return res.status(400).json({ message: error.message });
39112
39800
  }
39113
- const result = await cardReplacementSvc({ cardId, remarks, unitId, issuedCardId, userId });
39801
+ const result = await cardReplacementSvc({
39802
+ cardId,
39803
+ remarks,
39804
+ unitId,
39805
+ issuedCardId,
39806
+ userId
39807
+ });
39114
39808
  return res.status(200).json({ message: "Success", data: result });
39115
39809
  } catch (error) {
39116
39810
  return res.status(500).json({
@@ -39139,7 +39833,13 @@ function useAccessManagementController() {
39139
39833
  if (error) {
39140
39834
  return res.status(400).json({ message: error.message });
39141
39835
  }
39142
- const result = await visitorAccessCardsSvc({ site, page, limit, type, search });
39836
+ const result = await visitorAccessCardsSvc({
39837
+ site,
39838
+ page,
39839
+ limit,
39840
+ type,
39841
+ search
39842
+ });
39143
39843
  return res.status(200).json({ message: "Success", data: result });
39144
39844
  } catch (error) {
39145
39845
  return res.status(500).json({
@@ -39168,11 +39868,27 @@ function useAccessManagementController() {
39168
39868
  limit: Joi86.number().optional().default(10),
39169
39869
  site: Joi86.string().hex().required()
39170
39870
  });
39171
- const { error } = schema2.validate({ search, statusFilter, dateFrom, dateTo, page, limit, site });
39871
+ const { error } = schema2.validate({
39872
+ search,
39873
+ statusFilter,
39874
+ dateFrom,
39875
+ dateTo,
39876
+ page,
39877
+ limit,
39878
+ site
39879
+ });
39172
39880
  if (error) {
39173
39881
  return res.status(400).json({ message: error.message });
39174
39882
  }
39175
- const result = await getCardReplacementSvc({ site, page, limit, search, statusFilter, dateFrom, dateTo });
39883
+ const result = await getCardReplacementSvc({
39884
+ site,
39885
+ page,
39886
+ limit,
39887
+ search,
39888
+ statusFilter,
39889
+ dateFrom,
39890
+ dateTo
39891
+ });
39176
39892
  return res.status(200).json({ message: "Success", data: result });
39177
39893
  } catch (error) {
39178
39894
  return res.status(500).json({
@@ -39218,7 +39934,15 @@ function useAccessManagementController() {
39218
39934
  };
39219
39935
  const assignAccessCardToUnit = async (req, res) => {
39220
39936
  try {
39221
- const { units, type, quantity, site, userType, accessLevel, liftAccessLevel } = req.body;
39937
+ const {
39938
+ units,
39939
+ type,
39940
+ quantity,
39941
+ site,
39942
+ userType,
39943
+ accessLevel,
39944
+ liftAccessLevel
39945
+ } = req.body;
39222
39946
  const schema2 = Joi86.object({
39223
39947
  units: Joi86.array().items(Joi86.string().hex()).required(),
39224
39948
  quantity: Joi86.number().required(),
@@ -39228,11 +39952,27 @@ function useAccessManagementController() {
39228
39952
  accessLevel: Joi86.string().optional().allow("", null),
39229
39953
  liftAccessLevel: Joi86.string().optional().allow("", null)
39230
39954
  });
39231
- const { error } = schema2.validate({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
39955
+ const { error } = schema2.validate({
39956
+ units,
39957
+ quantity,
39958
+ type,
39959
+ site,
39960
+ userType,
39961
+ accessLevel,
39962
+ liftAccessLevel
39963
+ });
39232
39964
  if (error) {
39233
39965
  return res.status(400).json({ message: error.message });
39234
39966
  }
39235
- const result = await assignAccessCardToUnitSvc({ units, quantity, type, site, userType, accessLevel, liftAccessLevel });
39967
+ const result = await assignAccessCardToUnitSvc({
39968
+ units,
39969
+ quantity,
39970
+ type,
39971
+ site,
39972
+ userType,
39973
+ accessLevel,
39974
+ liftAccessLevel
39975
+ });
39236
39976
  return res.status(200).json({ message: "Success", data: result });
39237
39977
  } catch (error) {
39238
39978
  return res.status(500).json({
@@ -39330,7 +40070,12 @@ function useAccessManagementController() {
39330
40070
  };
39331
40071
  const availableCardContractors = async (req, res) => {
39332
40072
  try {
39333
- const { siteId, unitId, page = 1, limit = 20 } = req.query;
40073
+ const {
40074
+ siteId,
40075
+ unitId,
40076
+ page = 1,
40077
+ limit = 20
40078
+ } = req.query;
39334
40079
  const type = req.params.type;
39335
40080
  const schema2 = Joi86.object({
39336
40081
  siteId: Joi86.string().hex().required(),
@@ -39343,7 +40088,13 @@ function useAccessManagementController() {
39343
40088
  if (error) {
39344
40089
  return res.status(400).json({ message: error.message });
39345
40090
  }
39346
- const result = await availableCardContractorsSvc({ siteId, unitId, page, limit, type });
40091
+ const result = await availableCardContractorsSvc({
40092
+ siteId,
40093
+ unitId,
40094
+ page,
40095
+ limit,
40096
+ type
40097
+ });
39347
40098
  return res.status(200).json({ message: "Success", data: result });
39348
40099
  } catch (error) {
39349
40100
  return res.status(500).json({
@@ -39354,7 +40105,11 @@ function useAccessManagementController() {
39354
40105
  };
39355
40106
  const vmsgenerateQrCodes = async (req, res) => {
39356
40107
  try {
39357
- const { site, unitId, quantity = 100 } = req.body;
40108
+ const {
40109
+ site,
40110
+ unitId,
40111
+ quantity = 100
40112
+ } = req.body;
39358
40113
  const schema2 = Joi86.object({
39359
40114
  site: Joi86.string().hex().length(24).required(),
39360
40115
  unitId: Joi86.string().hex().length(24).required(),
@@ -39365,7 +40120,12 @@ function useAccessManagementController() {
39365
40120
  return res.status(400).json({ message: error.message });
39366
40121
  }
39367
40122
  const normalizedUnitId = [unitId];
39368
- const result = await vmsgenerateQrCodesSvc({ site, unitId, normalizedUnitId, quantity });
40123
+ const result = await vmsgenerateQrCodesSvc({
40124
+ site,
40125
+ unitId,
40126
+ normalizedUnitId,
40127
+ quantity
40128
+ });
39369
40129
  return res.status(200).json({ message: "Success", data: result });
39370
40130
  } catch (error) {
39371
40131
  return res.status(500).json({
@@ -39376,21 +40136,50 @@ function useAccessManagementController() {
39376
40136
  };
39377
40137
  const addVisitorAccessCard = async (req, res) => {
39378
40138
  try {
39379
- const { site, unitId, quantity = 1, type, nfcCards, visitorId, acm_url } = req.body;
40139
+ const {
40140
+ site,
40141
+ unitId,
40142
+ quantity = 1,
40143
+ type,
40144
+ nfcCards,
40145
+ visitorId,
40146
+ acm_url
40147
+ } = req.body;
39380
40148
  const schema2 = Joi86.object({
39381
40149
  site: Joi86.string().hex().length(24).required(),
39382
40150
  unitId: Joi86.string().hex().length(24).required(),
39383
40151
  quantity: Joi86.number().allow(null, "").optional(),
39384
40152
  type: Joi86.string().required(),
39385
- nfcCards: Joi86.array().items(Joi86.object({ _id: Joi86.string().hex().required(), cardNo: Joi86.string().required() })).required(),
40153
+ nfcCards: Joi86.array().items(
40154
+ Joi86.object({
40155
+ _id: Joi86.string().hex().required(),
40156
+ cardNo: Joi86.string().required()
40157
+ })
40158
+ ).required(),
39386
40159
  acm_url: Joi86.string().required(),
39387
40160
  visitorId: Joi86.string().hex().length(24).required()
39388
40161
  });
39389
- const { error } = schema2.validate({ site, unitId, quantity, type, nfcCards, visitorId, acm_url });
40162
+ const { error } = schema2.validate({
40163
+ site,
40164
+ unitId,
40165
+ quantity,
40166
+ type,
40167
+ nfcCards,
40168
+ visitorId,
40169
+ acm_url
40170
+ });
39390
40171
  if (error) {
39391
40172
  return res.status(400).json({ message: error.message });
39392
40173
  }
39393
- const result = await addVisitorAccessCardSvc({ site, unitId, quantity, type, nfcCards, visitorId, acm_url });
40174
+ const result = await addVisitorAccessCardSvc({
40175
+ site,
40176
+ unitId,
40177
+ quantity,
40178
+ type,
40179
+ nfcCards,
40180
+ visitorId,
40181
+ acm_url
40182
+ });
39394
40183
  return res.status(200).json({ message: "Success", data: result });
39395
40184
  } catch (error) {
39396
40185
  return res.status(500).json({
@@ -39438,7 +40227,11 @@ function useAccessManagementController() {
39438
40227
  });
39439
40228
  }
39440
40229
  };
39441
- const removeAccessCard = async ({ cardNo, staffNo, url }) => {
40230
+ const removeAccessCard = async ({
40231
+ cardNo,
40232
+ staffNo,
40233
+ url
40234
+ }) => {
39442
40235
  return removeAccessGroup({ cardNo, staffNo, url });
39443
40236
  };
39444
40237
  const getBlockLevelAndUnitList = async (req, res) => {
@@ -39457,7 +40250,13 @@ function useAccessManagementController() {
39457
40250
  }
39458
40251
  };
39459
40252
  const getTransactions2 = async (req, res) => {
39460
- const { page = 1, limit = 10, site, cardNo, url } = req.query;
40253
+ const {
40254
+ page = 1,
40255
+ limit = 10,
40256
+ site,
40257
+ cardNo,
40258
+ url
40259
+ } = req.query;
39461
40260
  const schema2 = Joi86.object({
39462
40261
  page: Joi86.number().required(),
39463
40262
  limit: Joi86.number().optional().default(10),
@@ -39496,7 +40295,12 @@ function useAccessManagementController() {
39496
40295
  if (error) {
39497
40296
  throw new Error(`${error.message}`);
39498
40297
  }
39499
- const result = await assignMultipleCardsSvc({ assignees, unit, type, acm_url });
40298
+ const result = await assignMultipleCardsSvc({
40299
+ assignees,
40300
+ unit,
40301
+ type,
40302
+ acm_url
40303
+ });
39500
40304
  return res.status(200).json({ message: "Success", data: result });
39501
40305
  } catch (error) {
39502
40306
  return res.status(400).json({
@@ -39539,6 +40343,27 @@ function useAccessManagementController() {
39539
40343
  });
39540
40344
  }
39541
40345
  };
40346
+ const getResidents = async (req, res) => {
40347
+ try {
40348
+ const { orgId, siteId, unitId } = req.query;
40349
+ const schema2 = Joi86.object({
40350
+ orgId: Joi86.string().hex().required(),
40351
+ siteId: Joi86.string().hex().required(),
40352
+ unitId: Joi86.string().hex().required()
40353
+ });
40354
+ const { error } = schema2.validate({ orgId, siteId, unitId });
40355
+ if (error) {
40356
+ return res.status(400).json({ message: error.message });
40357
+ }
40358
+ const result = await getResidentsSvc({ orgId, siteId, unitId });
40359
+ return res.status(200).json({ data: result });
40360
+ } catch (error) {
40361
+ return res.status(400).json({
40362
+ data: null,
40363
+ message: error.message
40364
+ });
40365
+ }
40366
+ };
39542
40367
  return {
39543
40368
  addPhysicalCard,
39544
40369
  addNonPhysicalCard,
@@ -39575,7 +40400,8 @@ function useAccessManagementController() {
39575
40400
  getTransactions: getTransactions2,
39576
40401
  assignMultipleCards,
39577
40402
  visitorCheckout,
39578
- uploadTemplate
40403
+ uploadTemplate,
40404
+ getResidents
39579
40405
  };
39580
40406
  }
39581
40407
 
@@ -54279,10 +55105,734 @@ function usePostPrelovedController() {
54279
55105
  updateStatus
54280
55106
  };
54281
55107
  }
55108
+
55109
+ // src/models/category-preloved.model.ts
55110
+ import Joi134 from "joi";
55111
+ import { ObjectId as ObjectId131 } from "mongodb";
55112
+ var schemaCategoryPreloved = Joi134.object({
55113
+ name: Joi134.string().required(),
55114
+ createdBy: Joi134.string().hex().optional().allow("", null),
55115
+ site: Joi134.string().hex().optional().allow("", null)
55116
+ });
55117
+ var schemaUpdateCategoryPreloved = Joi134.object({
55118
+ name: Joi134.string().optional().allow("", null),
55119
+ site: Joi134.string().hex().optional().allow("", null)
55120
+ });
55121
+ function MCategoryPreloved(value) {
55122
+ const { error } = schemaCategoryPreloved.validate(value);
55123
+ if (error) {
55124
+ throw new Error(error.details[0].message);
55125
+ }
55126
+ if (value.createdBy && typeof value.createdBy === "string") {
55127
+ try {
55128
+ value.createdBy = new ObjectId131(value.createdBy);
55129
+ } catch {
55130
+ throw new Error("Invalid createdBy ID.");
55131
+ }
55132
+ }
55133
+ if (value.site && typeof value.site === "string") {
55134
+ try {
55135
+ value.site = new ObjectId131(value.site);
55136
+ } catch {
55137
+ throw new Error("Invalid site ID.");
55138
+ }
55139
+ }
55140
+ return {
55141
+ name: value.name ?? "",
55142
+ createdBy: value.createdBy ?? "",
55143
+ site: value.site ?? null,
55144
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
55145
+ updatedAt: value.updatedAt ?? null
55146
+ };
55147
+ }
55148
+
55149
+ // src/repositories/category-preloved.repo.ts
55150
+ import {
55151
+ BadRequestError as BadRequestError212,
55152
+ InternalServerError as InternalServerError75,
55153
+ useAtlas as useAtlas118
55154
+ } from "@7365admin1/node-server-utils";
55155
+ import { ObjectId as ObjectId132 } from "mongodb";
55156
+ function useCategoryPrelovedRepo() {
55157
+ const db = useAtlas118.getDb();
55158
+ if (!db) {
55159
+ throw new InternalServerError75("Unable to connect to server.");
55160
+ }
55161
+ const CATEGORY_COLLECTION = "category-preloved";
55162
+ const collection = db.collection(CATEGORY_COLLECTION);
55163
+ async function getAll({
55164
+ search = "",
55165
+ site
55166
+ } = {}) {
55167
+ if (site) {
55168
+ try {
55169
+ site = new ObjectId132(site);
55170
+ } catch {
55171
+ throw new BadRequestError212("Invalid site ID format.");
55172
+ }
55173
+ }
55174
+ const query = {
55175
+ ...site && { site },
55176
+ ...search && { name: { $regex: search, $options: "i" } }
55177
+ };
55178
+ try {
55179
+ return await collection.find(query).sort({ name: 1 }).toArray();
55180
+ } catch (error) {
55181
+ console.error("Error in category-preloved getAll:", error);
55182
+ throw error;
55183
+ }
55184
+ }
55185
+ return { getAll };
55186
+ }
55187
+
55188
+ // src/controllers/category-preloved.controller.ts
55189
+ import { BadRequestError as BadRequestError213, logger as logger187 } from "@7365admin1/node-server-utils";
55190
+ import Joi135 from "joi";
55191
+ function useCategoryPrelovedController() {
55192
+ const { getAll: _getAll } = useCategoryPrelovedRepo();
55193
+ async function getAll(req, res, next) {
55194
+ const schema2 = Joi135.object({
55195
+ search: Joi135.string().optional().allow("", null),
55196
+ site: Joi135.string().hex().length(24).optional().allow("", null)
55197
+ });
55198
+ const { error, value } = schema2.validate(req.query, { abortEarly: false });
55199
+ if (error) {
55200
+ const messages = error.details.map((d) => d.message).join(", ");
55201
+ logger187.log({ level: "error", message: messages });
55202
+ next(new BadRequestError213(messages));
55203
+ return;
55204
+ }
55205
+ try {
55206
+ const data = await _getAll(value);
55207
+ res.status(200).json({ data });
55208
+ return;
55209
+ } catch (error2) {
55210
+ logger187.log({ level: "error", message: error2.message });
55211
+ next(error2);
55212
+ return;
55213
+ }
55214
+ }
55215
+ return { getAll };
55216
+ }
55217
+
55218
+ // src/models/subcategory-preloved.model.ts
55219
+ import Joi136 from "joi";
55220
+ import { ObjectId as ObjectId133 } from "mongodb";
55221
+ var schemaSubcategoryPreloved = Joi136.object({
55222
+ name: Joi136.string().required(),
55223
+ createdBy: Joi136.string().hex().optional().allow("", null),
55224
+ site: Joi136.string().hex().optional().allow("", null),
55225
+ category_id: Joi136.string().hex().required()
55226
+ });
55227
+ var schemaUpdateSubcategoryPreloved = Joi136.object({
55228
+ name: Joi136.string().optional().allow("", null),
55229
+ site: Joi136.string().hex().optional().allow("", null),
55230
+ category_id: Joi136.string().hex().optional().allow("", null)
55231
+ });
55232
+ function MSubcategoryPreloved(value) {
55233
+ const { error } = schemaSubcategoryPreloved.validate(value);
55234
+ if (error) {
55235
+ throw new Error(error.details[0].message);
55236
+ }
55237
+ if (value.createdBy && typeof value.createdBy === "string") {
55238
+ try {
55239
+ value.createdBy = new ObjectId133(value.createdBy);
55240
+ } catch {
55241
+ throw new Error("Invalid createdBy ID.");
55242
+ }
55243
+ }
55244
+ if (value.site && typeof value.site === "string") {
55245
+ try {
55246
+ value.site = new ObjectId133(value.site);
55247
+ } catch {
55248
+ throw new Error("Invalid site ID.");
55249
+ }
55250
+ }
55251
+ if (value.category_id && typeof value.category_id === "string") {
55252
+ try {
55253
+ value.category_id = new ObjectId133(value.category_id);
55254
+ } catch {
55255
+ throw new Error("Invalid category ID.");
55256
+ }
55257
+ }
55258
+ return {
55259
+ name: value.name ?? "",
55260
+ createdBy: value.createdBy ?? "",
55261
+ site: value.site ?? null,
55262
+ category_id: value.category_id ?? "",
55263
+ createdAt: value.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
55264
+ updatedAt: value.updatedAt ?? null
55265
+ };
55266
+ }
55267
+
55268
+ // src/repositories/subcategory-preloved.repo.ts
55269
+ import {
55270
+ BadRequestError as BadRequestError214,
55271
+ InternalServerError as InternalServerError76,
55272
+ useAtlas as useAtlas119
55273
+ } from "@7365admin1/node-server-utils";
55274
+ import { ObjectId as ObjectId134 } from "mongodb";
55275
+ function useSubcategoryPrelovedRepo() {
55276
+ const db = useAtlas119.getDb();
55277
+ if (!db) {
55278
+ throw new InternalServerError76("Unable to connect to server.");
55279
+ }
55280
+ const SUBCATEGORY_COLLECTION = "subcategory-preloved";
55281
+ const collection = db.collection(SUBCATEGORY_COLLECTION);
55282
+ async function getAll({
55283
+ search = "",
55284
+ site,
55285
+ category_id
55286
+ } = {}) {
55287
+ if (site) {
55288
+ try {
55289
+ site = new ObjectId134(site);
55290
+ } catch {
55291
+ throw new BadRequestError214("Invalid site ID format.");
55292
+ }
55293
+ }
55294
+ if (category_id) {
55295
+ try {
55296
+ category_id = new ObjectId134(category_id);
55297
+ } catch {
55298
+ throw new BadRequestError214("Invalid category ID format.");
55299
+ }
55300
+ }
55301
+ const query = {
55302
+ ...site && { site },
55303
+ ...category_id && { category_id },
55304
+ ...search && { name: { $regex: search, $options: "i" } }
55305
+ };
55306
+ try {
55307
+ return await collection.find(query).sort({ name: 1 }).toArray();
55308
+ } catch (error) {
55309
+ throw error;
55310
+ }
55311
+ }
55312
+ return { getAll };
55313
+ }
55314
+
55315
+ // src/controllers/subcategory-preloved.controller.ts
55316
+ import { BadRequestError as BadRequestError215, logger as logger188 } from "@7365admin1/node-server-utils";
55317
+ import Joi137 from "joi";
55318
+ function useSubcategoryPrelovedController() {
55319
+ const { getAll: _getAll } = useSubcategoryPrelovedRepo();
55320
+ async function getAll(req, res, next) {
55321
+ const schema2 = Joi137.object({
55322
+ search: Joi137.string().optional().allow("", null),
55323
+ site: Joi137.string().hex().length(24).optional().allow("", null),
55324
+ category_id: Joi137.string().hex().length(24).optional().allow("", null)
55325
+ });
55326
+ const { error, value } = schema2.validate(req.query, { abortEarly: false });
55327
+ if (error) {
55328
+ const messages = error.details.map((d) => d.message).join(", ");
55329
+ logger188.log({ level: "error", message: messages });
55330
+ next(new BadRequestError215(messages));
55331
+ return;
55332
+ }
55333
+ try {
55334
+ const data = await _getAll(value);
55335
+ res.status(200).json({ data });
55336
+ return;
55337
+ } catch (error2) {
55338
+ logger188.log({ level: "error", message: error2.message });
55339
+ next(error2);
55340
+ return;
55341
+ }
55342
+ }
55343
+ return { getAll };
55344
+ }
55345
+
55346
+ // src/models/online-forms-v2.model.ts
55347
+ import Joi138 from "joi";
55348
+ import { ObjectId as ObjectId135 } from "mongodb";
55349
+ var FormEntryStatus = /* @__PURE__ */ ((FormEntryStatus2) => {
55350
+ FormEntryStatus2["ACTIVE"] = "active";
55351
+ FormEntryStatus2["INACTIVE"] = "inactive";
55352
+ FormEntryStatus2["DELETED"] = "deleted";
55353
+ return FormEntryStatus2;
55354
+ })(FormEntryStatus || {});
55355
+ var schemaFormEntry = Joi138.object({
55356
+ _id: Joi138.string().hex().optional().allow("", null),
55357
+ formType: Joi138.string().required(),
55358
+ fields: Joi138.object().pattern(
55359
+ Joi138.string(),
55360
+ Joi138.alternatives().try(
55361
+ Joi138.string(),
55362
+ Joi138.number(),
55363
+ Joi138.boolean(),
55364
+ Joi138.valid(null)
55365
+ )
55366
+ ).required(),
55367
+ status: Joi138.string().optional().allow("", null),
55368
+ org: Joi138.string().hex().optional().allow("", null),
55369
+ site: Joi138.string().hex().optional().allow("", null),
55370
+ createdAt: Joi138.date().optional().allow("", null),
55371
+ updatedAt: Joi138.date().optional().allow("", null),
55372
+ deletedAt: Joi138.date().optional().allow("", null)
55373
+ });
55374
+ var schemaUpdateFormEntry = Joi138.object({
55375
+ _id: Joi138.string().hex().required(),
55376
+ formType: Joi138.string().optional().allow("", null),
55377
+ fields: Joi138.object().pattern(
55378
+ Joi138.string(),
55379
+ Joi138.alternatives().try(
55380
+ Joi138.string(),
55381
+ Joi138.number(),
55382
+ Joi138.boolean(),
55383
+ Joi138.valid(null)
55384
+ )
55385
+ ).optional(),
55386
+ status: Joi138.string().optional().allow("", null),
55387
+ createdAt: Joi138.date().optional().allow("", null),
55388
+ updatedAt: Joi138.date().optional().allow("", null),
55389
+ deletedAt: Joi138.date().optional().allow("", null)
55390
+ });
55391
+ function MFormEntry(value) {
55392
+ const { error } = schemaFormEntry.validate(value);
55393
+ if (error) {
55394
+ throw new Error(error.details[0].message);
55395
+ }
55396
+ if (value._id && typeof value._id === "string") {
55397
+ try {
55398
+ value._id = new ObjectId135(value._id);
55399
+ } catch {
55400
+ throw new Error("Invalid ID.");
55401
+ }
55402
+ }
55403
+ if (value.org && typeof value.org === "string") {
55404
+ try {
55405
+ value.org = new ObjectId135(value.org);
55406
+ } catch {
55407
+ throw new Error("Invalid org ID.");
55408
+ }
55409
+ }
55410
+ if (value.site && typeof value.site === "string") {
55411
+ try {
55412
+ value.site = new ObjectId135(value.site);
55413
+ } catch {
55414
+ throw new Error("Invalid site ID.");
55415
+ }
55416
+ }
55417
+ return {
55418
+ _id: value._id,
55419
+ formType: value.formType,
55420
+ fields: value.fields,
55421
+ status: value.status,
55422
+ org: value.org,
55423
+ site: value.site,
55424
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
55425
+ updatedAt: value.updatedAt ?? null,
55426
+ deletedAt: value.deletedAt ?? null
55427
+ };
55428
+ }
55429
+
55430
+ // src/repositories/online-forms-v2.repository.ts
55431
+ import {
55432
+ BadRequestError as BadRequestError216,
55433
+ InternalServerError as InternalServerError77,
55434
+ logger as logger189,
55435
+ useAtlas as useAtlas120,
55436
+ useCache as useCache69
55437
+ } from "@7365admin1/node-server-utils";
55438
+ var online_forms_namespace_collection = "online-forms";
55439
+ function useFormEntryRepo() {
55440
+ const db = useAtlas120.getDb();
55441
+ if (!db) {
55442
+ throw new InternalServerError77("Unable to connect to server.");
55443
+ }
55444
+ const collection = db.collection(online_forms_namespace_collection);
55445
+ const { delNamespace, getCache, setCache } = useCache69(
55446
+ online_forms_namespace_collection
55447
+ );
55448
+ async function createTextIndex() {
55449
+ try {
55450
+ await collection.createIndex({
55451
+ name: "text"
55452
+ });
55453
+ } catch (error) {
55454
+ throw new InternalServerError77(
55455
+ "Failed to create text index on online form."
55456
+ );
55457
+ }
55458
+ }
55459
+ async function add(value, session) {
55460
+ try {
55461
+ value = MFormEntry(value);
55462
+ const res = await collection.insertOne(value, { session });
55463
+ delNamespace().then(() => {
55464
+ logger189.info(
55465
+ `Cache cleared for namespace: ${online_forms_namespace_collection}`
55466
+ );
55467
+ }).catch((err) => {
55468
+ logger189.error(
55469
+ `Failed to clear cache for namespace: ${online_forms_namespace_collection}`,
55470
+ err
55471
+ );
55472
+ });
55473
+ return res.insertedId;
55474
+ } catch (error) {
55475
+ const isDuplicated = error.message.includes("duplicate");
55476
+ if (isDuplicated) {
55477
+ throw new BadRequestError216("Online Form already exists.");
55478
+ }
55479
+ throw error;
55480
+ }
55481
+ }
55482
+ return {
55483
+ add,
55484
+ createTextIndex
55485
+ };
55486
+ }
55487
+
55488
+ // src/controllers/online-forms-v2.controller.ts
55489
+ import { BadRequestError as BadRequestError217, logger as logger190 } from "@7365admin1/node-server-utils";
55490
+ import ExcelJS3 from "exceljs";
55491
+ import fs5 from "fs";
55492
+ function useFormEntryController() {
55493
+ const { add: _add } = useFormEntryRepo();
55494
+ function toCamelCase(str) {
55495
+ return str.replace(/\s(.)/g, (_, char) => char.toUpperCase()).replace(/\s+/g, "").replace(/^(.)/, (_, char) => char.toLowerCase());
55496
+ }
55497
+ function normalizeKeys(obj) {
55498
+ const normalized = {};
55499
+ for (const [key, value] of Object.entries(obj)) {
55500
+ normalized[toCamelCase(key)] = value;
55501
+ }
55502
+ return normalized;
55503
+ }
55504
+ async function uploadFormEntrys(req, res, next) {
55505
+ try {
55506
+ if (!req.file) {
55507
+ next(new BadRequestError217("Excel file is required."));
55508
+ return;
55509
+ }
55510
+ const workbook = new ExcelJS3.Workbook();
55511
+ await workbook.xlsx.readFile(req.file.path);
55512
+ const worksheet = workbook.worksheets[0];
55513
+ if (!worksheet) {
55514
+ next(new BadRequestError217("No worksheet found in uploaded Excel file."));
55515
+ return;
55516
+ }
55517
+ const headerRow = worksheet.getRow(1);
55518
+ const headers = headerRow.values.slice(1).map((h) => String(h ?? "").trim());
55519
+ const fields = {};
55520
+ headers.forEach((header) => {
55521
+ fields[header] = null;
55522
+ });
55523
+ const formType = req.file.originalname.replace(/\.[^/.]+$/, "");
55524
+ const normalizedFields = normalizeKeys(fields);
55525
+ const payload = {
55526
+ formType,
55527
+ fields: normalizedFields,
55528
+ status: "active" /* ACTIVE */
55529
+ };
55530
+ const { error, value } = schemaFormEntry.validate(payload, {
55531
+ abortEarly: false
55532
+ });
55533
+ if (error) {
55534
+ const messages = error.details.map((d) => d.message).join(", ");
55535
+ logger190.log({ level: "error", message: messages });
55536
+ next(new BadRequestError217(messages));
55537
+ return;
55538
+ }
55539
+ const result = await _add(value);
55540
+ res.status(201).json(result);
55541
+ fs5.unlink(req.file.path, () => {
55542
+ });
55543
+ } catch (error) {
55544
+ logger190.log({ level: "error", message: error.message });
55545
+ next(error);
55546
+ }
55547
+ }
55548
+ return {
55549
+ uploadFormEntrys
55550
+ };
55551
+ }
55552
+
55553
+ // src/models/building-level.model.ts
55554
+ import { BadRequestError as BadRequestError218 } from "@7365admin1/node-server-utils";
55555
+ import { ObjectId as ObjectId136 } from "mongodb";
55556
+ import Joi139 from "joi";
55557
+ import { logger as logger191 } from "@7365admin1/node-server-utils";
55558
+ var BuildingLevelStatus = /* @__PURE__ */ ((BuildingLevelStatus2) => {
55559
+ BuildingLevelStatus2["ACTIVE"] = "active";
55560
+ BuildingLevelStatus2["DELETED"] = "deleted";
55561
+ return BuildingLevelStatus2;
55562
+ })(BuildingLevelStatus || {});
55563
+ var schemaBuildingLevel = Joi139.object({
55564
+ org: Joi139.string().hex().optional(),
55565
+ site: Joi139.string().hex().optional(),
55566
+ blockId: Joi139.string().hex().optional(),
55567
+ name: Joi139.string().optional(),
55568
+ status: Joi139.string().valid(...Object.values(BuildingLevelStatus)).optional(),
55569
+ createdAt: Joi139.date().optional(),
55570
+ updatedAt: Joi139.date().optional().allow(null),
55571
+ deletedAt: Joi139.date().optional().allow(null)
55572
+ });
55573
+ function MBuildingLevel(value) {
55574
+ const { error } = schemaBuildingLevel.validate(value);
55575
+ if (error) {
55576
+ logger191.info(`Building Level Model: ${error.message}`);
55577
+ throw new BadRequestError218(error.message);
55578
+ }
55579
+ if (value.org && typeof value.org === "string") {
55580
+ try {
55581
+ value.org = new ObjectId136(value.org);
55582
+ } catch {
55583
+ throw new BadRequestError218("Invalid org ID format");
55584
+ }
55585
+ }
55586
+ if (value.site && typeof value.site === "string") {
55587
+ try {
55588
+ value.site = new ObjectId136(value.site);
55589
+ } catch {
55590
+ throw new BadRequestError218("Invalid site ID format");
55591
+ }
55592
+ }
55593
+ if (value.blockId && typeof value.blockId === "string") {
55594
+ try {
55595
+ value.blockId = new ObjectId136(value.blockId);
55596
+ } catch {
55597
+ throw new BadRequestError218("Invalid block ID format");
55598
+ }
55599
+ }
55600
+ return {
55601
+ _id: new ObjectId136(),
55602
+ org: value.org ?? void 0,
55603
+ site: value.site ?? void 0,
55604
+ blockId: value.blockId ?? void 0,
55605
+ name: value.name ?? "",
55606
+ status: value.status ?? "active" /* ACTIVE */,
55607
+ createdAt: value.createdAt ?? /* @__PURE__ */ new Date(),
55608
+ updatedAt: value.updatedAt ?? null,
55609
+ deletedAt: value.deletedAt ?? null
55610
+ };
55611
+ }
55612
+
55613
+ // src/repositories/building-level.repository.ts
55614
+ import {
55615
+ AppError as AppError29,
55616
+ BadRequestError as BadRequestError219,
55617
+ logger as logger192,
55618
+ makeCacheKey as makeCacheKey66,
55619
+ paginate as paginate61,
55620
+ toObjectId as toObjectId20,
55621
+ useAtlas as useAtlas121,
55622
+ useCache as useCache70
55623
+ } from "@7365admin1/node-server-utils";
55624
+ var building_level_namespace_collection = "building-levels";
55625
+ function useBuildingLevelRepo() {
55626
+ const db = useAtlas121.getDb();
55627
+ if (!db) {
55628
+ throw new Error("Unable to connect to server.");
55629
+ }
55630
+ const collection = db.collection(building_level_namespace_collection);
55631
+ const { getCache, setCache, delNamespace, delCache } = useCache70(
55632
+ building_level_namespace_collection
55633
+ );
55634
+ function delCachedData() {
55635
+ delNamespace().then(() => {
55636
+ logger192.log({
55637
+ level: "info",
55638
+ message: `Cache namespace cleared for ${building_level_namespace_collection}`
55639
+ });
55640
+ }).catch((err) => {
55641
+ logger192.log({
55642
+ level: "error",
55643
+ message: `Failed to clear cache namespace for ${building_level_namespace_collection}: ${err.message}`
55644
+ });
55645
+ });
55646
+ }
55647
+ async function add(value, session) {
55648
+ try {
55649
+ value = MBuildingLevel(value);
55650
+ const res = await collection.insertOne(value, { session });
55651
+ delCachedData();
55652
+ return res.insertedId;
55653
+ } catch (error) {
55654
+ logger192.log({
55655
+ level: "error",
55656
+ message: error.message
55657
+ });
55658
+ const isDuplicated = error.message.includes("duplicate");
55659
+ if (isDuplicated) {
55660
+ throw new BadRequestError219("Building unit already exists.");
55661
+ }
55662
+ if (error instanceof AppError29) {
55663
+ throw error;
55664
+ } else {
55665
+ throw new Error("Failed to create building unit.");
55666
+ }
55667
+ }
55668
+ }
55669
+ async function getAll({
55670
+ search = "",
55671
+ page = 1,
55672
+ limit = 10,
55673
+ sort = {},
55674
+ site = "",
55675
+ status = "active"
55676
+ } = {}) {
55677
+ page = page > 0 ? page - 1 : 0;
55678
+ const query = {
55679
+ status,
55680
+ ...search && { $text: { $search: search } },
55681
+ ...site && { site: toObjectId20(site) }
55682
+ };
55683
+ const cacheParams = {
55684
+ page,
55685
+ limit,
55686
+ sort: JSON.stringify(sort),
55687
+ ...search && { search },
55688
+ ...site && { site },
55689
+ ...status && { status }
55690
+ };
55691
+ const cacheKey = makeCacheKey66(
55692
+ building_level_namespace_collection,
55693
+ cacheParams
55694
+ );
55695
+ logger192.log({
55696
+ level: "info",
55697
+ message: `Cache key for getAll building units: ${cacheKey}`
55698
+ });
55699
+ try {
55700
+ const cached = await getCache(cacheKey);
55701
+ if (cached) {
55702
+ logger192.log({
55703
+ level: "info",
55704
+ message: `Cache hit for getAll building units: ${cacheKey}`
55705
+ });
55706
+ return cached;
55707
+ }
55708
+ const sortStage = Object.keys(sort).length > 0 ? { $sort: sort } : { $sort: { latestDate: -1 } };
55709
+ const items = await collection.aggregate([
55710
+ { $match: query },
55711
+ {
55712
+ $addFields: {
55713
+ latestDate: { $max: ["$updatedAt", "$createdAt"] }
55714
+ }
55715
+ },
55716
+ sortStage,
55717
+ { $unset: "latestDate" },
55718
+ { $skip: page * limit },
55719
+ { $limit: limit }
55720
+ ]).toArray();
55721
+ const length = await collection.countDocuments(query);
55722
+ const data = paginate61(items, page, limit, length);
55723
+ setCache(cacheKey, data, 600).then(() => {
55724
+ logger192.log({
55725
+ level: "info",
55726
+ message: `Cache set for getAll building units: ${cacheKey}`
55727
+ });
55728
+ }).catch((err) => {
55729
+ logger192.log({
55730
+ level: "error",
55731
+ message: `Failed to set cache for getAll building units: ${err.message}`
55732
+ });
55733
+ });
55734
+ return data;
55735
+ } catch (error) {
55736
+ console.log(error);
55737
+ logger192.log({ level: "error", message: `${error}` });
55738
+ throw error;
55739
+ }
55740
+ }
55741
+ return {
55742
+ // createIndexes,
55743
+ add,
55744
+ getAll
55745
+ };
55746
+ }
55747
+
55748
+ // src/services/building-level.service.ts
55749
+ import { useAtlas as useAtlas122 } from "@7365admin1/node-server-utils";
55750
+ function useBuildingLevelService() {
55751
+ const { add: _add } = useBuildingLevelRepo();
55752
+ async function add(value) {
55753
+ const session = useAtlas122.getClient()?.startSession();
55754
+ try {
55755
+ session?.startTransaction();
55756
+ await _add(value, session);
55757
+ await session?.commitTransaction();
55758
+ return "Successfully added building level.";
55759
+ } catch (error) {
55760
+ await session?.abortTransaction();
55761
+ throw error;
55762
+ } finally {
55763
+ session?.endSession();
55764
+ }
55765
+ }
55766
+ return {
55767
+ add
55768
+ };
55769
+ }
55770
+
55771
+ // src/controllers/building-level.controller.ts
55772
+ import { BadRequestError as BadRequestError220, logger as logger193 } from "@7365admin1/node-server-utils";
55773
+ import Joi140 from "joi";
55774
+ function useBuildingLevelController() {
55775
+ const { add: _add } = useBuildingLevelService();
55776
+ const { getAll: _getAll } = useBuildingLevelRepo();
55777
+ async function add(req, res, next) {
55778
+ try {
55779
+ const { error, value } = schemaBuildingLevel.validate(req.body, {
55780
+ abortEarly: false
55781
+ });
55782
+ if (error) {
55783
+ const messages = error.details.map((d) => d.message).join(", ");
55784
+ logger193.log({ level: "error", message: messages });
55785
+ next(new BadRequestError220(messages));
55786
+ return;
55787
+ }
55788
+ const result = await _add(value);
55789
+ res.status(201).json(result);
55790
+ } catch (error) {
55791
+ next(error);
55792
+ }
55793
+ }
55794
+ async function getAll(req, res, next) {
55795
+ try {
55796
+ const validation = Joi140.object({
55797
+ page: Joi140.number().min(1).optional().default(1),
55798
+ limit: Joi140.number().min(1).optional().default(20),
55799
+ search: Joi140.string().optional().allow("", null),
55800
+ site: Joi140.string().hex().length(24).optional().allow("", null),
55801
+ status: Joi140.string().valid(...Object.values(BuildingLevelStatus)).default("active" /* ACTIVE */)
55802
+ });
55803
+ const { error, value } = validation.validate(req.query, {
55804
+ abortEarly: false
55805
+ });
55806
+ if (error) {
55807
+ const messages = error.details.map((d) => d.message);
55808
+ logger193.log({ level: "error", message: messages.join(", ") });
55809
+ next(new BadRequestError220(messages.join(", ")));
55810
+ return;
55811
+ }
55812
+ const { page, limit, status, site, search } = value;
55813
+ const result = await _getAll({
55814
+ page,
55815
+ limit,
55816
+ status,
55817
+ site,
55818
+ search
55819
+ });
55820
+ res.json(result);
55821
+ return;
55822
+ } catch (error) {
55823
+ next(error);
55824
+ }
55825
+ }
55826
+ return {
55827
+ add,
55828
+ getAll
55829
+ };
55830
+ }
54282
55831
  export {
54283
55832
  ANPRMode,
54284
55833
  AccessTypeProps,
54285
55834
  AppServiceType,
55835
+ BuildingLevelStatus,
54286
55836
  BuildingStatus,
54287
55837
  BulletinOrder,
54288
55838
  BulletinRecipient,
@@ -54305,6 +55855,7 @@ export {
54305
55855
  EventType,
54306
55856
  FacilitySort,
54307
55857
  FacilityStatus,
55858
+ FormEntryStatus,
54308
55859
  GuestSort,
54309
55860
  GuestStatus,
54310
55861
  MAccessCard,
@@ -54315,9 +55866,11 @@ export {
54315
55866
  MBillingConfiguration,
54316
55867
  MBillingItem,
54317
55868
  MBuilding,
55869
+ MBuildingLevel,
54318
55870
  MBuildingUnit,
54319
55871
  MBulletinBoard,
54320
55872
  MBulletinVideo,
55873
+ MCategoryPreloved,
54321
55874
  MChat,
54322
55875
  MCustomer,
54323
55876
  MCustomerSite,
@@ -54326,6 +55879,7 @@ export {
54326
55879
  MEventManagement,
54327
55880
  MFeedback,
54328
55881
  MFile,
55882
+ MFormEntry,
54329
55883
  MGuestManagement,
54330
55884
  MIncidentReport,
54331
55885
  MManpowerDesignations,
@@ -54362,6 +55916,7 @@ export {
54362
55916
  MSiteFacility,
54363
55917
  MSiteFacilityBooking,
54364
55918
  MStatementOfAccount,
55919
+ MSubcategoryPreloved,
54365
55920
  MSubscription,
54366
55921
  MUnitBilling,
54367
55922
  MUser,
@@ -54409,6 +55964,7 @@ export {
54409
55964
  allowedNatures,
54410
55965
  attendanceSchema,
54411
55966
  attendanceSettingsSchema,
55967
+ building_level_namespace_collection,
54412
55968
  building_units_namespace_collection,
54413
55969
  buildings_namespace_collection,
54414
55970
  bulletin_boards_namespace_collection,
@@ -54437,6 +55993,7 @@ export {
54437
55993
  nfcPatrolSettingsSchema,
54438
55994
  nfcPatrolSettingsSchemaUpdate,
54439
55995
  occurrence_book_namespace_collection,
55996
+ online_forms_namespace_collection,
54440
55997
  orgSchema,
54441
55998
  overnight_parking_requests_namespace_collection,
54442
55999
  parseDahuaFind,
@@ -54452,15 +56009,18 @@ export {
54452
56009
  schemaBillingConfiguration,
54453
56010
  schemaBillingItem,
54454
56011
  schemaBuilding,
56012
+ schemaBuildingLevel,
54455
56013
  schemaBuildingUnit,
54456
56014
  schemaBuildingUpdateOptions,
54457
56015
  schemaBulletinBoard,
54458
56016
  schemaBulletinVideo,
56017
+ schemaCategoryPreloved,
54459
56018
  schemaCustomerSite,
54460
56019
  schemaDocumentManagement,
54461
56020
  schemaEntryPassSettings,
54462
56021
  schemaEventManagement,
54463
56022
  schemaFiles,
56023
+ schemaFormEntry,
54464
56024
  schemaGuestManagement,
54465
56025
  schemaIncidentReport,
54466
56026
  schemaNfcPatrolLog,
@@ -54485,12 +56045,15 @@ export {
54485
56045
  schemaSiteFacility,
54486
56046
  schemaSiteFacilityBooking,
54487
56047
  schemaStatementOfAccount,
56048
+ schemaSubcategoryPreloved,
54488
56049
  schemaUnitBilling,
54489
56050
  schemaUpdateBulletinBoard,
54490
56051
  schemaUpdateBulletinVideo,
56052
+ schemaUpdateCategoryPreloved,
54491
56053
  schemaUpdateDocumentManagement,
54492
56054
  schemaUpdateEntryPassSettings,
54493
56055
  schemaUpdateEventManagement,
56056
+ schemaUpdateFormEntry,
54494
56057
  schemaUpdateGuestManagement,
54495
56058
  schemaUpdateIncidentReport,
54496
56059
  schemaUpdateOccurrenceBook,
@@ -54512,6 +56075,7 @@ export {
54512
56075
  schemaUpdateSiteFacilityBooking,
54513
56076
  schemaUpdateSiteUnitBilling,
54514
56077
  schemaUpdateStatementOfAccount,
56078
+ schemaUpdateSubcategoryPreloved,
54515
56079
  schemaUpdateVisTrans,
54516
56080
  schemaVehicleTransaction,
54517
56081
  schemaVisitorTransaction,
@@ -54537,6 +56101,9 @@ export {
54537
56101
  useAuthService,
54538
56102
  useAuthServiceV2,
54539
56103
  useBuildingController,
56104
+ useBuildingLevelController,
56105
+ useBuildingLevelRepo,
56106
+ useBuildingLevelService,
54540
56107
  useBuildingRepo,
54541
56108
  useBuildingService,
54542
56109
  useBuildingUnitController,
@@ -54548,6 +56115,8 @@ export {
54548
56115
  useBulletinVideoController,
54549
56116
  useBulletinVideoRepo,
54550
56117
  useBulletinVideoService,
56118
+ useCategoryPrelovedController,
56119
+ useCategoryPrelovedRepo,
54551
56120
  useChatController,
54552
56121
  useChatRepo,
54553
56122
  useCounterModel,
@@ -54574,6 +56143,8 @@ export {
54574
56143
  useFileController,
54575
56144
  useFileRepo,
54576
56145
  useFileService,
56146
+ useFormEntryController,
56147
+ useFormEntryRepo,
54577
56148
  useGuestManagementController,
54578
56149
  useGuestManagementRepo,
54579
56150
  useGuestManagementService,
@@ -54683,6 +56254,8 @@ export {
54683
56254
  useSiteUnitBillingService,
54684
56255
  useStatementOfAccountController,
54685
56256
  useStatementOfAccountRepo,
56257
+ useSubcategoryPrelovedController,
56258
+ useSubcategoryPrelovedRepo,
54686
56259
  useSubscriptionController,
54687
56260
  useSubscriptionRepo,
54688
56261
  useSubscriptionService,