@7365admin1/core 3.52.7 → 3.52.8

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
@@ -11606,6 +11606,36 @@ import {
11606
11606
  } from "@7365admin1/node-server-utils";
11607
11607
  import Joi9 from "joi";
11608
11608
  import { ObjectId as ObjectId20 } from "mongodb";
11609
+
11610
+ // src/utils/site-timezone.util.ts
11611
+ import moment from "moment-timezone";
11612
+ var DEFAULT_SITE_TIMEZONE = "Asia/Singapore";
11613
+ function isValidTimezone(tz) {
11614
+ return typeof tz === "string" && tz.length > 0 && !!moment.tz.zone(tz);
11615
+ }
11616
+ function resolveSiteTimezone(site) {
11617
+ const tz = site?.timezone;
11618
+ return isValidTimezone(tz) ? tz : DEFAULT_SITE_TIMEZONE;
11619
+ }
11620
+ function siteDayBounds(value, timezone) {
11621
+ if (!value)
11622
+ return null;
11623
+ const tz = isValidTimezone(timezone) ? timezone : DEFAULT_SITE_TIMEZONE;
11624
+ const isDateOnly = typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value);
11625
+ const m = isDateOnly ? moment.tz(value, "YYYY-MM-DD", tz) : typeof value === "string" ? moment.tz(value, moment.ISO_8601, tz) : moment.tz(value, tz);
11626
+ if (!m.isValid())
11627
+ return null;
11628
+ return {
11629
+ start: m.clone().startOf("day").toDate(),
11630
+ end: m.clone().endOf("day").toDate(),
11631
+ date: m.format("YYYY-MM-DD")
11632
+ };
11633
+ }
11634
+
11635
+ // src/models/site.model.ts
11636
+ function siteTimezoneValidator(value, helpers) {
11637
+ return isValidTimezone(value) ? value : helpers.error("any.invalid");
11638
+ }
11609
11639
  var addressSchema = Joi9.object({
11610
11640
  line1: Joi9.string().min(3).required(),
11611
11641
  line2: Joi9.string().allow("", null),
@@ -11713,6 +11743,7 @@ var siteSchema = Joi9.object({
11713
11743
  orgId: Joi9.string().hex().required(),
11714
11744
  customerId: Joi9.string().hex().optional().allow("", null),
11715
11745
  address: addressSchema.optional(),
11746
+ timezone: Joi9.string().custom(siteTimezoneValidator, "IANA timezone").optional().default(DEFAULT_SITE_TIMEZONE),
11716
11747
  category: Joi9.string().valid(...Object.values(SiteCategories)).default("commercial" /* COMMERCIAL */),
11717
11748
  deliveryCompanyList: Joi9.array().items(Joi9.string()).optional().allow(null),
11718
11749
  isOpenGate: Joi9.boolean().optional().default(false),
@@ -11723,6 +11754,7 @@ var siteSchema = Joi9.object({
11723
11754
  var updateSiteSchema = Joi9.object({
11724
11755
  _id: Joi9.string().hex().length(24).required(),
11725
11756
  address: updateAddressSchema.optional(),
11757
+ timezone: Joi9.string().custom(siteTimezoneValidator, "IANA timezone").optional(),
11726
11758
  metadata: metadataSchema3.optional(),
11727
11759
  deliveryCompanyList: Joi9.array().items(Joi9.string().trim()).optional().allow(null),
11728
11760
  isOpenGate: Joi9.boolean().optional().allow(null),
@@ -11751,6 +11783,7 @@ function MSite(value) {
11751
11783
  status: "active",
11752
11784
  createdAt: /* @__PURE__ */ new Date(),
11753
11785
  address: value.address,
11786
+ timezone: value.timezone ?? DEFAULT_SITE_TIMEZONE,
11754
11787
  category: value.category,
11755
11788
  deliveryCompanyList: value.deliveryCompanyList ?? [],
11756
11789
  isOpenGate: value.isOpenGate,
@@ -13035,7 +13068,8 @@ function useCustomerSiteRepo() {
13035
13068
  limit = 10,
13036
13069
  sort = {},
13037
13070
  org = "",
13038
- status = "active"
13071
+ status = "active",
13072
+ siteScope = null
13039
13073
  }, session) {
13040
13074
  page = page > 0 ? page - 1 : 0;
13041
13075
  try {
@@ -13055,6 +13089,11 @@ function useCustomerSiteRepo() {
13055
13089
  page,
13056
13090
  limit
13057
13091
  };
13092
+ if (siteScope) {
13093
+ const scoped = siteScope.filter((id) => ObjectId24.isValid(id));
13094
+ query2.site = { $in: scoped.map((id) => new ObjectId24(id)) };
13095
+ cacheOptions.siteScope = scoped.length ? [...scoped].sort().join(",") : "no-site";
13096
+ }
13058
13097
  if (search) {
13059
13098
  query2.$or = [{ name: { $regex: search, $options: "i" } }];
13060
13099
  cacheOptions.search = search;
@@ -13361,7 +13400,8 @@ var EMPTY = {
13361
13400
  name: "",
13362
13401
  isSuperAdmin: false,
13363
13402
  orgIds: [],
13364
- propertyManagementOrgIds: []
13403
+ propertyManagementOrgIds: [],
13404
+ memberships: []
13365
13405
  };
13366
13406
  async function resolveInviteActor(userId) {
13367
13407
  const id = userId?.toString() ?? "";
@@ -13388,12 +13428,36 @@ async function resolveInviteActor(userId) {
13388
13428
  )
13389
13429
  );
13390
13430
  const user = await db2.collection("users").findOne({ _id: new ObjectId25(id) }, { projection: { name: 1 } });
13431
+ const memberRoleIds = Array.from(
13432
+ new Set(
13433
+ members.map((m) => m.role?.toString?.() ?? "").filter((r) => r && ObjectId25.isValid(r))
13434
+ )
13435
+ );
13436
+ const orgLevelRoleIds = /* @__PURE__ */ new Set();
13437
+ if (memberRoleIds.length) {
13438
+ const memberRoles = await db2.collection("roles").find(
13439
+ {
13440
+ _id: { $in: memberRoleIds.map((r) => new ObjectId25(r)) },
13441
+ ...LIVE_ROLE
13442
+ },
13443
+ { projection: { site: 1 } }
13444
+ ).toArray();
13445
+ for (const role of memberRoles) {
13446
+ if (!role.site)
13447
+ orgLevelRoleIds.add(role._id.toString());
13448
+ }
13449
+ }
13391
13450
  return {
13392
13451
  id,
13393
13452
  name: user?.name ?? adminMember?.name ?? "",
13394
13453
  isSuperAdmin: isSuperAdmin2,
13395
13454
  orgIds,
13396
- propertyManagementOrgIds
13455
+ propertyManagementOrgIds,
13456
+ memberships: members.map((m) => ({
13457
+ org: m.org?.toString?.() ?? "",
13458
+ siteId: m.siteId?.toString?.() ?? "",
13459
+ orgLevelRole: orgLevelRoleIds.has(m.role?.toString?.() ?? "")
13460
+ }))
13397
13461
  };
13398
13462
  }
13399
13463
  async function hasOrgInvitation(userId, orgId) {
@@ -19171,6 +19235,11 @@ var schemaVisitorTransaction = Joi21.object({
19171
19235
  ).optional().allow(null),
19172
19236
  unitName: Joi21.string().optional().allow(null, ""),
19173
19237
  expiredAt: Joi21.date().iso().optional().allow(null, ""),
19238
+ // The calendar day this invitation is valid for, in the site's timezone.
19239
+ // Stored as a bare YYYY-MM-DD so no offset conversion can shift the day.
19240
+ arrivalDate: Joi21.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow(null, "").messages({
19241
+ "string.pattern.base": "arrivalDate must be in YYYY-MM-DD format (e.g. 2026-09-02)"
19242
+ }),
19174
19243
  arrivalTime: Joi21.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
19175
19244
  "string.pattern.base": "arrivalTime must be in HH:mm format (e.g. 09:30, 18:45)"
19176
19245
  }),
@@ -19232,6 +19301,11 @@ var schemaSelfServiceVisitor = Joi21.object({
19232
19301
  // value through that schema via MVisitorTransaction(), and Joi.date()
19233
19302
  // would have already coerced it to a Date object by then, failing there.
19234
19303
  expectedCheckIn: Joi21.string().isoDate().required(),
19304
+ // The calendar day this invitation is valid for, in the site's timezone.
19305
+ // Stored as a bare YYYY-MM-DD so no offset conversion can shift the day.
19306
+ arrivalDate: Joi21.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow(null, "").messages({
19307
+ "string.pattern.base": "arrivalDate must be in YYYY-MM-DD format (e.g. 2026-09-02)"
19308
+ }),
19235
19309
  arrivalTime: Joi21.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({ "string.pattern.base": "arrivalTime must be in HH:mm format" }),
19236
19310
  duration: Joi21.number().integer().min(0).optional().allow(null, ""),
19237
19311
  isOvernightParking: Joi21.boolean().optional().default(false),
@@ -19265,6 +19339,13 @@ var schemaSelfServiceVisitor = Joi21.object({
19265
19339
  });
19266
19340
  var schemaUpdateVisTrans = Joi21.object({
19267
19341
  _id: Joi21.string().hex().length(24).required(),
19342
+ // Accepted here so a caller that moves `expectedCheckIn` can move the day
19343
+ // with it. Without this the two drift apart silently and the QR stays valid
19344
+ // on the ORIGINAL day, which is the failure the day-window work exists to
19345
+ // prevent.
19346
+ arrivalDate: Joi21.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow(null, "").messages({
19347
+ "string.pattern.base": "arrivalDate must be in YYYY-MM-DD format (e.g. 2026-09-02)"
19348
+ }),
19268
19349
  name: Joi21.string().optional().allow(null, ""),
19269
19350
  type: Joi21.string().valid(...PERSON_TYPES).optional().allow(null, ""),
19270
19351
  org: Joi21.string().hex().length(24).optional().allow(null, ""),
@@ -19495,6 +19576,7 @@ function MVisitorTransaction(value) {
19495
19576
  remarks: "",
19496
19577
  updatedBy: value.inviterId ?? ""
19497
19578
  } : null,
19579
+ arrivalDate: value.arrivalDate,
19498
19580
  arrivalTime: value.arrivalTime,
19499
19581
  duration: value.duration,
19500
19582
  members: value.members
@@ -19503,7 +19585,7 @@ function MVisitorTransaction(value) {
19503
19585
 
19504
19586
  // src/repositories/visitor-transaction.repo.ts
19505
19587
  import { ObjectId as ObjectId40 } from "mongodb";
19506
- import moment from "moment-timezone";
19588
+ import moment2 from "moment-timezone";
19507
19589
 
19508
19590
  // src/utils/compile-handlebars.ts
19509
19591
  var import_handlebars = __toESM(require_lib());
@@ -20334,7 +20416,7 @@ function useVisitorTransactionRepo() {
20334
20416
  const baseUrl = APP_MAIN;
20335
20417
  const qrLink = `${baseUrl}/resident/invite/register/${updatedDocument?._id}`;
20336
20418
  const logo = `${baseUrl}/images/resident/dark/seven-365.svg`;
20337
- const arrivalDate = updatedDocument?.expectedCheckIn ? moment(updatedDocument.expectedCheckIn).tz("Asia/Singapore").format("DD/MM/YYYY") : "No Arrival Date";
20419
+ const arrivalDate = updatedDocument?.expectedCheckIn ? moment2(updatedDocument.expectedCheckIn).tz("Asia/Singapore").format("DD/MM/YYYY") : "No Arrival Date";
20338
20420
  const isLead = !updatedDocument?.leadId;
20339
20421
  const memberRows = isLead && Array.isArray(updatedDocument?.members) ? updatedDocument.members.map((member, index) => ({
20340
20422
  position: index + 1,
@@ -24161,6 +24243,22 @@ function selectHealthTargets(cameraIds, cap, isValidId) {
24161
24243
  truncated: unique.length > limit
24162
24244
  };
24163
24245
  }
24246
+ function orgSiteScope(params) {
24247
+ const org = idOf(params.org);
24248
+ if (!org)
24249
+ return null;
24250
+ const inOrg = params.memberships.filter(
24251
+ (membership) => idOf(membership.org) === org
24252
+ );
24253
+ if (inOrg.some(
24254
+ (membership) => !idOf(membership.siteId) || membership.orgLevelRole === true
24255
+ )) {
24256
+ return null;
24257
+ }
24258
+ return Array.from(
24259
+ new Set(inOrg.map((membership) => idOf(membership.siteId)).filter(Boolean))
24260
+ );
24261
+ }
24164
24262
 
24165
24263
  // src/utils/camera-capability.util.ts
24166
24264
  var CAMERA_CAPABILITIES = [
@@ -39635,7 +39733,7 @@ var deleteVehicleRequestSchema = Joi55.object({
39635
39733
  });
39636
39734
 
39637
39735
  // src/utils/vehicle-import.util.ts
39638
- import moment2 from "moment-timezone";
39736
+ import moment3 from "moment-timezone";
39639
39737
  var SITE_TIME_ZONE = "Asia/Singapore";
39640
39738
  var DEFAULT_YEARS = 10;
39641
39739
  var CELL_FORMATS = [
@@ -39647,13 +39745,13 @@ var CELL_FORMATS = [
39647
39745
  ];
39648
39746
  function parseExpiryDate(value) {
39649
39747
  if (!value) {
39650
- return moment2.tz(SITE_TIME_ZONE).add(DEFAULT_YEARS, "years").toISOString();
39748
+ return moment3.tz(SITE_TIME_ZONE).add(DEFAULT_YEARS, "years").toISOString();
39651
39749
  }
39652
- const wallClock = value instanceof Date ? moment2.utc(value).format("YYYY-MM-DDTHH:mm:ss") : String(value).trim();
39750
+ const wallClock = value instanceof Date ? moment3.utc(value).format("YYYY-MM-DDTHH:mm:ss") : String(value).trim();
39653
39751
  if (!wallClock) {
39654
- return moment2.tz(SITE_TIME_ZONE).add(DEFAULT_YEARS, "years").toISOString();
39752
+ return moment3.tz(SITE_TIME_ZONE).add(DEFAULT_YEARS, "years").toISOString();
39655
39753
  }
39656
- const parsed = moment2.tz(wallClock, CELL_FORMATS, SITE_TIME_ZONE);
39754
+ const parsed = moment3.tz(wallClock, CELL_FORMATS, SITE_TIME_ZONE);
39657
39755
  return parsed.isValid() ? parsed.toISOString() : void 0;
39658
39756
  }
39659
39757
 
@@ -41403,13 +41501,16 @@ function useCustomerSiteController() {
41403
41501
  });
41404
41502
  try {
41405
41503
  await requireOrgAccess(req, org);
41504
+ const actor = await resolveInviteActor(callerId(req));
41505
+ const siteScope = actor.isSuperAdmin ? null : orgSiteScope({ memberships: actor.memberships, org });
41406
41506
  const data = await _getAll({
41407
41507
  search,
41408
41508
  page,
41409
41509
  limit,
41410
41510
  sort: sortObj,
41411
41511
  org,
41412
- status
41512
+ status,
41513
+ siteScope
41413
41514
  });
41414
41515
  res.json(data);
41415
41516
  return;
@@ -41863,7 +41964,7 @@ function MAttendance(value) {
41863
41964
 
41864
41965
  // src/repositories/attendance.repository.ts
41865
41966
  import { ObjectId as ObjectId77 } from "mongodb";
41866
- import moment3 from "moment-timezone";
41967
+ import moment4 from "moment-timezone";
41867
41968
  import {
41868
41969
  useAtlas as useAtlas60,
41869
41970
  InternalServerError as InternalServerError38,
@@ -41937,11 +42038,11 @@ function useAttendanceRepository() {
41937
42038
  cacheOptions.search = search;
41938
42039
  }
41939
42040
  const singaporeTz = "Asia/Singapore";
41940
- const normalizedStartDate = typeof startDate === "string" ? startDate : moment3(startDate).tz(singaporeTz).format("YYYY-MM-DD");
41941
- const normalizedEndDate = typeof endDate === "string" ? endDate : moment3(endDate).tz(singaporeTz).format("YYYY-MM-DD");
42041
+ const normalizedStartDate = typeof startDate === "string" ? startDate : moment4(startDate).tz(singaporeTz).format("YYYY-MM-DD");
42042
+ const normalizedEndDate = typeof endDate === "string" ? endDate : moment4(endDate).tz(singaporeTz).format("YYYY-MM-DD");
41942
42043
  if (startDate && endDate) {
41943
- const startOfDay = moment3.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate();
41944
- const endOfDay = moment3.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate();
42044
+ const startOfDay = moment4.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate();
42045
+ const endOfDay = moment4.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate();
41945
42046
  query2.$expr = {
41946
42047
  $and: [
41947
42048
  { $gte: [{ $toDate: "$checkIn.timestamp" }, startOfDay] },
@@ -41954,7 +42055,7 @@ function useAttendanceRepository() {
41954
42055
  query2.$expr = {
41955
42056
  $gte: [
41956
42057
  { $toDate: "$checkIn.timestamp" },
41957
- moment3.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate()
42058
+ moment4.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate()
41958
42059
  ]
41959
42060
  };
41960
42061
  cacheOptions.startDate = normalizedStartDate;
@@ -41962,7 +42063,7 @@ function useAttendanceRepository() {
41962
42063
  query2.$expr = {
41963
42064
  $lte: [
41964
42065
  { $toDate: "$checkIn.timestamp" },
41965
- moment3.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate()
42066
+ moment4.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate()
41966
42067
  ]
41967
42068
  };
41968
42069
  cacheOptions.endDate = normalizedEndDate;
@@ -42075,11 +42176,11 @@ function useAttendanceRepository() {
42075
42176
  cacheOptions.search = search;
42076
42177
  }
42077
42178
  const singaporeTz = "Asia/Singapore";
42078
- const normalizedStartDate = typeof startDate === "string" ? startDate : moment3(startDate).tz(singaporeTz).format("YYYY-MM-DD");
42079
- const normalizedEndDate = typeof endDate === "string" ? endDate : moment3(endDate).tz(singaporeTz).format("YYYY-MM-DD");
42179
+ const normalizedStartDate = typeof startDate === "string" ? startDate : moment4(startDate).tz(singaporeTz).format("YYYY-MM-DD");
42180
+ const normalizedEndDate = typeof endDate === "string" ? endDate : moment4(endDate).tz(singaporeTz).format("YYYY-MM-DD");
42080
42181
  if (startDate && endDate) {
42081
- const startOfDay = moment3.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate();
42082
- const endOfDay = moment3.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate();
42182
+ const startOfDay = moment4.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate();
42183
+ const endOfDay = moment4.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate();
42083
42184
  query2.$expr = {
42084
42185
  $and: [
42085
42186
  { $gte: [{ $toDate: "$checkIn.timestamp" }, startOfDay] },
@@ -42092,7 +42193,7 @@ function useAttendanceRepository() {
42092
42193
  query2.$expr = {
42093
42194
  $gte: [
42094
42195
  { $toDate: "$checkIn.timestamp" },
42095
- moment3.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate()
42196
+ moment4.tz(normalizedStartDate, "YYYY-MM-DD", singaporeTz).startOf("day").toDate()
42096
42197
  ]
42097
42198
  };
42098
42199
  cacheOptions.startDate = normalizedStartDate;
@@ -42100,7 +42201,7 @@ function useAttendanceRepository() {
42100
42201
  query2.$expr = {
42101
42202
  $lte: [
42102
42203
  { $toDate: "$checkIn.timestamp" },
42103
- moment3.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate()
42204
+ moment4.tz(normalizedEndDate, "YYYY-MM-DD", singaporeTz).endOf("day").toDate()
42104
42205
  ]
42105
42206
  };
42106
42207
  cacheOptions.endDate = normalizedEndDate;
@@ -51857,6 +51958,16 @@ function useVisitorTransactionService() {
51857
51958
  );
51858
51959
  const isAutoApprovedInvitation = settings?.isAutoApprovedInvitation === true;
51859
51960
  value.checkIn = null;
51961
+ if (!value.arrivalDate && value.expectedCheckIn) {
51962
+ let timezone;
51963
+ try {
51964
+ const site = await _getSiteById(inviter?.site);
51965
+ timezone = resolveSiteTimezone(site);
51966
+ } catch {
51967
+ timezone = resolveSiteTimezone(null);
51968
+ }
51969
+ value.arrivalDate = siteDayBounds(value.expectedCheckIn, timezone)?.date ?? null;
51970
+ }
51860
51971
  const payload = {
51861
51972
  ...value,
51862
51973
  block: inviter?.block?.toString(),
@@ -51917,18 +52028,31 @@ function useVisitorTransactionService() {
51917
52028
  }
51918
52029
  try {
51919
52030
  session.startTransaction();
52031
+ const refId = (value) => {
52032
+ if (!value)
52033
+ return void 0;
52034
+ const id = typeof value === "object" && "_id" in value ? value._id : value;
52035
+ return id ? String(id) : void 0;
52036
+ };
51920
52037
  const memberPayload = {
51921
- block: lead.block ? String(lead.block) : void 0,
51922
- level: lead.level ? String(lead.level) : void 0,
51923
- unit: lead.unit ? String(lead.unit) : void 0,
51924
- unitName: lead.unitName,
51925
- org: lead.org ? String(lead.org) : void 0,
51926
- site: lead.site ? String(lead.site) : void 0,
52038
+ block: refId(lead.block),
52039
+ level: refId(lead.level),
52040
+ unit: refId(lead.unit),
52041
+ // The same $lookup leaves the unit's name on the joined object, which
52042
+ // is the better source when the stored scalar is absent.
52043
+ unitName: lead.unitName ?? lead.unit?.name,
52044
+ org: refId(lead.org),
52045
+ site: refId(lead.site),
51927
52046
  type: lead.type,
51928
52047
  contractorType: lead.contractorType,
51929
52048
  company: lead.company,
51930
52049
  purpose: lead.purpose,
51931
52050
  expectedCheckIn: lead.expectedCheckIn ? new Date(lead.expectedCheckIn).toISOString() : void 0,
52051
+ // Carried so each member's QR is gated on the same calendar day as the
52052
+ // lead's. Without it a member falls back to deriving the day from
52053
+ // `expectedCheckIn`, which is the same answer today but drifts the
52054
+ // moment the lead's day is edited.
52055
+ arrivalDate: lead.arrivalDate,
51932
52056
  arrivalTime: lead.arrivalTime,
51933
52057
  duration: lead.duration,
51934
52058
  isOvernightParking: lead.isOvernightParking,
@@ -52020,7 +52144,7 @@ function useVisitorTransactionService() {
52020
52144
 
52021
52145
  // src/controllers/visitor-transaction.controller.ts
52022
52146
  import Joi67 from "joi";
52023
- import moment4 from "moment-timezone";
52147
+ import moment5 from "moment-timezone";
52024
52148
  import { ObjectId as ObjectId88 } from "mongodb";
52025
52149
  import { BadRequestError as BadRequestError123, NotFoundError as NotFoundError36, InternalServerError as InternalServerError44, logger as logger94 } from "@7365admin1/node-server-utils";
52026
52150
 
@@ -52028,6 +52152,15 @@ import { BadRequestError as BadRequestError123, NotFoundError as NotFoundError36
52028
52152
  import Joi66 from "joi";
52029
52153
  var schemaInviteVisitor = Joi66.object({
52030
52154
  expectedCheckIn: Joi66.string().isoDate().required(),
52155
+ // The calendar day the invitation is valid for, as the resident picked it.
52156
+ // A bare YYYY-MM-DD carries no offset, so no conversion between the phone's
52157
+ // zone and the site's can move it onto a neighbouring day - which is exactly
52158
+ // what `expectedCheckIn` alone cannot guarantee. Optional so that already
52159
+ // installed builds, which send only `expectedCheckIn`, keep working; the
52160
+ // server falls back to deriving the day from it in the site's zone.
52161
+ arrivalDate: Joi66.string().pattern(/^\d{4}-\d{2}-\d{2}$/).optional().allow(null, "").messages({
52162
+ "string.pattern.base": "arrivalDate must be in YYYY-MM-DD format (e.g. 2026-09-02)"
52163
+ }),
52031
52164
  arrivalTime: Joi66.string().pattern(/^([01]\d|2[0-3]):([0-5]\d)$/).optional().allow(null, "").messages({
52032
52165
  "string.pattern.base": "arrivalTime must be in HH:mm format (e.g. 09:30, 18:45)"
52033
52166
  }),
@@ -56100,7 +56233,7 @@ async function sendSelfServicePassEmail(record, occasion, remarks) {
56100
56233
  if (!to)
56101
56234
  return;
56102
56235
  const previewLink = `${APP_PROPERTY_MANAGEMENT}/public-view/visitor-onboarding/pass/${String(record._id ?? "")}`;
56103
- const arrivalDate = record.expectedCheckIn ? moment4(record.expectedCheckIn).format("DD/MM/YYYY") : "N/A";
56236
+ const arrivalDate = record.expectedCheckIn ? moment5(record.expectedCheckIn).format("DD/MM/YYYY") : "N/A";
56104
56237
  const html = occasion === "rejected" ? compile_handlebars_default({
56105
56238
  handlebar: "self-service-visitor-rejected",
56106
56239
  context: {
@@ -56648,6 +56781,7 @@ function useVisitorTransactionController() {
56648
56781
  }
56649
56782
  const {
56650
56783
  expectedCheckIn,
56784
+ arrivalDate,
56651
56785
  arrivalTime,
56652
56786
  duration,
56653
56787
  name,
@@ -56665,6 +56799,10 @@ function useVisitorTransactionController() {
56665
56799
  } = value;
56666
56800
  const rest = {
56667
56801
  expectedCheckIn,
56802
+ // Fall back to the day `expectedCheckIn` lands on in the SITE's zone, so
56803
+ // rows written by older builds still carry an explicit day. Resolved in
56804
+ // the invite service, which is where the site id is known.
56805
+ arrivalDate,
56668
56806
  arrivalTime,
56669
56807
  duration,
56670
56808
  name,
@@ -77390,10 +77528,10 @@ import {
77390
77528
  useAtlas as useAtlas116
77391
77529
  } from "@7365admin1/node-server-utils";
77392
77530
  import { ObjectId as ObjectId147 } from "mongodb";
77393
- import moment6 from "moment";
77531
+ import moment7 from "moment";
77394
77532
 
77395
77533
  // src/utils/dashboard-metrics.util.ts
77396
- import moment5 from "moment-timezone";
77534
+ import moment6 from "moment-timezone";
77397
77535
  var DASHBOARD_TIMEZONE = "Asia/Singapore";
77398
77536
  var PERIOD_UNITS = {
77399
77537
  thisWeek: { boundary: "isoWeek", step: "week" },
@@ -77404,7 +77542,7 @@ function unitsOf(period) {
77404
77542
  return PERIOD_UNITS[period] ?? DAY_UNIT;
77405
77543
  }
77406
77544
  function at(now) {
77407
- return now === void 0 || now === null ? moment5.tz(DASHBOARD_TIMEZONE) : moment5.tz(now, DASHBOARD_TIMEZONE);
77545
+ return now === void 0 || now === null ? moment6.tz(DASHBOARD_TIMEZONE) : moment6.tz(now, DASHBOARD_TIMEZONE);
77408
77546
  }
77409
77547
  function getPeriodRange(period, now) {
77410
77548
  const { boundary } = unitsOf(period);
@@ -77792,8 +77930,8 @@ function useNewDashboardRepo() {
77792
77930
  activePatrolLogs.map(async (log) => {
77793
77931
  const person = await getPatrolLogPerson(log);
77794
77932
  const status = getPatrolLogStatus(log);
77795
- const logTime = moment6(log.createdAt).tz("Asia/Singapore").format("HH:mm");
77796
- const logDate = moment6(log.createdAt).tz("Asia/Singapore").format("DD/MM/YYYY");
77933
+ const logTime = moment7(log.createdAt).tz("Asia/Singapore").format("HH:mm");
77934
+ const logDate = moment7(log.createdAt).tz("Asia/Singapore").format("DD/MM/YYYY");
77797
77935
  return {
77798
77936
  id: log._id.toString(),
77799
77937
  title: log.name,
@@ -77852,8 +77990,8 @@ function useNewDashboardRepo() {
77852
77990
  }
77853
77991
  async function getPropertyManagementDashboard(siteId, period = "today" /* TODAY */, type, facility) {
77854
77992
  const siteIdObj = toObjectId18(siteId);
77855
- const startOfToday = moment6.tz("Asia/Singapore").startOf("day").toDate();
77856
- const endOfToday = moment6.tz("Asia/Singapore").endOf("day").toDate();
77993
+ const startOfToday = moment7.tz("Asia/Singapore").startOf("day").toDate();
77994
+ const endOfToday = moment7.tz("Asia/Singapore").endOf("day").toDate();
77857
77995
  const facilityPeriodRange = getPeriodRange(period);
77858
77996
  const facilityPriorRange = getPreviousPeriodRange(period);
77859
77997
  const facilityCurrentStart = facilityPeriodRange.$gte;
@@ -78479,28 +78617,28 @@ function useNewDashboardRepo() {
78479
78617
  let labels = [];
78480
78618
  let getIntervalIndex;
78481
78619
  if (period === "today" /* TODAY */) {
78482
- rangeStart = moment6.tz("Asia/Singapore").startOf("day").toDate();
78483
- rangeEnd = moment6.tz("Asia/Singapore").endOf("day").toDate();
78620
+ rangeStart = moment7.tz("Asia/Singapore").startOf("day").toDate();
78621
+ rangeEnd = moment7.tz("Asia/Singapore").endOf("day").toDate();
78484
78622
  labels = ["12 AM", "4 AM", "8 AM", "12 PM", "4 PM", "8 PM"];
78485
78623
  getIntervalIndex = (date) => {
78486
- const hour = moment6(date).tz("Asia/Singapore").hour();
78624
+ const hour = moment7(date).tz("Asia/Singapore").hour();
78487
78625
  return Math.floor(hour / 4);
78488
78626
  };
78489
78627
  } else if (period === "thisWeek" /* THIS_WEEK */) {
78490
- rangeStart = moment6.tz("Asia/Singapore").startOf("isoWeek").toDate();
78491
- rangeEnd = moment6.tz("Asia/Singapore").endOf("isoWeek").toDate();
78628
+ rangeStart = moment7.tz("Asia/Singapore").startOf("isoWeek").toDate();
78629
+ rangeEnd = moment7.tz("Asia/Singapore").endOf("isoWeek").toDate();
78492
78630
  labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
78493
78631
  getIntervalIndex = (date) => {
78494
- const day = moment6(date).tz("Asia/Singapore").isoWeekday();
78632
+ const day = moment7(date).tz("Asia/Singapore").isoWeekday();
78495
78633
  return day - 1;
78496
78634
  };
78497
78635
  } else if (period === "thisMonth" /* THIS_MONTH */) {
78498
- rangeStart = moment6.tz("Asia/Singapore").startOf("month").toDate();
78499
- rangeEnd = moment6.tz("Asia/Singapore").endOf("month").toDate();
78500
- const daysInMonth = moment6.tz("Asia/Singapore").daysInMonth();
78636
+ rangeStart = moment7.tz("Asia/Singapore").startOf("month").toDate();
78637
+ rangeEnd = moment7.tz("Asia/Singapore").endOf("month").toDate();
78638
+ const daysInMonth = moment7.tz("Asia/Singapore").daysInMonth();
78501
78639
  labels = Array.from({ length: daysInMonth }, (_, i) => String(i + 1));
78502
78640
  getIntervalIndex = (date) => {
78503
- return moment6(date).tz("Asia/Singapore").date() - 1;
78641
+ return moment7(date).tz("Asia/Singapore").date() - 1;
78504
78642
  };
78505
78643
  } else {
78506
78644
  throw new BadRequestError208("Invalid period.");
@@ -79144,7 +79282,7 @@ import {
79144
79282
 
79145
79283
  // src/utils/hrmlabs-attendance.util.ts
79146
79284
  import axios3 from "axios";
79147
- import moment7 from "moment-timezone";
79285
+ import moment8 from "moment-timezone";
79148
79286
  var default_early_checkIn = 4;
79149
79287
  async function hrmLabsAuthentication({
79150
79288
  authUrl,
@@ -79216,13 +79354,13 @@ function filterByShiftTime(attendance, shiftData, timezone, format2) {
79216
79354
  return attendance.filter((item) => {
79217
79355
  if (!item.checkIn)
79218
79356
  return false;
79219
- const checkInLocal = moment7(item.checkIn, format2);
79357
+ const checkInLocal = moment8(item.checkIn, format2);
79220
79358
  if (!checkInLocal.isValid())
79221
79359
  return false;
79222
79360
  const [startHour, startMinute] = shiftData.checkIn.split(":").map(Number);
79223
79361
  const [endHour, endMinute] = shiftData.checkOut.split(":").map(Number);
79224
- const shiftStart = moment7(checkInLocal).set({ hour: startHour, minute: startMinute, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79225
- const shiftEnd = moment7(checkInLocal).set({
79362
+ const shiftStart = moment8(checkInLocal).set({ hour: startHour, minute: startMinute, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79363
+ const shiftEnd = moment8(checkInLocal).set({
79226
79364
  hour: endHour,
79227
79365
  minute: endMinute,
79228
79366
  second: 0,
@@ -79314,18 +79452,18 @@ function totalCountPerShift(attendance, shiftData, timezone, format2) {
79314
79452
  data = uniqueAttendanceData.filter((item) => {
79315
79453
  if (!item.checkIn)
79316
79454
  return false;
79317
- const checkInLocal = moment7(item.checkIn, format2);
79455
+ const checkInLocal = moment8(item.checkIn, format2);
79318
79456
  if (!checkInLocal.isValid())
79319
79457
  return false;
79320
79458
  const [startHour, startMinute] = shift.checkIn.split(":").map(Number);
79321
79459
  const [endHour, endMinute] = shift.checkOut.split(":").map(Number);
79322
- const shiftStart = moment7(checkInLocal).set({
79460
+ const shiftStart = moment8(checkInLocal).set({
79323
79461
  hour: startHour,
79324
79462
  minute: startMinute,
79325
79463
  second: 0,
79326
79464
  millisecond: 0
79327
79465
  }).subtract(default_early_checkIn, "hour");
79328
- const shiftEnd = moment7(checkInLocal).set({
79466
+ const shiftEnd = moment8(checkInLocal).set({
79329
79467
  hour: endHour,
79330
79468
  minute: endMinute,
79331
79469
  second: 0,
@@ -79355,11 +79493,11 @@ function filterByStatus(attendance, shiftData, timezone, format2, status) {
79355
79493
  return attendance.filter((item) => {
79356
79494
  if (!item.checkIn)
79357
79495
  return false;
79358
- const checkInLocal = moment7(item.checkIn, format2);
79496
+ const checkInLocal = moment8(item.checkIn, format2);
79359
79497
  if (!checkInLocal.isValid())
79360
79498
  return false;
79361
79499
  const [lateHour, lateMinute] = shiftData.lateCheckInAlert.split(":").map(Number);
79362
- const lateLoginTime = moment7(checkInLocal).set({
79500
+ const lateLoginTime = moment8(checkInLocal).set({
79363
79501
  hour: lateHour,
79364
79502
  minute: lateMinute,
79365
79503
  second: 0,
@@ -79431,14 +79569,14 @@ async function totalCountPerStatus(attendance, shiftName, shiftData, timezone, f
79431
79569
  } = item;
79432
79570
  if (!checkInStr || seenGlobal.has(identificationNumber))
79433
79571
  continue;
79434
- const checkIn = moment7(checkInStr, format2);
79435
- const checkOut = checkOutStr ? moment7(checkOutStr, format2) : null;
79436
- const checkOutChecker = checkOut ? moment7(checkOutStr, format2) : checkIn;
79572
+ const checkIn = moment8(checkInStr, format2);
79573
+ const checkOut = checkOutStr ? moment8(checkOutStr, format2) : null;
79574
+ const checkOutChecker = checkOut ? moment8(checkOutStr, format2) : checkIn;
79437
79575
  if (!checkIn.isValid())
79438
79576
  continue;
79439
- const shiftStart = moment7(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
79440
- const shiftEnd = moment7(checkOutChecker).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79441
- const lateCheckIn = moment7(checkIn).set({
79577
+ const shiftStart = moment8(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
79578
+ const shiftEnd = moment8(checkOutChecker).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79579
+ const lateCheckIn = moment8(checkIn).set({
79442
79580
  ...lateTime,
79443
79581
  second: 59,
79444
79582
  millisecond: 59
@@ -79476,8 +79614,8 @@ async function chartCountData(attendance, shiftData, timezone, format2, totalShi
79476
79614
  const [hour, minute] = timeStr.split(":").map(Number);
79477
79615
  return { hour, minute };
79478
79616
  };
79479
- const startDate = moment7(startDateStr, "DD-MM-YYYY");
79480
- const endDate = moment7(endDateStr, "DD-MM-YYYY");
79617
+ const startDate = moment8(startDateStr, "DD-MM-YYYY");
79618
+ const endDate = moment8(endDateStr, "DD-MM-YYYY");
79481
79619
  const daysInRange = [];
79482
79620
  for (let day = startDate.clone(); day.isSameOrBefore(endDate); day.add(1, "day")) {
79483
79621
  daysInRange.push(day.format("DD-MM-YYYY"));
@@ -79548,7 +79686,7 @@ async function chartCountData(attendance, shiftData, timezone, format2, totalShi
79548
79686
  } = item;
79549
79687
  if (!checkInStr)
79550
79688
  continue;
79551
- const checkIn = moment7(checkInStr, format2);
79689
+ const checkIn = moment8(checkInStr, format2);
79552
79690
  if (!checkIn.isValid())
79553
79691
  continue;
79554
79692
  const dayKey = `${identificationNumber}-${checkIn.format(
@@ -79557,10 +79695,10 @@ async function chartCountData(attendance, shiftData, timezone, format2, totalShi
79557
79695
  if (seenPerDay.has(dayKey))
79558
79696
  continue;
79559
79697
  seenPerDay.add(dayKey);
79560
- const checkOut = checkOutStr ? moment7(checkOutStr, format2) : checkIn;
79561
- const shiftStart = moment7(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
79562
- const shiftEnd = moment7(checkOut).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79563
- const lateCheckIn = moment7(checkIn).set({
79698
+ const checkOut = checkOutStr ? moment8(checkOutStr, format2) : checkIn;
79699
+ const shiftStart = moment8(checkIn).set({ ...shiftStartTime, second: 59, millisecond: 59 }).subtract(default_early_checkIn, "hour");
79700
+ const shiftEnd = moment8(checkOut).set({ ...shiftEndTime, second: 0, millisecond: 0 }).subtract(default_early_checkIn, "hour");
79701
+ const lateCheckIn = moment8(checkIn).set({
79564
79702
  ...lateTime,
79565
79703
  second: 59,
79566
79704
  millisecond: 59
@@ -79873,7 +80011,7 @@ var MManpowerRemarks = class {
79873
80011
 
79874
80012
  // src/repositories/manpower-remarks.repo.ts
79875
80013
  import { ObjectId as ObjectId151 } from "mongodb";
79876
- import moment8 from "moment-timezone";
80014
+ import moment9 from "moment-timezone";
79877
80015
  function useManpowerRemarksRepo() {
79878
80016
  const db2 = useAtlas118.getDb();
79879
80017
  if (!db2) {
@@ -79927,7 +80065,7 @@ function useManpowerRemarksRepo() {
79927
80065
  page = page ? page - 1 : 0;
79928
80066
  limit = limit || 10;
79929
80067
  const searchQuery = {};
79930
- const nowSGT = moment8().tz("Asia/Singapore");
80068
+ const nowSGT = moment9().tz("Asia/Singapore");
79931
80069
  searchQuery.serviceProviderId = new ObjectId151(serviceProviderId);
79932
80070
  if (search != "") {
79933
80071
  searchQuery.siteName = { $regex: search, $options: "i" };
@@ -80039,7 +80177,7 @@ function useManpowerRemarksRepo() {
80039
80177
  }
80040
80178
 
80041
80179
  // src/services/manpower-monitoring.service.ts
80042
- import moment9 from "moment-timezone";
80180
+ import moment10 from "moment-timezone";
80043
80181
  function useManpowerMonitoringSrvc() {
80044
80182
  const {
80045
80183
  createManpowerMonitoringSettings: _createManpowerMonitoringSettings
@@ -80057,10 +80195,10 @@ function useManpowerMonitoringSrvc() {
80057
80195
  const morningAlertFrequencyMins = payload?.shifts?.[payload.shiftType][0]?.alertFrequencyMins;
80058
80196
  const afternoonAlertFrequencyMins = payload.shiftType == "3-shifts" ? payload?.shifts?.[payload.shiftType][1]?.alertFrequencyMins : null;
80059
80197
  const nightAlertFrequencyMins = payload.shiftType == "3-shifts" ? payload?.shifts?.[payload.shiftType][2]?.alertFrequencyMins : payload?.shifts?.[payload.shiftType][1]?.alertFrequencyMins;
80060
- const morningAlertTime = moment9.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
80061
- const afternoonAlertTime = afternoonCheckInTime ? moment9.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
80062
- const nightAlertTime = moment9.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
80063
- const nowSGT = moment9().tz("Asia/Singapore");
80198
+ const morningAlertTime = moment10.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
80199
+ const afternoonAlertTime = afternoonCheckInTime ? moment10.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
80200
+ const nightAlertTime = moment10.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
80201
+ const nowSGT = moment10().tz("Asia/Singapore");
80064
80202
  try {
80065
80203
  const remarksPayload = {
80066
80204
  siteId: payload.siteId,
@@ -82472,7 +82610,7 @@ import {
82472
82610
  logger as logger192
82473
82611
  } from "@7365admin1/node-server-utils";
82474
82612
  import { ObjectId as ObjectId156 } from "mongodb";
82475
- import moment10 from "moment-timezone";
82613
+ import moment11 from "moment-timezone";
82476
82614
  var createManpowerRemarksDaily = async () => {
82477
82615
  const db2 = useAtlas126.getDb();
82478
82616
  if (!db2) {
@@ -82483,9 +82621,9 @@ var createManpowerRemarksDaily = async () => {
82483
82621
  const remarks = db2.collection("manpower-remarks");
82484
82622
  const serviceProviders = db2.collection("site.service-providers");
82485
82623
  const items = [];
82486
- const yesterday = moment10().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
82624
+ const yesterday = moment11().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
82487
82625
  try {
82488
- const nowSGT = moment10().tz("Asia/Singapore");
82626
+ const nowSGT = moment11().tz("Asia/Singapore");
82489
82627
  const servideProvider = await serviceProviders.findOne({
82490
82628
  name: { $regex: process.env.HRMLABS_DOMAIN, $options: "i" }
82491
82629
  });
@@ -82523,9 +82661,9 @@ var createManpowerRemarksDaily = async () => {
82523
82661
  const morningAlertFrequencyMins = setting?.shifts?.[shiftType][0]?.alertFrequencyMins;
82524
82662
  const afternoonAlertFrequencyMins = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][1]?.alertFrequencyMins : null;
82525
82663
  const nightAlertFrequencyMins = shiftType == "3-shifts" ? setting?.shifts?.[shiftType][2]?.alertFrequencyMins : setting?.shifts?.[shiftType][1]?.alertFrequencyMins;
82526
- const morningAlertTime = moment10.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
82527
- const afternoonAlertTime = afternoonCheckInTime ? moment10.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
82528
- const nightAlertTime = moment10.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
82664
+ const morningAlertTime = moment11.tz(morningCheckInTime, "HH:mm", "Asia/Singapore").add(morningAlertFrequencyMins, "minutes").format("HH:mm");
82665
+ const afternoonAlertTime = afternoonCheckInTime ? moment11.tz(afternoonCheckInTime, "HH:mm", "Asia/Singapore").add(afternoonAlertFrequencyMins, "minutes").format("HH:mm") : "";
82666
+ const nightAlertTime = moment11.tz(nightCheckInTime, "HH:mm", "Asia/Singapore").add(nightAlertFrequencyMins, "minutes").format("HH:mm");
82529
82667
  const remark2 = {
82530
82668
  siteId: site.siteId,
82531
82669
  siteName: site.siteName,
@@ -82582,14 +82720,14 @@ var createManpowerRemarksDaily = async () => {
82582
82720
  };
82583
82721
  var updateRemarksisAcknowledged = async () => {
82584
82722
  const { getAttendanceDataCount: _getAttendanceDataCount } = useHrmLabsAttendanceSrvc();
82585
- const nowSGT = moment10().tz("Asia/Singapore").format("DD-MM-YYYY");
82723
+ const nowSGT = moment11().tz("Asia/Singapore").format("DD-MM-YYYY");
82586
82724
  const db2 = useAtlas126.getDb();
82587
82725
  if (!db2) {
82588
82726
  throw new Error("Unable to connect to server.");
82589
82727
  }
82590
82728
  const namespace_collection = "manpower-remarks";
82591
82729
  const remarks = db2.collection(namespace_collection);
82592
- const timeNow = moment10().tz("Asia/Singapore").format("HH:mm");
82730
+ const timeNow = moment11().tz("Asia/Singapore").format("HH:mm");
82593
82731
  const settings = db2.collection("manpower-settings");
82594
82732
  try {
82595
82733
  const matchingDocs = await remarks.find({
@@ -82717,9 +82855,9 @@ var updateRemarksStatusEod = async () => {
82717
82855
  }
82718
82856
  const remarks = db2.collection("manpower-remarks");
82719
82857
  const settings = db2.collection("manpower-settings");
82720
- const nowSGT = moment10().tz("Asia/Singapore").format("DD-MM-YYYY");
82721
- const yesterdaySGT = moment10().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
82722
- const timeNow = moment10().tz("Asia/Singapore").format("HH:mm");
82858
+ const nowSGT = moment11().tz("Asia/Singapore").format("DD-MM-YYYY");
82859
+ const yesterdaySGT = moment11().tz("Asia/Singapore").subtract(1, "days").format("DD-MM-YYYY");
82860
+ const timeNow = moment11().tz("Asia/Singapore").format("HH:mm");
82723
82861
  const docs = await remarks.find({
82724
82862
  $or: [
82725
82863
  // Morning & Afternoon from today
@@ -82855,7 +82993,7 @@ var isWithinHour = (alertTime, timeNow) => {
82855
82993
  // src/events/manpower.event.ts
82856
82994
  import { useAtlas as useAtlas127 } from "@7365admin1/node-server-utils";
82857
82995
  import { ObjectId as ObjectId157 } from "mongodb";
82858
- import moment11 from "moment-timezone";
82996
+ import moment12 from "moment-timezone";
82859
82997
  async function manpowerEvents(io) {
82860
82998
  let intervalId = null;
82861
82999
  let activeConnections = 0;
@@ -82867,9 +83005,9 @@ async function manpowerEvents(io) {
82867
83005
  }
82868
83006
  const remarks = db2.collection("manpower-remarks");
82869
83007
  const settings = db2.collection("manpower-settings");
82870
- const selectedDateMoment = moment11.tz(date, "DD-MM-YYYY", "Asia/Singapore");
83008
+ const selectedDateMoment = moment12.tz(date, "DD-MM-YYYY", "Asia/Singapore");
82871
83009
  const selectedDateSGT = selectedDateMoment.format("DD-MM-YYYY");
82872
- const currentSGT = moment11().tz("Asia/Singapore");
83010
+ const currentSGT = moment12().tz("Asia/Singapore");
82873
83011
  const docs = await remarks.find({
82874
83012
  createdAtSGT: selectedDateSGT,
82875
83013
  $or: [
@@ -82891,7 +83029,7 @@ async function manpowerEvents(io) {
82891
83029
  }
82892
83030
  if (currentSGT.isSame(selectedDateMoment, "day")) {
82893
83031
  if (currentSGT.isSameOrAfter(
82894
- moment11.tz("19:55", "HH:mm", "Asia/Singapore")
83032
+ moment12.tz("19:55", "HH:mm", "Asia/Singapore")
82895
83033
  )) {
82896
83034
  shiftsToCheck.push({ index: 2, key: "nightShift" });
82897
83035
  }
@@ -91457,6 +91595,7 @@ export {
91457
91595
  CameraType,
91458
91596
  ConsoleAuditAction,
91459
91597
  ConsoleAuditTarget,
91598
+ DEFAULT_SITE_TIMEZONE,
91460
91599
  DEVICE_STATUS,
91461
91600
  DOBStatus,
91462
91601
  DUPLICATE_TERMS_VERSION_MESSAGE,
@@ -91711,6 +91850,7 @@ export {
91711
91850
  isSafeRelativePath,
91712
91851
  isSuperAdmin,
91713
91852
  isTermsCurrent,
91853
+ isValidTimezone,
91714
91854
  manpowerDesignationsSchema,
91715
91855
  manpowerEvents,
91716
91856
  manpowerMonitoringSchema,
@@ -91730,6 +91870,7 @@ export {
91730
91870
  occurrence_book_namespace_collection,
91731
91871
  online_forms_namespace_collection,
91732
91872
  orgSchema,
91873
+ orgSiteScope,
91733
91874
  overnight_parking_requests_namespace_collection,
91734
91875
  parseCameraChannel,
91735
91876
  parseCameraHost,
@@ -91763,6 +91904,7 @@ export {
91763
91904
  resolveDeviceHttp,
91764
91905
  resolveHidPhysicalCardValue,
91765
91906
  resolveInviteActor,
91907
+ resolveSiteTimezone,
91766
91908
  robotSchema,
91767
91909
  rtspUrl,
91768
91910
  schema,
@@ -91919,6 +92061,7 @@ export {
91919
92061
  sessionSchema,
91920
92062
  setIO,
91921
92063
  shiftSchema,
92064
+ siteDayBounds,
91922
92065
  siteSchema,
91923
92066
  site_people_namespace_collection,
91924
92067
  snapshotEndpoint,