import express from 'express'; import multer from 'multer'; import { SessionProvaService } from '../services/SessionProvaService'; import { prisma } from '../config/database'; import * as path from 'path'; import * as fs from 'fs'; const router = express.Router(); const upload = multer({ storage: multer.memoryStorage() }); const sessionService = new SessionProvaService(); // Criar nova sessão de gravação router.post('/create', async (req, res) => { try { // Coletar IP real const realIP = req.headers['x-forwarded-for']?.toString().split(',')[0].trim() || req.ip || req.socket?.remoteAddress || '127.0.0.1'; const metadata = { ...req.body, ipAddress: realIP, serverTimestamp: new Date().toISOString(), headers: { 'user-agent': req.headers['user-agent'], 'accept-language': req.headers['accept-language'], 'referer': req.headers['referer'], 'host': req.headers['host'] } }; const sessionData = await sessionService.createSession(metadata); res.json({ success: true, sessionId: sessionData.id, metadata: sessionData.metadata }); } catch (error) { console.error('Erro ao criar sessão:', error); res.status(500).json({ error: 'Erro ao criar sessão de gravação', details: error.message }); } }); // Adicionar screenshot à sessão router.post('/:sessionId/screenshot', async (req, res) => { try { const { sessionId } = req.params; const { screenshot } = req.body; if (!screenshot) { return res.status(400).json({ error: 'Screenshot não fornecido' }); } const filename = await sessionService.addScreenshot(sessionId, screenshot); res.json({ success: true, filename, timestamp: new Date().toISOString() }); } catch (error) { console.error('Erro ao salvar screenshot:', error); res.status(500).json({ error: 'Erro ao salvar screenshot', details: error.message }); } }); // Upload do vídeo da sessão router.post('/:sessionId/video', upload.single('video'), async (req, res) => { try { const { sessionId } = req.params; if (!req.file) { return res.status(400).json({ error: 'Vídeo não fornecido' }); } const filename = await sessionService.saveSessionVideo(sessionId, req.file.buffer); res.json({ success: true, filename, size: req.file.size, timestamp: new Date().toISOString() }); } catch (error) { console.error('Erro ao salvar vídeo:', error); res.status(500).json({ error: 'Erro ao salvar vídeo', details: error.message }); } }); // Finalizar sessão e gerar relatório router.post('/:sessionId/finalize', async (req, res) => { try { const { sessionId } = req.params; const reportPath = await sessionService.finalizeSession(sessionId); res.json({ success: true, sessionId, reportPath, timestamp: new Date().toISOString() }); } catch (error) { console.error('Erro ao finalizar sessão:', error); res.status(500).json({ error: 'Erro ao finalizar sessão', details: error.message }); } }); // Obter informações da sessão router.get('/:sessionId', async (req, res) => { try { const { sessionId } = req.params; const sessionData = await sessionService.getSession(sessionId); if (!sessionData) { return res.status(404).json({ error: 'Sessão não encontrada' }); } res.json({ success: true, session: sessionData }); } catch (error) { console.error('Erro ao buscar sessão:', error); res.status(500).json({ error: 'Erro ao buscar sessão', details: error.message }); } }); // Baixar relatório da sessão router.get('/:sessionId/report', async (req, res) => { try { const { sessionId } = req.params; const session = await prisma.sessaoProva.findUnique({ where: { id: sessionId } }); if (!session || !session.relatorioPath) { return res.status(404).json({ error: 'Relatório não encontrado' }); } const reportPath = session.relatorioPath; if (!fs.existsSync(reportPath)) { return res.status(404).json({ error: 'Arquivo do relatório não encontrado' }); } res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', `attachment; filename="relatorio_sessao_${sessionId}.pdf"`); const fileStream = fs.createReadStream(reportPath); fileStream.pipe(res); } catch (error) { console.error('Erro ao servir relatório:', error); res.status(500).json({ error: 'Erro ao baixar relatório', details: error.message }); } }); // Verificar sessão por hash router.get('/verify/:hash', async (req, res) => { try { const { hash } = req.params; const result = await sessionService.verifySession(hash); res.json(result); } catch (error) { console.error('Erro ao verificar sessão:', error); res.status(500).json({ error: 'Erro ao verificar sessão', details: error.message }); } }); // Listar sessões (admin) router.get('/admin/list', async (req, res) => { try { const sessions = await prisma.sessaoProva.findMany({ orderBy: { dataInicio: 'desc' }, take: 50 }); res.json({ success: true, sessions: sessions.map(session => ({ id: session.id, status: session.status, dataInicio: session.dataInicio, dataFim: session.dataFim, hashSessao: session.hashSessao, temRelatorio: !!session.relatorioPath })) }); } catch (error) { console.error('Erro ao listar sessões:', error); res.status(500).json({ error: 'Erro ao listar sessões', details: error.message }); } }); export default router;