This commit is contained in:
Alex Holliday committed 2026-02-21 03:43:11 +00:00
1 parent 673f47983a
commit f94afb63c6
5 files changed
+53 -22

No files matched your search

+12 -14
View File
@@ -23,6 +23,7 @@ import {
parseMonitorTypeFilter,
parseSortOrder,
requireTeamId,
requireUserId,
} from "./controllerUtils.js";
import { AppError } from "@/utils/AppError.js";
import { IMonitorService } from "@/service/index.js";
@@ -172,26 +173,23 @@ class MonitorController {
}
};
// TODO rename to Import, change to accept JSON
createBulkMonitors = async (req: Request, res: Response, next: NextFunction) => {
importMonitorsFromJSON = async (req: Request, res: Response, next: NextFunction) => {
try {
const userId = req.user?.id; // TODO use the correct helper function
if (!userId) {
throw new AppError({ message: "User ID is required", status: 400 });
const teamId = requireTeamId(req?.user?.teamId);
const userId = requireUserId(req?.user?.id);
const { monitors } = req.body;
if (!monitors || !Array.isArray(monitors)) {
throw new AppError({ message: "Invalid request: monitors array is required", status: 400 });
}
const teamId = requireTeamId(req?.user?.teamId);
const data = req.body;
// TODO extract JSON, validate?
const monitors = await this.monitorService.createBulkMonitors(data, userId, teamId);
const result = await this.monitorService.importMonitorsFromJSON({ teamId, userId, monitors });
return res.status(200).json({
success: true,
msg: "Bulk monitors created successfully",
data: monitors,
msg: `Successfully imported ${result.imported} monitor(s)`,
data: result,
});
} catch (error) {
next(error);
@@ -17,7 +17,6 @@ export interface SummaryConfig {
export interface IMonitorsRepository {
// create
create(monitor: Monitor, teamId: string, userId: string): Promise<Monitor | null>;
// TODO rename createMonitors
createBulkMonitors(monitors: Monitor[]): Promise<Monitor[]>;
// single fetch
findById(monitorId: string, teamId: string): Promise<Monitor>;
@@ -12,7 +12,6 @@ class MongoMonitorsRepository implements IMonitorsRepository {
return this.toEntity(saved);
};
// TODO rename to createMonitors, must accept JSON
createBulkMonitors = async (monitors: Monitor[]): Promise<Monitor[]> => {
if (!monitors.length) {
return [];
+1 -4
View File
@@ -45,10 +45,7 @@ class MonitorRoutes {
// Other static routes
this.router.post("/demo", isAllowed(["admin", "superadmin"]), this.monitorController.addDemoMonitors);
this.router.get("/export/json", isAllowed(["admin", "superadmin"]), this.monitorController.exportMonitorsToJSON);
// TODO this needs to be modified to accept JSON, change to /import
this.router.post("/bulk", isAllowed(["admin", "superadmin"]), upload.single("csvFile"), this.monitorController.createBulkMonitors);
// END TODO
this.router.post("/import/json", isAllowed(["admin", "superadmin"]), this.monitorController.importMonitorsFromJSON);
this.router.post("/test-email", isAllowed(["admin", "superadmin"]), this.monitorController.sendTestEmail);
this.router.get("/games", this.monitorController.getAllGames);
+40 -2
View File
@@ -29,8 +29,6 @@ export interface IMonitorService {
// create
createMonitor(teamId: string, userId: string, body: Monitor): Promise<void>;
// TODO rename createMonitors
createBulkMonitors(monitors: Array<Monitor>, userId: string, teamId: string): Promise<Monitor[] | null>;
addDemoMonitors(args: { userId: string; teamId: string }): Promise<Monitor[]>;
// read
@@ -73,6 +71,7 @@ export interface IMonitorService {
// other
sendTestEmail(args: { to: string }): Promise<string>;
exportMonitorsToJSON(args: { teamId: string }): Promise<Monitor[]>;
importMonitorsFromJSON(args: { teamId: string; userId: string; monitors: any[] }): Promise<{ imported: number; errors: string[] }>;
}
export class MonitorService implements IMonitorService {
@@ -488,4 +487,43 @@ export class MonitorService implements IMonitorService {
return monitors;
};
importMonitorsFromJSON = async ({
teamId,
userId,
monitors,
}: {
teamId: string;
userId: string;
monitors: any[];
}): Promise<{ imported: number; errors: string[] }> => {
const errors: string[] = [];
// Clean the data: remove id, _id, createdAt, updatedAt, recentChecks fields
const cleanedMonitors = monitors.map((monitor) => {
const cleanData = { ...monitor };
delete cleanData.id;
delete cleanData._id;
delete cleanData.createdAt;
delete cleanData.updatedAt;
delete cleanData.recentChecks;
// Force the monitor to belong to the current team
cleanData.teamId = teamId;
return cleanData;
});
// Use createBulkMonitors for efficient bulk insert
const createdMonitors = await this.createBulkMonitors(cleanedMonitors, userId, teamId);
if (!createdMonitors || createdMonitors.length === 0) {
throw new AppError({
message: "Failed to import any monitors. Please check the file format and try again.",
service: SERVICE_NAME,
method: "importMonitorsFromJSON",
status: 400,
});
}
return { imported: createdMonitors.length, errors };
};
}