From d190d9c8cda40cd1634cae96eb27a2224bd6be60 Mon Sep 17 00:00:00 2001 From: Nico <47644445+nicotsx@users.noreply.github.com> Date: Wed, 26 Nov 2025 19:02:29 +0100 Subject: [PATCH] feat: partial success warning status (#74) * feat: report partial backups with warnings * chore: rebase * chore: remove un-used size prop --- app/client/api-client/types.gen.ts | 10 ++--- app/client/components/volume-icon.tsx | 5 +-- .../backups/components/schedule-summary.tsx | 10 +++++ .../modules/volumes/routes/volume-details.tsx | 2 +- app/schemas/notifications.ts | 1 + app/server/core/events.ts | 2 +- app/server/db/schema.ts | 2 +- app/server/modules/backups/backups.dto.ts | 2 +- app/server/modules/backups/backups.service.ts | 14 ++++--- .../modules/events/events.controller.ts | 2 +- .../notifications/notifications.service.ts | 22 +++++++++- app/server/utils/errors.ts | 22 ++++++++++ app/server/utils/restic.ts | 42 +++++++++++-------- app/server/utils/spawn.ts | 3 +- docker-compose.yml | 5 +-- 15 files changed, 102 insertions(+), 42 deletions(-) diff --git a/app/client/api-client/types.gen.ts b/app/client/api-client/types.gen.ts index 8a983f9..fb47740 100644 --- a/app/client/api-client/types.gen.ts +++ b/app/client/api-client/types.gen.ts @@ -1181,7 +1181,7 @@ export type ListBackupSchedulesResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: 'error' | 'in_progress' | 'success' | null; + lastBackupStatus: 'error' | 'in_progress' | 'success' | 'warning' | null; nextBackupAt: number | null; repository: { compressionMode: 'auto' | 'better' | 'fastest' | 'max' | 'off' | null; @@ -1351,7 +1351,7 @@ export type CreateBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: 'error' | 'in_progress' | 'success' | null; + lastBackupStatus: 'error' | 'in_progress' | 'success' | 'warning' | null; nextBackupAt: number | null; repositoryId: string; retentionPolicy: { @@ -1412,7 +1412,7 @@ export type GetBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: 'error' | 'in_progress' | 'success' | null; + lastBackupStatus: 'error' | 'in_progress' | 'success' | 'warning' | null; nextBackupAt: number | null; repository: { compressionMode: 'auto' | 'better' | 'fastest' | 'max' | 'off' | null; @@ -1583,7 +1583,7 @@ export type UpdateBackupScheduleResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: 'error' | 'in_progress' | 'success' | null; + lastBackupStatus: 'error' | 'in_progress' | 'success' | 'warning' | null; nextBackupAt: number | null; repositoryId: string; retentionPolicy: { @@ -1624,7 +1624,7 @@ export type GetBackupScheduleForVolumeResponses = { includePatterns: Array | null; lastBackupAt: number | null; lastBackupError: string | null; - lastBackupStatus: 'error' | 'in_progress' | 'success' | null; + lastBackupStatus: 'error' | 'in_progress' | 'success' | 'warning' | null; nextBackupAt: number | null; repository: { compressionMode: 'auto' | 'better' | 'fastest' | 'max' | 'off' | null; diff --git a/app/client/components/volume-icon.tsx b/app/client/components/volume-icon.tsx index d2936c3..0d3e00e 100644 --- a/app/client/components/volume-icon.tsx +++ b/app/client/components/volume-icon.tsx @@ -3,7 +3,6 @@ import type { BackendType } from "~/schemas/volumes"; type VolumeIconProps = { backend: BackendType; - size?: number; }; const getIconAndColor = (backend: BackendType) => { @@ -41,12 +40,12 @@ const getIconAndColor = (backend: BackendType) => { } }; -export const VolumeIcon = ({ backend, size = 10 }: VolumeIconProps) => { +export const VolumeIcon = ({ backend }: VolumeIconProps) => { const { icon: Icon, label } = getIconAndColor(backend); return ( - + {label} ); diff --git a/app/client/modules/backups/components/schedule-summary.tsx b/app/client/modules/backups/components/schedule-summary.tsx index ba18d80..4422c77 100644 --- a/app/client/modules/backups/components/schedule-summary.tsx +++ b/app/client/modules/backups/components/schedule-summary.tsx @@ -164,10 +164,20 @@ export const ScheduleSummary = (props: Props) => { {schedule.lastBackupStatus === "success" && "✓ Success"} {schedule.lastBackupStatus === "error" && "✗ Error"} {schedule.lastBackupStatus === "in_progress" && "⟳ in progress..."} + {schedule.lastBackupStatus === "warning" && "! Warning"} {!schedule.lastBackupStatus && "—"}

+ {schedule.lastBackupStatus === "warning" && ( +
+

Warning Details

+

+ Last backup completed with warnings. Check your container logs for more details. +

+
+ )} + {schedule.lastBackupError && (

Error Details

diff --git a/app/client/modules/volumes/routes/volume-details.tsx b/app/client/modules/volumes/routes/volume-details.tsx index 1cd1e07..3ee690a 100644 --- a/app/client/modules/volumes/routes/volume-details.tsx +++ b/app/client/modules/volumes/routes/volume-details.tsx @@ -142,7 +142,7 @@ export default function VolumeDetails({ loaderData }: Route.ComponentProps) {   {volume.status[0].toUpperCase() + volume.status.slice(1)} - +