Every fix, improvement, and new feature — documented transparently.
🚧 In development — changelog will be published on release.
Every scheduled backup was creating a brand new Google Drive folder and re-uploading the entire dataset from scratch, instead of incrementally updating the existing one.
scheduler.ts — Scheduled cron callback now queries the most recent job and passes incrementalFromJobIdscheduler.ts — Health Watcher auto-recovery now passes incrementalFromJobId from the stalled jobThe "Backup Now" button returned a 500 error. The API route ordered jobs by createdAt — a field that doesn't exist in the schema.
orderBy from createdAt to startedAttry-catch for graceful degradationincrementalFromJobIdWhen a backup hit Google's daily API quota, workers would park but the job kept running silently for ~5 minutes until the Health Watcher killed it.
job-runner.ts — Added [Parked] detection in both completion and fatal catch blocksrunFolderId and counters for incremental continuationCancelling a running backup left zombie threads alive — long-running Google API requests continued consuming RAM, eventually crashing the server.
AbortController registry in cancel-store.tsAbortSignal throughout the entire pipelinePermanently deleting a client appeared to succeed but the client remained. Multiple missing columns and methods in the DB wrapper caused silent crashes.
AuditLog schema migrationcount() and aggregate() methods to backupFileIndexgetGlobalAuth import and TypeScript type castingThe custom node:sqlite wrapper didn't support the not operator and silently coerced the filter object to "[object Object]".
not operator support to buildWhere() in lib/db.tsStatusBadge componentThe optimization tool was only running SQLite VACUUM, which reported "already optimised" even with 400 MB of bloat.
BackupJob rows (500 KB–5 MB each)BackupFileIndex rowsAuditLog entries older than 90 daysVACUUM to rebuild the SQLite filePRAGMA wal_checkpoint(TRUNCATE) to shrink WAL to zero.pre-vacuum.bak safety backup before destructive operationsPRAGMA wal_checkpoint(TRUNCATE) after VACUUMALTER TABLE bootstrap migrations for lastVacuumAt, vacuumTargetHour, and masterScheduleEnabledClients can now be archived (soft-deleted with configurable retention) before permanent destruction.
/clients/archive) with countdown timers and restore capabilityReplaced the legacy 3-step restore modal with a comprehensive 5-step Recovery Wizard.
/preflight APIupdate.php now searches a cascade of DB paths before extractionnpm run pack generates update.zip (Enterprise) and update-family.zip (Family)| Area | Files | Apps |
|---|---|---|
| Scheduler | lib/scheduler.ts | Both |
| Job Runner | lib/backup/job-runner.ts | Both |
| Cancel Store | lib/backup/cancel-store.ts | Both |
| Backup API | app/api/clients/[id]/backup/route.ts | Both |
| Client API | app/api/clients/[id]/route.ts | Enterprise |
| Clients API | app/api/clients/route.ts | Both |
| Archive API | app/api/clients/archive/route.ts | Enterprise |
| Database | lib/db.ts | Both |
| Backup Console | app/(admin)/backup/[id]/page.tsx | Both |
| Settings UI | app/(admin)/settings/page.tsx | Both |
| Recovery Wizard | RecoveryWizard.tsx | Both |
| Update Script | install/server/update.php | Enterprise |