import type { Request, Response } from 'express'; import { startSync, getSyncStatus, getSyncHistory, retryJob, } from '../services/sat/sat.service.js'; import { getJobInfo, runSatSyncJobManually } from '../jobs/sat-sync.job.js'; import type { StartSyncRequest } from '@horux/shared'; import { isGlobalAdmin } from '../utils/global-admin.js'; /** * Inicia una sincronización manual */ export async function start(req: Request, res: Response): Promise { try { const tenantId = req.user!.tenantId; const { type, dateFrom, dateTo } = req.body as StartSyncRequest; const jobId = await startSync( tenantId, type || 'daily', dateFrom ? new Date(dateFrom) : undefined, dateTo ? new Date(dateTo) : undefined ); res.json({ jobId, message: 'Sincronización iniciada', }); } catch (error: any) { console.error('[SAT Controller] Error en start:', error); if (error.message.includes('FIEL') || error.message.includes('sincronización en curso')) { res.status(400).json({ error: error.message }); return; } res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Obtiene el estado actual de sincronización */ export async function status(req: Request, res: Response): Promise { try { const tenantId = req.user!.tenantId; const syncStatus = await getSyncStatus(tenantId); res.json(syncStatus); } catch (error: any) { console.error('[SAT Controller] Error en status:', error); res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Obtiene el historial de sincronizaciones */ export async function history(req: Request, res: Response): Promise { try { const tenantId = req.user!.tenantId; const page = parseInt(req.query.page as string) || 1; const limit = parseInt(req.query.limit as string) || 10; const result = await getSyncHistory(tenantId, page, limit); res.json({ ...result, page, limit, }); } catch (error: any) { console.error('[SAT Controller] Error en history:', error); res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Obtiene detalle de un job específico */ export async function jobDetail(req: Request, res: Response): Promise { try { const tenantId = req.user!.tenantId; const { id } = req.params; const { jobs } = await getSyncHistory(tenantId, 1, 100); const job = jobs.find(j => j.id === id); if (!job) { res.status(404).json({ error: 'Job no encontrado' }); return; } res.json(job); } catch (error: any) { console.error('[SAT Controller] Error en jobDetail:', error); res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Reintenta un job fallido */ export async function retry(req: Request, res: Response): Promise { try { const id = req.params.id as string; const newJobId = await retryJob(id); res.json({ jobId: newJobId, message: 'Job reintentado', }); } catch (error: any) { console.error('[SAT Controller] Error en retry:', error); if (error.message.includes('no encontrado') || error.message.includes('Solo se pueden')) { res.status(400).json({ error: error.message }); return; } res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Obtiene información del job programado (solo admin global) */ export async function cronInfo(req: Request, res: Response): Promise { try { if (!(await isGlobalAdmin(req.user!.tenantId, req.user!.role))) { res.status(403).json({ error: 'Solo el administrador global puede ver info del cron' }); return; } const info = getJobInfo(); res.json(info); } catch (error: any) { console.error('[SAT Controller] Error en cronInfo:', error); res.status(500).json({ error: 'Error interno del servidor' }); } } /** * Ejecuta el job de sincronización manualmente (solo admin global) */ export async function runCron(req: Request, res: Response): Promise { try { if (!(await isGlobalAdmin(req.user!.tenantId, req.user!.role))) { res.status(403).json({ error: 'Solo el administrador global puede ejecutar el cron' }); return; } // Ejecutar en background runSatSyncJobManually().catch(err => console.error('[SAT Controller] Error ejecutando cron manual:', err) ); res.json({ message: 'Job de sincronización iniciado' }); } catch (error: any) { console.error('[SAT Controller] Error en runCron:', error); res.status(500).json({ error: 'Error interno del servidor' }); } }