@7365admin1/module-hygiene 4.24.0 → 4.24.1
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/CHANGELOG.md +6 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +161 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +161 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2473,7 +2473,8 @@ import { AppServiceType as AppServiceType6 } from "@7365admin1/core";
|
|
|
2473
2473
|
var parentChecklistSchema = Joi6.object({
|
|
2474
2474
|
createdAt: Joi6.alternatives().try(Joi6.date(), Joi6.string()).optional().allow("", null),
|
|
2475
2475
|
site: Joi6.string().hex().required(),
|
|
2476
|
-
serviceType: Joi6.string().valid(...Object.values(AppServiceType6)).required()
|
|
2476
|
+
serviceType: Joi6.string().valid(...Object.values(AppServiceType6)).required(),
|
|
2477
|
+
dateStr: Joi6.string().optional().allow("", null)
|
|
2477
2478
|
});
|
|
2478
2479
|
function MParentChecklist(value) {
|
|
2479
2480
|
const { error } = parentChecklistSchema.validate(value);
|
|
@@ -2488,18 +2489,22 @@ function MParentChecklist(value) {
|
|
|
2488
2489
|
throw new BadRequestError11(`Invalid site ID format: ${value.site}`);
|
|
2489
2490
|
}
|
|
2490
2491
|
}
|
|
2492
|
+
const currentDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
2493
|
+
const sgOffset = 8 * 60 * 60 * 1e3;
|
|
2494
|
+
const sgTime = new Date(currentDate.getTime() + sgOffset);
|
|
2495
|
+
const dateStr = `${sgTime.getUTCFullYear()}-${String(sgTime.getUTCMonth() + 1).padStart(2, "0")}-${String(sgTime.getUTCDate()).padStart(2, "0")}`;
|
|
2491
2496
|
return {
|
|
2492
2497
|
site: value.site,
|
|
2493
2498
|
serviceType: value.serviceType,
|
|
2494
2499
|
status: "open",
|
|
2495
|
-
createdAt:
|
|
2496
|
-
updatedAt: value.updatedAt ?? ""
|
|
2500
|
+
createdAt: currentDate,
|
|
2501
|
+
updatedAt: value.updatedAt ?? "",
|
|
2502
|
+
dateStr
|
|
2497
2503
|
};
|
|
2498
2504
|
}
|
|
2499
2505
|
|
|
2500
2506
|
// src/repositories/hygiene-parent-checklist.repository.ts
|
|
2501
2507
|
import { ObjectId as ObjectId7 } from "mongodb";
|
|
2502
|
-
import moment2 from "moment-timezone";
|
|
2503
2508
|
import {
|
|
2504
2509
|
useAtlas as useAtlas5,
|
|
2505
2510
|
InternalServerError as InternalServerError4,
|
|
@@ -2522,13 +2527,55 @@ function useParentChecklistRepo() {
|
|
|
2522
2527
|
const { delNamespace, setCache, getCache } = useCache4(namespace_collection);
|
|
2523
2528
|
async function createIndex() {
|
|
2524
2529
|
try {
|
|
2530
|
+
await collection.updateMany(
|
|
2531
|
+
{ dateStr: { $exists: false } },
|
|
2532
|
+
[
|
|
2533
|
+
{
|
|
2534
|
+
$set: {
|
|
2535
|
+
dateStr: {
|
|
2536
|
+
$let: {
|
|
2537
|
+
vars: {
|
|
2538
|
+
sgTime: { $add: ["$createdAt", 8 * 60 * 60 * 1e3] }
|
|
2539
|
+
},
|
|
2540
|
+
in: {
|
|
2541
|
+
$dateToString: {
|
|
2542
|
+
format: "%Y-%m-%d",
|
|
2543
|
+
date: "$$sgTime",
|
|
2544
|
+
timezone: "UTC"
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
]
|
|
2552
|
+
);
|
|
2553
|
+
const duplicates = await collection.aggregate([
|
|
2554
|
+
{
|
|
2555
|
+
$group: {
|
|
2556
|
+
_id: { site: "$site", serviceType: "$serviceType", dateStr: "$dateStr" },
|
|
2557
|
+
docs: { $push: "$_id" },
|
|
2558
|
+
count: { $sum: 1 }
|
|
2559
|
+
}
|
|
2560
|
+
},
|
|
2561
|
+
{ $match: { count: { $gt: 1 } } }
|
|
2562
|
+
]).toArray();
|
|
2563
|
+
for (const group of duplicates) {
|
|
2564
|
+
const toDelete = group.docs.slice(1);
|
|
2565
|
+
await collection.deleteMany({ _id: { $in: toDelete } });
|
|
2566
|
+
logger14.info(
|
|
2567
|
+
`Deleted ${toDelete.length} duplicate parent checklists for site ${group._id.site} / ${group._id.serviceType} on date ${group._id.dateStr}`
|
|
2568
|
+
);
|
|
2569
|
+
}
|
|
2525
2570
|
await collection.createIndexes([
|
|
2526
2571
|
{ key: { serviceType: 1 } },
|
|
2527
2572
|
{ key: { createdAt: 1 } },
|
|
2528
2573
|
{ key: { site: 1 } },
|
|
2529
|
-
{ key: { status: 1 } }
|
|
2574
|
+
{ key: { status: 1 } },
|
|
2575
|
+
{ key: { site: 1, serviceType: 1, dateStr: 1 }, unique: true }
|
|
2530
2576
|
]);
|
|
2531
2577
|
} catch (error) {
|
|
2578
|
+
logger14.error("Failed to create index/backfill on hygiene parent checklist:", error);
|
|
2532
2579
|
throw new InternalServerError4(
|
|
2533
2580
|
"Failed to create index on hygiene parent checklist."
|
|
2534
2581
|
);
|
|
@@ -2537,10 +2584,13 @@ function useParentChecklistRepo() {
|
|
|
2537
2584
|
async function createParentChecklist(value, session) {
|
|
2538
2585
|
try {
|
|
2539
2586
|
const currentDate = value.createdAt ? new Date(value.createdAt) : /* @__PURE__ */ new Date();
|
|
2540
|
-
const
|
|
2541
|
-
const
|
|
2587
|
+
const sgOffset = 8 * 60 * 60 * 1e3;
|
|
2588
|
+
const sgTime = new Date(currentDate.getTime() + sgOffset);
|
|
2589
|
+
const startOfDay = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 0, 0, 0, 0) - sgOffset);
|
|
2590
|
+
const endOfDay = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 23, 59, 59, 999) - sgOffset);
|
|
2591
|
+
const targetDateStr = `${sgTime.getUTCFullYear()}-${String(sgTime.getUTCMonth() + 1).padStart(2, "0")}-${String(sgTime.getUTCDate()).padStart(2, "0")}`;
|
|
2592
|
+
const dateStr = targetDateStr;
|
|
2542
2593
|
const allServiceTypes = Object.values(AppServiceType7);
|
|
2543
|
-
const dateStr = currentDate.toISOString().split("T")[0];
|
|
2544
2594
|
if (value.site) {
|
|
2545
2595
|
let siteObjectId;
|
|
2546
2596
|
try {
|
|
@@ -2550,9 +2600,12 @@ function useParentChecklistRepo() {
|
|
|
2550
2600
|
}
|
|
2551
2601
|
if (value.serviceType) {
|
|
2552
2602
|
const existingChecklist = await collection.findOne({
|
|
2553
|
-
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2554
2603
|
site: siteObjectId,
|
|
2555
|
-
serviceType: value.serviceType
|
|
2604
|
+
serviceType: value.serviceType,
|
|
2605
|
+
$or: [
|
|
2606
|
+
{ dateStr: targetDateStr },
|
|
2607
|
+
{ createdAt: { $gte: startOfDay, $lte: endOfDay } }
|
|
2608
|
+
]
|
|
2556
2609
|
});
|
|
2557
2610
|
if (existingChecklist) {
|
|
2558
2611
|
logger14.info(
|
|
@@ -2565,22 +2618,41 @@ function useParentChecklistRepo() {
|
|
|
2565
2618
|
createdAt: currentDate,
|
|
2566
2619
|
serviceType: value.serviceType
|
|
2567
2620
|
});
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2621
|
+
let insertedId;
|
|
2622
|
+
try {
|
|
2623
|
+
const result = await collection.insertOne(doc, { session });
|
|
2624
|
+
insertedId = result.insertedId;
|
|
2625
|
+
delNamespace().catch((err) => {
|
|
2626
|
+
logger14.error(
|
|
2627
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2628
|
+
err
|
|
2629
|
+
);
|
|
2630
|
+
});
|
|
2631
|
+
logger14.info(
|
|
2632
|
+
`Created parent checklist for site ${value.site} / ${value.serviceType} for today: ${dateStr}`
|
|
2573
2633
|
);
|
|
2574
|
-
})
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2634
|
+
} catch (error) {
|
|
2635
|
+
if (error.code === 11e3) {
|
|
2636
|
+
const existingChecklist2 = await collection.findOne({
|
|
2637
|
+
site: siteObjectId,
|
|
2638
|
+
serviceType: value.serviceType,
|
|
2639
|
+
dateStr: targetDateStr
|
|
2640
|
+
});
|
|
2641
|
+
if (existingChecklist2) {
|
|
2642
|
+
return existingChecklist2._id;
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
throw error;
|
|
2646
|
+
}
|
|
2647
|
+
return insertedId;
|
|
2579
2648
|
}
|
|
2580
2649
|
const existingServiceTypes = await collection.distinct("serviceType", {
|
|
2581
|
-
createdAt: { $gte: startOfDay, $lte: endOfDay },
|
|
2582
2650
|
site: siteObjectId,
|
|
2583
|
-
serviceType: { $exists: true, $ne: null }
|
|
2651
|
+
serviceType: { $exists: true, $ne: null },
|
|
2652
|
+
$or: [
|
|
2653
|
+
{ dateStr: targetDateStr },
|
|
2654
|
+
{ createdAt: { $gte: startOfDay, $lte: endOfDay } }
|
|
2655
|
+
]
|
|
2584
2656
|
});
|
|
2585
2657
|
const missingServiceTypes = allServiceTypes.filter(
|
|
2586
2658
|
(st) => !existingServiceTypes.includes(st)
|
|
@@ -2590,8 +2662,11 @@ function useParentChecklistRepo() {
|
|
|
2590
2662
|
`All serviceType checklists already exist for site ${value.site} on ${dateStr}`
|
|
2591
2663
|
);
|
|
2592
2664
|
const first = await collection.findOne({
|
|
2593
|
-
|
|
2594
|
-
|
|
2665
|
+
site: siteObjectId,
|
|
2666
|
+
$or: [
|
|
2667
|
+
{ dateStr: targetDateStr },
|
|
2668
|
+
{ createdAt: { $gte: startOfDay, $lte: endOfDay } }
|
|
2669
|
+
]
|
|
2595
2670
|
});
|
|
2596
2671
|
return first._id;
|
|
2597
2672
|
}
|
|
@@ -2602,17 +2677,30 @@ function useParentChecklistRepo() {
|
|
|
2602
2677
|
serviceType
|
|
2603
2678
|
})
|
|
2604
2679
|
);
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2680
|
+
let insertedIds2 = [];
|
|
2681
|
+
try {
|
|
2682
|
+
const result = await collection.insertMany(checklistDocs2, { session, ordered: false });
|
|
2683
|
+
insertedIds2 = Object.values(result.insertedIds);
|
|
2684
|
+
delNamespace().catch((err) => {
|
|
2685
|
+
logger14.error(
|
|
2686
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2687
|
+
err
|
|
2688
|
+
);
|
|
2689
|
+
});
|
|
2690
|
+
logger14.info(
|
|
2691
|
+
`Created ${checklistDocs2.length} parent checklists for site ${value.site} for today: ${dateStr}`
|
|
2610
2692
|
);
|
|
2611
|
-
})
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2693
|
+
} catch (error) {
|
|
2694
|
+
if (error.code === 11e3 || error.writeErrors) {
|
|
2695
|
+
const existing = await collection.find({
|
|
2696
|
+
site: siteObjectId,
|
|
2697
|
+
dateStr: targetDateStr
|
|
2698
|
+
}).toArray();
|
|
2699
|
+
return existing.map((e) => e._id);
|
|
2700
|
+
}
|
|
2701
|
+
throw error;
|
|
2702
|
+
}
|
|
2703
|
+
return insertedIds2;
|
|
2616
2704
|
}
|
|
2617
2705
|
const siteIds = await getHygieneSiteIds();
|
|
2618
2706
|
if (!Array.isArray(siteIds)) {
|
|
@@ -2625,8 +2713,11 @@ function useParentChecklistRepo() {
|
|
|
2625
2713
|
}
|
|
2626
2714
|
const existingPairs = await collection.find(
|
|
2627
2715
|
{
|
|
2628
|
-
|
|
2629
|
-
|
|
2716
|
+
serviceType: { $exists: true, $ne: null },
|
|
2717
|
+
$or: [
|
|
2718
|
+
{ dateStr: targetDateStr },
|
|
2719
|
+
{ createdAt: { $gte: startOfDay, $lte: endOfDay } }
|
|
2720
|
+
]
|
|
2630
2721
|
},
|
|
2631
2722
|
{ projection: { site: 1, serviceType: 1 } }
|
|
2632
2723
|
).toArray();
|
|
@@ -2658,19 +2749,31 @@ function useParentChecklistRepo() {
|
|
|
2658
2749
|
logger14.info(
|
|
2659
2750
|
`createParentChecklist: Creating ${checklistDocs.length} missing site+serviceType checklist(s) for today: ${dateStr}`
|
|
2660
2751
|
);
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
`
|
|
2667
|
-
|
|
2752
|
+
let insertedIds = [];
|
|
2753
|
+
try {
|
|
2754
|
+
const result = await collection.insertMany(checklistDocs, { session, ordered: false });
|
|
2755
|
+
insertedIds = Object.values(result.insertedIds);
|
|
2756
|
+
delNamespace().then(() => {
|
|
2757
|
+
logger14.info(`Cache cleared for namespace: ${namespace_collection}`);
|
|
2758
|
+
}).catch((err) => {
|
|
2759
|
+
logger14.error(
|
|
2760
|
+
`Failed to clear cache for namespace: ${namespace_collection}`,
|
|
2761
|
+
err
|
|
2762
|
+
);
|
|
2763
|
+
});
|
|
2764
|
+
logger14.info(
|
|
2765
|
+
`Created ${Object.keys(result.insertedIds).length} parent checklists for today: ${dateStr}`
|
|
2668
2766
|
);
|
|
2669
|
-
})
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2767
|
+
} catch (error) {
|
|
2768
|
+
if (error.code === 11e3 || error.writeErrors) {
|
|
2769
|
+
const existing = await collection.find({
|
|
2770
|
+
dateStr: targetDateStr
|
|
2771
|
+
}).toArray();
|
|
2772
|
+
return existing.map((e) => e._id);
|
|
2773
|
+
}
|
|
2774
|
+
throw error;
|
|
2775
|
+
}
|
|
2776
|
+
return insertedIds;
|
|
2674
2777
|
} catch (error) {
|
|
2675
2778
|
logger14.error("Failed to create daily parent checklist", error);
|
|
2676
2779
|
throw error;
|
|
@@ -2889,8 +2992,11 @@ function useParentChecklistRepo() {
|
|
|
2889
2992
|
}
|
|
2890
2993
|
}
|
|
2891
2994
|
async function getTodayParentChecklists() {
|
|
2892
|
-
const
|
|
2893
|
-
const
|
|
2995
|
+
const sgOffset = 8 * 60 * 60 * 1e3;
|
|
2996
|
+
const now = /* @__PURE__ */ new Date();
|
|
2997
|
+
const sgTime = new Date(now.getTime() + sgOffset);
|
|
2998
|
+
const start = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 0, 0, 0, 0) - sgOffset);
|
|
2999
|
+
const end = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 23, 59, 59, 999) - sgOffset);
|
|
2894
3000
|
try {
|
|
2895
3001
|
const items = await collection.find(
|
|
2896
3002
|
{ createdAt: { $gte: start, $lte: end } },
|
|
@@ -2903,8 +3009,11 @@ function useParentChecklistRepo() {
|
|
|
2903
3009
|
}
|
|
2904
3010
|
}
|
|
2905
3011
|
async function getTodayParentChecklistsForAreaGen() {
|
|
2906
|
-
const
|
|
2907
|
-
const
|
|
3012
|
+
const sgOffset = 8 * 60 * 60 * 1e3;
|
|
3013
|
+
const now = /* @__PURE__ */ new Date();
|
|
3014
|
+
const sgTime = new Date(now.getTime() + sgOffset);
|
|
3015
|
+
const start = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 0, 0, 0, 0) - sgOffset);
|
|
3016
|
+
const end = new Date(Date.UTC(sgTime.getUTCFullYear(), sgTime.getUTCMonth(), sgTime.getUTCDate(), 23, 59, 59, 999) - sgOffset);
|
|
2908
3017
|
try {
|
|
2909
3018
|
const items = await collection.find(
|
|
2910
3019
|
{
|