/** * POST /api/route53/sync — trigger a manual full or incremental Route 53 sync. * Body: { syncType?: 'full' | 'incremental' } (default 'full') * requireAdmin() gated. Fire-and-forget — returns immediately, sync runs in * the background. * * GET /api/route53/sync — sync status + recent history. * requireAuth() gated. * * D-10: Route 53 is NOT gated by the admin-integrations disable toggle — * that disable-blocks-sync behavior is a PAX8-only exception. Every other * integration's toggle (including this one) is display-only. */ import { NextRequest, NextResponse } from 'next/server'; import { requireAuth, requireAdmin } from '@/lib/auth-utils'; import postgresClient from '@/lib/services/postgres-client'; import { isRoute53Configured } from '@/lib/services/route53-factory'; import { getRoute53SyncService } from '@/lib/services/route53-sync-service'; import { sanitizeAwsError } from '@/lib/services/route53-record-validation'; export async function POST(req: NextRequest) { const { session, error } = await requireAdmin(); if (error) return error; if (!isRoute53Configured()) { return NextResponse.json( { error: 'Route 53 not configured', message: 'AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set to sync Route 53', }, { status: 503 } ); } const body = await req.json().catch(() => ({})); const syncType = body.syncType === 'incremental' ? 'incremental' : 'full'; const svc = getRoute53SyncService(); if (svc.isSyncInProgress()) { return NextResponse.json({ error: 'Sync already in progress' }, { status: 409 }); } const triggeredBy = session!.user.email; const runSync = syncType === 'incremental' ? svc.incrementalSync(triggeredBy) : svc.fullSync(triggeredBy); runSync.catch((err) => console.error('[ROUTE53-SYNC] Background sync error:', sanitizeAwsError(err)) ); return NextResponse.json({ ok: true, message: 'Route 53 sync started' }); } export async function GET() { const { error } = await requireAuth(); if (error) return error; try { const svc = getRoute53SyncService(); const inProgress = svc.isSyncInProgress(); const counts = await postgresClient.query(` SELECT (SELECT COUNT(*) FROM route53_zones WHERE is_deleted = false) AS zones, (SELECT COUNT(*) FROM route53_records WHERE is_deleted = false) AS records, (SELECT COUNT(*) FROM route53_record_history) AS "historyRows" `); const history = await postgresClient.query( `SELECT id, sync_type, status, started_at, completed_at, records_added, records_updated, records_deleted, error_message, triggered_by FROM sync_history WHERE entity_type = 'route53' ORDER BY started_at DESC LIMIT 10` ); return NextResponse.json({ inProgress, counts: counts.rows[0], history: history.rows, }); } catch (err) { console.error('[ROUTE53-SYNC] Failed to get sync status:', err); return NextResponse.json( { error: err instanceof Error ? err.message : 'Failed to get Route 53 sync status' }, { status: 500 } ); } }