mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8edf0ca742 | ||
|
|
568d9612c5 |
+1
-1
@@ -33,5 +33,5 @@ keywords:
|
||||
- web-ui
|
||||
- agent
|
||||
license: Apache-2.0
|
||||
version: 1.21.0
|
||||
version: 1.21.1
|
||||
date-released: '2026-03-02'
|
||||
|
||||
@@ -4,7 +4,7 @@ import {Agent} from "@/db/schema/08_agent";
|
||||
import {DatabaseWith} from "@/db/schema/07_database";
|
||||
import * as drizzleDb from "@/db";
|
||||
import {db, db as dbClient} from "@/db";
|
||||
import {and, eq, inArray} from "drizzle-orm";
|
||||
import {and, eq, inArray, desc, sql} from "drizzle-orm";
|
||||
import {dbmsEnumSchema, EDbmsSchema} from "@/db/schema/types";
|
||||
import {withUpdatedAt} from "@/db/utils";
|
||||
import {Setting} from "@/db/schema/01_setting";
|
||||
@@ -123,7 +123,11 @@ export async function handleDatabases(body: Body, agent: Agent, lastContact: Dat
|
||||
where: and(
|
||||
eq(drizzleDb.schemas.backup.databaseId, databaseUpdated.id),
|
||||
inArray(drizzleDb.schemas.backup.status, ["waiting", "ongoing"])
|
||||
)
|
||||
),
|
||||
orderBy: [
|
||||
sql`case when ${drizzleDb.schemas.backup.status} = 'waiting' then 0 else 1 end`,
|
||||
desc(drizzleDb.schemas.backup.createdAt)
|
||||
]
|
||||
})
|
||||
|
||||
const restoration = await dbClient.query.restoration.findFirst({
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "portabase",
|
||||
"version": "1.21.0",
|
||||
"version": "1.21.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --turbopack -p 8887",
|
||||
|
||||
@@ -64,6 +64,7 @@ export const env = createEnv({
|
||||
process.env.NODE_ENV === "production" ? "0 * * * *" : "* * * * *",
|
||||
),
|
||||
|
||||
STALE_BACKUP_THRESHOLD_HOURS: z.coerce.number().default(6),
|
||||
|
||||
AUTH_OIDC_ID: z.string().optional().default("oidc"),
|
||||
AUTH_OIDC_TITLE: z.string().optional(),
|
||||
@@ -147,6 +148,7 @@ export const env = createEnv({
|
||||
|
||||
RETENTION_CRON: process.env.RETENTION_CRON,
|
||||
CLEANING_HEALTHCHECK_LOGS_CRON: process.env.CLEANING_HEALTHCHECK_LOGS_CRON,
|
||||
STALE_BACKUP_THRESHOLD_HOURS: process.env.STALE_BACKUP_THRESHOLD_HOURS,
|
||||
|
||||
AUTH_OIDC_ID: process.env.AUTH_OIDC_ID,
|
||||
AUTH_OIDC_TITLE: process.env.AUTH_OIDC_TITLE,
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import {db} from "@/db";
|
||||
import {and, eq, isNotNull, isNull} from "drizzle-orm";
|
||||
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"});
|
||||
|
||||
@@ -23,6 +25,36 @@ export const backupCleanTask = async () => {
|
||||
.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: eq(drizzleDb.schemas.database.id, backup.databaseId),
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user