implement remaining check methods
This commit is contained in:
1 parent
9af25a19e5
commit
27dea6a08e
8 files changed
+138
-339
No files matched your search
@@ -1,247 +0,0 @@
|
||||
import { ObjectId } from "mongodb";
|
||||
import mongoose from "mongoose";
|
||||
import { CheckModel } from "@/db/models/index.js";
|
||||
import { buildChecksSummaryByTeamIdPipeline } from "./checkModuleQueries.js";
|
||||
|
||||
const SERVICE_NAME = "checkModule";
|
||||
const dateRangeLookup = {
|
||||
recent: new Date(new Date().setDate(new Date().getDate() - 2)),
|
||||
hour: new Date(new Date().setHours(new Date().getHours() - 1)),
|
||||
day: new Date(new Date().setDate(new Date().getDate() - 1)),
|
||||
week: new Date(new Date().setDate(new Date().getDate() - 7)),
|
||||
month: new Date(new Date().setMonth(new Date().getMonth() - 1)),
|
||||
all: undefined,
|
||||
};
|
||||
|
||||
class CheckModule {
|
||||
constructor({ logger, Monitor, User }) {
|
||||
this.logger = logger;
|
||||
this.Monitor = Monitor;
|
||||
this.User = User;
|
||||
}
|
||||
|
||||
getChecksByMonitor = async ({ monitorId, sortOrder, dateRange, filter, page, rowsPerPage, status }) => {
|
||||
try {
|
||||
status = status === "true" ? true : status === "false" ? false : undefined;
|
||||
page = parseInt(page);
|
||||
rowsPerPage = parseInt(rowsPerPage);
|
||||
|
||||
// Match
|
||||
const matchStage = {
|
||||
"metadata.monitorId": new ObjectId(monitorId),
|
||||
...(typeof status !== "undefined" && { status }),
|
||||
...(dateRangeLookup[dateRange] && {
|
||||
createdAt: {
|
||||
$gte: dateRangeLookup[dateRange],
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
if (filter !== undefined) {
|
||||
switch (filter) {
|
||||
case "all":
|
||||
break;
|
||||
case "down":
|
||||
break;
|
||||
case "resolve":
|
||||
matchStage.statusCode = 5000;
|
||||
break;
|
||||
default:
|
||||
this.logger.warn({
|
||||
message: "invalid filter",
|
||||
service: SERVICE_NAME,
|
||||
method: "getChecks",
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Sort
|
||||
sortOrder = sortOrder === "asc" ? 1 : -1;
|
||||
|
||||
// Pagination
|
||||
let skip = 0;
|
||||
if (page && rowsPerPage) {
|
||||
skip = page * rowsPerPage;
|
||||
}
|
||||
|
||||
const checks = await CheckModel.aggregate([
|
||||
{ $match: matchStage },
|
||||
{ $sort: { createdAt: sortOrder } },
|
||||
{
|
||||
$facet: {
|
||||
summary: [{ $count: "checksCount" }],
|
||||
checks: [{ $skip: skip }, { $limit: rowsPerPage }],
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
checksCount: {
|
||||
$ifNull: [{ $arrayElemAt: ["$summary.checksCount", 0] }, 0],
|
||||
},
|
||||
checks: {
|
||||
$ifNull: ["$checks", []],
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
return checks[0];
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "getChecks";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getChecksByTeam = async ({ sortOrder, dateRange, filter, page, rowsPerPage, teamId }) => {
|
||||
try {
|
||||
console.log({
|
||||
sortOrder,
|
||||
dateRange,
|
||||
filter,
|
||||
page,
|
||||
rowsPerPage,
|
||||
teamId,
|
||||
});
|
||||
page = parseInt(page);
|
||||
rowsPerPage = parseInt(rowsPerPage);
|
||||
|
||||
const matchStage = {
|
||||
"metadata.teamId": new ObjectId(teamId),
|
||||
status: false,
|
||||
...(dateRangeLookup[dateRange] && {
|
||||
createdAt: {
|
||||
$gte: dateRangeLookup[dateRange],
|
||||
},
|
||||
}),
|
||||
};
|
||||
// Add filter to match stage
|
||||
if (filter !== undefined) {
|
||||
switch (filter) {
|
||||
case "all":
|
||||
break;
|
||||
case "down":
|
||||
break;
|
||||
case "resolve":
|
||||
matchStage.statusCode = 5000;
|
||||
break;
|
||||
default:
|
||||
this.logger.warn({
|
||||
message: "invalid filter",
|
||||
service: SERVICE_NAME,
|
||||
method: "getChecksByTeam",
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sortOrder = sortOrder === "asc" ? 1 : -1;
|
||||
|
||||
// pagination
|
||||
let skip = 0;
|
||||
if (page && rowsPerPage) {
|
||||
skip = page * rowsPerPage;
|
||||
}
|
||||
|
||||
const aggregatePipeline = [
|
||||
{ $match: matchStage },
|
||||
|
||||
{ $sort: { createdAt: sortOrder } },
|
||||
{
|
||||
$facet: {
|
||||
summary: [{ $count: "checksCount" }],
|
||||
checks: [{ $skip: skip }, { $limit: rowsPerPage }],
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
checksCount: { $arrayElemAt: ["$summary.checksCount", 0] },
|
||||
checks: "$checks",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const checks = await CheckModel.aggregate(aggregatePipeline);
|
||||
return checks[0];
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "getChecksByTeam";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
getChecksSummaryByTeamId = async ({ teamId }) => {
|
||||
try {
|
||||
const matchStage = {
|
||||
"metadata.teamId": new ObjectId(teamId),
|
||||
};
|
||||
const checks = await CheckModel.aggregate(buildChecksSummaryByTeamIdPipeline({ matchStage }));
|
||||
return checks[0].summary;
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "getChecksSummaryByTeamId";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
deleteChecks = async (monitorId) => {
|
||||
try {
|
||||
const result = await CheckModel.deleteMany({ "metadata.monitorId": monitorId });
|
||||
return result.deletedCount;
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "deleteChecks";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteChecksByTeamId = async (teamId) => {
|
||||
try {
|
||||
// Find all monitor IDs for this team (only get _id field for efficiency)
|
||||
const teamMonitors = await this.Monitor.find({ teamId }, { _id: 1 });
|
||||
const monitorIds = teamMonitors.map((monitor) => monitor._id);
|
||||
|
||||
// Delete all checks for these monitors in one operation
|
||||
const deleteResult = await CheckModel.deleteMany({ "metadata.monitorId": { $in: monitorIds } });
|
||||
|
||||
return deleteResult.deletedCount;
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "deleteChecksByTeamId";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateChecksTTL = async (teamId, ttl) => {
|
||||
try {
|
||||
await CheckModel.collection.dropIndex("expiry_1");
|
||||
} catch (error) {
|
||||
this.logger.error({
|
||||
message: error.message,
|
||||
service: SERVICE_NAME,
|
||||
method: "updateChecksTTL",
|
||||
stack: error.stack,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await CheckModel.collection.createIndex(
|
||||
{ expiry: 1 },
|
||||
{ expireAfterSeconds: ttl, partialFilterExpression: { "metadata.mode": { $exists: true } } }
|
||||
);
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "updateChecksTTL";
|
||||
throw error;
|
||||
}
|
||||
// Update user
|
||||
try {
|
||||
await this.User.updateMany({ teamId: teamId }, { checkTTL: ttl });
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "updateChecksTTL";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default CheckModule;
|
||||
@@ -1,44 +0,0 @@
|
||||
const buildChecksSummaryByTeamIdPipeline = ({ matchStage }) => {
|
||||
return [
|
||||
{ $match: matchStage },
|
||||
{
|
||||
$facet: {
|
||||
summary: [
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalChecks: { $sum: { $cond: [{ $eq: ["$status", false] }, 1, 0] } },
|
||||
resolvedChecks: {
|
||||
$sum: {
|
||||
$cond: [{ $and: [{ $eq: ["$ack", true] }, { $eq: ["$status", false] }] }, 1, 0],
|
||||
},
|
||||
},
|
||||
downChecks: {
|
||||
$sum: {
|
||||
$cond: [{ $and: [{ $eq: ["$ack", false] }, { $eq: ["$status", false] }] }, 1, 0],
|
||||
},
|
||||
},
|
||||
cannotResolveChecks: {
|
||||
$sum: {
|
||||
$cond: [{ $eq: ["$statusCode", 5000] }, 1, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
_id: 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
$project: {
|
||||
summary: { $arrayElemAt: ["$summary", 0] },
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export { buildChecksSummaryByTeamIdPipeline };
|
||||
Reference in new issue
Block a user