zerobyte/app/server/jobs/backup-execution.ts
Nico 451aed8983
Multi users (#381)
* feat(db): add support for multiple users and organizations

* feat: backfill entities with new organization id

* refactor: filter all backend queries to surface only organization specific entities

* refactor: each org has its own restic password

* test: ensure organization is created

* chore: pr feedbacks

* refactor: filter by org id in all places

* refactor: download restic password from stored db password

* refactor(navigation): use volume id in urls instead of name

* feat: disable registrations

* refactor(auth): bubble up auth error to hono

* refactor: use async local storage for cleaner context sharing

* refactor: enable user registration vs disabling it

* test: multi-org isolation

* chore: final cleanup
2026-01-20 22:28:22 +01:00

41 lines
1.2 KiB
TypeScript

import { Job } from "../core/scheduler";
import { backupsService } from "../modules/backups/backups.service";
import { logger } from "../utils/logger";
import { db } from "../db/db";
import { withContext } from "../core/request-context";
export class BackupExecutionJob extends Job {
async run() {
logger.debug("Checking for backup schedules to execute...");
const organizations = await db.query.organization.findMany({});
let totalExecuted = 0;
for (const org of organizations) {
await withContext({ organizationId: org.id }, async () => {
const scheduleIds = await backupsService.getSchedulesToExecute();
if (scheduleIds.length === 0) {
return;
}
logger.info(`Found ${scheduleIds.length} backup schedule(s) to execute for organization ${org.name}`);
for (const scheduleId of scheduleIds) {
backupsService.executeBackup(scheduleId).catch((err) => {
logger.error(`Error executing backup for schedule ${scheduleId}:`, err);
});
}
totalExecuted += scheduleIds.length;
});
}
if (totalExecuted === 0) {
logger.debug("No backup schedules to execute");
}
return { done: true, timestamp: new Date(), executed: totalExecuted };
}
}