mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
fix: Retention cron error.
This commit is contained in:
@@ -18,9 +18,9 @@ export const retentionCleanTask = async () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
console.log(`Retention databases number: ${databases.length}`);
|
||||||
for (const db of databases) {
|
for (const db of databases) {
|
||||||
if (!db.retentionPolicy) continue; // no policy = skip
|
if (!db.retentionPolicy) continue;
|
||||||
await enforceRetention(db.id, db.retentionPolicy);
|
await enforceRetention(db.id, db.retentionPolicy);
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@@ -33,7 +33,7 @@ export async function enforceRetention(
|
|||||||
databaseId: string,
|
databaseId: string,
|
||||||
policy: typeof retentionPolicy.$inferSelect
|
policy: typeof retentionPolicy.$inferSelect
|
||||||
) {
|
) {
|
||||||
|
console.log(`Retention started for ${databaseId}`);
|
||||||
switch (policy.type) {
|
switch (policy.type) {
|
||||||
case "count":
|
case "count":
|
||||||
await enforceRetentionCount(databaseId, policy.count ?? 7);
|
await enforceRetentionCount(databaseId, policy.count ?? 7);
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import * as drizzleDb from "@/db";
|
|||||||
import {db} from "@/db";
|
import {db} from "@/db";
|
||||||
import {and, desc, eq, isNull} from "drizzle-orm";
|
import {and, desc, eq, isNull} from "drizzle-orm";
|
||||||
import {deleteBackupCronAction} from "@/lib/tasks/database/utils/delete";
|
import {deleteBackupCronAction} from "@/lib/tasks/database/utils/delete";
|
||||||
|
import {toast} from "sonner";
|
||||||
|
|
||||||
export async function enforceRetentionCount(databaseId: string, count: number) {
|
export async function enforceRetentionCount(databaseId: string, count: number) {
|
||||||
|
console.log(`[Retention Count] - ${databaseId} : started`);
|
||||||
const backups = await db.query.backup.findMany({
|
const backups = await db.query.backup.findMany({
|
||||||
where: and(eq(drizzleDb.schemas.backup.databaseId, databaseId), isNull(drizzleDb.schemas.backup.deletedAt)),
|
where: and(eq(drizzleDb.schemas.backup.databaseId, databaseId), isNull(drizzleDb.schemas.backup.deletedAt)),
|
||||||
orderBy: desc(drizzleDb.schemas.backup.createdAt),
|
orderBy: desc(drizzleDb.schemas.backup.createdAt),
|
||||||
@@ -16,12 +18,20 @@ export async function enforceRetentionCount(databaseId: string, count: number) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const toDelete = backups.slice(count); // keep first `count`, delete rest
|
const toDelete = backups.slice(count);
|
||||||
|
console.log(`[Retention Count] - ${databaseId} : ${toDelete.length} backups to delete`);
|
||||||
|
|
||||||
for (const b of toDelete) {
|
for (const b of toDelete) {
|
||||||
await deleteBackupCronAction({
|
const result = await deleteBackupCronAction({
|
||||||
backupId: b.id,
|
backupId: b.id,
|
||||||
databaseId: b.databaseId,
|
databaseId: b.databaseId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inner = result?.data;
|
||||||
|
if (inner?.success) {
|
||||||
|
console.log(`[Retention Count] - (databaseId:${b.databaseId}) - (backupId: ${b.id}) : successfully deleted`);
|
||||||
|
} else {
|
||||||
|
console.log(`[Retention Count] - (databaseId:${b.databaseId}) - (backupId: ${b.id}) : an error occurred - ${inner?.actionError?.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import * as drizzleDb from "@/db";
|
|||||||
import {deleteBackupCronAction} from "@/lib/tasks/database/utils/delete";
|
import {deleteBackupCronAction} from "@/lib/tasks/database/utils/delete";
|
||||||
|
|
||||||
export async function enforceRetentionDays(databaseId: string, days: number) {
|
export async function enforceRetentionDays(databaseId: string, days: number) {
|
||||||
|
console.log(`Enforce Retention Days starting for ${databaseId}`);
|
||||||
const cutoff = new Date(Date.now() - days * 86400000);
|
const cutoff = new Date(Date.now() - days * 86400000);
|
||||||
|
|
||||||
const expiredBackups = await db.query.backup.findMany({
|
const expiredBackups = await db.query.backup.findMany({
|
||||||
@@ -22,11 +23,18 @@ export async function enforceRetentionDays(databaseId: string, days: number) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const backup of expiredBackups) {
|
for (const backup of expiredBackups) {
|
||||||
await deleteBackupCronAction({
|
|
||||||
|
const result = await deleteBackupCronAction({
|
||||||
backupId: backup.id,
|
backupId: backup.id,
|
||||||
databaseId: backup.databaseId,
|
databaseId: backup.databaseId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inner = result?.data;
|
||||||
|
if (inner?.success) {
|
||||||
|
console.log(`[Retention Days] - (databaseId:${backup.databaseId}) - (backupId: ${backup.id}) : successfully deleted`);
|
||||||
|
} else {
|
||||||
|
console.log(`[Retention Days] - (databaseId:${backup.databaseId}) - (backupId: ${backup.id}) : an error occurred - ${inner?.actionError?.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ export async function enforceRetentionGFS(databaseId: string, gfsSettings: {
|
|||||||
monthly: number;
|
monthly: number;
|
||||||
yearly: number;
|
yearly: number;
|
||||||
}) {
|
}) {
|
||||||
|
console.log(`Enforce Retention GFS starting for ${databaseId}`);
|
||||||
|
|
||||||
const backups = await db.query.backup.findMany({
|
const backups = await db.query.backup.findMany({
|
||||||
where: and(eq(drizzleDb.schemas.backup.databaseId, databaseId), isNull(drizzleDb.schemas.backup.deletedAt)),
|
where: and(eq(drizzleDb.schemas.backup.databaseId, databaseId), isNull(drizzleDb.schemas.backup.deletedAt)),
|
||||||
orderBy: desc(drizzleDb.schemas.backup.createdAt),
|
orderBy: desc(drizzleDb.schemas.backup.createdAt),
|
||||||
@@ -30,7 +32,7 @@ export async function enforceRetentionGFS(databaseId: string, gfsSettings: {
|
|||||||
if (b.createdAt >= subDays(now, gfsSettings.daily)) toKeep.add(b.id);
|
if (b.createdAt >= subDays(now, gfsSettings.daily)) toKeep.add(b.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
const weekStartDates = Array.from({length: gfsSettings.weekly}, (_, i) => startOfWeek(subWeeks(now, i), { weekStartsOn: 1 }));
|
const weekStartDates = Array.from({length: gfsSettings.weekly}, (_, i) => startOfWeek(subWeeks(now, i), {weekStartsOn: 1}));
|
||||||
weekStartDates.forEach((weekStart) => {
|
weekStartDates.forEach((weekStart) => {
|
||||||
const backupOfWeek = backups.find(
|
const backupOfWeek = backups.find(
|
||||||
(b) => b.createdAt >= weekStart && b.createdAt < subWeeks(weekStart, -1)
|
(b) => b.createdAt >= weekStart && b.createdAt < subWeeks(weekStart, -1)
|
||||||
@@ -60,10 +62,17 @@ export async function enforceRetentionGFS(databaseId: string, gfsSettings: {
|
|||||||
for (const b of backups) {
|
for (const b of backups) {
|
||||||
if (!toKeep.has(b.id)) {
|
if (!toKeep.has(b.id)) {
|
||||||
|
|
||||||
await deleteBackupCronAction({
|
const result = await deleteBackupCronAction({
|
||||||
backupId: b.id,
|
backupId: b.id,
|
||||||
databaseId: b.databaseId,
|
databaseId: b.databaseId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const inner = result?.data;
|
||||||
|
if (inner?.success) {
|
||||||
|
console.log(`[Retention GFS] - (databaseId:${b.databaseId}) - (backupId: ${b.id}) : successfully deleted`);
|
||||||
|
} else {
|
||||||
|
console.log(`[Retention GFS] - (databaseId:${b.databaseId}) - (backupId: ${b.id}) : an error occurred - ${inner?.actionError?.message}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ export const deleteBackupCronAction = action
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
const backup = await db.query.backup.findFirst({
|
const backup = await db.query.backup.findFirst({
|
||||||
where: and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.backupId))
|
where: and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.databaseId))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (!backup) {
|
if (!backup) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
@@ -42,17 +43,6 @@ export const deleteBackupCronAction = action
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (!backupStorages) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
actionError: {
|
|
||||||
message: "Backup storage not found.",
|
|
||||||
status: 404,
|
|
||||||
messageParams: {backupId: parsedInput.backupId},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const backupStorage of backupStorages) {
|
for (const backupStorage of backupStorages) {
|
||||||
|
|
||||||
await db
|
await db
|
||||||
@@ -81,7 +71,7 @@ export const deleteBackupCronAction = action
|
|||||||
.set(withUpdatedAt({
|
.set(withUpdatedAt({
|
||||||
deletedAt: new Date(),
|
deletedAt: new Date(),
|
||||||
}))
|
}))
|
||||||
.where(and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.backupId)))
|
.where(and(eq(drizzleDb.schemas.backup.id, parsedInput.backupId), eq(drizzleDb.schemas.backup.databaseId, parsedInput.databaseId)))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user