mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
80 lines
3.0 KiB
TypeScript
80 lines
3.0 KiB
TypeScript
import {db} from "@/db";
|
|
import {and, eq, isNotNull, isNull, lt} from "drizzle-orm";
|
|
import * as drizzleDb from "@/db";
|
|
import {withUpdatedAt} from "@/db/utils";
|
|
import {logger} from "@/lib/logger";
|
|
import {env} from "@/env.mjs";
|
|
import {sendNotificationsBackupRestore} from "@/features/notifications/utils/notifications.helpers";
|
|
|
|
const log = logger.child({module: "tasks/cleaning"});
|
|
|
|
export const backupCleanTask = async () => {
|
|
try {
|
|
const ongoingBackups = await db.query.backup.findMany({
|
|
where: and(
|
|
isNotNull(drizzleDb.schemas.backup.deletedAt),
|
|
eq(drizzleDb.schemas.backup.status, "ongoing")
|
|
)
|
|
});
|
|
log.debug(`Backups to clean: ${ongoingBackups.length}`);
|
|
|
|
for (const backup of ongoingBackups) {
|
|
await db.update(drizzleDb.schemas.backup).set(withUpdatedAt({
|
|
status: "failed",
|
|
}))
|
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
|
}
|
|
|
|
const staleCutoff = new Date(Date.now() - env.STALE_BACKUP_THRESHOLD_HOURS * 60 * 60 * 1000);
|
|
|
|
const staleOngoingBackups = await db.query.backup.findMany({
|
|
where: and(
|
|
isNull(drizzleDb.schemas.backup.deletedAt),
|
|
eq(drizzleDb.schemas.backup.status, "ongoing"),
|
|
lt(drizzleDb.schemas.backup.createdAt, staleCutoff)
|
|
)
|
|
});
|
|
log.debug(`Stale ongoing backups to fail: ${staleOngoingBackups.length}`);
|
|
|
|
for (const backup of staleOngoingBackups) {
|
|
await db.update(drizzleDb.schemas.backup).set(withUpdatedAt({
|
|
status: "failed",
|
|
}))
|
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
|
|
|
try {
|
|
const database = await db.query.database.findFirst({
|
|
where: and(
|
|
eq(drizzleDb.schemas.database.id, backup.databaseId),
|
|
isNull(drizzleDb.schemas.database.deletedAt),
|
|
),
|
|
with: {alertPolicies: true},
|
|
});
|
|
if (database) {
|
|
await sendNotificationsBackupRestore(database, "error_backup");
|
|
}
|
|
} catch (notifyError) {
|
|
log.error({name: "backupCleanTask", error: notifyError}, "Stale backup notification failed");
|
|
}
|
|
}
|
|
|
|
const failedBackups = await db.query.backup.findMany({
|
|
where: and(
|
|
isNull(drizzleDb.schemas.backup.deletedAt),
|
|
eq(drizzleDb.schemas.backup.status, "failed")
|
|
)
|
|
});
|
|
log.debug(`Failed backups to clean: ${failedBackups.length}`);
|
|
|
|
for (const backup of failedBackups) {
|
|
await db.update(drizzleDb.schemas.backup).set(withUpdatedAt({
|
|
deletedAt: new Date(),
|
|
}))
|
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
|
}
|
|
|
|
} catch (e: any) {
|
|
log.error({name: "backupCleanTask", error: e},`Backup cleanup failed`);
|
|
throw e;
|
|
}
|
|
}; |