import type { FastifyInstance } from 'fastify'; import pino from 'pino'; import { withTenant } from '../data/db.js'; const logger = pino({ name: 'api-discovery' }); export function registerDiscoveryRoutes(app: FastifyInstance) { // Trigger AWS discovery scan app.post('/api/v1/discovery/aws', async (req, reply) => { const tenantId = (req as any).tenantId; // TODO: Enqueue scan job (Redis queue or direct execution) logger.info({ tenantId }, 'AWS discovery scan triggered'); return reply.status(202).send({ status: 'scan_queued', scanner: 'aws' }); }); // Trigger GitHub discovery scan app.post('/api/v1/discovery/github', async (req, reply) => { const tenantId = (req as any).tenantId; logger.info({ tenantId }, 'GitHub discovery scan triggered'); return reply.status(202).send({ status: 'scan_queued', scanner: 'github' }); }); // Get scan history app.get('/api/v1/discovery/history', async (req, reply) => { const tenantId = (req as any).tenantId; const result = await withTenant(tenantId, async (client) => { return client.query('SELECT * FROM scan_history ORDER BY started_at DESC LIMIT 20'); }); return { scans: result.rows }; }); // List staged updates (from partial scans) app.get('/api/v1/discovery/staged', async (req, reply) => { const tenantId = (req as any).tenantId; const result = await withTenant(tenantId, async (client) => { return client.query("SELECT * FROM staged_updates WHERE status = 'pending' ORDER BY created_at DESC"); }); return { staged: result.rows }; }); // Apply or reject staged update app.post('/api/v1/discovery/staged/:id/:action', async (req, reply) => { const { id, action } = req.params as { id: string; action: string }; const tenantId = (req as any).tenantId; if (action !== 'apply' && action !== 'reject') { return reply.status(400).send({ error: 'Action must be apply or reject' }); } const newStatus = action === 'apply' ? 'applied' : 'rejected'; await withTenant(tenantId, async (client) => { await client.query('UPDATE staged_updates SET status = $1 WHERE id = $2', [newStatus, id]); // TODO: If applied, merge changes into services table }); return { status: newStatus }; }); }