Add USB policy improvements and emprestimos details modal
- Add cron job to cleanup stale pending USB policies every 30 min - Add cleanupStalePendingPolicies mutation to usbPolicy.ts - Add USB policy fields to machines listByTenant query - Display USB status chip in device details and bulk control modal - Add details modal for emprestimos with all loan information - Add observacoesDevolucao field to preserve original observations - Fix status text size in details modal title 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e493ec9d5d
commit
7469d3b5e6
7 changed files with 346 additions and 66 deletions
|
|
@ -25,4 +25,12 @@ if (autoPauseCronEnabled) {
|
|||
)
|
||||
}
|
||||
|
||||
// Cleanup de policies USB pendentes por mais de 1 hora (sem flag, sempre ativo)
|
||||
crons.interval(
|
||||
"cleanup-stale-usb-policies",
|
||||
{ minutes: 30 },
|
||||
api.usbPolicy.cleanupStalePendingPolicies,
|
||||
{}
|
||||
)
|
||||
|
||||
export default crons
|
||||
|
|
|
|||
|
|
@ -68,8 +68,10 @@ export const list = query({
|
|||
clienteId: emprestimo.clienteId,
|
||||
clienteNome: emprestimo.clienteSnapshot.name,
|
||||
responsavelNome: emprestimo.responsavelNome,
|
||||
responsavelContato: emprestimo.responsavelContato,
|
||||
tecnicoId: emprestimo.tecnicoId,
|
||||
tecnicoNome: emprestimo.tecnicoSnapshot.name,
|
||||
tecnicoEmail: emprestimo.tecnicoSnapshot.email,
|
||||
equipamentos: emprestimo.equipamentos,
|
||||
quantidade: emprestimo.quantidade,
|
||||
valor: emprestimo.valor,
|
||||
|
|
@ -78,6 +80,7 @@ export const list = query({
|
|||
dataDevolucao: emprestimo.dataDevolucao,
|
||||
status: emprestimo.status,
|
||||
observacoes: emprestimo.observacoes,
|
||||
observacoesDevolucao: emprestimo.observacoesDevolucao,
|
||||
multaDiaria: emprestimo.multaDiaria,
|
||||
multaCalculada: emprestimo.multaCalculada,
|
||||
createdAt: emprestimo.createdAt,
|
||||
|
|
@ -231,7 +234,7 @@ export const devolver = mutation({
|
|||
status: "DEVOLVIDO",
|
||||
dataDevolucao: now,
|
||||
multaCalculada,
|
||||
observacoes: args.observacoes ?? emprestimo.observacoes,
|
||||
observacoesDevolucao: args.observacoes,
|
||||
updatedBy: args.updatedBy,
|
||||
updatedAt: now,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1015,6 +1015,9 @@ export const listByTenant = query({
|
|||
lastPostureAt,
|
||||
remoteAccess: machine.remoteAccess ?? null,
|
||||
customFields: machine.customFields ?? [],
|
||||
usbPolicy: machine.usbPolicy ?? null,
|
||||
usbPolicyStatus: machine.usbPolicyStatus ?? null,
|
||||
usbPolicyError: machine.usbPolicyError ?? null,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
|||
|
|
@ -801,6 +801,7 @@ export default defineSchema({
|
|||
dataDevolucao: v.optional(v.number()),
|
||||
status: v.string(),
|
||||
observacoes: v.optional(v.string()),
|
||||
observacoesDevolucao: v.optional(v.string()),
|
||||
multaDiaria: v.optional(v.number()),
|
||||
multaCalculada: v.optional(v.number()),
|
||||
createdBy: v.id("users"),
|
||||
|
|
|
|||
|
|
@ -249,3 +249,54 @@ export const bulkSetUsbPolicy = mutation({
|
|||
return { results, total: args.machineIds.length, successful: results.filter((r) => r.success).length }
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Cleanup de policies USB pendentes por mais de 1 hora.
|
||||
* Marca como FAILED com mensagem de timeout.
|
||||
*/
|
||||
export const cleanupStalePendingPolicies = mutation({
|
||||
args: {
|
||||
staleThresholdMs: v.optional(v.number()),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
const thresholdMs = args.staleThresholdMs ?? 3600000 // 1 hora por padrao
|
||||
const now = Date.now()
|
||||
const cutoff = now - thresholdMs
|
||||
|
||||
// Buscar maquinas com status PENDING e appliedAt antigo
|
||||
const allMachines = await ctx.db.query("machines").collect()
|
||||
const staleMachines = allMachines.filter(
|
||||
(m) =>
|
||||
m.usbPolicyStatus === "PENDING" &&
|
||||
m.usbPolicyAppliedAt !== undefined &&
|
||||
m.usbPolicyAppliedAt < cutoff
|
||||
)
|
||||
|
||||
let cleaned = 0
|
||||
for (const machine of staleMachines) {
|
||||
await ctx.db.patch(machine._id, {
|
||||
usbPolicyStatus: "FAILED",
|
||||
usbPolicyError: "Timeout: Agent nao reportou status apos 1 hora. Verifique se o agent esta ativo.",
|
||||
updatedAt: now,
|
||||
})
|
||||
|
||||
// Atualizar evento correspondente
|
||||
const latestEvent = await ctx.db
|
||||
.query("usbPolicyEvents")
|
||||
.withIndex("by_machine_created", (q) => q.eq("machineId", machine._id))
|
||||
.order("desc")
|
||||
.first()
|
||||
|
||||
if (latestEvent && latestEvent.status === "PENDING") {
|
||||
await ctx.db.patch(latestEvent._id, {
|
||||
status: "FAILED",
|
||||
error: "Timeout automatico",
|
||||
})
|
||||
}
|
||||
|
||||
cleaned++
|
||||
}
|
||||
|
||||
return { cleaned, checked: allMachines.length }
|
||||
},
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue