sistema-de-chamados/src/lib/sla-utils.ts
2025-11-08 02:34:43 -03:00

66 lines
2 KiB
TypeScript

import type { Ticket } from "@/lib/schemas/ticket"
export type SlaTimerType = "response" | "solution"
export type SlaDisplayStatus = "on_track" | "at_risk" | "breached" | "met" | "n/a"
const DEFAULT_ALERT_THRESHOLD = 0.8
export function getSlaDueDate(ticket: Ticket, type: SlaTimerType): Date | null {
if (type === "response") {
return ticket.slaResponseDueAt ?? null
}
return ticket.slaSolutionDueAt ?? ticket.dueAt ?? null
}
export function getSlaDisplayStatus(ticket: Ticket, type: SlaTimerType, now: Date = new Date()): SlaDisplayStatus {
const snapshot = ticket.slaSnapshot
const dueAt = getSlaDueDate(ticket, type)
const finalStatus = type === "response" ? ticket.slaResponseStatus : ticket.slaSolutionStatus
if (!snapshot || !dueAt) {
if (finalStatus === "met" || finalStatus === "breached") {
return finalStatus
}
return "n/a"
}
if (finalStatus === "met" || finalStatus === "breached") {
return finalStatus
}
const completedAt = type === "response" ? ticket.firstResponseAt : ticket.resolvedAt
if (completedAt) {
return completedAt.getTime() <= dueAt.getTime() ? "met" : "breached"
}
const elapsed = getEffectiveElapsedMs(ticket, now)
const total = dueAt.getTime() - ticket.createdAt.getTime()
if (total <= 0) {
return now.getTime() <= dueAt.getTime() ? "on_track" : "breached"
}
if (now.getTime() > dueAt.getTime()) {
return "breached"
}
const threshold = snapshot.alertThreshold ?? DEFAULT_ALERT_THRESHOLD
const ratio = elapsed / total
if (ratio >= 1) {
return "breached"
}
if (ratio >= threshold) {
return "at_risk"
}
return "on_track"
}
function getEffectiveElapsedMs(ticket: Ticket, now: Date) {
const pausedMs = ticket.slaPausedMs ?? 0
const pausedAt = ticket.slaPausedAt ?? null
const createdAt = ticket.createdAt instanceof Date ? ticket.createdAt : new Date(ticket.createdAt)
let elapsed = now.getTime() - createdAt.getTime() - pausedMs
if (pausedAt) {
elapsed -= now.getTime() - pausedAt.getTime()
}
return Math.max(0, elapsed)
}