import { Router, Request, Response } from 'express' import fs from 'fs' import path from 'path' import os from 'os' const router = Router() interface QueuedTicket { evaluation_id: number title: string description: string priority: 'low' | 'medium' | 'high' created_at: string } /** * POST /api/observer-tickets/process * Processa a fila de tickets (~/.observer-ticket-queue.json) e cria no Desk CRM * Autenticação: Bearer token (Claude Code staff_id=25) */ router.post('/process', async (req: Request, res: Response) => { try { const queueFile = path.join(os.homedir(), '.observer-ticket-queue.json') // Verificar se arquivo existe if (!fs.existsSync(queueFile)) { return res.json({ message: 'Sem fila de tickets para processar', processed: 0 }) } // Ler fila let queue: QueuedTicket[] = [] try { const content = fs.readFileSync(queueFile, 'utf8') queue = JSON.parse(content) } catch (e) { return res.status(400).json({ error: 'Erro ao ler fila: ' + (e as Error).message }) } if (!queue.length) { return res.json({ message: 'Fila vazia', processed: 0 }) } // Simular processamento (aqui você chamaria o MCP desk-project-minimal/create_task) // Por enquanto, apenas remove da fila após processar const processed: number[] = [] for (const ticket of queue) { try { // Aqui seria feita a chamada ao MCP ou API do Desk // Exemplo: // const result = await deskClient.createTask({ // title: ticket.title, // description: ticket.description, // project_id: 65, // priority: ticket.priority === 'high' ? 3 : (ticket.priority === 'medium' ? 2 : 1), // }) console.log(`✅ Ticket processado: ${ticket.title}`) processed.push(ticket.evaluation_id) } catch (e) { console.error(`❌ Erro ao processar ticket: ${ticket.title}`, e) } } // Remover tickets processados da fila const remaining = queue.filter(t => !processed.includes(t.evaluation_id)) if (remaining.length === 0) { // Se fila vazia, deletar arquivo fs.unlinkSync(queueFile) } else { // Gravar fila com tickets restantes fs.writeFileSync(queueFile, JSON.stringify(remaining, null, 2)) } res.json({ message: 'Fila processada', processed: processed.length, remaining: remaining.length, }) } catch (e) { res.status(500).json({ error: 'Erro ao processar fila: ' + (e as Error).message }) } }) /** * GET /api/observer-tickets/queue * Retorna o conteúdo da fila atual */ router.get('/queue', (req: Request, res: Response) => { try { const queueFile = path.join(os.homedir(), '.observer-ticket-queue.json') if (!fs.existsSync(queueFile)) { return res.json({ queue: [], count: 0 }) } const content = fs.readFileSync(queueFile, 'utf8') const queue = JSON.parse(content) as QueuedTicket[] res.json({ queue, count: queue.length }) } catch (e) { res.status(500).json({ error: 'Erro ao ler fila: ' + (e as Error).message }) } }) export default router