feat: automated backup and production monitoring
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
d7d04eb2d7
commit
69601cce3a
@@ -0,0 +1,53 @@
|
||||
import { copyFileSync, readdirSync, unlinkSync, mkdirSync, existsSync } from 'fs'
|
||||
import { join, dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { logger } from '../lib/logger.js'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const DB_PATH = process.env.DB_PATH || join(__dirname, '..', '..', 'data', 'botfights.db')
|
||||
const BACKUP_DIR = join(dirname(DB_PATH), 'backups')
|
||||
const MAX_BACKUPS = 7
|
||||
|
||||
/** Create a timestamped backup of the database */
|
||||
export function createBackup(): string {
|
||||
mkdirSync(BACKUP_DIR, { recursive: true })
|
||||
|
||||
const timestamp = new Date().toISOString().slice(0, 10)
|
||||
const backupPath = join(BACKUP_DIR, `botfights-${timestamp}.db`)
|
||||
|
||||
copyFileSync(DB_PATH, backupPath)
|
||||
logger.info('backup', `created backup: ${backupPath}`)
|
||||
|
||||
// Rotate: keep only the latest MAX_BACKUPS
|
||||
rotateBackups()
|
||||
|
||||
return backupPath
|
||||
}
|
||||
|
||||
/** Remove old backups beyond MAX_BACKUPS */
|
||||
function rotateBackups(): void {
|
||||
if (!existsSync(BACKUP_DIR)) return
|
||||
|
||||
const files = readdirSync(BACKUP_DIR)
|
||||
.filter(f => f.startsWith('botfights-') && f.endsWith('.db'))
|
||||
.sort()
|
||||
.reverse()
|
||||
|
||||
for (let i = MAX_BACKUPS; i < files.length; i++) {
|
||||
const path = join(BACKUP_DIR, files[i])
|
||||
try {
|
||||
unlinkSync(path)
|
||||
logger.info('backup', `rotated out: ${files[i]}`)
|
||||
} catch { /* ok */ }
|
||||
}
|
||||
}
|
||||
|
||||
/** Start daily backup timer */
|
||||
export function startDailyBackups(): void {
|
||||
// Run first backup after 1 minute, then every 24 hours
|
||||
setTimeout(() => {
|
||||
createBackup()
|
||||
setInterval(() => createBackup(), 24 * 60 * 60 * 1000)
|
||||
}, 60_000)
|
||||
logger.info('backup', 'daily backups scheduled')
|
||||
}
|
||||
Reference in New Issue
Block a user