Files
pn-new-crm/scripts/create-full-backup.ts

49 lines
1.5 KiB
TypeScript
Raw Permalink Normal View History

/**
* Produce a full disaster-recovery bundle (db.dump + every blob + manifest.json)
* to a local file. Same code path as the admin "Download full backup" button
* (`createFullBackupTar`), minus the HTTP layer for headless/ops use and for
* rehearsing the restore runbook (docs/backup-restore-runbook.md).
*
* pnpm tsx scripts/create-full-backup.ts [outfile.tar]
*
* Defaults the output name to ./pn-crm-backup-<timestamp>.tar in the CWD.
*/
import 'dotenv/config';
import { copyFile } from 'node:fs/promises';
import path from 'node:path';
import { createFullBackupTar } from '@/lib/services/backup-export.service';
import { logger } from '@/lib/logger';
async function main(): Promise<void> {
const { tarPath, filename, manifest, cleanup } = await createFullBackupTar();
try {
const dest = path.resolve(process.argv[2] ?? filename);
await copyFile(tarPath, dest);
logger.info(
{
dest,
storageBackend: manifest.storageBackend,
dbDumpBytes: manifest.database.sizeBytes,
blobs: manifest.counts.blobs,
blobBytes: manifest.counts.blobBytes,
skipped: manifest.counts.skipped,
},
'Full backup written',
);
if (manifest.skipped.length) {
logger.warn({ skipped: manifest.skipped }, 'Some referenced blobs were missing in storage');
}
} finally {
await cleanup();
}
}
main()
.then(() => process.stdout.write('', () => process.exit(0)))
.catch((err) => {
logger.error({ err }, 'Full backup failed');
process.stderr.write('', () => process.exit(1));
});