@7365admin1/module-hygiene 4.10.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2529,12 +2529,30 @@ function useParentChecklistRepo() {
2529
2529
  throw error;
2530
2530
  }
2531
2531
  }
2532
+ async function getTodayParentChecklists() {
2533
+ const now = /* @__PURE__ */ new Date();
2534
+ const start = new Date(now);
2535
+ start.setUTCHours(0, 0, 0, 0);
2536
+ const end = new Date(now);
2537
+ end.setUTCHours(23, 59, 59, 999);
2538
+ try {
2539
+ const items = await collection.find(
2540
+ { createdAt: { $gte: start, $lte: end } },
2541
+ { projection: { _id: 1, site: 1 } }
2542
+ ).toArray();
2543
+ return items;
2544
+ } catch (error) {
2545
+ import_node_server_utils14.logger.error("Failed to get today's parent checklists", error);
2546
+ throw error;
2547
+ }
2548
+ }
2532
2549
  return {
2533
2550
  createIndex,
2534
2551
  createParentChecklist,
2535
2552
  getAllParentChecklist,
2536
2553
  updateParentChecklistStatuses,
2537
- closeExpiredParentChecklists
2554
+ closeExpiredParentChecklists,
2555
+ getTodayParentChecklists
2538
2556
  };
2539
2557
  }
2540
2558
 
@@ -2630,7 +2648,9 @@ var areaChecklistSchema = import_joi8.default.object({
2630
2648
  unit: import_joi8.default.string().hex().required(),
2631
2649
  name: import_joi8.default.string().required()
2632
2650
  }).required()
2633
- ).min(1).required()
2651
+ ).min(1).required(),
2652
+ isScheduleTask: import_joi8.default.boolean().optional().default(false),
2653
+ scheduleTaskId: import_joi8.default.string().hex().optional().allow(null)
2634
2654
  }).required()
2635
2655
  ).optional().default([]),
2636
2656
  createdBy: import_joi8.default.string().hex().required()
