From eb1a0af6c4cd8ff871c8b3a13f45412327bc38c8 Mon Sep 17 00:00:00 2001 From: Casper Juel Date: Wed, 21 Jan 2026 14:24:59 +0100 Subject: [PATCH] Simplify cron route to use handleCronBackup from package All backup logic is now in the @casperjuel/datocms-backup-api package. The template just calls handleCronBackup() for easier maintenance. --- app/api/cron/backup/route.ts | 148 +---------------------------------- package.json | 4 +- 2 files changed, 6 insertions(+), 146 deletions(-) diff --git a/app/api/cron/backup/route.ts b/app/api/cron/backup/route.ts index 882e289..276c879 100644 --- a/app/api/cron/backup/route.ts +++ b/app/api/cron/backup/route.ts @@ -1,21 +1,8 @@ import { NextResponse } from 'next/server'; -import { v4 as uuidv4 } from 'uuid'; import { - getConfig, - getActiveProjects, - getRunHistory, - addRun, - updateRun, - updateProjectActivity, verifyCronSecret, - createBackup, - getScheduledBackups, - generateBackupEnvironmentId, - enforceRetention, - type BackupRun, - type BackupType, + handleCronBackup, type CronBackupResponse, - type CronBackupResult, } from '@casperjuel/datocms-backup-api'; export const dynamic = 'force-dynamic'; @@ -31,137 +18,10 @@ export async function GET(): Promise = { - daily: null, - weekly: null, - monthly: null, - manual: null, - }; - - for (const run of runs) { - // Track when each type was last triggered (any status) - // We only care if we already started one, not whether it succeeded - if (!lastRuns[run.type]) { - lastRuns[run.type] = new Date(run.startedAt); - } - } - - const scheduledBackups = getScheduledBackups(config, lastRuns); - console.log(`[CRON] Project ${projectId}: ${scheduledBackups.length} backups due`); - - // Only run ONE backup per cron to avoid timeout (backups take ~200s each) - // Priority: daily > weekly > monthly - const backupToRun = scheduledBackups[0]; - if (!backupToRun) continue; - - const backupsToProcess = [backupToRun]; - for (const backup of backupsToProcess) { - const targetEnvironmentId = generateBackupEnvironmentId(backup.schedule.prefix); - - const run: BackupRun = { - id: uuidv4(), - projectId, - type: backup.type, - status: 'in_progress', - sourceEnvironment: config.sourceEnvironment, - targetEnvironment: targetEnvironmentId, - startedAt: new Date().toISOString(), - metadata: { - triggeredBy: 'cron', - }, - }; - - await addRun(run); - - const startTime = Date.now(); - const result = await createBackup( - config.apiToken, - config.sourceEnvironment, - targetEnvironmentId - ); - const duration = Date.now() - startTime; - - const completedRun: BackupRun = { - ...run, - status: result.success ? 'completed' : 'failed', - completedAt: new Date().toISOString(), - duration, - error: result.error, - metadata: { - ...run.metadata, - environmentId: result.environmentId, - }, - }; - - try { - await updateRun(completedRun); - } catch (updateError) { - console.error(`[CRON] Failed to update run status for ${run.id}:`, updateError); - } - - results.push({ - projectId, - type: backup.type, - runId: run.id, - status: result.success ? 'started' : 'error', - error: result.error, - }); - - console.log( - `[CRON] Project ${projectId}: ${backup.type} backup ${result.success ? 'completed' : 'failed'}` - ); - - if (result.success) { - try { - const retentionResult = await enforceRetention(config, backup.type); - console.log( - `[CRON] Project ${projectId}: cleaned up ${retentionResult.deletedEnvironments.length} old environments` - ); - } catch (error) { - console.error(`[CRON] Retention cleanup error:`, error); - } - } - } - - await updateProjectActivity(projectId); - } catch (error) { - console.error(`[CRON] Error processing project ${projectId}:`, error); - results.push({ - projectId, - type: 'daily', - runId: '', - status: 'error', - error: error instanceof Error ? error.message : 'Unknown error', - }); - } - } - - console.log(`[CRON] Backup cron completed. Processed ${results.length} backups`); - - return NextResponse.json({ - success: true, - executed: results, - timestamp, - }); + // All logic is in the package - just call the handler + const result = await handleCronBackup(); + return NextResponse.json(result); } catch (error) { console.error('[CRON] Critical error:', error); return NextResponse.json( diff --git a/package.json b/package.json index 4f2c485..61f0067 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,12 @@ "private": true, "scripts": { "dev": "next dev --port 3001", - "build": "next build", + "build": "npm update @casperjuel/datocms-backup-api && next build", "start": "next start", "lint": "next lint" }, "dependencies": { - "@casperjuel/datocms-backup-api": "^1.0.3", + "@casperjuel/datocms-backup-api": "^1.0.8", "@vercel/kv": "^3.0.0", "next": "^15.0.0", "react": "^19.0.0",