Align report filters and update work session flows

This commit is contained in:
Esdras Renan 2025-11-19 09:24:30 -03:00
parent 17c1de2272
commit ff9d95746e
7 changed files with 106 additions and 83 deletions

View file

@ -2806,7 +2806,8 @@ export const changeAssignee = mutation({
throw new ConvexError("Gestores não podem reatribuir chamados")
}
const normalizedStatus = normalizeStatus(ticketDoc.status)
if (normalizedStatus === "AWAITING_ATTENDANCE" || ticketDoc.activeSessionId) {
const hasActiveSession = Boolean(ticketDoc.activeSessionId)
if (normalizedStatus === "AWAITING_ATTENDANCE" && !hasActiveSession) {
throw new ConvexError("Pause o atendimento antes de reatribuir o chamado")
}
const currentAssigneeId = ticketDoc.assigneeId ?? null
@ -2833,7 +2834,51 @@ export const changeAssignee = mutation({
avatarUrl: assignee.avatarUrl ?? undefined,
teams: assignee.teams ?? undefined,
}
await ctx.db.patch(ticketId, { assigneeId, assigneeSnapshot, updatedAt: now });
const ticketPatch: Partial<Doc<"tickets">> = {
assigneeId,
assigneeSnapshot,
updatedAt: now,
}
if (hasActiveSession) {
const session = await ctx.db.get(ticketDoc.activeSessionId as Id<"ticketWorkSessions">)
if (session) {
const durationMs = Math.max(0, now - session.startedAt)
const sessionType = (session.workType ?? "INTERNAL").toUpperCase()
const deltaInternal = sessionType === "INTERNAL" ? durationMs : 0
const deltaExternal = sessionType === "EXTERNAL" ? durationMs : 0
await ctx.db.patch(session._id, {
stoppedAt: now,
durationMs,
})
ticketPatch.totalWorkedMs = (ticketDoc.totalWorkedMs ?? 0) + durationMs
ticketPatch.internalWorkedMs = (ticketDoc.internalWorkedMs ?? 0) + deltaInternal
ticketPatch.externalWorkedMs = (ticketDoc.externalWorkedMs ?? 0) + deltaExternal
const newSessionId = await ctx.db.insert("ticketWorkSessions", {
ticketId,
agentId: assigneeId,
workType: sessionType,
startedAt: now,
})
ticketPatch.activeSessionId = newSessionId
ticketPatch.working = true
ticketPatch.status = "AWAITING_ATTENDANCE"
ticketDoc.totalWorkedMs = ticketPatch.totalWorkedMs as number
ticketDoc.internalWorkedMs = ticketPatch.internalWorkedMs as number
ticketDoc.externalWorkedMs = ticketPatch.externalWorkedMs as number
ticketDoc.activeSessionId = newSessionId
} else {
ticketPatch.activeSessionId = undefined
ticketPatch.working = false
}
}
await ctx.db.patch(ticketId, ticketPatch);
await ctx.db.insert("ticketEvents", {
ticketId,
type: "ASSIGNEE_CHANGED",
@ -3717,12 +3762,11 @@ export const startWork = mutation({
}
const ticketDoc = ticket as Doc<"tickets">
const viewer = await requireTicketStaff(ctx, actorId, ticketDoc)
const isAdmin = viewer.role === "ADMIN"
const currentAssigneeId = ticketDoc.assigneeId ?? null
const now = Date.now()
if (currentAssigneeId && currentAssigneeId !== actorId && !isAdmin) {
throw new ConvexError("Somente o responsável atual pode iniciar este chamado")
if (!currentAssigneeId) {
throw new ConvexError("Defina um responsável antes de iniciar o atendimento")
}
if (ticketDoc.activeSessionId) {
@ -3735,26 +3779,9 @@ export const startWork = mutation({
}
}
let assigneePatched = false
const previousAssigneeIdForStart = currentAssigneeId
const previousAssigneeNameForStart =
((ticketDoc.assigneeSnapshot as { name?: string } | null)?.name as string | undefined) ?? "Não atribuído"
if (!currentAssigneeId) {
const assigneeSnapshot = {
name: viewer.user.name,
email: viewer.user.email,
avatarUrl: viewer.user.avatarUrl ?? undefined,
teams: viewer.user.teams ?? undefined,
}
await ctx.db.patch(ticketId, { assigneeId: actorId, assigneeSnapshot, updatedAt: now })
ticketDoc.assigneeId = actorId
assigneePatched = true
}
const sessionId = await ctx.db.insert("ticketWorkSessions", {
ticketId,
agentId: actorId,
agentId: currentAssigneeId,
workType: (workType ?? "INTERNAL").toUpperCase(),
startedAt: now,
})
@ -3768,23 +3795,6 @@ export const startWork = mutation({
...slaStartPatch,
})
if (assigneePatched) {
await ctx.db.insert("ticketEvents", {
ticketId,
type: "ASSIGNEE_CHANGED",
payload: {
assigneeId: actorId,
assigneeName: viewer.user.name,
actorId,
actorName: viewer.user.name,
actorAvatar: viewer.user.avatarUrl ?? undefined,
previousAssigneeId: previousAssigneeIdForStart,
previousAssigneeName: previousAssigneeNameForStart,
},
createdAt: now,
})
}
await ctx.db.insert("ticketEvents", {
ticketId,
type: "WORK_STARTED",