- stack.yml: reduz replicas web para 1 (SQLite nao suporta escrita concorrente)
- chat.rs: janela de chat ja abre minimizada para evitar marcar mensagens como lidas prematuramente
- rustdesk.rs: preserva ID existente do RustDesk ao reprovisionar (evita criar novo ID a cada reinstalacao do Raven)
- ChatWidget.tsx: remove isMinimized das dependencias do useEffect para evitar memory leak de resubscriptions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Web: markChatRead agora zera unreadByAgent na sessao ativa
- Desktop: usa unreadCount do backend ao inves de calcular localmente
- Backend: listMachineMessages retorna unreadCount da sessao
- Centraliza colunas da tabela de tickets do dispositivo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reescrita completa das secoes 10-13 do OPERATIONS.md:
- Secao 10: Historico completo do problema de memoria OOM
- Cronologia do problema (Nov/2025 ate 10/12/2025)
- Causa raiz identificada (versoes de documentos em memoria)
- Solucao em 3 partes: crons, limpeza, codigo do heartbeat
- Resultados: 450MB -> 17MB banco, 19GB -> 395MB memoria
- Secao 11: Erros shape_inference marcados como RESOLVIDOS
- Problema eliminado pela limpeza do banco
- Crons movidos = nenhum novo registro problematico
- Secao 12: Arquitetura final dos crons
- Diagrama da nova arquitetura (Linux crontab -> Next.js -> Convex)
- Mapeamento completo dos crons migrados
- Configuracao atual do crontab na VPS
- Secao 13 (NOVA): Guia de monitoramento pos-correcao
- Metricas esperadas para sistema saudavel
- Comandos de verificacao
- Procedimento de limpeza (se necessario)
- Resumo de commits e backups disponiveis
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Compara inventory/metrics com valores atuais antes de incluir no patch
- Usa JSON.stringify para comparacao eficiente de objetos
- Filtra campos de metadata que realmente mudaram
- Evita criacao de versoes quando heartbeat envia dados identicos
Isso previne o acumulo de versoes no Convex que causava OOM.
Reducao de memoria apos limpeza manual:
- DB: 450MB -> 16MB (96%)
- RAM: 7GB -> 189MB (97%)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problema:
- Cron jobs do Convex criam registros em _scheduled_job_logs
- Convex self-hosted carrega TODAS as versoes em memoria
- 1488 execucoes/dia = ~45k registros/mes acumulando
- Uso de memoria chegando a 19GB, causando 12 OOM kills/dia
Solucao:
- Criar endpoints HTTP em /api/cron/* para substituir crons
- Desabilitar crons no Convex (comentados em crons.ts)
- Chamar endpoints via crontab do Linux
Novos arquivos:
- src/app/api/cron/chat-cleanup/route.ts
- src/app/api/cron/usb-cleanup/route.ts
- scripts-static/* (copiado da VPS para versionamento)
Documentacao:
- docs/OPERATIONS.md secao 12 com instrucoes do crontab
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adicionar console.log no inicio de autoEndInactiveSessions (liveChat.ts)
- Adicionar console.log no inicio de cleanupStalePendingPolicies (usbPolicy.ts)
- Documentar problema de shape_inference e solucao em OPERATIONS.md (Secao 11)
- Atualizar .env.example com BETTER_AUTH_SECRET de 32+ caracteres
O shape_inference do Convex self-hosted falha ao unificar arrays vazios
(logLines: []) com arrays de strings (logLines: ["msg"]). Garantindo que
todo cron job produza ao menos um log, evitamos o conflito de tipos.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adicionar mock da nova tabela machineHeartbeats com metodo first()
para corrigir teste getById apos refatoracao do heartbeat.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Criar tabela machineHeartbeats para armazenar lastHeartbeatAt separadamente
- Modificar heartbeat para so atualizar machines quando ha mudancas reais
- Atualizar queries listByTenant e getById para usar nova tabela
- Reducao drastica de versoes de documentos criadas a cada heartbeat
Antes: ~54 versoes por maquina (3524 linhas para 65 maquinas)
Agora: heartbeat atualiza documento leve, machines so muda com dados novos
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add INVENTORY_BLOCKLIST to filter 'software' and 'extended' fields
from machine metadata (these fields can be 100KB+ each)
- Add compactMachineMetadata migration to clean existing large documents
- Preserve essential fields: metrics, postureAlerts, collaborator,
inventory.os, cpu, memory, disks, network, services
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fechar ConvexClient antigo antes de criar novo (evita memory leak)
- Adicionar flag disposed para prevenir race condition em useEffect
- Reduzir polling SSE de 1s para 5s (balanco entre responsividade e carga)
- Adicionar .take() aos mocks de testes para compatibilidade
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problema: Convex backend consumindo 16GB+ de RAM causando OOM kills
Correcoes aplicadas:
- Substituido todos os .collect() por .take(LIMIT) em 27+ arquivos
- Adicionado indice by_usbPolicyStatus para otimizar query de maquinas
- Corrigido N+1 problem em alerts.ts usando Map lookup
- Corrigido full table scan em usbPolicy.ts
- Corrigido subscription leaks no frontend (tickets-view, use-ticket-categories)
- Atualizado versao do Convex backend para precompiled-2025-12-04-cc6af4c
Arquivos principais modificados:
- convex/*.ts - limites em todas as queries .collect()
- convex/schema.ts - novo indice by_usbPolicyStatus
- convex/alerts.ts - N+1 fix com Map
- convex/usbPolicy.ts - uso do novo indice
- src/components/tickets/tickets-view.tsx - skip condicional
- src/hooks/use-ticket-categories.ts - skip condicional
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Corrige warning do eslint sobre dependencia faltante no hook useEffect
da assinatura de chat updates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adiciona tickets.listPaginated no backend com paginacao nativa Convex
- Converte TicketsView para usePaginatedQuery com controles numerados
- Converte PortalTicketList para usePaginatedQuery com controles numerados
- Atualiza tauri e @tauri-apps/api para versao 2.9
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The take() method isn't available in test mocks, so using
collect() followed by slice() to limit results.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adicionar verificacao final antes de window.location.href
- Substituir localhost por URL de producao como fallback
- Adicionar logs de debug para diagnostico
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Adicionar ticket_ref ao comando Tauri open_chat_window
- Passar ticket_ref nas chamadas do tray menu
- Usar 0 como fallback para deeplinks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Mudar texto 'Chat #' para 'Ticket #' no desktop
- Passar ticketRef via URL para exibir numero correto
- Ajustar tamanho da janela minimizada (240px)
- Incluir ticketRef no checkMachineUpdates (Convex)
- Ajustar padding dos botoes no chat web
- Mudar icone 'Todos os tickets' para ClipboardList
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Substituir WebSocket por SSE para real-time (chat.rs)
- Corrigir inicialização do chat runtime em lib.rs
- Iniciar unreadByMachine em 0 ao criar sessão (liveChat.ts)
- Corrigir área de clique do chip minimizado (pointer-events)
- Corrigir roteamento SPA no Tauri (index.html?view=chat)
- Corrigir estado inicial isMinimized como true
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Histórico de chat:
- Adiciona Card branco igual à linha do tempo
- Corrige acentuações (Histórico, sessão, sessões)
CI/CD:
- Adiciona step de lint antes do build no workflow de deploy
- Se o lint falhar, o deploy é cancelado (fail fast)
- Evita que código com erros de lint seja deployado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extrai chatHistory?.sessions para variavel antes do useMemo
para satisfazer o React Compiler que exigia dependencias inferidas
iguais as especificadas manualmente.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove fundo cinza/Card do historico de chat
- Agrupa sessoes por dia (Hoje, Ontem, data completa)
- Adiciona expansao/colapso por dia e por sessao
- Implementa paginacao de dias (5 por vez) e mensagens (20 por vez)
- Move historico para baixo da timeline (web e portal)
Estrutura escalavel para muitas interacoes de chat.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O step "Ensure Convex service envs" fazia docker service update
para adicionar env vars que já são passadas pelo stack.yml via
substituição de variáveis. Isso disparava um rolling update
desnecessário com ~60s de downtime a cada deploy.
As env vars (MACHINE_PROVISIONING_SECRET, etc) já são definidas
no stack.yml e interpoladas do .env durante o docker stack deploy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona hidden: true no item Incidentes
- Página /incidentes continua acessível via URL direta
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove docker service update --force que causava downtime
- Agrupa env vars do Convex em um único update (evita múltiplos restarts)
- Adiciona delay: 10s e monitor: 30s no update_config
- Healthcheck do web usa /api/health com timeout
- Ajusta start_period: 180s (web) e 60s (convex)
- Convex backend não é mais forçado a reiniciar após stack deploy
Fluxo correto de deploy:
1. docker stack deploy detecta mudança
2. Novo container é criado (start-first)
3. Swarm espera healthcheck passar
4. Swarm espera monitor period (30s)
5. Container antigo é removido
6. Zero downtime durante todo o processo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>