@@ -2659,6 +2679,8 @@ function MAreaChecklist(value) {
2659
2679
  value.checklist = value.checklist.map((checklistItem) => {
2660
2680
  return {
2661
2681
  set: checklistItem.set,
2682
+ isScheduleTask: checklistItem.isScheduleTask ?? false,
2683
+ scheduleTaskId: checklistItem.scheduleTaskId ?? void 0,
2662
2684
  units: checklistItem.units.map((unit) => ({
2663
2685
  unit: new import_mongodb8.ObjectId(unit.unit),
2664
2686
  name: unit.name,
@@ -2694,7 +2716,9 @@ function MAreaChecklist(value) {
2694
2716
  }
2695
2717
 
2696
2718
  // src/services/hygiene-area-checklist.service.ts
2719
+ var import_mongodb10 = require("mongodb");
2697
2720
  var import_node_server_utils18 = require("@7365admin1/node-server-utils");
2721
+ var import_core = require("@7365admin1/core");
2698
2722
 
2699
2723
  // src/repositories/hygiene-area-checklist.repository.ts
2700
2724
  var import_mongodb9 = require("mongodb");
@@ -2736,26 +2760,26 @@ function useAreaChecklistRepo() {
2736
2760
  );
2737
2761
  }
2738
2762
  }
2763
+ async function createUniqueIndex() {
2764
+ try {
2765
+ await collection.createIndex({ schedule: 1, area: 1 }, { unique: true });
2766
+ } catch (error) {
2767
+ throw new import_node_server_utils17.InternalServerError(
2768
+ "Failed to create unique index on hygiene checklist area."
2769
+ );
2770
+ }
2771
+ }
2739
2772
  async function createAreaChecklist(value, session) {
2740
2773
  try {
2741
2774
  const parentChecklistId = new import_mongodb9.ObjectId(value.schedule);
2742
- const currentDate = /* @__PURE__ */ new Date();
2743
- const startOfDay = new Date(currentDate);
2744
- startOfDay.setUTCHours(0, 0, 0, 0);
2745
- const endOfDay = new Date(currentDate);
2746
- endOfDay.setUTCHours(23, 59, 59, 999);
2747
- const existingChecklist = await collection.findOne({
2748
- type: value.type,
2749
- schedule: parentChecklistId,
2750
- name: value.name,
2751
- createdAt: {
2752
- $gte: startOfDay,
2753
- $lte: endOfDay
2754
- }
2755
- });
2775
+ const areaId = new import_mongodb9.ObjectId(value.area);
2776
+ const existingChecklist = await collection.findOne(
2777
+ { schedule: parentChecklistId, area: areaId },
2778
+ { session }
2779
+ );
2756
2780
  if (existingChecklist) {
2757
2781
  import_node_server_utils17.logger.info(
2758
- `Area checklist already exists for area ${value.name} on ${currentDate.toISOString().split("T")[0]}`
2782
+ `Area checklist already exists for area ${value.name} (schedule: ${parentChecklistId}, area: ${areaId})`
2759
2783
  );
2760
2784
  return existingChecklist._id;
2761
2785
  }
@@ -2771,6 +2795,14 @@ function useAreaChecklistRepo() {
2771
2795
  });
2772
2796
  return result.insertedId;
2773
2797
  } catch (error) {
2798
+ if (error?.code === 11e3) {
2799
+ import_node_server_utils17.logger.info(`Duplicate area checklist skipped for area ${value.name}`);
2800
+ const existing = await collection.findOne({
2801
+ schedule: new import_mongodb9.ObjectId(value.schedule),
2802
+ area: new import_mongodb9.ObjectId(value.area)
2803
+ });
2804
+ return existing._id;
2805
+ }
2774
2806
  throw error;
2775
2807
  }
2776
2808
  }
@@ -3108,6 +3140,9 @@ function useAreaChecklistRepo() {
3108
3140
  $project: {
3109
3141
  _id: 0,
3110
3142
  set: "$checklist.set",
3143
+ isScheduleTask: {
3144
+ $ifNull: ["$checklist.isScheduleTask", false]
3145
+ },
3111
3146
  unit: "$checklist.units.unit",
3112
3147
  name: "$checklist.units.name",
3113
3148
  remarks: "$checklist.units.remarks",
@@ -3138,6 +3173,7 @@ function useAreaChecklistRepo() {
3138
3173
  {
3139
3174
  $group: {
3140
3175
  _id: "$set",
3176
+ isScheduleTask: { $first: "$isScheduleTask" },
3141
3177
  units: {
3142
3178
  $push: {
3143
3179
  unit: "$unit",
@@ -3154,6 +3190,7 @@ function useAreaChecklistRepo() {
3154
3190
  $project: {
3155
3191
  _id: 0,
3156
3192
  set: "$_id",
3193
+ isScheduleTask: 1,
3157
3194
  units: 1
3158
3195
  }
3159
3196
  },
@@ -3227,7 +3264,19 @@ function useAreaChecklistRepo() {
3227
3264
  },
3228
3265
  {
3229
3266
  $addFields: {
3230
- isCompleted: { $ne: ["$checklist.units.completedBy", ""] }
3267
+ isCompleted: { $ne: ["$checklist.units.completedBy", ""] },
3268
+ isActioned: {
3269
+ $cond: {
3270
+ if: {
3271
+ $or: [
3272
+ { $eq: ["$checklist.units.approve", true] },
3273
+ { $eq: ["$checklist.units.reject", true] }
3274
+ ]
3275
+ },
3276
+ then: 1,
3277
+ else: 0
3278
+ }
3279
+ }
3231
3280
  }
3232
3281
  },
3233
3282
  {
@@ -3256,11 +3305,24 @@ function useAreaChecklistRepo() {
3256
3305
  preserveNullAndEmptyArrays: true
3257
3306
  }
3258
3307
  },
3259
- { $sort: { set: 1, isCompleted: -1, "checklist.units.timestamp": 1 } },
3308
+ {
3309
+ $sort: {
3310
+ "checklist.set": 1,
3311
+ isActioned: 1,
3312
+ "checklist.units.timestamp": 1,
3313
+ isCompleted: -1
3314
+ }
3315
+ },
3260
3316
  {
3261
3317
  $project: {
3262
3318
  _id: 0,
3263
3319
  set: "$checklist.set",
3320
+ isScheduleTask: {
3321
+ $ifNull: ["$checklist.isScheduleTask", false]
3322
+ },
3323
+ scheduleTaskId: {
3324
+ $ifNull: ["$checklist.scheduleTaskId", null]
3325
+ },
3264
3326
  remarks: "$checklist.remarks",
3265
3327
  attachment: "$checklist.attachment",
3266
3328
  unit: "$checklist.units.unit",
@@ -3293,6 +3355,8 @@ function useAreaChecklistRepo() {
3293
3355
  {
3294
3356
  $group: {
3295
3357
  _id: "$set",
3358
+ isScheduleTask: { $first: "$isScheduleTask" },
3359
+ scheduleTaskId: { $first: "$scheduleTaskId" },
3296
3360
  remarks: { $first: "$remarks" },
3297
3361
  attachment: { $first: "$attachment" },
3298
3362
  completedByName: { $first: "$completedByName" },
@@ -3314,13 +3378,33 @@ function useAreaChecklistRepo() {
3314
3378
  $project: {
3315
3379
  _id: 0,
3316
3380
  set: "$_id",
3381
+ isScheduleTask: 1,
3382
+ scheduleTaskId: 1,
3317
3383
  remarks: "$remarks",
3318
3384
  attachment: "$attachment",
3319
3385
  completedByName: 1,
3320
3386
  units: 1
3321
3387
  }
3322
3388
  },
3323
- { $sort: { set: 1 } },
3389
+ {
3390
+ $addFields: {
3391
+ isFullyActioned: {
3392
+ $allElementsTrue: {
3393
+ $map: {
3394
+ input: "$units",
3395
+ as: "u",
3396
+ in: {
3397
+ $or: [
3398
+ { $eq: ["$$u.approve", true] },
3399
+ { $eq: ["$$u.reject", true] }
3400
+ ]
3401
+ }
3402
+ }
3403
+ }
3404
+ }
3405
+ }
3406
+ },
3407
+ { $sort: { isFullyActioned: 1, set: 1 } },
3324
3408
  { $skip: page * limit },
3325
3409
  { $limit: limit }
3326
3410
  ];
@@ -3524,12 +3608,26 @@ function useAreaChecklistRepo() {
3524
3608
  throw error;
3525
3609
  }
3526
3610
  }
3611
+ async function getAreaChecklistSetOwner(_id, set, session) {
3612
+ try {
3613
+ _id = new import_mongodb9.ObjectId(_id);
3614
+ } catch (error) {
3615
+ throw new import_node_server_utils17.BadRequestError("Invalid area checklist ID format.");
3616
+ }
3617
+ const existing = await collection.findOne(
3618
+ { _id, "checklist.set": set },
3619
+ { projection: { "checklist.$": 1 }, session }
3620
+ );
3621
+ if (!existing?.checklist?.length)
3622
+ return null;
3623
+ return existing.checklist[0].units.map((u) => u.completedBy).find((cb) => cb && cb.toString() !== "") ?? null;
3624
+ }
3527
3625
  async function getMaxSetNumberForArea(areaId, session) {
3528
3626
  try {
3529
3627
  const _id = new import_mongodb9.ObjectId(areaId);
3530
3628
  const result = await collection.aggregate(
3531
3629
  [
3532
- { $match: { area: _id.toString() } },
3630
+ { $match: { area: _id } },
3533
3631
  { $unwind: "$checklist" },
3534
3632
  { $group: { _id: null, maxSet: { $max: "$checklist.set" } } }
3535
3633
  ],
@@ -3577,9 +3675,155 @@ function useAreaChecklistRepo() {
3577
3675
  throw error;
3578
3676
  }
3579
3677
  }
3678
+ async function pushScheduleTaskSets(scheduleId, areaId, scheduleTaskId, newSets) {
3679
+ try {
3680
+ const schedule = new import_mongodb9.ObjectId(scheduleId);
3681
+ const area = new import_mongodb9.ObjectId(areaId);
3682
+ const taskId = new import_mongodb9.ObjectId(scheduleTaskId);
3683
+ const result = await collection.updateOne(
3684
+ {
3685
+ schedule,
3686
+ area,
3687
+ checklist: { $not: { $elemMatch: { scheduleTaskId: taskId } } }
3688
+ },
3689
+ {
3690
+ $push: { checklist: { $each: newSets } },
3691
+ $set: { updatedAt: /* @__PURE__ */ new Date() }
3692
+ }
3693
+ );
3694
+ if (result.modifiedCount > 0) {
3695
+ delNamespace().catch((err) => {
3696
+ import_node_server_utils17.logger.error(
3697
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3698
+ err
3699
+ );
3700
+ });
3701
+ }
3702
+ return result.modifiedCount;
3703
+ } catch (error) {
3704
+ import_node_server_utils17.logger.error("Error in pushScheduleTaskSets:", error);
3705
+ throw error;
3706
+ }
3707
+ }
3708
+ async function insertAutoGenSets(scheduleId, areaId, newSets) {
3709
+ try {
3710
+ const schedule = new import_mongodb9.ObjectId(scheduleId);
3711
+ const area = new import_mongodb9.ObjectId(areaId);
3712
+ const result = await collection.updateOne(
3713
+ {
3714
+ schedule,
3715
+ area,
3716
+ checklist: {
3717
+ $not: { $elemMatch: { isScheduleTask: { $ne: true } } }
3718
+ }
3719
+ },
3720
+ {
3721
+ $push: { checklist: { $each: newSets } },
3722
+ $set: { updatedAt: /* @__PURE__ */ new Date() }
3723
+ }
3724
+ );
3725
+ if (result.modifiedCount > 0) {
3726
+ delNamespace().catch((err) => {
3727
+ import_node_server_utils17.logger.error(
3728
+ `Failed to clear cache for namespace: ${namespace_collection}`,
3729
+ err
3730
+ );
3731
+ });
3732
+ }
3733
+ return result.modifiedCount;
3734
+ } catch (error) {
3735
+ import_node_server_utils17.logger.error("Error in insertAutoGenSets:", error);
3736
+ throw error;
3737
+ }
3738
+ }
3739
+ async function trimOverflowSets() {
3740
+ try {
3741
+ const db2 = import_node_server_utils17.useAtlas.getDb();
3742
+ if (!db2)
3743
+ return 0;
3744
+ const bloated = await collection.aggregate([
3745
+ {
3746
+ $lookup: {
3747
+ from: "site.cleaning.areas",
3748
+ localField: "area",
3749
+ foreignField: "_id",
3750
+ as: "areaDoc"
3751
+ }
3752
+ },
3753
+ {
3754
+ $unwind: { path: "$areaDoc", preserveNullAndEmptyArrays: false }
3755
+ },
3756
+ {
3757
+ $addFields: {
3758
+ configuredSet: { $max: [1, { $ifNull: ["$areaDoc.set", 1] }] },
3759
+ autoGenSets: {
3760
+ $filter: {
3761
+ input: { $ifNull: ["$checklist", []] },
3762
+ as: "item",
3763
+ cond: { $ne: ["$$item.isScheduleTask", true] }
3764
+ }
3765
+ },
3766
+ scheduledSets: {
3767
+ $filter: {
3768
+ input: { $ifNull: ["$checklist", []] },
3769
+ as: "item",
3770
+ cond: { $eq: ["$$item.isScheduleTask", true] }
3771
+ }
3772
+ }
3773
+ }
3774
+ },
3775
+ {
3776
+ $match: {
3777
+ $expr: {
3778
+ $gt: [{ $size: "$autoGenSets" }, "$configuredSet"]
3779
+ }
3780
+ }
3781
+ },
3782
+ {
3783
+ $project: {
3784
+ _id: 1,
3785
+ checklist: 1,
3786
+ configuredSet: 1,
3787
+ autoGenSets: 1,
3788
+ scheduledSets: 1
3789
+ }
3790
+ }
3791
+ ]).toArray();
3792
+ if (bloated.length === 0) {
3793
+ import_node_server_utils17.logger.info(
3794
+ "trimOverflowSets: no bloated area-checklist documents found"
3795
+ );
3796
+ return 0;
3797
+ }
3798
+ let trimmed = 0;
3799
+ for (const doc of bloated) {
3800
+ const limit = Number(doc.configuredSet) || 1;
3801
+ const trimmedAutoGen = [...doc.autoGenSets ?? []].sort((a, b) => (a.set ?? 0) - (b.set ?? 0)).slice(0, limit);
3802
+ const keep = [...trimmedAutoGen, ...doc.scheduledSets ?? []];
3803
+ const res = await collection.updateOne(
3804
+ { _id: doc._id },
3805
+ { $set: { checklist: keep, updatedAt: /* @__PURE__ */ new Date() } }
3806
+ );
3807
+ if (res.modifiedCount > 0) {
3808
+ trimmed++;
3809
+ import_node_server_utils17.logger.info(
3810
+ `trimOverflowSets: trimmed doc ${doc._id} \u2014 kept ${keep.length} sets (${trimmedAutoGen.length} auto-gen, ${(doc.scheduledSets ?? []).length} scheduled), removed ${doc.checklist.length - keep.length} excess auto-gen`
3811
+ );
3812
+ }
3813
+ }
3814
+ delNamespace().catch(() => {
3815
+ });
3816
+ import_node_server_utils17.logger.info(`trimOverflowSets: trimmed ${trimmed} document(s)`);
3817
+ return trimmed;
3818
+ } catch (error) {
3819
+ import_node_server_utils17.logger.error("Error in trimOverflowSets:", error);
3820
+ return 0;
3821
+ }
3822
+ }
3580
3823
  return {
3581
3824
  createIndex,
3582
3825
  createTextIndex,
3826
+ createUniqueIndex,
3583
3827
  createAreaChecklist,
3584
3828
  getAllAreaChecklist,
3585
3829
  getAreaChecklistHistory,
@@ -3587,11 +3831,15 @@ function useAreaChecklistRepo() {
3587
3831
  getAreaChecklistUnits,
3588
3832
  getAreaChecklistById,
3589
3833
  getAreaChecklistByAreaAndSchedule,
3834
+ getAreaChecklistSetOwner,
3590
3835
  updateAreaChecklist,
3591
3836
  updateAreaChecklistStatus,
3592
3837
  updateAreaChecklistUnits,
3593
3838
  getMaxSetNumberForArea,
3594
- closeExpiredAreaChecklists
3839
+ closeExpiredAreaChecklists,
3840
+ pushScheduleTaskSets,
3841
+ insertAutoGenSets,
3842
+ trimOverflowSets
3595
3843
  };
3596
3844
  }
3597
3845
 
@@ -3603,17 +3851,18 @@ function useAreaChecklistService() {
3603
3851
  getAllAreaChecklist,
3604
3852
  getAreaChecklistUnits,
3605
3853
  getAreaChecklistById,
3854
+ getAreaChecklistByAreaAndSchedule,
3855
+ getAreaChecklistSetOwner,
3606
3856
  updateAreaChecklistUnits: _updateAreaChecklistUnits,
3607
3857
  updateAreaChecklistStatus,
3608
- getMaxSetNumberForArea
3858
+ insertAutoGenSets
3609
3859
  } = useAreaChecklistRepo();
3610
3860
  const { updateParentChecklistStatuses } = useParentChecklistRepo();
3861
+ const { getUserById } = (0, import_core.useUserRepo)();
3611
3862
  async function createAreaChecklist(value) {
3612
- const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
3863
+ const results = [];
3864
+ let totalChecklistsCreated = 0;
3613
3865
  try {
3614
- session?.startTransaction();
3615
- const results = [];
3616
- let totalChecklistsCreated = 0;
3617
3866
  const BATCH_SIZE = 10;
3618
3867
  const areasResult = await getAreasForChecklist(value.site);
3619
3868
  const areas = areasResult || [];
@@ -3627,15 +3876,72 @@ function useAreaChecklistService() {
3627
3876
  );
3628
3877
  return null;
3629
3878
  }
3630
- const maxSet = await getMaxSetNumberForArea(area._id, session);
3631
- const setCount = area.set || 1;
3879
+ let existing = null;
3880
+ try {
3881
+ existing = await getAreaChecklistByAreaAndSchedule(
3882
+ value.schedule.toString(),
3883
+ area._id.toString()
3884
+ );
3885
+ } catch (_) {
3886
+ }
3887
+ if (existing) {
3888
+ const hasAutoGenSets = existing.checklist?.some(
3889
+ (c) => c.isScheduleTask !== true
3890
+ );
3891
+ if (hasAutoGenSets) {
3892
+ import_node_server_utils18.logger.info(
3893
+ `Area checklist already exists with auto-gen sets for area ${area.name}, skipping`
3894
+ );
3895
+ return existing._id;
3896
+ }
3897
+ import_node_server_utils18.logger.info(
3898
+ `Area checklist for area ${area.name} exists but has no auto-gen sets. Inserting auto-gen sets.`
3899
+ );
3900
+ const setCount2 = Number(area.set) || 1;
3901
+ const totalExistingSets = existing.checklist?.length ?? 0;
3902
+ if (totalExistingSets >= setCount2) {
3903
+ import_node_server_utils18.logger.info(
3904
+ `Area checklist for area ${area.name} already has ${totalExistingSets} set(s) (configured: ${setCount2}). Skipping auto-gen sets.`
3905
+ );
3906
+ return existing._id;
3907
+ }
3908
+ const maxExistingSet = existing.checklist?.reduce(
3909
+ (max, c) => Math.max(max, c.set ?? 0),
3910
+ 0
3911
+ ) ?? 0;
3912
+ const setsToAdd = setCount2 - totalExistingSets;
3913
+ const autoGenSets = Array.from(
3914
+ { length: setsToAdd },
3915
+ (_, index) => ({
3916
+ set: maxExistingSet + index + 1,
3917
+ isScheduleTask: false,
3918
+ units: area.units.map((unit) => ({
3919
+ unit: new import_mongodb10.ObjectId(unit.unit),
3920
+ name: unit.name,
3921
+ approve: false,
3922
+ reject: false,
3923
+ status: "open",
3924
+ remarks: "",
3925
+ completedBy: "",
3926
+ timestamp: ""
3927
+ }))
3928
+ })
3929
+ );
3930
+ await insertAutoGenSets(
3931
+ value.schedule.toString(),
3932
+ area._id.toString(),
3933
+ autoGenSets
3934
+ );
3935
+ return existing._id;
3936
+ }
3937
+ const setCount = Number(area.set) || 1;
3632
3938
  const checklistData = {
3633
3939
  schedule: value.schedule,
3634
3940
  area: area._id.toString(),
3635
3941
  name: area.name,
3636
3942
  type: area.type,
3637
3943
  checklist: Array.from({ length: setCount }, (_, index) => ({
3638
- set: maxSet + index + 1,
3944
+ set: index + 1,
3639
3945
  units: area.units.map((unit) => ({
3640
3946
  unit: unit.unit.toString(),
3641
3947
  name: unit.name
@@ -3643,10 +3949,7 @@ function useAreaChecklistService() {
3643
3949
  })),
3644
3950
  createdBy: value.createdBy
3645
3951
  };
3646
- const insertedId = await _createAreaChecklist(
3647
- checklistData,
3648
- session
3649
- );
3952
+ const insertedId = await _createAreaChecklist(checklistData);
3650
3953
  totalChecklistsCreated++;
3651
3954
  return insertedId;
3652
3955
  });
@@ -3659,25 +3962,26 @@ function useAreaChecklistService() {
3659
3962
  } else {
3660
3963
  import_node_server_utils18.logger.warn(`No common areas found for site: ${value.site}`);
3661
3964
  }
3662
- await session?.commitTransaction();
3663
3965
  import_node_server_utils18.logger.info(
3664
3966
  `Successfully created ${totalChecklistsCreated} area checklists for site: ${value.site}`
3665
3967
  );
3666
3968
  return results;
3667
3969
  } catch (error) {
3668
3970
  import_node_server_utils18.logger.error(`Error generating area checklists:`, error);
3669
- if (session?.inTransaction()) {
3670
- await session?.abortTransaction();
3671
- }
3672
3971
  throw error;
3673
- } finally {
3674
- session?.endSession();
3675
3972
  }
3676
3973
  }
3677
3974
  async function updateAreaChecklistUnits(_id, set, unitId, value) {
3678
3975
  const session = import_node_server_utils18.useAtlas.getClient()?.startSession();
3679
3976
  try {
3680
3977
  session?.startTransaction();
3978
+ const setOwner = await getAreaChecklistSetOwner(_id, set, session);
3979
+ if (setOwner && value.completedBy && setOwner.toString() !== value.completedBy.toString()) {
3980
+ const acceptedBy = await getUserById(setOwner.toString());
3981
+ throw new import_node_server_utils18.UnauthorizedError(
3982
+ `${acceptedBy.name} has already taken this set.`
3983
+ );
3984
+ }
3681
3985
  await _updateAreaChecklistUnits(_id, set, unitId, value, session);
3682
3986
  const allUnitsResult = await getAreaChecklistUnits(
3683
3987
  {
@@ -3768,7 +4072,7 @@ var import_node_server_utils20 = require("@7365admin1/node-server-utils");
3768
4072
  // src/services/hygiene-checklist-pdf.service.ts
3769
4073
  var import_puppeteer = require("puppeteer");
3770
4074
  var import_node_server_utils19 = require("@7365admin1/node-server-utils");
3771
- var import_mongodb10 = require("mongodb");
4075
+ var import_mongodb11 = require("mongodb");
3772
4076
  function escapeHtml(text) {
3773
4077
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
3774
4078
  }
@@ -3942,7 +4246,7 @@ function useChecklistPdfService() {
3942
4246
  const collection = db.collection("site.cleaning.schedule.areas");
3943
4247
  let scheduleObjectId;
3944
4248
  try {
3945
- scheduleObjectId = new import_mongodb10.ObjectId(scheduleId);
4249
+ scheduleObjectId = new import_mongodb11.ObjectId(scheduleId);
3946
4250
  } catch {
3947
4251
  throw new import_node_server_utils19.InternalServerError("Invalid schedule ID format.");
3948
4252
  }
@@ -4251,7 +4555,7 @@ function useAreaChecklistController() {
4251
4555
 
4252
4556
  // src/models/hygiene-supply.model.ts
4253
4557
  var import_joi10 = __toESM(require("joi"));
4254
- var import_mongodb11 = require("mongodb");
4558
+ var import_mongodb12 = require("mongodb");
4255
4559
  var import_node_server_utils21 = require("@7365admin1/node-server-utils");
4256
4560
  var supplySchema = import_joi10.default.object({
4257
4561
  site: import_joi10.default.string().hex().required(),
@@ -4266,7 +4570,7 @@ function MSupply(value) {
4266
4570
  }
4267
4571
  if (value.site) {
4268
4572
  try {
4269
- value.site = new import_mongodb11.ObjectId(value.site);
4573
+ value.site = new import_mongodb12.ObjectId(value.site);
4270
4574
  } catch (error2) {
4271
4575
  throw new import_node_server_utils21.BadRequestError("Invalid site ID format.");
4272
4576
  }
@@ -4284,7 +4588,7 @@ function MSupply(value) {
4284
4588
  }
4285
4589
 
4286
4590
  // src/repositories/hygiene-supply.repository.ts
4287
- var import_mongodb12 = require("mongodb");
4591
+ var import_mongodb13 = require("mongodb");
4288
4592
  var import_node_server_utils22 = require("@7365admin1/node-server-utils");
4289
4593
  function useSupplyRepository() {
4290
4594
  const db = import_node_server_utils22.useAtlas.getDb();
@@ -4360,7 +4664,7 @@ function useSupplyRepository() {
4360
4664
  limit
4361
4665
  };
4362
4666
  try {
4363
- site = new import_mongodb12.ObjectId(site);
4667
+ site = new import_mongodb13.ObjectId(site);
4364
4668
  query.site = site;
4365
4669
  cacheOptions.site = site.toString();
4366
4670
  } catch (error) {
@@ -4404,7 +4708,7 @@ function useSupplyRepository() {
4404
4708
  }
4405
4709
  async function getSupplyById(_id, session) {
4406
4710
  try {
4407
- _id = new import_mongodb12.ObjectId(_id);
4711
+ _id = new import_mongodb13.ObjectId(_id);
4408
4712
  } catch (error) {
4409
4713
  throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
4410
4714
  }
@@ -4450,7 +4754,7 @@ function useSupplyRepository() {
4450
4754
  }
4451
4755
  async function updateSupply(_id, value, session) {
4452
4756
  try {
4453
- _id = new import_mongodb12.ObjectId(_id);
4757
+ _id = new import_mongodb13.ObjectId(_id);
4454
4758
  } catch (error) {
4455
4759
  throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
4456
4760
  }
@@ -4483,7 +4787,7 @@ function useSupplyRepository() {
4483
4787
  }
4484
4788
  async function deleteSupply(_id, session) {
4485
4789
  try {
4486
- _id = new import_mongodb12.ObjectId(_id);
4790
+ _id = new import_mongodb13.ObjectId(_id);
4487
4791
  } catch (error) {
4488
4792
  throw new import_node_server_utils22.BadRequestError("Invalid supply ID format.");
4489
4793
  }
@@ -4664,7 +4968,7 @@ function useSupplyController() {
4664
4968
 
4665
4969
  // src/models/hygiene-stock.model.ts
4666
4970
  var import_joi12 = __toESM(require("joi"));
4667
- var import_mongodb13 = require("mongodb");
4971
+ var import_mongodb14 = require("mongodb");
4668
4972
  var import_node_server_utils24 = require("@7365admin1/node-server-utils");
4669
4973
  var stockSchema = import_joi12.default.object({
4670
4974
  site: import_joi12.default.string().hex().required(),
@@ -4682,14 +4986,14 @@ function MStock(value) {
4682
4986
  }
4683
4987
  if (value.site) {
4684
4988
  try {
4685
- value.site = new import_mongodb13.ObjectId(value.site);
4989
+ value.site = new import_mongodb14.ObjectId(value.site);
4686
4990
  } catch (error2) {
4687
4991
  throw new import_node_server_utils24.BadRequestError("Invalid site ID format.");
4688
4992
  }
4689
4993
  }
4690
4994
  if (value.supply) {
4691
4995
  try {
4692
- value.supply = new import_mongodb13.ObjectId(value.supply);
4996
+ value.supply = new import_mongodb14.ObjectId(value.supply);
4693
4997
  } catch (error2) {
4694
4998
  throw new import_node_server_utils24.BadRequestError("Invalid supply ID format.");
4695
4999
  }
@@ -4709,7 +5013,7 @@ function MStock(value) {
4709
5013
  }
4710
5014
 
4711
5015
  // src/repositories/hygiene-stock.repository.ts
4712
- var import_mongodb14 = require("mongodb");
5016
+ var import_mongodb15 = require("mongodb");
4713
5017
  var import_node_server_utils25 = require("@7365admin1/node-server-utils");
4714
5018
  function useStockRepository() {
4715
5019
  const db = import_node_server_utils25.useAtlas.getDb();
@@ -4774,14 +5078,14 @@ function useStockRepository() {
4774
5078
  limit
4775
5079
  };
4776
5080
  try {
4777
- site = new import_mongodb14.ObjectId(site);
5081
+ site = new import_mongodb15.ObjectId(site);
4778
5082
  query.site = site;
4779
5083
  cacheOptions.site = site.toString();
4780
5084
  } catch (error) {
4781
5085
  throw new import_node_server_utils25.BadRequestError("Invalid site ID format.");
4782
5086
  }
4783
5087
  try {
4784
- supply = new import_mongodb14.ObjectId(supply);
5088
+ supply = new import_mongodb15.ObjectId(supply);
4785
5089
  query.supply = supply;
4786
5090
  cacheOptions.supply = supply.toString();
4787
5091
  } catch (error) {
@@ -4955,7 +5259,7 @@ function useStockController() {
4955
5259
 
4956
5260
  // src/models/hygiene-checkout-item.model.ts
4957
5261
  var import_joi14 = __toESM(require("joi"));
4958
- var import_mongodb15 = require("mongodb");
5262
+ var import_mongodb16 = require("mongodb");
4959
5263
  var import_node_server_utils28 = require("@7365admin1/node-server-utils");
4960
5264
  var allowedCheckOutItemStatus = ["pending", "completed"];
4961
5265
  var checkOutItemSchema = import_joi14.default.object({
@@ -4975,14 +5279,14 @@ function MCheckOutItem(value) {
4975
5279
  }
4976
5280
  if (value.site) {
4977
5281
  try {
4978
- value.site = new import_mongodb15.ObjectId(value.site);
5282
+ value.site = new import_mongodb16.ObjectId(value.site);
4979
5283
  } catch (error2) {
4980
5284
  throw new import_node_server_utils28.BadRequestError("Invalid site ID format.");
4981
5285
  }
4982
5286
  }
4983
5287
  if (value.supply) {
4984
5288
  try {
4985
- value.supply = new import_mongodb15.ObjectId(value.supply);
5289
+ value.supply = new import_mongodb16.ObjectId(value.supply);
4986
5290
  } catch (error2) {
4987
5291
  throw new import_node_server_utils28.BadRequestError("Invalid supply ID format.");
4988
5292
  }
@@ -5003,7 +5307,7 @@ function MCheckOutItem(value) {
5003
5307
  }
5004
5308
 
5005
5309
  // src/repositories/hygiene-checkout-item.repository.ts
5006
- var import_mongodb16 = require("mongodb");
5310
+ var import_mongodb17 = require("mongodb");
5007
5311
  var import_node_server_utils29 = require("@7365admin1/node-server-utils");
5008
5312
  function useCheckOutItemRepository() {
5009
5313
  const db = import_node_server_utils29.useAtlas.getDb();
@@ -5067,7 +5371,7 @@ function useCheckOutItemRepository() {
5067
5371
  limit
5068
5372
  };
5069
5373
  try {
5070
- site = new import_mongodb16.ObjectId(site);
5374
+ site = new import_mongodb17.ObjectId(site);
5071
5375
  query.site = site;
5072
5376
  cacheOptions.site = site.toString();
5073
5377
  } catch (error) {
@@ -5140,7 +5444,7 @@ function useCheckOutItemRepository() {
5140
5444
  }
5141
5445
  async function getCheckOutItemById(_id, session) {
5142
5446
  try {
5143
- _id = new import_mongodb16.ObjectId(_id);
5447
+ _id = new import_mongodb17.ObjectId(_id);
5144
5448
  } catch (error) {
5145
5449
  throw new import_node_server_utils29.BadRequestError("Invalid check out item ID format.");
5146
5450
  }
@@ -5204,7 +5508,7 @@ function useCheckOutItemRepository() {
5204
5508
  }
5205
5509
  async function completeCheckOutItem(_id, session) {
5206
5510
  try {
5207
- _id = new import_mongodb16.ObjectId(_id);
5511
+ _id = new import_mongodb17.ObjectId(_id);
5208
5512
  } catch (error) {
5209
5513
  throw new import_node_server_utils29.BadRequestError("Invalid check out item ID format.");
5210
5514
  }
@@ -5245,7 +5549,7 @@ function useCheckOutItemRepository() {
5245
5549
  }
5246
5550
 
5247
5551
  // src/services/hygiene-checkout-item.service.ts
5248
- var import_core = require("@7365admin1/core");
5552
+ var import_core2 = require("@7365admin1/core");
5249
5553
  var import_node_server_utils30 = require("@7365admin1/node-server-utils");
5250
5554
  function useCheckOutItemService() {
5251
5555
  const {
@@ -5254,7 +5558,7 @@ function useCheckOutItemService() {
5254
5558
  completeCheckOutItem
5255
5559
  } = useCheckOutItemRepository();
5256
5560
  const { getSupplyById } = useSupplyRepository();
5257
- const { getUserById } = (0, import_core.useUserRepo)();
5561
+ const { getUserById } = (0, import_core2.useUserRepo)();
5258
5562
  const { createStock } = useStockService();
5259
5563
  async function createCheckOutItem(value) {
5260
5564
  const session = import_node_server_utils30.useAtlas.getClient()?.startSession();
@@ -5490,7 +5794,7 @@ function useCheckOutItemController() {
5490
5794
  // src/models/hygiene-schedule-task.model.ts
5491
5795
  var import_node_server_utils32 = require("@7365admin1/node-server-utils");
5492
5796
  var import_joi16 = __toESM(require("joi"));
5493
- var import_mongodb17 = require("mongodb");
5797
+ var import_mongodb18 = require("mongodb");
5494
5798
  var scheduleTaskSchema = import_joi16.default.object({
5495
5799
  site: import_joi16.default.string().hex().required(),
5496
5800
  title: import_joi16.default.string().required(),
@@ -5515,7 +5819,7 @@ function MScheduleTask(value) {
5515
5819
  }
5516
5820
  if (value.site) {
5517
5821
  try {
5518
- value.site = new import_mongodb17.ObjectId(value.site);
5822
+ value.site = new import_mongodb18.ObjectId(value.site);
5519
5823
  } catch (error2) {
5520
5824
  throw new import_node_server_utils32.BadRequestError("Invalid site ID format.");
5521
5825
  }
@@ -5525,7 +5829,7 @@ function MScheduleTask(value) {
5525
5829
  try {
5526
5830
  return {
5527
5831
  name: area.name,
5528
- value: new import_mongodb17.ObjectId(area.value.toString())
5832
+ value: new import_mongodb18.ObjectId(area.value.toString())
5529
5833
  };
5530
5834
  } catch (error2) {
5531
5835
  throw new import_node_server_utils32.BadRequestError(`Invalid area value format: ${area.name}`);
@@ -5534,7 +5838,7 @@ function MScheduleTask(value) {
5534
5838
  }
5535
5839
  if (value.createdBy) {
5536
5840
  try {
5537
- value.createdBy = new import_mongodb17.ObjectId(value.createdBy);
5841
+ value.createdBy = new import_mongodb18.ObjectId(value.createdBy);
5538
5842
  } catch (error2) {
5539
5843
  throw new import_node_server_utils32.BadRequestError("Invalid createdBy ID format.");
5540
5844
  }
@@ -5555,7 +5859,7 @@ function MScheduleTask(value) {
5555
5859
  }
5556
5860
 
5557
5861
  // src/repositories/hygiene-schedule-task.repository.ts
5558
- var import_mongodb18 = require("mongodb");
5862
+ var import_mongodb19 = require("mongodb");
5559
5863
  var import_node_server_utils33 = require("@7365admin1/node-server-utils");
5560
5864
  function useScheduleTaskRepository() {
5561
5865
  const db = import_node_server_utils33.useAtlas.getDb();
@@ -5618,7 +5922,7 @@ function useScheduleTaskRepository() {
5618
5922
  limit
5619
5923
  };
5620
5924
  try {
5621
- site = new import_mongodb18.ObjectId(site);
5925
+ site = new import_mongodb19.ObjectId(site);
5622
5926
  query.site = site;
5623
5927
  cacheOptions.site = site.toString();
5624
5928
  } catch (error) {
@@ -5686,7 +5990,7 @@ function useScheduleTaskRepository() {
5686
5990
  limit
5687
5991
  };
5688
5992
  try {
5689
- site = new import_mongodb18.ObjectId(site);
5993
+ site = new import_mongodb19.ObjectId(site);
5690
5994
  query.site = site;
5691
5995
  cacheOptions.site = site.toString();
5692
5996
  } catch (error) {
@@ -5729,7 +6033,7 @@ function useScheduleTaskRepository() {
5729
6033
  }
5730
6034
  async function getScheduleTaskById(_id, session) {
5731
6035
  try {
5732
- _id = new import_mongodb18.ObjectId(_id);
6036
+ _id = new import_mongodb19.ObjectId(_id);
5733
6037
  } catch (error) {
5734
6038
  throw new import_node_server_utils33.BadRequestError("Invalid schedule task ID format.");
5735
6039
  }
@@ -5779,7 +6083,7 @@ function useScheduleTaskRepository() {
5779
6083
  }
5780
6084
  async function updateScheduleTask(_id, value, session) {
5781
6085
  try {
5782
- _id = new import_mongodb18.ObjectId(_id);
6086
+ _id = new import_mongodb19.ObjectId(_id);
5783
6087
  } catch (error) {
5784
6088
  throw new import_node_server_utils33.BadRequestError("Invalid schedule task ID format.");
5785
6089
  }
@@ -5788,7 +6092,7 @@ function useScheduleTaskRepository() {
5788
6092
  try {
5789
6093
  return {
5790
6094
  name: area.name,
5791
- value: new import_mongodb18.ObjectId(area.value.toString())
6095
+ value: new import_mongodb19.ObjectId(area.value.toString())
5792
6096
  };
5793
6097
  } catch (error) {
5794
6098
  throw new import_node_server_utils33.BadRequestError(`Invalid area value format: ${area.name}`);
@@ -5833,6 +6137,7 @@ function useScheduleTaskRepository() {
5833
6137
  }
5834
6138
 
5835
6139
  // src/services/hygiene-schedule-task.service.ts
6140
+ var import_mongodb20 = require("mongodb");
5836
6141
  var import_node_server_utils34 = require("@7365admin1/node-server-utils");
5837
6142
  function useScheduleTaskService() {
5838
6143
  const { createParentChecklist } = useParentChecklistRepo();
@@ -5840,7 +6145,7 @@ function useScheduleTaskService() {
5840
6145
  const {
5841
6146
  createAreaChecklist,
5842
6147
  getAreaChecklistByAreaAndSchedule,
5843
- updateAreaChecklist
6148
+ pushScheduleTaskSets
5844
6149
  } = useAreaChecklistRepo();
5845
6150
  const { getAreaById } = useAreaRepo();
5846
6151
  function checkScheduleConditions(schedule, currentDate = /* @__PURE__ */ new Date()) {
@@ -5879,6 +6184,35 @@ function useScheduleTaskService() {
5879
6184
  );
5880
6185
  return false;
5881
6186
  }
6187
+ const relevantTimestamp = schedule.updatedAt || schedule.createdAt;
6188
+ if (relevantTimestamp) {
6189
+ const savedAt = new Date(relevantTimestamp);
6190
+ const savedHour = parseInt(
6191
+ savedAt.toLocaleTimeString("en-US", {
6192
+ hour: "2-digit",
6193
+ hour12: false,
6194
+ timeZone: "Asia/Singapore"
6195
+ }),
6196
+ 10
6197
+ );
6198
+ const savedMinute = savedAt.toLocaleString("en-US", {
6199
+ minute: "2-digit",
6200
+ timeZone: "Asia/Singapore"
6201
+ });
6202
+ const savedDateFormatted = savedAt.toLocaleDateString("en-CA", {
6203
+ timeZone: "Asia/Singapore"
6204
+ });
6205
+ const savedMinNum = parseInt(savedMinute, 10);
6206
+ const wasSavedThisMinute = savedDateFormatted === currentDateFormatted && savedHour === currentHour && savedMinNum === currentMinute;
6207
+ if (wasSavedThisMinute) {
6208
+ import_node_server_utils34.logger.info(
6209
+ `Schedule ${schedule._id}: Skipping \u2014 task was saved this minute (${savedHour}:${String(
6210
+ savedMinNum
6211
+ ).padStart(2, "0")}). Will fire on next occurrence.`
6212
+ );
6213
+ return false;
6214
+ }
6215
+ }
5882
6216
  import_node_server_utils34.logger.info(
5883
6217
  `Schedule ${schedule._id}: All conditions matched - Date is within range and time matches`
5884
6218
  );
@@ -5946,8 +6280,14 @@ function useScheduleTaskService() {
5946
6280
  let units = [];
5947
6281
  if (areaDetails.units && areaDetails.units.length > 0) {
5948
6282
  units = areaDetails.units.map((unit) => ({
5949
- unit: unit.unit.toString(),
5950
- name: unit.name
6283
+ unit: new import_mongodb20.ObjectId(unit.unit),
6284
+ name: unit.name,
6285
+ approve: false,
6286
+ reject: false,
6287
+ status: "open",
6288
+ remarks: "",
6289
+ completedBy: "",
6290
+ timestamp: ""
5951
6291
  }));
5952
6292
  import_node_server_utils34.logger.info(
5953
6293
  `Area ${area.name} (${areaId}): Using units from area details: ${JSON.stringify(
@@ -5984,79 +6324,62 @@ function useScheduleTaskService() {
5984
6324
  );
5985
6325
  }
5986
6326
  if (existingAreaChecklist) {
5987
- const currentSetNumber = existingAreaChecklist.checklist?.length || 0;
5988
- const newSet = {
5989
- set: currentSetNumber + 1,
5990
- units
5991
- };
5992
- const updatedChecklist = [
5993
- ...existingAreaChecklist.checklist || [],
5994
- newSet
5995
- ];
5996
- import_node_server_utils34.logger.info(
5997
- `Area ${area.name} (${areaId}): Appending new set ${newSet.set} to checklist. Updated checklist: ${JSON.stringify(
5998
- updatedChecklist
5999
- )}`
6327
+ const areaSetConfig = Number(areaDetails.set) || 1;
6328
+ const maxSetInChecklist = existingAreaChecklist.checklist?.length ? Math.max(
6329
+ ...existingAreaChecklist.checklist.map(
6330
+ (c) => c.set
6331
+ )
6332
+ ) : 0;
6333
+ const startSetNumber = maxSetInChecklist + 1;
6334
+ const newSets = Array.from(
6335
+ { length: areaSetConfig },
6336
+ (_, index) => ({
6337
+ set: startSetNumber + index,
6338
+ units,
6339
+ isScheduleTask: true,
6340
+ scheduleTaskId: scheduleTask._id
6341
+ })
6000
6342
  );
6001
- await updateAreaChecklist(existingAreaChecklist._id, {
6002
- checklist: updatedChecklist
6003
- });
6004
- import_node_server_utils34.logger.info(
6005
- `Appended set ${newSet.set} to area checklist for area ${area.name}`
6343
+ const modified = await pushScheduleTaskSets(
6344
+ parentChecklistId.toString(),
6345
+ areaId,
6346
+ scheduleTask._id.toString(),
6347
+ newSets
6006
6348
  );
6007
- try {
6008
- const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
6009
- parentChecklistId.toString(),
6010
- areaId
6011
- );
6349
+ if (modified > 0) {
6012
6350
  import_node_server_utils34.logger.info(
6013
- `Area ${area.name} (${areaId}): Checklist after update: ${JSON.stringify(
6014
- verifyChecklist.checklist
6015
- )}`
6351
+ `Appended ${areaSetConfig} set(s) starting from ${startSetNumber} to area checklist for area ${area.name}`
6016
6352
  );
6017
- } catch (verifyError) {
6018
- import_node_server_utils34.logger.warn(
6019
- `Area ${area.name} (${areaId}): Error verifying checklist after update:`,
6020
- verifyError
6353
+ } else {
6354
+ import_node_server_utils34.logger.info(
6355
+ `Area ${area.name} (${areaId}): Schedule task ${scheduleTask._id} already processed (atomic check), skipping.`
6021
6356
  );
6022
6357
  }
6023
6358
  } else {
6359
+ const areaSetConfig = Number(areaDetails.set) || 1;
6360
+ const schedTaskId = scheduleTask._id;
6361
+ const schedTaskSets = Array.from(
6362
+ { length: areaSetConfig },
6363
+ (_, index) => ({
6364
+ set: index + 1,
6365
+ units,
6366
+ isScheduleTask: true,
6367
+ scheduleTaskId: schedTaskId
6368
+ })
6369
+ );
6024
6370
  const checklistData = {
6025
6371
  schedule: parentChecklistId.toString(),
6026
6372
  area: areaId,
6027
6373
  name: area.name,
6028
6374
  type: areaDetails.type || "common",
6029
- checklist: [
6030
- {
6031
- set: 1,
6032
- units
6033
- }
6034
- ],
6375
+ checklist: schedTaskSets,
6035
6376
  createdBy: scheduleTask.createdBy
6036
6377
  };
6037
6378
  import_node_server_utils34.logger.info(
6038
- `Area ${area.name} (${areaId}): Creating new area checklist with data: ${JSON.stringify(
6039
- checklistData
6040
- )}`
6379
+ `Area ${area.name} (${areaId}): Creating new area checklist with schedule-task sets only`
6041
6380
  );
6042
6381
  await createAreaChecklist(checklistData);
6043
6382
  import_node_server_utils34.logger.info(`Created new area checklist for area ${area.name}`);
6044
- try {
6045
- const verifyChecklist = await getAreaChecklistByAreaAndSchedule(
6046
- parentChecklistId.toString(),
6047
- areaId
6048
- );
6049
- import_node_server_utils34.logger.info(
6050
- `Area ${area.name} (${areaId}): Checklist after creation: ${JSON.stringify(
6051
- verifyChecklist.checklist
6052
- )}`
6053
- );
6054
- } catch (verifyError) {
6055
- import_node_server_utils34.logger.warn(
6056
- `Area ${area.name} (${areaId}): Error verifying checklist after creation:`,
6057
- verifyError
6058
- );
6059
- }
6060
6383
  }
6061
6384
  } catch (error) {
6062
6385
  import_node_server_utils34.logger.error(`Error processing area ${area.name}:`, error);