feat: implement backup management features

- Added `createBackupAction`, `verifyDatabaseAction`, and `refreshBackupStatsAction` for handling backup operations.
- Introduced `getBackupStats` method in `BackupClient` to retrieve daily backup statistics.
- Updated API route to support fetching backup stats.
- Integrated backup stats into the `BackupSettingsPage` and visualized them with `BackupTimelineChart`.
- Enhanced `BackupSettingsPageClient` to manage backup stats and actions more effectively.
This commit is contained in:
Julien Froidefond
2025-09-25 22:28:17 +02:00
parent cd71824cc8
commit f2b18e4527
8 changed files with 471 additions and 67 deletions

View File

@@ -281,7 +281,7 @@ export class BackupService {
id: backupId,
filename: path.basename(finalPath),
size: stats.size,
createdAt: getToday(),
createdAt: new Date(), // Utiliser l'heure actuelle au lieu de getToday()
type,
status: 'success',
databaseHash,
@@ -290,7 +290,7 @@ export class BackupService {
// Sauvegarder les métadonnées du backup
await this.saveBackupMetadata(path.basename(finalPath), {
databaseHash,
createdAt: getToday(),
createdAt: new Date(), // Utiliser l'heure actuelle
type,
});
@@ -314,7 +314,7 @@ export class BackupService {
id: backupId,
filename,
size: 0,
createdAt: getToday(),
createdAt: new Date(), // Utiliser l'heure actuelle même en cas d'erreur
type,
status: 'failed',
error: errorMessage,
@@ -565,6 +565,59 @@ export class BackupService {
return [];
}
}
/**
* Récupère les statistiques de sauvegarde par jour pour les N derniers jours
*/
async getBackupStats(days: number = 30): Promise<Array<{
date: string;
manual: number;
automatic: number;
total: number;
}>> {
try {
const backups = await this.listBackups();
const now = new Date();
const stats: { [date: string]: { manual: number; automatic: number; total: number } } = {};
// Initialiser les stats pour chaque jour
for (let i = 0; i < days; i++) {
const date = new Date(now);
date.setDate(date.getDate() - i);
// Utiliser la date locale pour éviter les décalages UTC
const localDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000);
const dateStr = localDate.toISOString().split('T')[0]; // Format YYYY-MM-DD
stats[dateStr] = { manual: 0, automatic: 0, total: 0 };
}
// Compter les sauvegardes par jour et par type
backups.forEach(backup => {
// Utiliser la date locale pour éviter les décalages UTC
const backupDate = new Date(backup.createdAt.getTime() - backup.createdAt.getTimezoneOffset() * 60000)
.toISOString().split('T')[0];
if (stats[backupDate]) {
if (backup.type === 'manual') {
stats[backupDate].manual++;
} else {
stats[backupDate].automatic++;
}
stats[backupDate].total++;
}
});
// Convertir en tableau et trier par date
return Object.entries(stats)
.map(([date, counts]) => ({
date,
...counts
}))
.sort((a, b) => a.date.localeCompare(b.date));
} catch (error) {
console.error('Error getting backup stats:', error);
return [];
}
}
}
// Instance singleton