feat: mirror repositories

feat: mirror backup repositories
This commit is contained in:
Nicolas Meienberger
2025-11-28 19:17:05 +01:00
parent 8e90c4ace1
commit b0e09c61e2
22 changed files with 2351 additions and 88 deletions

View File

@@ -93,6 +93,7 @@ export const backupSchedulesTable = sqliteTable("backup_schedules_table", {
createdAt: int("created_at", { mode: "number" }).notNull().default(sql`(unixepoch() * 1000)`),
updatedAt: int("updated_at", { mode: "number" }).notNull().default(sql`(unixepoch() * 1000)`),
});
export const backupScheduleRelations = relations(backupSchedulesTable, ({ one, many }) => ({
volume: one(volumesTable, {
fields: [backupSchedulesTable.volumeId],
@@ -103,6 +104,7 @@ export const backupScheduleRelations = relations(backupSchedulesTable, ({ one, m
references: [repositoriesTable.id],
}),
notifications: many(backupScheduleNotificationsTable),
mirrors: many(backupScheduleMirrorsTable),
}));
export type BackupSchedule = typeof backupSchedulesTable.$inferSelect;
@@ -154,6 +156,37 @@ export const backupScheduleNotificationRelations = relations(backupScheduleNotif
}));
export type BackupScheduleNotification = typeof backupScheduleNotificationsTable.$inferSelect;
/**
* Backup Schedule Mirrors Junction Table (Many-to-Many)
* Allows copying snapshots to secondary repositories after backup completes
*/
export const backupScheduleMirrorsTable = sqliteTable("backup_schedule_mirrors_table", {
id: int().primaryKey({ autoIncrement: true }),
scheduleId: int("schedule_id")
.notNull()
.references(() => backupSchedulesTable.id, { onDelete: "cascade" }),
repositoryId: text("repository_id")
.notNull()
.references(() => repositoriesTable.id, { onDelete: "cascade" }),
enabled: int("enabled", { mode: "boolean" }).notNull().default(true),
lastCopyAt: int("last_copy_at", { mode: "number" }),
lastCopyStatus: text("last_copy_status").$type<"success" | "error">(),
lastCopyError: text("last_copy_error"),
createdAt: int("created_at", { mode: "number" }).notNull().default(sql`(unixepoch() * 1000)`),
});
export const backupScheduleMirrorRelations = relations(backupScheduleMirrorsTable, ({ one }) => ({
schedule: one(backupSchedulesTable, {
fields: [backupScheduleMirrorsTable.scheduleId],
references: [backupSchedulesTable.id],
}),
repository: one(repositoriesTable, {
fields: [backupScheduleMirrorsTable.repositoryId],
references: [repositoriesTable.id],
}),
}));
export type BackupScheduleMirror = typeof backupScheduleMirrorsTable.$inferSelect;
/**
* App Metadata Table
* Used for storing key-value pairs like migration checkpoints