feat: export reports as xlsx and add machine inventory

This commit is contained in:
Esdras Renan 2025-10-27 18:00:28 -03:00
parent 29b865885c
commit 714b199879
34 changed files with 2304 additions and 245 deletions

View file

@ -6,6 +6,7 @@ import { sha256 } from "@noble/hashes/sha256"
import { randomBytes } from "@noble/hashes/utils"
import type { Doc, Id } from "./_generated/dataModel"
import type { MutationCtx } from "./_generated/server"
import { normalizeStatus } from "./tickets"
const DEFAULT_TENANT_ID = "tenant-atlas"
const DEFAULT_TOKEN_TTL_MS = 1000 * 60 * 60 * 24 * 30 // 30 dias
@ -27,7 +28,7 @@ function getTokenTtlMs(): number {
return parsed
}
function getOfflineThresholdMs(): number {
export function getOfflineThresholdMs(): number {
const raw = process.env["MACHINE_OFFLINE_THRESHOLD_MS"]
if (!raw) return DEFAULT_OFFLINE_THRESHOLD_MS
const parsed = Number(raw)
@ -37,7 +38,7 @@ function getOfflineThresholdMs(): number {
return parsed
}
function getStaleThresholdMs(offlineMs: number): number {
export function getStaleThresholdMs(offlineMs: number): number {
const raw = process.env["MACHINE_STALE_THRESHOLD_MS"]
if (!raw) return offlineMs * 12
const parsed = Number(raw)
@ -1019,6 +1020,51 @@ export const listAlerts = query({
},
})
export const listOpenTickets = query({
args: {
machineId: v.id("machines"),
limit: v.optional(v.number()),
},
handler: async (ctx, { machineId, limit }) => {
const machine = await ctx.db.get(machineId)
if (!machine) {
return []
}
const takeLimit = Math.max(1, Math.min(limit ?? 10, 50))
const candidates = await ctx.db
.query("tickets")
.withIndex("by_tenant_machine", (q) => q.eq("tenantId", machine.tenantId).eq("machineId", machineId))
.order("desc")
.take(200)
const openTickets = candidates
.filter((ticket) => normalizeStatus(ticket.status) !== "RESOLVED")
.sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0))
.slice(0, takeLimit)
return openTickets.map((ticket) => ({
id: ticket._id,
reference: ticket.reference,
subject: ticket.subject,
status: normalizeStatus(ticket.status),
priority: ticket.priority ?? "MEDIUM",
updatedAt: ticket.updatedAt,
createdAt: ticket.createdAt,
assignee: ticket.assigneeSnapshot
? {
name: (ticket.assigneeSnapshot as { name?: string })?.name ?? null,
email: (ticket.assigneeSnapshot as { email?: string })?.email ?? null,
}
: null,
machine: {
id: String(ticket.machineId ?? machineId),
hostname:
((ticket.machineSnapshot as { hostname?: string } | undefined)?.hostname ?? machine.hostname ?? null),
},
}))
},
})
export const updatePersona = mutation({
args: {
machineId: v.id("machines"),