feat: add health dashboard and local ticket archive

This commit is contained in:
rever-tecnologia 2025-12-10 14:43:13 -03:00
parent 0d78abbb6f
commit 0a6b808d99
15 changed files with 824 additions and 60 deletions

View file

@ -5028,3 +5028,68 @@ export const listPaginated = query({
};
},
})
// Exporta tickets resolvidos para arquivamento externo (somente com segredo)
export const exportForArchive = query({
args: {
tenantId: v.string(),
before: v.number(), // timestamp ms
limit: v.optional(v.number()),
secret: v.optional(v.string()),
},
handler: async (ctx, args) => {
const allowedSecret = process.env["INTERNAL_HEALTH_TOKEN"] ?? process.env["REPORTS_CRON_SECRET"]
if (allowedSecret && args.secret !== allowedSecret) {
throw new ConvexError("Nao autorizado")
}
const cutoff = args.before
const limit = Math.min(args.limit ?? 50, 200)
const candidates = await ctx.db
.query("tickets")
.withIndex("by_tenant_resolved", (q) => q.eq("tenantId", args.tenantId).lt("resolvedAt", cutoff))
.order("desc")
.take(limit)
const result: Array<{
ticket: Doc<"tickets">
comments: Array<Doc<"ticketComments">>
events: Array<Doc<"ticketEvents">>
}> = []
for (const t of candidates) {
const comments = await ctx.db
.query("ticketComments")
.withIndex("by_ticket", (q) => q.eq("ticketId", t._id))
.take(200)
const events = await ctx.db
.query("ticketEvents")
.withIndex("by_ticket", (q) => q.eq("ticketId", t._id))
.order("desc")
.take(200)
result.push({
ticket: t,
comments,
events,
})
}
return {
total: result.length,
items: result.map((item) => ({
ticket: item.ticket,
comments: item.comments.map((c) => ({
...c,
attachments: (c.attachments ?? []).map((att) => ({
storageId: att.storageId,
name: att.name,
size: att.size ?? null,
type: att.type ?? null,
})),
})),
events: item.events,
})),
}
},
})