wulf-pulse/app/api/veeam/companies/[companyId]/jobs/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

38 lines
1.2 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import postgresClient from '@/lib/services/postgres-client';
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ companyId: string }> }
) {
try {
const { companyId } = await params;
const companyIdInt = parseInt(companyId);
// Get backup server jobs
const serverJobs = await postgresClient.query(`
SELECT bj.*, 'server' as job_source
FROM veeam_backup_jobs bj
JOIN veeam_organizations vo ON vo.instance_uid = bj.organization_uid
WHERE vo.company_id = $1
ORDER BY bj.last_run DESC NULLS LAST
`, [companyIdInt]);
// Get backup agent jobs
const agentJobs = await postgresClient.query(`
SELECT aj.*, 'agent' as job_source
FROM veeam_backup_agent_jobs aj
JOIN veeam_organizations vo ON vo.instance_uid = aj.organization_uid
WHERE vo.company_id = $1
ORDER BY aj.last_run DESC NULLS LAST
`, [companyIdInt]);
return NextResponse.json({
serverJobs: serverJobs.rows,
agentJobs: agentJobs.rows,
});
} catch (error) {
console.error('[VEEAM-API] company jobs error:', error);
return NextResponse.json({ serverJobs: [], agentJobs: [] });
}
}