Consolidate chat timeline events + auto-end inactive sessions

Timeline consolidation:
- Replace multiple LIVE_CHAT_STARTED/ENDED events with single LIVE_CHAT_SUMMARY
- Show total duration accumulated across all sessions
- Display session count (e.g., "23min 15s total - 3 sessoes")
- Show "Ativo" badge when session is active

Auto-end inactive chat sessions:
- Add cron job running every minute to check inactive sessions
- Automatically end sessions after 5 minutes of client inactivity
- Mark auto-ended sessions with "(encerrado por inatividade)" flag

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-07 14:44:34 -03:00
parent 409da8afda
commit 115c5128a6
5 changed files with 224 additions and 2 deletions

View file

@ -692,6 +692,67 @@ export const getTicketChatHistory = query({
},
})
// ============================================
// ENCERRAMENTO AUTOMATICO POR INATIVIDADE
// ============================================
// Timeout de inatividade: 5 minutos
const INACTIVITY_TIMEOUT_MS = 5 * 60 * 1000
// Mutation interna para encerrar sessoes inativas (chamada pelo cron)
export const autoEndInactiveSessions = mutation({
args: {},
handler: async (ctx) => {
const now = Date.now()
const cutoffTime = now - INACTIVITY_TIMEOUT_MS
// Buscar todas as sessoes ativas com inatividade > 5 minutos
const inactiveSessions = await ctx.db
.query("liveChatSessions")
.filter((q) =>
q.and(
q.eq(q.field("status"), "ACTIVE"),
q.lt(q.field("lastActivityAt"), cutoffTime)
)
)
.collect()
let endedCount = 0
for (const session of inactiveSessions) {
// Encerrar a sessao
await ctx.db.patch(session._id, {
status: "ENDED",
endedAt: now,
})
// Calcular duracao da sessao
const durationMs = now - session.startedAt
// Registrar evento na timeline
await ctx.db.insert("ticketEvents", {
ticketId: session.ticketId,
type: "LIVE_CHAT_ENDED",
payload: {
sessionId: session._id,
agentId: session.agentId,
agentName: session.agentSnapshot?.name ?? "Sistema",
durationMs,
startedAt: session.startedAt,
endedAt: now,
autoEnded: true, // Flag para indicar encerramento automatico
reason: "inatividade",
},
createdAt: now,
})
endedCount++
}
return { endedCount }
},
})
// ============================================
// UPLOAD DE ARQUIVOS (Maquina/Cliente)
// ============================================