Phase 7: scheduled (recurring) backups (0.7.0)
- BackupSchedule model + schedule_service: next-run calc (hourly/daily/weekly, UTC), background scheduler loop (lifespan), run-one with retention pruning (keep newest N per stack on the destination), backup_failed notify event. - routers/schedules.py: schedules CRUD + run-now; registered in main.py. - Frontend: api/schedules.ts + Settings → Scheduled backups (list with next/last run + status, enable/disable, run-now, delete; add form with stack/destination/ frequency/time/weekday/retention/volumes). Rough-verified only (per request): py_compile, frontend tsc build, app import (95 routes), next-run math sanity. Full live run to be tested after deploy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
7bd449101d
commit
84ef3df59e
@@ -0,0 +1,49 @@
|
||||
import api from "./client";
|
||||
|
||||
export interface BackupSchedule {
|
||||
id: number;
|
||||
stack_id: string;
|
||||
destination_id: number;
|
||||
destination_name: string | null;
|
||||
frequency: "hourly" | "daily" | "weekly";
|
||||
hour: number;
|
||||
minute: number;
|
||||
weekday: number;
|
||||
include_volumes: boolean;
|
||||
stop_first: boolean;
|
||||
keep: number;
|
||||
enabled: boolean;
|
||||
last_run: string | null;
|
||||
last_status: string | null;
|
||||
next_run: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface ScheduleInput {
|
||||
stack_id: string;
|
||||
destination_id: number;
|
||||
frequency: string;
|
||||
hour: number;
|
||||
minute: number;
|
||||
weekday: number;
|
||||
include_volumes: boolean;
|
||||
stop_first: boolean;
|
||||
keep: number;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
export const schedulesApi = {
|
||||
list: () => api.get<BackupSchedule[]>("/api/backups/schedules").then((r) => r.data),
|
||||
create: (body: ScheduleInput) =>
|
||||
api.post<BackupSchedule>("/api/backups/schedules", body).then((r) => r.data),
|
||||
update: (id: number, body: Partial<ScheduleInput>) =>
|
||||
api.put<BackupSchedule>(`/api/backups/schedules/${id}`, body).then((r) => r.data),
|
||||
remove: (id: number) =>
|
||||
api.delete(`/api/backups/schedules/${id}`).then((r) => r.data),
|
||||
run: (id: number) =>
|
||||
api
|
||||
.post<{ ok: boolean; name?: string; destination?: string; error?: string }>(
|
||||
`/api/backups/schedules/${id}/run`
|
||||
)
|
||||
.then((r) => r.data),
|
||||
};
|
||||
Reference in New Issue
Block a user