feat: agenda polish, SLA sync, filters

This commit is contained in:
Esdras Renan 2025-11-08 02:34:43 -03:00
parent 7fb6c65d9a
commit 6ab8a6ce89
40 changed files with 2771 additions and 154 deletions

View file

@ -75,6 +75,67 @@ function pruneUndefined<T extends Record<string, unknown>>(input: T): T {
return input
}
type TicketSlaSnapshotRecord = {
categoryId?: Id<"ticketCategories">
categoryName?: string
priority?: string
responseTargetMinutes?: number
responseMode?: string
solutionTargetMinutes?: number
solutionMode?: string
alertThreshold?: number
pauseStatuses?: string[]
}
type ExportedSlaSnapshot = {
categoryId?: string
categoryName?: string
priority?: string
responseTargetMinutes?: number
responseMode?: string
solutionTargetMinutes?: number
solutionMode?: string
alertThreshold?: number
pauseStatuses?: string[]
}
function serializeSlaSnapshot(snapshot?: TicketSlaSnapshotRecord | null): ExportedSlaSnapshot | undefined {
if (!snapshot) return undefined
const exported = pruneUndefined<ExportedSlaSnapshot>({
categoryId: snapshot.categoryId ? String(snapshot.categoryId) : undefined,
categoryName: snapshot.categoryName,
priority: snapshot.priority,
responseTargetMinutes: snapshot.responseTargetMinutes,
responseMode: snapshot.responseMode,
solutionTargetMinutes: snapshot.solutionTargetMinutes,
solutionMode: snapshot.solutionMode,
alertThreshold: snapshot.alertThreshold,
pauseStatuses: snapshot.pauseStatuses && snapshot.pauseStatuses.length > 0 ? snapshot.pauseStatuses : undefined,
})
return Object.keys(exported).length > 0 ? exported : undefined
}
function normalizeImportedSlaSnapshot(snapshot: unknown): TicketSlaSnapshotRecord | undefined {
if (!snapshot || typeof snapshot !== "object") return undefined
const record = snapshot as Record<string, unknown>
const pauseStatuses = Array.isArray(record.pauseStatuses)
? record.pauseStatuses.filter((value): value is string => typeof value === "string")
: undefined
const normalized = pruneUndefined<TicketSlaSnapshotRecord>({
categoryName: typeof record.categoryName === "string" ? record.categoryName : undefined,
priority: typeof record.priority === "string" ? record.priority : undefined,
responseTargetMinutes: typeof record.responseTargetMinutes === "number" ? record.responseTargetMinutes : undefined,
responseMode: typeof record.responseMode === "string" ? record.responseMode : undefined,
solutionTargetMinutes: typeof record.solutionTargetMinutes === "number" ? record.solutionTargetMinutes : undefined,
solutionMode: typeof record.solutionMode === "string" ? record.solutionMode : undefined,
alertThreshold: typeof record.alertThreshold === "number" ? record.alertThreshold : undefined,
pauseStatuses: pauseStatuses && pauseStatuses.length > 0 ? pauseStatuses : undefined,
})
return Object.keys(normalized).length > 0 ? normalized : undefined
}
async function ensureUser(
ctx: MutationCtx,
tenantId: string,
@ -333,6 +394,14 @@ export const exportTenantSnapshot = query({
createdAt: ticket.createdAt,
updatedAt: ticket.updatedAt,
tags: ticket.tags ?? [],
slaSnapshot: serializeSlaSnapshot(ticket.slaSnapshot as TicketSlaSnapshotRecord | null),
slaResponseDueAt: ticket.slaResponseDueAt ?? undefined,
slaSolutionDueAt: ticket.slaSolutionDueAt ?? undefined,
slaResponseStatus: ticket.slaResponseStatus ?? undefined,
slaSolutionStatus: ticket.slaSolutionStatus ?? undefined,
slaPausedAt: ticket.slaPausedAt ?? undefined,
slaPausedBy: ticket.slaPausedBy ?? undefined,
slaPausedMs: ticket.slaPausedMs ?? undefined,
comments: comments
.map((comment) => {
const author = userMap.get(comment.authorId)
@ -446,6 +515,14 @@ export const importPrismaSnapshot = mutation({
createdAt: v.number(),
updatedAt: v.number(),
tags: v.optional(v.array(v.string())),
slaSnapshot: v.optional(v.any()),
slaResponseDueAt: v.optional(v.number()),
slaSolutionDueAt: v.optional(v.number()),
slaResponseStatus: v.optional(v.string()),
slaSolutionStatus: v.optional(v.string()),
slaPausedAt: v.optional(v.number()),
slaPausedBy: v.optional(v.string()),
slaPausedMs: v.optional(v.number()),
comments: v.array(
v.object({
authorEmail: v.string(),
@ -513,6 +590,9 @@ export const importPrismaSnapshot = mutation({
let eventsInserted = 0
for (const ticket of snapshot.tickets) {
const normalizedSnapshot = normalizeImportedSlaSnapshot(ticket.slaSnapshot)
const slaPausedMs = typeof ticket.slaPausedMs === "number" ? ticket.slaPausedMs : undefined
const requesterId = await ensureUser(
ctx,
snapshot.tenantId,
@ -567,6 +647,14 @@ export const importPrismaSnapshot = mutation({
updatedAt: ticket.updatedAt,
createdAt: ticket.createdAt,
tags: ticket.tags && ticket.tags.length > 0 ? ticket.tags : undefined,
slaSnapshot: normalizedSnapshot,
slaResponseDueAt: ticket.slaResponseDueAt ?? undefined,
slaSolutionDueAt: ticket.slaSolutionDueAt ?? undefined,
slaResponseStatus: ticket.slaResponseStatus ?? undefined,
slaSolutionStatus: ticket.slaSolutionStatus ?? undefined,
slaPausedAt: ticket.slaPausedAt ?? undefined,
slaPausedBy: ticket.slaPausedBy ?? undefined,
slaPausedMs,
customFields: undefined,
totalWorkedMs: undefined,
activeSessionId: undefined,