mirror of
https://github.com/nicotsx/zerobyte.git
synced 2026-04-17 21:37:06 -04:00
* refactor: extract restic in core package * chore: add turbo task runner * refactor: split server utils * chore: simplify withDeps signature and fix non-null assertion
174 lines
6.6 KiB
TypeScript
174 lines
6.6 KiB
TypeScript
import { Hono } from "hono";
|
|
import { validator } from "hono-openapi";
|
|
import {
|
|
createBackupScheduleBody,
|
|
createBackupScheduleDto,
|
|
deleteBackupScheduleDto,
|
|
getBackupScheduleDto,
|
|
getBackupScheduleForVolumeDto,
|
|
listBackupSchedulesDto,
|
|
runBackupNowDto,
|
|
runForgetDto,
|
|
stopBackupDto,
|
|
updateBackupScheduleDto,
|
|
updateBackupScheduleBody,
|
|
getScheduleMirrorsDto,
|
|
updateScheduleMirrorsDto,
|
|
updateScheduleMirrorsBody,
|
|
getMirrorCompatibilityDto,
|
|
reorderBackupSchedulesDto,
|
|
reorderBackupSchedulesBody,
|
|
getBackupProgressDto,
|
|
type CreateBackupScheduleDto,
|
|
type DeleteBackupScheduleDto,
|
|
type GetBackupScheduleDto,
|
|
type GetBackupScheduleForVolumeResponseDto,
|
|
type ListBackupSchedulesResponseDto,
|
|
type RunBackupNowDto,
|
|
type RunForgetDto,
|
|
type StopBackupDto,
|
|
type UpdateBackupScheduleDto,
|
|
type GetScheduleMirrorsDto,
|
|
type UpdateScheduleMirrorsDto,
|
|
type GetMirrorCompatibilityDto,
|
|
type ReorderBackupSchedulesDto,
|
|
type GetBackupProgressDto,
|
|
} from "./backups.dto";
|
|
import { backupsService } from "./backups.service";
|
|
import {
|
|
getScheduleNotificationsDto,
|
|
updateScheduleNotificationsBody,
|
|
updateScheduleNotificationsDto,
|
|
type GetScheduleNotificationsDto,
|
|
type UpdateScheduleNotificationsDto,
|
|
} from "../notifications/notifications.dto";
|
|
import { notificationsService } from "../notifications/notifications.service";
|
|
import { requireAuth } from "../auth/auth.middleware";
|
|
import { backupsExecutionService } from "./backups.execution";
|
|
import { logger } from "@zerobyte/core/node";
|
|
import { asShortId } from "~/server/utils/branded";
|
|
|
|
export const backupScheduleController = new Hono()
|
|
.use(requireAuth)
|
|
.get("/", listBackupSchedulesDto, async (c) => {
|
|
const schedules = await backupsService.listSchedules();
|
|
|
|
return c.json<ListBackupSchedulesResponseDto>(schedules, 200);
|
|
})
|
|
.get("/:shortId", getBackupScheduleDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
|
|
return c.json<GetBackupScheduleDto>(schedule, 200);
|
|
})
|
|
.get("/volume/:volumeShortId", getBackupScheduleForVolumeDto, async (c) => {
|
|
const volumeShortId = asShortId(c.req.param("volumeShortId"));
|
|
const schedule = await backupsService.getScheduleForVolume(volumeShortId);
|
|
|
|
return c.json<GetBackupScheduleForVolumeResponseDto>(schedule, 200);
|
|
})
|
|
.post("/", createBackupScheduleDto, validator("json", createBackupScheduleBody), async (c) => {
|
|
const body = c.req.valid("json");
|
|
const schedule = await backupsService.createSchedule(body);
|
|
|
|
return c.json<CreateBackupScheduleDto>(schedule, 201);
|
|
})
|
|
.patch("/:shortId", updateBackupScheduleDto, validator("json", updateBackupScheduleBody), async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const body = c.req.valid("json");
|
|
const schedule = await backupsService.updateSchedule(shortId, body);
|
|
|
|
return c.json<UpdateBackupScheduleDto>(schedule, 200);
|
|
})
|
|
.delete("/:shortId", deleteBackupScheduleDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
await backupsService.deleteSchedule(shortId);
|
|
|
|
return c.json<DeleteBackupScheduleDto>({ success: true }, 200);
|
|
})
|
|
.post("/:shortId/run", runBackupNowDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
const result = await backupsExecutionService.validateBackupExecution(schedule.id, true);
|
|
|
|
if (result.type === "failure") {
|
|
throw result.error;
|
|
}
|
|
|
|
if (result.type === "skipped") {
|
|
return c.json<RunBackupNowDto>({ success: true }, 200);
|
|
}
|
|
|
|
backupsExecutionService.executeBackup(schedule.id, true).catch((err) => {
|
|
logger.error(`Error executing manual backup for schedule ${shortId}:`, err);
|
|
});
|
|
|
|
return c.json<RunBackupNowDto>({ success: true }, 200);
|
|
})
|
|
.post("/:shortId/stop", stopBackupDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
await backupsExecutionService.stopBackup(schedule.id);
|
|
|
|
return c.json<StopBackupDto>({ success: true }, 200);
|
|
})
|
|
.post("/:shortId/forget", runForgetDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
await backupsExecutionService.runForget(schedule.id);
|
|
|
|
return c.json<RunForgetDto>({ success: true }, 200);
|
|
})
|
|
.get("/:shortId/notifications", getScheduleNotificationsDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
const assignments = await notificationsService.getScheduleNotifications(schedule.id);
|
|
|
|
return c.json<GetScheduleNotificationsDto>(assignments, 200);
|
|
})
|
|
.put(
|
|
"/:shortId/notifications",
|
|
updateScheduleNotificationsDto,
|
|
validator("json", updateScheduleNotificationsBody),
|
|
async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
const body = c.req.valid("json");
|
|
const assignments = await notificationsService.updateScheduleNotifications(schedule.id, body.assignments);
|
|
|
|
return c.json<UpdateScheduleNotificationsDto>(assignments, 200);
|
|
},
|
|
)
|
|
.get("/:shortId/mirrors", getScheduleMirrorsDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const mirrors = await backupsService.getMirrors(shortId);
|
|
|
|
return c.json<GetScheduleMirrorsDto>(mirrors, 200);
|
|
})
|
|
.put("/:shortId/mirrors", updateScheduleMirrorsDto, validator("json", updateScheduleMirrorsBody), async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const body = c.req.valid("json");
|
|
const mirrors = await backupsService.updateMirrors(shortId, body);
|
|
|
|
return c.json<UpdateScheduleMirrorsDto>(mirrors, 200);
|
|
})
|
|
.get("/:shortId/mirrors/compatibility", getMirrorCompatibilityDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const compatibility = await backupsService.getMirrorCompatibility(shortId);
|
|
|
|
return c.json<GetMirrorCompatibilityDto>(compatibility, 200);
|
|
})
|
|
.post("/reorder", reorderBackupSchedulesDto, validator("json", reorderBackupSchedulesBody), async (c) => {
|
|
const body = c.req.valid("json");
|
|
await backupsService.reorderSchedules(body.scheduleShortIds.map(asShortId));
|
|
|
|
return c.json<ReorderBackupSchedulesDto>({ success: true }, 200);
|
|
})
|
|
.get("/:shortId/progress", getBackupProgressDto, async (c) => {
|
|
const shortId = asShortId(c.req.param("shortId"));
|
|
const schedule = await backupsService.getScheduleByShortId(shortId);
|
|
const progress = backupsExecutionService.getBackupProgress(schedule.id);
|
|
|
|
return c.json<GetBackupProgressDto>(progress ?? null, 200);
|
|
});
|