wulf-pulse/app/api/veeam/sync/route.ts
lorentz 5dc7a7e66b feat: Veeam VSPC backup integration - sync, compliance, UI
- Database: 7 Veeam tables + backup_type_udf column on configuration_items
- API Client: VSPC REST API v3 client with pagination, rate limiting, Bearer auth
- Sync Service: full/incremental sync for orgs, servers, repos, jobs, agent jobs, workloads
- Scheduler: veeam-incremental (30min) and veeam-full (daily 2AM) schedules
- Compliance Engine: cross-references Autotask config items vs Veeam workloads
- API Endpoints: backup-status, companies, workloads, jobs, repos, compliance, sync
- UI: Backup Status page with Overview + Contract Compliance tabs
- Navigation: added Backup Status link with HardDrive icon
- Docker: added VEEAM_VSPC_URL and VEEAM_VSPC_API_KEY env vars to compose
2026-02-11 21:04:28 -05:00

61 lines
1.6 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { VeeamSyncService } from '@/lib/services/veeam-sync-service';
let syncServiceInstance: VeeamSyncService | null = null;
function getSyncService(): VeeamSyncService {
if (!syncServiceInstance) {
syncServiceInstance = new VeeamSyncService();
}
return syncServiceInstance;
}
export async function POST(request: NextRequest) {
try {
const syncService = getSyncService();
if (syncService.isSyncInProgress()) {
return NextResponse.json(
{ error: 'A Veeam sync is already in progress' },
{ status: 409 }
);
}
const body = await request.json().catch(() => ({}));
const syncType = body.syncType === 'full' ? 'full' : 'incremental';
// Run sync in background, return immediately
const resultPromise = syncType === 'full'
? syncService.fullSync('manual')
: syncService.incrementalSync('manual');
resultPromise.catch((err) => {
console.error('[VEEAM-SYNC-API] Background sync failed:', err);
});
return NextResponse.json({
message: `Veeam ${syncType} sync started`,
syncType,
});
} catch (error) {
console.error('[VEEAM-SYNC-API] Error:', error);
return NextResponse.json(
{ error: 'Failed to start Veeam sync' },
{ status: 500 }
);
}
}
export async function GET() {
try {
const syncService = getSyncService();
return NextResponse.json({
isSyncing: syncService.isSyncInProgress(),
});
} catch (error) {
return NextResponse.json(
{ error: 'Failed to get sync status' },
{ status: 500 }
);
}
}