diff --git a/convex/crons.ts b/convex/crons.ts
index 7279f87..74c7fb2 100644
--- a/convex/crons.ts
+++ b/convex/crons.ts
@@ -1,14 +1,5 @@
import { cronJobs } from "convex/server"
-import { api } from "./_generated/api"
const crons = cronJobs()
-// Check hourly and the action will gate by America/Sao_Paulo hour
-crons.interval(
- "hours-usage-alerts-hourly",
- { hours: 1 },
- api.alerts_actions.sendHoursUsageAlerts,
- {}
-)
-
export default crons
diff --git a/convex/queues.ts b/convex/queues.ts
index 4705d3c..985f493 100644
--- a/convex/queues.ts
+++ b/convex/queues.ts
@@ -113,20 +113,39 @@ export const summary = query({
const queues = await ctx.db.query("queues").withIndex("by_tenant", (q) => q.eq("tenantId", tenantId)).collect();
const result = await Promise.all(
queues.map(async (qItem) => {
- const pending = await ctx.db
+ const tickets = await ctx.db
.query("tickets")
.withIndex("by_tenant_queue", (q) => q.eq("tenantId", tenantId).eq("queueId", qItem._id))
.collect();
- const waiting = pending.filter((t) => {
- const status = normalizeStatus(t.status);
- return status === "PENDING" || status === "PAUSED";
- }).length;
- const open = pending.filter((t) => {
- const status = normalizeStatus(t.status);
- return status !== "RESOLVED";
- }).length;
- const breached = 0;
- return { id: qItem._id, name: renameQueueString(qItem.name), pending: open, waiting, breached };
+ let pending = 0;
+ let inProgress = 0;
+ let paused = 0;
+ let breached = 0;
+ const now = Date.now();
+ for (const ticket of tickets) {
+ const status = normalizeStatus(ticket.status);
+ if (status === "PENDING") {
+ pending += 1;
+ } else if (status === "AWAITING_ATTENDANCE") {
+ inProgress += 1;
+ } else if (status === "PAUSED") {
+ paused += 1;
+ }
+ if (status !== "RESOLVED") {
+ const dueAt = typeof ticket.dueAt === "number" ? ticket.dueAt : null;
+ if (dueAt && dueAt < now) {
+ breached += 1;
+ }
+ }
+ }
+ return {
+ id: qItem._id,
+ name: renameQueueString(qItem.name),
+ pending,
+ inProgress,
+ paused,
+ breached,
+ };
})
);
return result;
diff --git a/docs/requests-status.md b/docs/requests-status.md
new file mode 100644
index 0000000..fbb2132
--- /dev/null
+++ b/docs/requests-status.md
@@ -0,0 +1,35 @@
+# Solicitações mapeadas
+
+## Tickets e fluxo
+- [feito] Revisão dos status para Pendente / Em andamento / Pausado / Resolvido em listagens e componente de fila.
+- [feito] Botões de play interno/externo com rastreio de horas.
+- [feito] Pausa com motivo obrigatório registrado na timeline.
+- [feito] Encerramento manual com diálogo atualizado e templates.
+- [pendente] Encerramento automático após 3 tentativas de contato (não implementado).
+
+## Comentários e notificações
+- [feito] Comentários internos como padrão para equipe; públicos visíveis ao cliente.
+- [feito] Exportação do histórico completo do ticket em PDF.
+- [feito] E-mails automáticos para comentários públicos e encerramento.
+- [não aplicável] Resumo com IA (feature solicitada, ainda não iniciada).
+
+## Relatórios e contratos
+- [feito] Relatório de horas internas x externas por cliente com exportação XLSX.
+- [feito] Campo "Cliente avulso" e horas contratadas no cadastro de empresas, com alertas configuráveis.
+- [removido] Alertas automáticos por e-mail de uso de horas (cron desativado a pedido).
+
+## Inventário e dispositivos
+- [feito] Unificação de máquinas em “Dispositivos”, suporte a desktops e celulares.
+- [feito] Campos personalizados e templates de exportação no inventário.
+- [aguardando uso] Tag de serviço pode ser adicionada como campo personalizado conforme necessidade.
+
+## Perfis e acesso
+- [feito] Perfis Admin/Agente/Gestor/Usuário com restrições de visualização por empresa.
+- [feito] Motivo da troca de responsável registrado como comentário interno.
+- [feito] Templates de comentário e encerramento gerenciáveis na área de configurações.
+- [feito] Ajuste de horas manual com motivo e log.
+
+## Itens adicionais
+- [pendente] Dashboard personalizado para gestores (fora do escopo atual).
+- [pendente] Integração com IA/assistente para resumo automático.
+- [pendente] Gatilho automático para encerramento por falta de contato (ver item em Tickets e fluxo).
diff --git a/src/components/admin/devices/admin-devices-overview.tsx b/src/components/admin/devices/admin-devices-overview.tsx
index d918bee..e3a6696 100644
--- a/src/components/admin/devices/admin-devices-overview.tsx
+++ b/src/components/admin/devices/admin-devices-overview.tsx
@@ -3520,13 +3520,13 @@ export function DeviceDetails({ device }: DeviceDetailsProps) {
{device.authEmail ?? "E-mail não definido"}
{device.authEmail ? (
-