feat: MVP-5 Sprint 1 - Backup/Restore system
- Add backup types and RecallBackup format - Create backup snapshot engine (createBackupSnapshot) - Add IndexedDB storage for local backups - Implement retention policy (max 10, 30-day cleanup) - Add backup validation and restore logic (merge/replace modes) - Add backup restore UI dialog with preview and confirmation - Add unsaved changes guard hook - Integrate backups section in Settings - Add backup endpoint to export-import API
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { getBackups } from '@/lib/backup-storage'
|
||||
import { deleteBackup } from '@/lib/backup-storage'
|
||||
import { BackupSource } from '@/types/backup'
|
||||
|
||||
const MAX_AUTOMATIC_BACKUPS = 10
|
||||
const MAX_BACKUP_AGE_DAYS = 30
|
||||
|
||||
function daysAgo(date: Date): number {
|
||||
const now = new Date()
|
||||
const diffMs = now.getTime() - date.getTime()
|
||||
return diffMs / (1000 * 60 * 60 * 24)
|
||||
}
|
||||
|
||||
export async function shouldCleanup(): Promise<boolean> {
|
||||
const backups = await getBackups()
|
||||
|
||||
const automaticBackups = backups.filter((b) => b.source === 'automatic')
|
||||
if (automaticBackups.length > MAX_AUTOMATIC_BACKUPS) {
|
||||
return true
|
||||
}
|
||||
|
||||
const oldBackups = backups.filter(
|
||||
(b) => daysAgo(new Date(b.createdAt)) > MAX_BACKUP_AGE_DAYS
|
||||
)
|
||||
if (oldBackups.length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
export async function cleanupOldBackups(): Promise<number> {
|
||||
const backups = await getBackups()
|
||||
let deletedCount = 0
|
||||
|
||||
// Remove automatic backups exceeding the limit
|
||||
const automaticBackups = backups.filter((b) => b.source === 'automatic')
|
||||
if (automaticBackups.length > MAX_AUTOMATIC_BACKUPS) {
|
||||
const toRemove = automaticBackups.slice(MAX_AUTOMATIC_BACKUPS)
|
||||
for (const backup of toRemove) {
|
||||
await deleteBackup(backup.id)
|
||||
deletedCount++
|
||||
}
|
||||
}
|
||||
|
||||
// Remove backups older than 30 days
|
||||
const recentBackups = await getBackups()
|
||||
for (const backup of recentBackups) {
|
||||
if (daysAgo(new Date(backup.createdAt)) > MAX_BACKUP_AGE_DAYS) {
|
||||
await deleteBackup(backup.id)
|
||||
deletedCount++
|
||||
}
|
||||
}
|
||||
|
||||
return deletedCount
|
||||
}
|
||||
Reference in New Issue
Block a user