- Muda collapsible de offcanvas para icon na sidebar
- Adiciona tooltips aos itens de menu quando colapsado
- Itens com submenu mostram mini-menu no tooltip
- Logo mostra apenas icone quando colapsado
- NavUser mostra apenas avatar quando colapsado
- Adiciona separadores entre secoes quando colapsado
- Centraliza icones horizontalmente no modo colapsado
- Persiste estado da sidebar via cookie entre navegacoes
- Corrige hydration mismatch com sincronizacao pos-hidratacao
- Desabilita transicoes durante sincronizacao inicial
- Remove bolinha do tooltip e ajusta espacamento
- Corrige redirecionamento ao resetar dispositivo no Tauri
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa window.location.href com URL do Tauri em vez de API inexistente
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa getCurrentWebviewWindow().navigate() para voltar para a pagina
inicial do app Tauri em vez de ir para o servidor web
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa mesmo layout da sidebar: Raven + badge Plataforma de chamados
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Limpa todos os campos de input ao resetar (codigo, email, nome)
- Forca recarregar pagina inicial para sair de pagina web carregada
- Evita redirect para login web quando dispositivo e resetado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa fixed inset-0 com overflow-hidden para bloquear scroll
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove exibicao do nome da empresa
- Coloca botoes lado a lado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona verificacao de isMachineActive antes de redirecionar para handshake
- Remove mensagens de erro antigas com erro gramatical
- Corrige texto do template HTML de desativacao no servidor
- Corrige mensagem de erro na API de sessions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona bordas arredondadas e efeito suspenso no painel direito
- Aumenta proporcionalmente o header (Raven, Helpdesk, Por Rever Tecnologia)
- Ajusta posicionamento do header com margem superior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove identificador machine-xxx do header dos cards
- Substitui badge de arquitetura (X86_64) por status de ativacao do Windows
- Remove badge redundante de tipo de dispositivo
- Ajusta altura da badge na sidebar para nao cortar texto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Subtitulo agora aparece como badge com fundo escuro
- Alterado texto para "Plataforma de chamados"
- Estilo consistente com badges da plataforma
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- "Sistema de chamados" agora aparece como badge pill
- Estilo consistente com badges usadas na plataforma web
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona logo-raven.png local no public do desktop
- Usa logo local como padrao em vez de buscar do servidor
- Fallback continua buscando do servidor se local falhar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria DeviceCardSkeleton que simula a estrutura do DeviceCard
- Exibe grid de 6 skeletons durante carregamento
- Mantém mesmo layout responsivo dos cards reais
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona text-center em todos os TableCell
- Centraliza conteudo interno com justify-center
- Mantem texto a esquerda dentro dos cards de contrato/contato
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige erro NaN nos campos numericos (reopenWindowDays, contractedHoursPerMonth)
usando z.preprocess para converter NaN para null
- Ajusta espacamento nos AccordionContent para melhor legibilidade
- Define tamanho consistente nos botoes Cancelar/Salvar (size="sm")
- Accordions agora iniciam fechados por padrao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige erro gramatical: "Dispositivo desativada" -> "Dispositivo desativado"
- Adiciona botao "Verificar novamente" na tela de desativacao
- Adiciona callback onReactivated no MachineStateMonitor
- Corrige fundo escuro para cobrir toda a tela quando desativado
- Corrige acentuacoes faltantes no historico de automacoes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona linhas expandiveis no historico de execucoes
- Mostra detalhes completos de cada acao (destinatarios, assunto, etc.)
- Salva mais informacoes no backend para acoes de e-mail
- Remove log de progresso do dashboard de reports
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O agente envia o inventory dentro de metadata, não diretamente em args.inventory.
Agora o backend verifica ambos os lugares.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Agente Rust: captura LastBootTime, uptime e contagem de boots
- Backend: extrai campos do extended (bootInfo, discos, RAM, etc) antes de salvar
- Frontend /devices: exibe secao de ultimo reinicio
- SLA global: adiciona campos de modo, threshold de alerta e status de pausa
- Corrige acento em "destinatario" -> "destinatario" em automations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige formatacao de tempo para exibir segundos (ex: 2m 04s)
- Adiciona campo de segundos nos inputs de ajuste de tempo
- Melhora espacamento entre secoes de tempo interno e externo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Softwares instalados:
- Corrige contador de paginação (mostra 1-30, 31-60, etc.)
- Remove tooltip do botão de limpar pesquisa
Campos personalizados:
- Adiciona mensagem indicando tipo de dispositivo (desktop/celular)
- Melhora mensagem quando não há campos disponíveis
- Adiciona botão X para limpar valor de campos texto/número
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona botao de limpar pesquisa em softwares
- Corrige paginacao com historico de cursores
- Corrige acentuacao em politicas de SLA (politica -> política)
- Corrige acentuacao em varios textos do frontend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- versao -> versão
- nao -> não
- Atualizacao -> Atualização
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona tipos TypeScript para novos dados do Windows
- Exibe informacoes de bateria com status traduzido
- Exibe sensores termicos em tabela
- Exibe adaptadores de rede com velocidade e status
- Exibe monitores conectados com fabricante e serial
- Exibe info do chassis/gabinete com tipo traduzido
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Captura info de bateria (Win32_Battery) com status traduzido
- Captura sensores termicos via WMI ThermalZone e OpenHardwareMonitor
- Captura adaptadores de rede fisicos com status de conexao
- Captura monitores conectados (fabricante, serial, modelo)
- Captura info de chassis/gabinete com tipo traduzido
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria tabela machineSoftware no schema com indices otimizados
- Adiciona mutations para sincronizar softwares do heartbeat
- Atualiza heartbeat para processar e salvar softwares
- Cria componente DeviceSoftwareList com pesquisa e paginacao
- Integra lista de softwares no drawer de detalhes do dispositivo
feat(sla): transforma formulario em modal completo
- Substitui formulario inline por modal guiado
- Adiciona badge "Global" para indicar escopo da politica
- Adiciona seletor de unidade de tempo (minutos, horas, dias)
- Melhora textos e adiciona dica sobre hierarquia de SLAs
fix(reports): ajusta altura do SearchableCombobox
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona try-catch para cada envio individual
- Registra logs detalhados de sucesso e falha por destinatario
- Retorna informacao sobre quantos e-mails falharam
- Imprime resumo de envios no console para debug
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Frontend: usa usePersistentCompanyFilter para persistir selecao
- Frontend: adiciona opcao "Todas as empresas" como primeira opcao
- Backend: torna companyId opcional na query companyOverview
- Backend: usa resolveScopedCompanyId para scoping de gestores
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Ao iniciar chat: inicia timer EXTERNAL automaticamente se nao houver sessao ativa
- Ao encerrar chat: pausa timer automaticamente se houver sessao ativa
- Adiciona razao de pausa END_LIVE_CHAT para identificar pausas automaticas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona CompanySlaManager para gerenciar empresas com SLA customizado
- Adiciona CompanySlaDrawer para configurar regras de SLA por empresa
- Integra componentes no SlasManager existente
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## SLA por Empresa
- Adiciona tabela companySlaSettings no schema
- Cria convex/companySlas.ts com queries e mutations
- Modifica resolveTicketSlaSnapshot para verificar SLA da empresa primeiro
- Fallback: empresa > categoria > padrao
## Modal de Exclusao de Automacoes
- Substitui confirm() nativo por Dialog gracioso
- Segue padrao do delete-ticket-dialog
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria hook useMachineStateMonitor com subscription Convex
- Cria MachineDeactivationOverlay para bloquear acesso
- Integra no PortalShell para exibir overlay quando máquina é desativada
- Adiciona refreshMachineContext ao AuthProvider para retry manual
- Funciona tanto via Raven quanto via navegador web
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Renderiza MachineStateMonitor mesmo durante tela de loading
- Adiciona verificação de isMachineActive na condição de early return
- Detecta estado de desativação/reset já na carga inicial
- Adiciona logs para facilitar debugging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona modais de confirmacao para resetar e desativar dispositivos
- Cria query getMachineState no Convex para monitoramento em tempo real
- Implementa MachineStateMonitor no desktop para detectar mudancas
- Desktop redireciona para tela de registro apos reset
- Desktop mostra tela de desativacao imediatamente apos bloqueio
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona filtro excludeVisits no estado de filtros
- Aplica excludeVisits: true em /tickets e /tickets/resolved
- Visitas agora aparecem apenas em /tickets/visits
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona item "Visitas" no submenu de Tickets com icone MapPin
- Cria pagina /tickets/visits que filtra apenas tickets da fila Visitas
- Corrige teste de automacao para usar emailProps ao inves de html
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move renderizacao do React Email para a action Node.js
- Passa props do email em vez do HTML ja renderizado
- Resolve erro "dynamic module import unsupported"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Tickets com status AWAITING_ATTENDANCE mas sem play ativo
agora contam como "Em aberto"
- "Em andamento" mostra apenas tickets onde working === true
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Corrige erro de TypeScript ao usar o componente legado que
aceita o formato { ticket: TicketCardData }
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona campo reopenWindowDays no cadastro de empresa (padrao 7 dias)
- Ticket usa automaticamente o prazo da empresa ao ser resolvido
- Remove selecao de prazo do modal de encerramento de ticket
- Valor e gravado no ticket no momento da resolucao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove templates incompativeis quando empresa do ticket muda
- Limpa selecao de template ao mudar empresa
- Remove texto "(opcional)" do titulo da secao de checklist
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Centraliza dados das celulas em todas as tabelas (text-center)
- Melhora layout do modal de exclusao com card destacado
- Exibe nome e email do usuario no card de confirmacao
- Usa cores rose para indicar acao destrutiva
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona text-center em todas as celulas de dados
- Centraliza botoes de acoes com inline-flex
- Mantem consistencia visual entre headers e dados
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove text-[11px] e tracking-wide dos headers
- Remove table-fixed e larguras fixas das colunas
- Usa mesmo estilo de /admin/companies (tamanho padrao)
- Remove bordas laterais desnecessarias dos headers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove uppercase dos headers das tabelas
- Corrige acentuacao em "Acoes" para "Ações"
- Ajusta tamanho da fonte para text-[11px] (consistente com outras tabelas)
- Remove min-width das tabelas para evitar scroll horizontal
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria 10 novos templates React Email (invite, password-reset, new-login,
sla-warning, sla-breached, ticket-created, ticket-resolved,
ticket-assigned, ticket-status, ticket-comment)
- Adiciona envio de email ao criar convite de usuario
- Adiciona security_invite em COLLABORATOR_VISIBLE_TYPES
- Melhora tabela de equipe com badges de papel e colunas fixas
- Atualiza TicketCard com nova interface de props
- Remove botao de limpeza de dados antigos do admin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Propaga Set-Cookie do Better Auth no endpoint de avatar\n- Forca refresh da sessao apos upload/remocao\n- Adiciona teste de propagacao e defaults de env para testes
- Remove texto com encoding quebrado ("informações da máquina")
- Corrige gênero de "dispositivo" (masculino, não feminino)
- Remove lógica redundante - skeleton já cobre o estado de carregamento
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona skeleton loading no formulario de novo chamado do portal
- Remove texto confuso do tipo de solicitacao padrao
- Padroniza estilo dos labels Categoria/Subcategoria com os demais campos
- Move botao "Criar" do header para parte inferior do modal na web
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona skeleton no header quando dados do usuario estao carregando
- Remove mensagem "Sem e-mail definido" durante loading
- Substitui spinner por skeleton cards na lista de tickets
- Cria componente PortalTicketCardSkeleton para estado de loading
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige avatar desincronizado na listagem de tickets usando sessao do usuario logado
- Otimiza timer da tickets-table de 1s para 15s (reduz re-renders)
- Remove useEffect desnecessario em status-select (usa prop diretamente)
- Remove useEffects desnecessarios em ticket-custom-fields (usa ticket.customFields diretamente)
- Adiciona React.memo no AssigneeCell para evitar re-renders
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Usa next/font/google para carregar Inter e JetBrains Mono
- Remove @font-face manuais do globals.css
- Corrige variaveis CSS confusas (--font-geist-* com 4 hifens)
- Remove duplicacao de @layer base
- Fontes agora sao otimizadas automaticamente (WOFF2, subset, preload)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Altera altura para h-9 (36px) igual ao componente web
- Aumenta fonte de text-xs para text-sm
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O fix de permissao anterior limpou o diretorio mas o rsync nao
copiou os arquivos corretamente. Este commit dispara um novo deploy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Atualiza docs/SETUP.md e scripts/setup-dev.sh com:
- Instrucoes para configurar chave SSH
- Opcao de usar Personal Access Token (PAT)
- Comandos para clonar/configurar via SSH ou HTTPS
- Script setup-dev.sh agora aceita --ssh para repo privado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O problema anterior: apos limpar o conteudo do diretorio, o proprio
diretorio ainda tinha permissoes de root, fazendo o cp do .env falhar.
Nova abordagem:
- Salvar .env usando Docker (monta origem e /tmp)
- Remover o diretorio COMPLETAMENTE usando Docker (monta diretorio pai)
- Recriar o diretorio com mkdir -p (permissoes do usuario runner)
- Restaurar o .env (agora o diretorio tem permissoes corretas)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O problema: Docker cria arquivos como root durante o build, e em
deploys subsequentes o rsync falha com "Permission denied" porque
o usuario runner nao consegue sobrescrever arquivos de root.
A solucao anterior (chown do destino) falhava silenciosamente porque
alguns arquivos ja tinham permissoes de root de deploys anteriores.
Nova abordagem:
- Antes do rsync, limpar completamente o destino usando Docker Alpine
- Docker Alpine roda como root e consegue remover qualquer arquivo
- O .env eh preservado (backup/restore)
- rsync copia para diretorio limpo, sem conflitos de permissao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona step dedicado para corrigir permissoes apos build Docker:
- Usa container Alpine para fazer chown -R 1000:1000 no build
- Tambem corrige permissoes do destino antes do rsync
Isso resolve o erro "Permission denied" do rsync causado por
arquivos criados pelo Docker como root.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move .github/workflows para .github/workflows.disabled
- Adiciona docs/SETUP.md com guia de setup em novo computador
- Adiciona scripts/setup-dev.sh para setup automatizado
- Remove GitHub Actions runner da VPS (agora usa apenas Forgejo)
CI/CD agora e feito exclusivamente via Forgejo Actions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Arquivos em src/generated/prisma/ criados por containers Docker
(como root) impediam o rsync de sobrescrever no proximo deploy.
Adiciona correcao de permissoes antes do rsync para garantir que
o usuario runner consiga sobrescrever os arquivos.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona solucoes para problemas comuns:
- Regeneracao de hooks quando workflows nao disparam
- Correcao de erro de LevelDB lock
- Reinicio do runner apos reinicio do Forgejo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O Forgejo estava falhando ao iniciar as queues devido ao LevelDB
nao funcionar bem em containers Docker. A mudanca para queue
type=channel resolve o problema de lock.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove setup pnpm e Node.js (bun ja inclui Node.js)
- Remove steps Verify Bun e Permissions diagnostic
- Remove Prune workspace (criava pnpm-workspace.yaml)
- Remove smoke test (register + heartbeat) - nao mais necessario
- Atualiza chaves de cache para usar apenas bun.lock
- Atualiza docs para indicar desktop_release comentado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O job ficava 'aguardando' eternamente porque nao existe runner
com labels [self-hosted, windows, desktop]. Comentado ate que
um runner Windows seja configurado.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove referencias ao mirror (desabilitado) e documenta o novo fluxo
de push para ambos os remotes (GitHub + Forgejo).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O rsync estava preservando o UID 1000 dos arquivos criados pelo
container Docker, causando erros de permissao para o runner (UID 999).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O runner do Forgejo roda com UID 999, mas o workflow estava
fazendo chown para UID 1000, causando erros de permissao no rsync.
- Usa id -u e id -g para pegar o UID/GID correto do runner
- Remove --chown do rsync para usar permissoes do runner
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona type: boolean aos inputs para compatibilidade com Forgejo Actions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O Forgejo agora esta configurado como pull mirror do GitHub:
- Sincronizacao automatica a cada 10 minutos
- Usuario continua usando apenas git push origin main
- CI/CD dispara automaticamente apos sincronizacao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O runner Forgejo esta configurado como self-hosted, entao todos os jobs
precisam usar as labels corretas em vez de ubuntu-latest.
Alteracoes:
- ci-cd-web-desktop.yml: job changes agora usa [self-hosted, linux, vps]
- quality-checks.yml: job lint-test-build agora usa [self-hosted, linux, vps]
- docs/FORGEJO-CI-CD.md: documentacao atualizada com essa diferenca
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Configura o Forgejo como plataforma de CI/CD self-hosted para evitar
custos futuros do GitHub Actions (a partir de marco/2026).
Arquivos adicionados:
- .forgejo/workflows/ci-cd-web-desktop.yml: workflow principal de deploy
- .forgejo/workflows/quality-checks.yml: lint, test e build
- forgejo/stack.yml: stack Docker do Forgejo para Swarm
- forgejo/setup-runner.sh: script de configuracao do runner
- docs/FORGEJO-CI-CD.md: documentacao completa
Forgejo rodando em: https://git.esdrasrenan.com.br🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O campo templateDescription nao estava sendo exibido porque o schema
Zod em src/lib/mappers/ticket.ts nao incluia esse campo, fazendo com
que ele fosse removido durante a validacao dos dados do servidor.
- Adiciona templateDescription ao schema Zod do checklist
- Remove logs de debug dos arquivos de backend e frontend
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Logs adicionados:
- Na criacao do template para ver se description esta sendo salva
- Na aplicacao do template para ver se description existe
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona:
- Query debugTemplateAndTicketChecklist para verificar dados no backend
- Console.log no frontend para verificar dados recebidos
Esses logs serao removidos apos identificar o problema.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O campo templateDescription estava sendo salvo no checklist mas nao
era incluido no mapeamento quando o ticket era retornado pela query.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona apps/desktop/src/convex/_generated/** ao ignore do ESLint
para evitar warnings de diretivas eslint-disable nao utilizadas em
arquivos gerados automaticamente.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona campo templateDescription ao schema do checklist
- Copia descricao do template ao aplicar checklist no ticket
- Exibe ambas descricoes na visualizacao do ticket (template em italico)
- Adiciona documentacao de desenvolvimento local (docs/LOCAL-DEV.md)
- Corrige prisma-client.mjs para usar PostgreSQL em vez de SQLite
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona core🪟allow-start-dragging para corrigir erro ACL do drag-region
- Adiciona logging detalhado no ChatHubWidget para debug de clicks
- Adiciona logging no comando open_chat_window para diagnostico
- Ajusta ordem size/position e set_ignore_cursor_events no Hub
- Remove set_hub_minimized apos build para evitar conflitos de timing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fecha janelas individuais de chat ao abrir o Hub (2+ sessoes)
- Fecha o Hub ao voltar para apenas 1 sessao
- Evita problemas de clique causados por sobreposicao de janelas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O filtro anterior excluia sessoes novas onde o agente ainda nao
enviou mensagem, impedindo que o segundo chat aparecesse no desktop.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona set_focus() apos show() para trazer janela para frente
- Adiciona unminimize() para garantir visibilidade
- Aplica mesma logica para Hub e janelas individuais de chat
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Usa camelCase (ticketId, ticketRef) em vez de snake_case
- Tauri converte automaticamente snake_case do Rust para camelCase no JS
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Inicializa isMinimized baseado na altura real da janela
- Usa h-full em vez de h-screen para layout correto
- Evita inconsistencia entre estado React e tamanho da janela
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona ConvexMachineProvider para autenticacao via machine token
- Cria hooks customizados (useMachineSessions, useMachineMessages, etc)
- Refatora ChatWidget e ChatHubWidget para usar useQuery/useMutation
- Remove polling e dependencia de Tauri events para mensagens
- Adiciona copia local dos arquivos _generated do Convex
- Remove componentes obsoletos (ChatSessionItem, ChatSessionList)
Beneficios:
- Tempo real verdadeiro via WebSocket (sem polling)
- Melhor escalabilidade e performance
- Codigo mais simples e maintivel
- Consistencia de estado entre multiplas janelas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O Better Auth usa cookie cache de 5 minutos para a sessao.
Quando o avatar era removido via Prisma, o cache ainda tinha
o avatar antigo. Agora usamos auth.api.updateUser para
atualizar o usuario e invalidar o cache da sessao.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Melhora UX do select de subcategorias nas condicoes de automacao,
agrupando visualmente as subcategorias dentro de suas respectivas
categorias usando SelectGroup e SelectLabel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige sincronização do avatar no perfil após upload
- Reduz tamanho dos ícones de câmera/lixeira no avatar
- Remove atributos title (tooltips nativos) de toda aplicação
- Adiciona regra no AGENTS.md sobre uso de tooltips
- Permite desmarcar resposta no checklist (toggle)
- Torna campo answer opcional na mutation setChecklistItemAnswer
- Adiciona edição inline dos campos de resumo no painel de detalhes
- Redesenha comentários com layout mais limpo e consistente
- Cria tratamento especial para comentários automáticos de sistema
- Aplica fundo ciano semi-transparente em comentários públicos
- Corrige import do Loader2 no notification-preferences-form
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove classes customizadas para usar mesmo estilo do Somente pendentes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Icone ? com fundo preto semitransparente e texto branco
- Badges maiores (text-[11px], px-2.5) e mais espacadas (gap-2)
- Badge Pergunta com estilo slate ao inves de cyan
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Opcoes de resposta como botoes com estilo pill
- Opcao selecionada em preto com texto branco
- Badges menores e mais compactos
- Icone ? com estilo cyan
- Melhor espacamento geral
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Altera para variant outline com estilo similar ao botao Acessar remoto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Os campos estavam sendo salvos corretamente no banco, mas a query
getById nao os incluia no mapeamento de resposta, fazendo com que
as opcoes de resposta e descricao nao aparecessem no frontend.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige todas as acentuacoes em portugues nos templates de e-mail
- Adiciona @radix-ui/react-radio-group como dependencia
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sincroniza cores com globals.css e status-badge.tsx
- Adiciona botoes grandes e destacados (cyan primary, preto secondary)
- Implementa badges pill com border-radius arredondado
- Importa fonte Inter do Google Fonts
- Adiciona icones em circulos grandes (64px) para templates de status
- Cria cards de informacao do ticket bem estruturados
- Aumenta espacamentos e padding para layout mais limpo
- Centraliza estrelas de avaliacao
- Melhora tipografia com pesos bem definidos
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige hydration mismatch no Toaster (sonner) e ChatWidgetProvider
- Corrige API de preferencias de notificacao (typePreferences como string)
- Melhora visual do Switch (estado ativo em preto)
- Adiciona icones em circulos na pagina de notificacoes
- Corrige acentuacao em "Obrigatorio"
- Corrige centralizacao das estrelas de avaliacao nos e-mails
- Aplica Sentence case nos titulos dos templates de e-mail
- Adiciona script de teste de e-mail
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove coluna de acoes sem implementacao em data-table
- Corrige loading states travados em new-ticket-dialog, close-ticket-dialog
- Adiciona finally blocks em forgot-password e reset-password
- Adiciona tratamento de erros em invokes do Tauri (ChatWidget, ChatHubWidget)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa by_tenant_requester e by_tenant_assignee com tenantId
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove criacao automatica de comentario ao trocar responsavel (ja aparece na timeline)
- Adiciona migration removeAssigneeChangeComments para limpar comentarios antigos
- Adiciona campos description, type, options, answer ao schema de checklist no mapper
- Cria mutation updateAvatar no Convex para sincronizar avatar com snapshots
- Atualiza rota /api/profile/avatar para sincronizar com Convex ao adicionar/remover foto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adiciona filtro para ignorar sessões sem lastAgentMessageAt
(sessões legadas que causam erro de shape no Convex)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Usa patch direto sem buscar sessao (evita erro de shape)
- Encerra sessao pd71bvfbxx7th3npdj519hcf3s7xbe2j que estava causando erros
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- POST /api/admin/fix-chat-sessions
- Chama mutation fixLegacySessions do Convex
- Requer autenticação de admin
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige acentuações: Opções, Não, Descrição, Obrigatório, máx
- Adiciona modal de confirmação para exclusão de itens do checklist
- Remove uso de confirm() nativo
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Busca todas as sessoes, nao apenas por index
- Corrige sessoes encerradas que tambem nao tem o campo
- Adiciona log das sessoes problematicas encontradas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona campo `type` (checkbox/question) nos itens do checklist
- Adiciona campo `description` para descricao do item
- Adiciona campo `options` para opcoes de resposta em perguntas
- Adiciona campo `answer` para resposta selecionada
- Atualiza UI para mostrar descricao e opcoes de pergunta
- Cria componente radio-group para selecao de respostas
- Adiciona mutation setChecklistItemAnswer para salvar respostas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Botao Play habilitado mesmo sem responsavel
- Ao clicar Play sem responsavel, atribui usuario logado automaticamente
- Ao iniciar chat ao vivo sem responsavel, atribui usuario logado
- Adiciona mutation fixLegacySessions para corrigir sessoes antigas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Aceitar convite: cria User com mesmo ID do AuthUser
- Criar usuario admin: usa ID do AuthUser no upsert do User
- Garante sincronismo entre tabelas de auth e dominio
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Desktop:
- Adiciona chamada para start_chat_polling no frontend
- Chat agora inicia corretamente quando usuario faz login
SMTP:
- Atualiza documentacao com nomes corretos das variaveis
- Variaveis configuradas no container da VPS
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduz tamanho de 380x480 para 340x400 (cabe melhor na tela)
- Reposiciona antes de redimensionar para evitar corte
- Melhora logging de debug
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- NSIS: remove servico antigo antes de instalar novo (corrige reinstalacoes)
- NSIS: adiciona retry ao iniciar servico
- agent.rs: usa service_client para aplicar politica USB via IPC primeiro
- Fallback para aplicacao direta se servico indisponivel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Label no formulário de perfil deve ficar alinhado à esquerda.
O botão na seção Segurança está centralizado corretamente.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove justify-start para centralizar conteúdo como o botão Encerrar sessão.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problemas corrigidos:
- Removido always_on_top de todas as janelas (causava competição de Z-order)
- Removido inner_size() síncrono que bloqueava a UI thread
- Simplificado process_chat_update para não fazer múltiplas operações de janela
- Removidos logs de debug
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Background agora usa position absolute para cobrir desde o
topo do card, eliminando a faixa branca acima.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Aumenta de h-20 para h-28 e ajusta margin-top do CardHeader
para cobrir toda a área superior do card.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tauri 2 espera parâmetros em snake_case nos comandos Rust.
Corrigido: ticketId -> ticket_id, ticketRef -> ticket_ref, etc.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove rounded-t-2xl redundante que criava gap branco nos cantos
superiores. O card pai já possui overflow-hidden com rounded-2xl.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Correções implementadas:
1. Adiciona .resizable(false) nas janelas de chat e hub para impedir redimensionamento manual
2. Corrige área clicável invisível quando minimizado (janela agora tem tamanho correto)
3. Corrige clique na lista de sessões para expandir janela quando clicado
4. Diferencia abertura automática (minimizada) de abertura manual (expandida)
- Chat agora abre expandido quando clicado na lista do hub
- Chat abre minimizado quando nova mensagem chega (menos intrusivo)
- Janelas não permitem mais redimensionamento manual
- Área clicável agora corresponde ao tamanho visual da janela
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona chat-hub explicitamente nas capabilities do Tauri
- Adiciona .resizable(false) nas janelas de chat e hub
- Corrige problema de comandos invoke nao funcionando no hub
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Logs para debugar problema de clique não funcionando
na lista de sessões do desktop.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove o icone circular preto do header do chat
quando esta dentro de uma conversa, mantendo mais
espaco para informacoes do ticket.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sessoes de chat sao encerradas apos 12 horas sem atividade
- Criterios de encerramento automatico:
1. Maquina offline (5 min sem heartbeat)
2. Chat inativo (12 horas sem atividade) - NOVO
3. Ticket orfao (sem maquina vinculada)
- Log detalhado com contagem por motivo de encerramento
- Evento no timeline com reason "inatividade_chat"
Isso evita acumular sessoes abertas indefinidamente
quando usuario esquece de encerrar o chat.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria ChatSessionList, ChatSessionItem e ChatHubWidget no desktop
- Adiciona comandos Rust para gerenciar hub window
- Quando ha multiplas sessoes, abre hub ao inves de janela individual
- Hub lista todas as sessoes ativas com badge de nao lidos
- Clicar em sessao abre/foca janela de chat especifica
- Menu do tray abre hub quando ha multiplas sessoes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria ChatSessionList e ChatSessionItem para listar sessões ativas
- Refatora ChatWidget para usar viewMode (list/chat)
- Ordena por não lidos primeiro, depois por última atividade
- Adiciona botão de voltar quando há múltiplos chats
- Persiste viewMode no localStorage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O botão "Concluir todos" agora alterna para "Desmarcar todos"
quando todos os itens do checklist estão marcados como concluídos.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige campo de avatar na API (avatarUrl ao invés de image)
- Altera fluxo para salvar foto apenas ao clicar em "Salvar alterações"
- Adiciona preview local antes do upload definitivo
- Ajusta shader para preencher bordas arredondadas do card
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona endpoint DELETE em /api/profile/avatar
- Mostra dois botões ao hover: câmera (upload) e lixeira (remover)
- Lixeira só aparece quando há uma foto definida
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Substitui o degradê estático pelo shader animado usado nas páginas de login.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Badge Helpdesk preta com texto branco
- Texto maior no painel direito das páginas de auth
- Badge de papel preta em settings
- Adiciona descrição na seção Segurança
- Espaçamento entre título e campos no formulário de login
- Autocomplete nos inputs de senha
- Link de notificações funcional no menu do usuário
- Fallback do avatar com fundo cinza e texto preto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Atualiza cores das badges para padrão cyan do projeto
- Adiciona degradê no header do card de perfil
- Implementa upload de foto de perfil via API Convex
- Integra notificações do Convex com preferências do usuário
- Cria API /api/notifications/send para verificar preferências
- Melhora layout das páginas de login/recuperação com degradê
- Adiciona badge "Helpdesk" e título "Raven" consistente
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona página /recuperar para solicitar redefinição de senha
- Adiciona página /redefinir-senha para definir nova senha com token
- Cria APIs /api/auth/forgot-password e /api/auth/reset-password
- Adiciona notificação por e-mail quando ticket é criado
- Repagina página de configurações removendo informações técnicas
- Adiciona script de teste para todos os tipos de e-mail
- Corrige acentuações em templates de e-mail
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona separador de data entre mensagens de dias diferentes (estilo WhatsApp)
- Mostra "Hoje", "Ontem" ou data completa (ex: "segunda-feira, 15 de dezembro")
- Separa hostname da maquina em linha propria no header
- Hostname com truncate e tooltip para nomes longos
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implementa deteccao dual: timestamp (lastActivityAt) + contador
- Adiciona persistencia de estado em ~/.local/share/Raven/chat-state.json
- Corrige race condition no servidor com refetch antes do patch
- Adiciona campo lastAgentMessageAt no schema do Convex
- Adiciona logs de diagnostico detalhados
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implementa Windows Service (raven-service) para operacoes privilegiadas
- Comunicacao via Named Pipes sem necessidade de UAC adicional
- Adiciona single-instance para evitar multiplos icones na bandeja
- Corrige todos os warnings do clippy (rustdesk, lib, usb_control, agent)
- Remove fallback de elevacao para evitar UAC desnecessario
- USB Policy e RustDesk provisioning agora usam o servico quando disponivel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove campo de busca "Buscar tickets" do header da sidebar
- Aumenta logo de 40x40 para 48x48 pixels
- Aumenta titulo e subtitulo da marca para melhor destaque
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Badges de variáveis agora com fundo preto e texto branco
- Corrige todos os textos sem acentuação (Referência, Título, etc.)
- Adiciona suporte a drag and drop das badges de variáveis
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Substitui cores sky por cyan para manter consistencia visual
- Usa transparencia (cyan-50/60, cyan-200/60) conforme padrao do projeto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Cria componente EmailActionConfig dedicado para configuracao de e-mail
- Layout expandido (full-width) para melhor aproveitamento do espaco
- Variaveis como badges clicaveis que inserem no campo ativo
- Editor TipTap para mensagem com suporte a variaveis inline
- Autocomplete de variaveis ao digitar {{
- Organizacao visual melhorada com secoes claras
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O overflow-hidden no PopoverContent impedia o scroll da
ScrollArea filha. Removendo, o scroll funciona corretamente.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona collisionPadding e overflow-hidden no SearchableCombobox
- Reduz tamanho do botão Adicionar no checklist (size=sm)
- Adiciona espaçamento antes do botão Adicionar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Melhora UX da exclusão de templates de checklist usando
modal estilizado ao invés do alert nativo do navegador.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona YAxis com domain=[0, dataMax+1] para forçar mínimo em 0
- Muda type="monotone" para type="linear" para evitar curvas que
ultrapassam os pontos de dados
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ao clicar em "Encerrar" ou "Sair da tela cheia" no modo apresentação,
agora desativa corretamente o modo TV (remove param ?tv=1), evitando
que o fullscreen seja reativado automaticamente pelo useEffect.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Truncate com ellipsis na coluna Empresa (tickets-table)
- Botão excluir em templates de checklist + mutation remove no backend
- Botões Editar/Arquivar com size="sm" em checklist templates
- Hover com borda no botão "Tornar opcional" do checklist
- Botão Resetar em devices com estilo padrão (remove amarelo)
- Botão "Encerrar" no modo apresentação do dashboard
- Sidebar abre automaticamente ao sair do fullscreen
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reorganiza header da página de automações (título/descrição em cima, filtros embaixo)
- Aumenta espaçamento da badge "quando" na tabela
- Ajusta largura do input de checklist nos tickets para melhor distribuição
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Windows 10/11 ja possuem WebView2 pre-instalado. Usar "skip" elimina
o segundo prompt de UAC durante a instalacao.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Usa size=sm nos botões (Nova automação/Novo template) para bater com Empréstimos\n- Ajusta altura do input e selects na listagem de automações e deixa filtros autoexplicativos
- Usa @react-email/components nos templates para evitar módulos ausentes no Bun 1.3.1\n- Ajusta preload do bun test para expor global Element (evita crash do PrismJS)
- Adiciona checklist no ticket (itens obrigatórios/opcionais) e bloqueia encerramento com pendências\n- Cria templates de checklist (globais/por empresa) + tela em /settings/checklists\n- Nova ação de automação: aplicar template de checklist\n- Corrige crash do Select (value vazio), warnings de Dialog e dimensionamento de charts\n- Ajusta SMTP (STARTTLS) e melhora teste de integração
Adiciona scroll explicito apos enviar mensagem com sucesso para
garantir que a mensagem mais recente fique visivel.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A query estava usando .take(50) sem .order("desc"), retornando as 50
mensagens mais antigas ao inves das mais recentes. Isso fazia com que
novas mensagens do desktop nao aparecessem na web quando o ticket
tinha mais de 50 mensagens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Web: adiciona ref hasMarkedReadRef para evitar chamadas duplicadas ao
markChatRead e garante que mensagens sejam marcadas como lidas mesmo
quando o chat carrega apos isOpen se tornar true
- Desktop: aumenta periodo de estabilizacao do resize handler para 500ms,
evitando que eventos transitórios alterem o estado isMinimized
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O BroadcastChannel nao estava funcionando corretamente porque
cada aba restaurava do localStorage independentemente na montagem.
Mudanca:
- Substituido BroadcastChannel pelo evento 'storage' do localStorage
- O evento storage dispara automaticamente em TODAS as outras abas
quando o localStorage e alterado (mais confiavel)
- Removido broadcastChannelRef e CHAT_WIDGET_CHANNEL nao mais usados
Comportamento:
- Abrir/fechar/minimizar chat em uma aba sincroniza com todas as outras
- Estado persiste entre reloads via localStorage
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O problema era que o resize handler executava imediatamente na
montagem do componente, potencialmente lendo window.innerHeight
incorreto antes do Tauri aplicar o tamanho da janela.
Isso fazia o isMinimized ser setado como false (expandido) mesmo
quando a janela foi criada minimizada pelo Rust.
Correcao:
- Ignorar a primeira execucao do resize handler
- Preservar o estado inicial isMinimized=true definido no useState
- Sincronizar apenas em resizes reais (interacao do usuario)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O bug era causado pelo useEffect de auto-open que executava
na montagem inicial do componente, sobrescrevendo o estado
do localStorage (isMinimized) e fazendo o chat abrir expandido.
Isso causava o useEffect de markChatRead executar e zerar
o contador de mensagens nao lidas.
Correcao:
- prevSessionCountRef agora inicia como -1 (nao inicializado)
- Primeira execucao apenas inicializa o ref, sem abrir o chat
- Auto-open so acontece para sessoes NOVAS criadas APOS montagem
- Estado do localStorage (minimizado/expandido) e preservado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrige contador de mensagens resetando sozinho (web)
- Adiciona verificacao de visibilidade antes de marcar como lido
- Verifica se aba esta ativa antes de marcar como lido
- Adiciona sincronizacao de estado do chat entre abas (web)
- Usa BroadcastChannel para sincronizar aberto/fechado/minimizado
- Persiste estado no localStorage
- Corrige chat minimizando sozinho no desktop (Rust)
- Verifica se chat esta expandido antes de minimizar
- Mantem chat aberto quando usuario esta usando
- Melhora encerramento automatico de sessoes de chat
- Muda criterio de inatividade de chat para maquina offline
- Sessao permanece ativa enquanto Raven estiver aberto
- Encerra apenas quando maquina fica offline por 5+ min
- Corrige tabela de tickets em /devices
- Adiciona acentuacao correta (Ultima atualizacao, Responsavel)
- Torna linha inteira clicavel para abrir ticket
- Ajusta sidebar
- Menu Tickets agora expande ao clicar (igual Cadastros)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona rota API para arquivar tickets por ID
- Atualiza configuracao do Prisma para PostgreSQL
- Simplifica workflow CI/CD
- Adiciona src/generated ao gitignore
- Atualiza documentacao e dependencias
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Muda provider Prisma de sqlite para postgresql
- Remove dependencias SQLite (better-sqlite3, adapter)
- Atualiza Better Auth para provider postgresql
- Simplifica prisma.ts removendo adapter SQLite
- Atualiza stack.yml para usar PostgreSQL existente com 2 replicas
- Remove logica de rebuild better-sqlite3 do start-web.sh
- Adiciona script de migracao de dados SQLite -> PostgreSQL
- Atualiza healthcheck para testar PostgreSQL via Prisma
- Habilita start-first deploy para zero-downtime
Melhoria: permite multiplas replicas e deploys sem downtime.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
- Remove abertura automática do chat quando sessão é iniciada
- Chat só aparece minimizado quando há novas mensagens (primeira msg do agente)
- Remove notificação nativa redundante na criação da sessão
- Mantém evento session-started para outros usos internos
Fluxo correto:
1. Agente inicia chat → nada aparece no desktop
2. Agente envia mensagem → chat aparece minimizado com badge
3. Usuário clica → chat expande
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Substitui mensagem técnica por "Não foi possível conectar ao servidor"
- Muda cor do alerta de vermelho para âmbar (menos alarmante)
- Remove detalhes técnicos do erro (ficam apenas no console)
- Adiciona dica para verificar conexão com internet
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Aumenta de 210px para 220px para acomodar badge completamente
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove window.show() que forçava chat reabrir a cada polling
- Chat só abre minimizado quando há NOVAS mensagens (janela não existia)
- Se usuário fechou o chat, não reabre automaticamente
- Corrige acentuação: "Voce" → "Você", "nao" → "não"
- Simplifica toast para "Chat ao vivo iniciado"
- Melhora mensagem de erro quando máquina está offline
- Loga erro técnico no console ao invés de exibir para usuário
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove scrollbars com overflow: hidden no CSS
- Aumenta tamanho da janela minimizada (210x52) para não cortar badge
- Adiciona bordas arredondadas (rounded-2xl) no chat expandido
- Adiciona sombra (shadow-xl) no chat expandido
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Desabilita sombra da janela para transparência funcionar corretamente
- Adiciona badge de mensagens não lidas no chip minimizado
- Ajusta tamanho da janela minimizada para acomodar badge e texto offline
- Mostra chat minimizado com badge quando há novas mensagens (menos intrusivo)
- Adiciona listener para atualização de unread count em tempo real
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Chat do agente abre expandido automaticamente ao iniciar nova sessao
- Toasts fecham apos tempo fixo independente do foco da janela
- Janela de chat do desktop com transparencia (sem fundo branco)
- Chat reabre quando usuario abre o Raven (duplo clique no tray)
- Chat nao reabre sozinho com novas mensagens (apenas notificacao)
- Mensagem de toast simplificada: "Chat ao vivo iniciado"
- Reduz intervalo de polling SSE de 2s para 1s (mais responsivo)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Altera typePreferences e categoryPreferences de Json para String no Prisma
- Atualiza API de preferências para fazer parse/stringify de JSON
- Corrige todos os textos sem acentuação nos componentes de notificação
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implementa sistema de notificacoes por e-mail com:
- Notificacoes de ciclo de vida (abertura, resolucao, atribuicao, status)
- Sistema de avaliacao de chamados com estrelas (1-5)
- Deep linking via protocolo raven:// para abrir chamados no desktop
- Tokens de acesso seguro para visualizacao sem login
- Preferencias de notificacao configuraveis por usuario
- Templates HTML responsivos com design tokens da plataforma
- API completa para preferencias, tokens e avaliacoes
Modelos Prisma:
- TicketRating: avaliacoes de chamados
- TicketAccessToken: tokens de acesso direto
- NotificationPreferences: preferencias por usuario
Turbopack como bundler padrao (Next.js 16)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
O campo estava duplicado - ChatRuntime ja tem seu proprio is_using_sse.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove /dashboard do path do ticket.
Antes: /dashboard/tickets/{id}
Depois: /tickets/{id}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona funcao set_chat_minimized que redimensiona a janela
- Modo minimizado: 200x56 (tamanho do chip)
- Modo expandido: 380x520 (tamanho completo)
- Janela reposiciona automaticamente no canto inferior direito
- Adiciona comando is_chat_using_sse para verificar modo de conexao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@noble/hashes v2 no longer accepts strings directly, only Uint8Array.
Added utf8() helper to encode strings before hashing.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implementa Server-Sent Events (SSE) para chat no desktop com fallback HTTP
- Adiciona rate limiting nas APIs de chat (poll, messages, sessions)
- Adiciona retry com backoff exponencial para mutations
- Cria testes para modulo liveChat (20 testes)
- Corrige testes de SMTP (unit tests para extractEnvelopeAddress)
- Adiciona indice by_status_lastActivity para cron de sessoes inativas
- Atualiza stack: Bun 1.3.4, React 19, recharts 3, noble/hashes 2, etc
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Corrigir acentuações (sessão, sessões, duração)
- Auto-minimizar chat nativo quando sessão termina
- Corrigir race condition em markMachineMessagesRead (Promise.all)
- Adicionar paginação no cron autoEndInactiveSessions (.take(50))
- Otimizar listMachineMessages com limite de 100 mensagens
- Corrigir memory leak no ChatWidget (limite de 200 mensagens)
- Exibir estado offline quando não há sessão ativa
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Timeline consolidation:
- Replace multiple LIVE_CHAT_STARTED/ENDED events with single LIVE_CHAT_SUMMARY
- Show total duration accumulated across all sessions
- Display session count (e.g., "23min 15s total - 3 sessoes")
- Show "Ativo" badge when session is active
Auto-end inactive chat sessions:
- Add cron job running every minute to check inactive sessions
- Automatically end sessions after 5 minutes of client inactivity
- Mark auto-ended sessions with "(encerrado por inatividade)" flag
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Format duration as hours+minutes when > 60min (e.g., 2h 26min)
- Change minimized chat to compact chip style (matching web)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change agent icon from Headphones to MessageCircle
- Adjust avatar size to size-7 and icons to size-3.5
- Reposition attach button next to send button (textarea -> attach -> send)
- Add Online indicator in header with animated green dot
- Implement minimized state (collapsed view like web)
- Hide web chat widget when running in Tauri context (avoid duplicate)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Client messages on left with white background and border
- Agent messages on right with black background
- Added circular avatars (User icon for client, Headphones for agent)
- Improved spacing and visual consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Revert to frameless window with custom header containing
minimize/close buttons and drag region.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add file upload support in chat (PDF, images, txt, docs, xlsx)
- Limited to 10MB max file size
- Only allowed extensions for security
- Use native Windows decorations for chat window
- Remove ChatFloatingWidget (replaced by native window)
- Simplify chat event listeners (window managed by Rust)
- Fix typo "sessao" -> "sessão"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ChatWidget and ChatFloatingWidget were using relative path
"machine-agent.json" instead of the full path with appLocalDataDir().
This caused "Maquina nao registrada" error in chat window.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a new message arrives from a support agent, the chat window
now opens automatically without user interaction.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows unread count and sessions count next to the chat button
for debugging purposes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add detailed debug logs in Rust (chat.rs) to trace polling flow
- Add console.log in frontend (main.tsx) to trace event reception
- Add red border to "Encerrar" button in chat panels for better visibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The unreadByMachine counter was never being incremented when agents sent
chat messages, causing the badge to always show 0. Now when an agent
(ADMIN/MANAGER/AGENT) posts a message to a ticket with an active chat
session, the counter is incremented properly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix session sync: events now send complete ChatSession data instead of
partial ChatSessionSummary, ensuring proper ticket/agent info display
- Add session-ended event detection to remove closed sessions from client
- Add ChatFloatingWidget component for in-app chat experience
- Restrict endSession to ADMIN/MANAGER/AGENT roles only
- Improve polling logic to detect new and ended sessions properly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove automatic window opening when agent starts a chat session
- Remove automatic window focus when new messages arrive
- Only show Windows notification, user opens chat manually via tray icon
- Update notification message to instruct user to click Raven icon
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow COLLABORATOR users who are linked to the ticket's machine
(via assignedUserId or linkedUserIds) to access the chat, not
just the ticket requester.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Lint fixes:
- Move HIDDEN_EVENT_TYPES constant outside component to fix useMemo dependency
- Add eslint-disable comments for img elements using blob URLs
Chat widget improvements:
- Add view and download buttons with loading and success indicators
- Click image to open in new tab, download button to save file
- Show check icon after successful download
Chat history fixes:
- Fix title to "Histórico de chat" with proper accents
- Change agent icon from Headphones to MessageCircle
- Change agent icon background from primary to gray
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Widget improvements:
- Pulsating badge with unread message count on floating button
- Clickable ticket reference link in chat header
- ExternalLink icon on hover
Desktop (Raven) improvements:
- Track previous unread count for new message detection
- Send native Windows notifications for new messages
- Focus chat window when new messages arrive
Chat history:
- New query getTicketChatHistory for fetching chat sessions and messages
- New component TicketChatHistory displaying chat sessions
- Sessions can be expanded/collapsed to view messages
- Pagination support for long conversations
- Added to both dashboard and portal ticket views
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tauri-plugin-notification for native Windows notifications
- Send notification when new chat session is started
- Configure notification permissions in capabilities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Allow sending messages with only attachments (no text required)
- Change "Chat Ativo" header to just "Chat"
- Replace Headphones icon with MessageCircle for own messages
- Replace PhoneOff icon with XCircle for end chat button
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A query getTicketSession agora sempre retorna machineOnline,
permitindo que o botao de chat seja habilitado corretamente
quando a maquina esta online mas nao ha sessao ativa.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Usa ticket.machine?.id ao inves de ticket.machineId inexistente
para determinar se o botao de chat deve aparecer.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Troca o emoji de lupa pelo icone SearchX do lucide-react
para manter consistencia visual com o resto da plataforma.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reestrutura visual do widget de chat (header branco, status emerald)
- Adiciona sistema de anexos com upload e drag-and-drop
- Substitui select nativo por componente Select do shadcn
- Adiciona eventos LIVE_CHAT_STARTED e LIVE_CHAT_ENDED na timeline
- Traduz labels de chat para portugues (Chat iniciado/finalizado)
- Filtra CHAT_MESSAGE_ADDED da timeline (apenas inicio/fim aparecem)
- Restringe inicio de chat a tickets com responsavel atribuido
- Exibe duracao da sessao ao finalizar chat
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Verifica se api.liveChat.listAgentSessions existe antes de renderizar
- Retorna null no provider se Convex nao estiver sincronizado
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Widget no canto inferior direito em todas as paginas
- Mostra sessoes de chat ativas do agente
- Suporta multiplas sessoes com seletor
- Badge com contador de mensagens nao lidas
- Pode minimizar ou fechar
- Query listAgentSessions para buscar sessoes ativas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Layout estilo messenger com baloes de mensagem
- Avatares para agente (headphones) e usuario (user)
- Cores distintas: preto para agente, branco para cliente
- Header com status online/offline da maquina
- Input com Enter para enviar
- Scroll automatico para novas mensagens
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove @assistant-ui/react, @assistant-ui/react-markdown e remark-gfm
que foram adicionadas mas nao estao sendo usadas (componente customizado)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Adiciona tabela liveChatSessions no schema Convex
- Cria convex/liveChat.ts com mutations e queries para chat
- Adiciona API routes para maquinas (sessions, messages, poll)
- Cria modulo chat.rs no Tauri com ChatRuntime e polling
- Adiciona comandos de chat no lib.rs (start/stop polling, open/close window)
- Cria componentes React do chat widget (ChatWidget, types)
- Adiciona botao "Iniciar Chat" no dashboard (ticket-chat-panel)
- Implementa menu de chat no system tray
- Polling de 2 segundos para maior responsividade
- Janela de chat flutuante, frameless, always-on-top
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace parentheses text with styled badge
- Use color-coded badges: success (green), warning (amber), error (red)
- Add APPLYING status support
- Match badge style with custom fields counter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Info icon in black (text-foreground)
- Badges in gray (bg-slate-100, border-slate-200)
- Badge text in black (text-foreground)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use primary/accent colors instead of hardcoded blue
- Increase text sizes (text-sm for title, text-xs for chips and note)
- Increase icon and chip sizes for better readability
- Use text-secondary for chip text, text-muted-foreground for note
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Shows affected devices: pen drives, external HDs, SD cards
- Clarifies that keyboards, mice, printers are not affected
- Uses subtle blue info card design with device chips
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use grid layout with 2 columns for better space usage
- Increase filter height to h-9 for better readability
- Move "Limpar" button to header row
- Add proper padding and spacing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix bug where APPLYING status would not transition to APPLIED
- Add status and date range filters to policy history
- Add cursor-based pagination with "Load more" button
- Use DateRangeButton component for date filtering
- Reset filters and pagination when switching filters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rust serializes Option<String>::None as null, not undefined.
Updated reportUsbPolicyStatus mutation to accept both null and undefined
for error and currentPolicy fields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix Zod schema to accept null values (nullable) for error/currentPolicy
- Add robust logging system writing to raven-agent.log file
- Rewrite auto-start using winreg with validation
- Auto-start agent on app setup if credentials exist
- Reduce retry attempts to 2 (1 + 1 retry after 2s)
- Replace provider's remote access on ID change (prevents duplicates)
- Update agent to v0.2.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduce USB policy polling from 60s to 15s for faster response
- Add retry with exponential backoff (2s, 4s, 8s) on report failures
- Add APPLYING state for real-time progress bar feedback
- Check if policy is already applied locally before re-applying
- Fix API schema to accept APPLYING status
- Update agent to v0.1.9
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reorganiza layout da tela de dispositivos admin
- Renomeia secao "Controles do dispositivo" para "Atalhos"
- Adiciona botao de Tickets com badge de quantidade
- Simplifica textos de botoes (Acesso, Resetar)
- Remove email da maquina do cabecalho
- Move empresa e status para mesma linha
- Remove chip de Build do resumo
- Corrige deteccao de VRAM para GPUs >4GB usando nvidia-smi
- Adiciona prefixo "VRAM" na exibicao de memoria da GPU
- Documenta sincronizacao RustDesk
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add config.machineId to openSystem dependency array
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add requester filter to device tickets history page
- Create listMachineRequesters query to list unique requesters
- Add friendly API error formatting in desktop agent
- Translate validation errors to user-friendly Portuguese messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add by_tenant_hostname index for hostname-based lookup
- Add third search in register mutation for hardware matching
- Search by hostname + MAC/serial when fingerprint/email differ
- Fallback to MAC/serial match across all tenant machines
- Preserves ticket history when user changes on same physical machine
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reload config/token directly from store before syncing
- Avoid race condition when register() calls ensureRustdesk before React state updates
- Ensures machineId and token are always fresh from disk
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update .env.example with SMTP variables
- Create docs/SMTP.md with credentials and usage examples
- Tested successfully on 2025-12-05
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add RUSTDESK_SERVER and RUSTDESK_SERVER_KEY constants
- Update buildRustDeskUri to use ID@SERVER format
- Include server key in URI for proper server identification
- This allows 1-click connection without client pre-configuration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The RustDesk data saved by Rust directly to file was not being
synced to the backend because the app redirected to the web platform
before the sync could complete.
- Reload store from disk in openSystem to get Rust-saved data
- Sync RustDesk before redirecting with 3s timeout
- Fire-and-forget sync to avoid blocking the redirect
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Resolve conflito entre Tauri Store (TypeScript) e escrita direta (Rust)
- O Rust agora salva a chave "rustdesk" no arquivo apos provisionamento
- O TypeScript pode ler os dados via Store.load() normalmente
- Garante que os dados do RustDesk estejam disponiveis para sincronizacao
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Corrigir indentacao do useEffect que dispara ensureRustdesk
- Adicionar logs detalhados em handleRustdeskProvision e ensureRustdesk
- Logs ajudam a diagnosticar falhas na sincronizacao do acesso remoto
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove initial spinner and show skeleton layout immediately
- Add skeleton to stats cards during loading
- Show skeleton rows in table while data loads
- Provides better visual feedback with layout structure
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Use colgroup with fixed pixel widths instead of percentages
- Add tableLayout: fixed with minWidth for stable layout
- Add truncate to cells to prevent content overflow
- Show placeholder in Actions column for non-active items
- Column widths now stay consistent across all filter states
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix Portuguese accents in UI text (devolucao -> devolução, emprestimo -> empréstimo, etc.)
- Restructure table to always show header with fixed column widths
- Move empty state inside TableBody with colSpan to maintain layout consistency
- Column widths now stay consistent regardless of filter selection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace spinner with skeleton table rows during loading
- Apply optimistic closing for devolver dialog (instant feedback)
- Use toast.promise for background mutation with loading state
- Remove unnecessary isSubmitting state from devolver button
- Maintain table layout during filter changes (no layout shift)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace centered spinner with skeleton table rows
- Maintain table structure and width during loading
- Show 5 skeleton rows with proper column widths
- Prevents layout collapse when changing filters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The getByIdHandler was missing usbPolicy, usbPolicyStatus,
and usbPolicyError fields, causing the chip to always show
"Permitido" instead of the actual policy value.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change focus: to focus-visible: so the ring only appears
during keyboard navigation, not on initial modal open
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move USB policy control from bottom of page to modal dialog
- Add "Controle USB" button in device controls section
- Show USB chip for all Windows devices (default to ALLOW)
- Add close button (X) with hover effect in modal header
- Fix all Portuguese accents in USB control component
- Position status badge at top of modal content
- Add variant prop to UsbPolicyControl (card/inline)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add USB modal state and clickable InfoChip for USB policy chip
- Create Dialog with UsbPolicyControl component for USB management
- Add variant prop to UsbPolicyControl (card/inline) for flexible rendering
- Remove inline UsbPolicyControl from bottom of device page
- USB control now accessible by clicking USB chip in device summary
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The getPendingUsbPolicy and reportUsbPolicyStatus functions were
comparing the plain token against the tokenHash in the database,
which would never match. Now properly hashing the token before
database lookup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- 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>
- Force SKIP_SQLITE_REBUILD=false in stack.yml
- Copy binding to multiple locations including @prisma/client paths
- Include version-specific paths for Node.js compiled bindings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add production domain to trustedOrigins explicitly
- Add health API endpoint for diagnostics
- Improve emprestimos page layout to match tickets design
- Use correct primary color for buttons
- Fix segmented control styling with rounded borders
- Use Empty component for empty state
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds typescript.ignoreBuildErrors to prevent OOM during build
on production server with limited memory.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update Next.js to 16.0.7
- Fix accent on menu item "Emprestimos" to "Empréstimos"
- Standardize loan page with project patterns (DateRangeButton, cyan color scheme, ToggleGroup)
- Add company filter to USB bulk policy dialog
- Update CardDescription text in devices overview
- Fix useEffect dependency warning in desktop main.tsx
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add emprestimos (equipment loan) module in Convex with queries/mutations
- Create emprestimos page with full CRUD and status tracking
- Add USB bulk control to admin devices overview
- Fix Portuguese accents in USB policy control component
- Fix dead code warnings in Rust agent
- Fix tiptap type error in rich text editor
- Add USB policy fields to machines schema (policy, status, error)
- Create usbPolicyEvents table for audit logging
- Implement Convex mutations/queries for USB policy management
- Add REST API endpoints for desktop agent communication
- Create Rust usb_control module for Windows registry manipulation
- Integrate USB policy check in agent heartbeat loop
- Add USB policy control component in admin device overview
- Add localhost:3001 to auth trustedOrigins for dev
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
fix(export): return 501 with hint when Playwright browsers missing; nicer error toast in UI
fix(site-header): export primary/secondary buttons as named for SC safety; keep static props for compat
fix(portal): add DialogDescription for a11y; tidy preview dialog
fix(csats): avoid reinit state loops with timestamp guard
chore(prisma): default dev DB to prisma/db.dev.sqlite and log path
chore(auth): add dev bypass flags wiring (server/client) for local testing
dev: seed script for Convex demo data
feat(calendar): migrate to react-day-picker v9 and polish UI
- Update classNames and CSS import (style.css)
- Custom Dropdown via shadcn Select
- Nav arrows aligned with caption (around)
- Today highlight with cyan tone, weekdays in sentence case
- Wider layout to avoid overflow; remove inner wrapper
chore(tickets): make 'Patrimônio do computador (se houver)' optional
- Backend hotfix to enforce optional + label on existing tenants
- Hide required asterisk for this field in portal/new-ticket
refactor(new-ticket): remove channel dropdown from admin/agent flow
- Keep default channel as MANUAL
feat(ux): simplify requester section and enlarge combobox trigger
- Remove RequesterPreview redundancy; show company badge in trigger
- Strongly type company-service and API routes
- Fix Next.js searchParams (promise) in admin/machines page
- Add vitest module marker + stub for tsconfig-paths/register
- Use Convex query in client as primary fallback for machine details
- Replace any casts in admin machines components
Build + lint are clean locally; details page no longer skeleton-loops.
- Update GET signature to (req: NextRequest, ctx: { params: Promise<{id:string}> })
- Await ctx.params and pass id to Convex client
- Keeps NextResponse return type
- Add Convex query machines.getById with full payload (metrics/inventory)
- Update AdminMachineDetailsClient to use getById instead of listByTenant+find
- Update MachineBreadcrumbs to fetch hostname by ID
This prevents the empty state when the list query hasn’t loaded or filtered out the machine.
- Add docs/README.md as index
- Consolidate ops in docs/operations.md; mark legacy runbooks as archive
- Create docs/desktop/ and docs/admin/ structure and move relevant docs
- Update root README to link docs index
- Keep historical and planning notes under docs/archive/
- Add Acquire Convex admin key step in convex_deploy
- Provide CONVEX_DEPLOYMENT env and stop unsetting it
- Pass envs into container for env list + deploy
- Acquire admin key in convex_deploy job (id:key)
- Copy existing convex.json from APP_DIR to build dir (EFFECTIVE_APP_DIR)
- Prevent ‘No CONVEX_DEPLOYMENT set’ by ensuring project link present
- Usa Store.load com caminho absoluto em C:\Raven\data quando possível; fallback para AppData
- Remove import de fs (plugin) e opção 'dir' não suportada pelo plugin-store v2
- main.tsx: resolveDataDir usa executableDir/data quando possível; se falhar, cai para appLocalDataDir
- tauri.conf.json: remove bloco windows.nsis inválido no schema v2 para build passar
Objetivo: instalar dados fora do AppData (ex.: C:\Raven\data) quando o diretório de instalação permitir escrita.
- src-tauri: adiciona comando open_devtools que chama window.open_devtools()
- frontend: listeners para F12/Ctrl+Shift+I e botão direito com Ctrl/Shift
Facilita depuração de UI no executável Tauri.
- tauri.conf.json: configura nsis (installMode perMachine, allowToChangeInstallDirectory, installDirName, createDesktopShortcut)
- main.tsx: Store.load agora usa appLocalDataDir (dados do app em AppData do usuário)
- README: documenta instalação Windows, dados em AppData e build leve (--bundles nsis)
- middleware: torna /machines/handshake público para permitir criação de sessão de máquina sem login prévio
- nav-user: oculta botão 'Encerrar sessão' quando a sessão é de máquina (role === 'machine')
Efeito: no app desktop (Tauri), o handshake passa a autenticar corretamente, o cabeçalho exibe nome/e-mail do colaborador/gestor e o portal permite abrir chamados.
Nota: em navegação web comum, 'Sair' permanece visível para usuários humanos.
- /tickets/[id], /tickets/resolved, /views, /play, /reports/*, /settings agora exigem sessão via requireAuthenticatedSession()
- Complementa o middleware e evita casos não-redirecionados em DEV/SSG
- Mantém /settings/templates com requireStaffSession() como já estava.
- Chama requireAuthenticatedSession() no page.tsx para redirecionar anônimos a /login
- Garante comportamento idêntico ao /dashboard quando acessado diretamente.
- Define dynamic="force-dynamic" no layout global para garantir que o middleware rode para todas as páginas
- Evita cache s-maxage de páginas protegidas (ex.: /tickets) que impedia redirect em anônimo.
- Chama requireAuthenticatedSession() em /dashboard para redirecionar anônimos a /login
- Evita página vazia quando aberto diretamente em janela anônima.
- Em /, decidir destino via getServerSession():
- Sem sessão: /login
- Staff: /dashboard
- Colaborador: /portal
- Evita depender do redirect client-side e garante comportamento correto em aba anônima.
- Simplifica AuthGuard para não redirecionar no cliente (gate feito no middleware)
- Adiciona skeleton de carregamento no AppShell enquanto
- Troca anchors por Next Link no sidebar para navegação client-side
Sem mudanças de schema/DB; apenas UX e roteamento no cliente.
"Bash(\"\"\" OWNER TO renan; FROM pg_tables WHERE schemaname = public;\"\" | docker exec -i c95ebc27eb82 psql -U sistema -d strapi_blog\")",
"Bash(sequence_name)",
"Bash(\"\"\" OWNER TO renan; FROM information_schema.sequences WHERE sequence_schema = public;\"\" | docker exec -i c95ebc27eb82 psql -U sistema -d strapi_blog\")",
"Bash(DATABASE_URL=\"postgresql://postgres:dev@localhost:5432/sistema_chamados\" bun tsx:*)",
"Bash(docker stop:*)",
"Bash(docker rm:*)",
"Bash(git commit -m \"$(cat <<''EOF''\nfeat(checklist): exibe descricao do template e do item no ticket\n\n- Adiciona campo templateDescription ao schema do checklist\n- Copia descricao do template ao aplicar checklist no ticket\n- Exibe ambas descricoes na visualizacao do ticket (template em italico)\n- Adiciona documentacao de desenvolvimento local (docs/LOCAL-DEV.md)\n- Corrige prisma-client.mjs para usar PostgreSQL em vez de SQLite\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n)\")",
bash -lc "set -euo pipefail; bun install --frozen-lockfile --filter '!appsdesktop'; bun run prisma:generate; bun run build:bun"
- name:Fix Docker-created file permissions
run:|
# Docker cria arquivos como root - corrigir para o usuario runner (UID 1000)
docker run --rm -v "$EFFECTIVE_APP_DIR":/target alpine:3 \
chown -R 1000:1000 /target
echo "Permissoes do build corrigidas"
- name:Atualizar symlink do APP_DIR estavel (deploy atomico)
run:|
set -euo pipefail
ROOT="$HOME/apps"
STABLE_LINK="$ROOT/sistema.current"
mkdir -p "$ROOT"
# Sanidade: se esses arquivos nao existirem, o container vai falhar no boot.
test -f "$EFFECTIVE_APP_DIR/scripts/start-web.sh" || { echo "ERROR: scripts/start-web.sh nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; }
test -f "$EFFECTIVE_APP_DIR/stack.yml" || { echo "ERROR: stack.yml nao encontrado em $EFFECTIVE_APP_DIR" >&2; exit 1; }
test -d "$EFFECTIVE_APP_DIR/node_modules" || { echo "ERROR: node_modules nao encontrado em $EFFECTIVE_APP_DIR (necessario para next start)" >&2; exit 1; }
test -d "$EFFECTIVE_APP_DIR/.next" || { echo "ERROR: .next nao encontrado em $EFFECTIVE_APP_DIR (build nao gerado)" >&2; exit 1; }
PREV=""
if [ -L "$STABLE_LINK" ]; then
PREV="$(readlink -f "$STABLE_LINK" || true)"
fi
echo "PREV_APP_DIR=$PREV" >> "$GITHUB_ENV"
ln -sfn "$EFFECTIVE_APP_DIR" "$STABLE_LINK"
# Compat: mantem $HOME/apps/sistema como symlink quando possivel (nao mexe se for pasta).
if [ -L "$ROOT/sistema" ] || [ ! -e "$ROOT/sistema" ]; then
Aplicação Next.js 15 com Convex e Better Auth para gestão de tickets da Rever. Todo o código-fonte está organizado diretamente na raiz do repositório, conforme convenções do Next.js.
Aplicacao **Next.js 16 (App Router)** com **React 19**, **Convex** e **Better Auth** para gestao de tickets da Rever. A stack ainda inclui **Prisma 7** (PostgreSQL), **Tailwind** e **Turbopack** como bundler padrao (webpack permanece disponivel como fallback). Todo o codigo-fonte fica na raiz do monorepo seguindo as convencoes do App Router.
## Requisitos
- Node.js >= 20
- pnpm >= 8
- CLI do Convex (`pnpm dlx convex dev` instalará automaticamente no primeiro uso)
- Bun >= 1.3 (recomendado 1.3.1). Após instalar via script oficial, adicione `export PATH="$HOME/.bun/bin:$PATH"` ao seu shell (ex.: `.bashrc`) para ter `bun` disponível globalmente.
- Node.js >= 20 (necessário para ferramentas auxiliares como Prisma CLI e Next.js em modo fallback).
- CLI do Convex (`bunx convex dev` instalará automaticamente no primeiro uso, se ainda não estiver presente).
- GitHub Actions/autodeploy dependem dessas versões e do CLI do Convex disponível; use `npx convex --help` para confirmar.
## Configuração rápida
1. Instale as dependências:
```bash
pnpm install
bun install
```
2. Ajuste o arquivo `.env` (ou crie a partir de `.env.example`) e confirme os valores de:
- `NEXT_PUBLIC_CONVEX_URL` (gerado pelo Convex Dev)
6. Em um terminal, execute o backend em tempo real do Convex:
2. Aplique as migracoes:
```bash
pnpm convex:dev
bunx prisma migrate deploy
```
7. Em outro terminal, suba o frontend Next.js:
3. Recrie/garanta as contas padrao de login:
```bash
pnpm dev
bun run auth:seed
```
8. Com o Convex ativo, acesse `http://localhost:3000/dev/seed` uma vez para popular dados de demonstração (tickets, usuários, comentários) diretamente no banco do Convex.
4. Suba o servidor normalmente com `bun run dev`.
### Subir serviços locais
- (Opcional) Para re-sincronizar manualmente as filas padrão, execute `bun run queues:ensure`.
- Em um terminal, rode o backend em tempo real do Convex com `bun run convex:dev:bun` (ou `bun run convex:dev` para o runtime Node).
- Em outro terminal, suba o frontend Next.js (Turbopack) com `bun run dev:bun` (`bun run dev:webpack` serve como fallback).
- Com o Convex rodando, acesse `http://localhost:3000/dev/seed` uma vez para popular dados de demonstração (tickets, usuários, comentários).
> Se o CLI perguntar sobre configuração do projeto Convex, escolha criar um novo deployment local (opção padrão) e confirme. As credenciais são armazenadas em `.convex/` automaticamente.
### Deploy em produção (Traefik + Convex self‑hosted)
- Guia completo: `docs/OPERACAO-PRODUCAO.md:1`.
- Histórico de setup/decisões: `docs/SETUP-HISTORICO.md:1`.
- Stack Swarm: `stack.yml:1` (roteado por Traefik, rede `traefik_public`).
### Documentação
- Índice de docs: `docs/README.md`
- Operações (produção): `docs/OPERATIONS.md` (versão EN) e `docs/OPERACAO-PRODUCAO.md` (PT-BR)
- Stack Swarm: `stack.yml` (roteado por Traefik, rede `traefik_public`).
### Variáveis de ambiente
@ -55,32 +69,63 @@ Aplicação Next.js 15 com Convex e Better Auth para gestão de tickets da Rever
### Guia de DEV (Prisma, Auth e Desktop/Tauri)
Para fluxos detalhados de desenvolvimento — banco de dados local (SQLite/Prisma), seed do Better Auth, ajustes do Prisma CLI no DEV e build do Desktop (Tauri) — consulte `docs/DEV.md`.
Para fluxos detalhados de desenvolvimento — banco de dados local (PostgreSQL/Prisma), seed do Better Auth, ajustes do Prisma CLI no DEV e build do Desktop (Tauri) — consulte `docs/DEV.md`.
## Scripts úteis
- `pnpm lint` — ESLint com as regras do projeto.
- `pnpm exec vitest run` — suíte de testes unitários.
- `pnpm auth:seed` — atualiza/cria contas padrão do Better Auth (credenciais em `agents.md`).
- `convex/` — queries, mutations e seeds do Convex.
- `prisma/` — schema, migrações e banco SQLite (`prisma/db.sqlite`).
- `prisma/` — schema e migracoes do Prisma (PostgreSQL).
- `scripts/` — utilitários em Node para sincronização e seeds adicionais.
- `agents.md` — guia operacional e contexto funcional (em PT-BR).
- `PROXIMOS_PASSOS.md` — backlog de melhorias futuras.
## Credenciais de demonstração
Após executar `pnpm auth:seed`, as credenciais padrão ficam disponíveis conforme descrito em `agents.md` (seção “Credenciais padrão”). Ajuste variáveis `SEED_USER_*` se precisar sobrepor usuários ou senhas durante o seed.
Após executar `bun run auth:seed`, as credenciais padrão ficam disponíveis conforme descrito em `agents.md` (seção “Credenciais padrão”). Ajuste variáveis `SEED_USER_*` se precisar sobrepor usuários ou senhas durante o seed.
## Próximos passos
Consulte `PROXIMOS_PASSOS.md` para acompanhar o backlog funcional e o progresso das iniciativas planejadas.
### Executar com Bun
- `bun install` é o fluxo padrão (o arquivo `bun.lock` deve ser versionado; use `bun install --frozen-lockfile` em CI).
- `bun run dev:bun`, `bun run convex:dev:bun`, `bun run build:bun` e `bun run start:bun` já estão configurados; internamente executam `bun run --bun <script>` para usar o runtime do Bun sem abrir mão dos scripts existentes. O `cross-env` garante os valores esperados de `NODE_ENV` (`development`/`production`).
- O bundler padrão é o Turbopack; se precisar comparar/debugar com webpack, use `bun run build:webpack`.
- `bun test` utiliza o test runner do Bun. O teste de snapshot de screenshot é automaticamente ignorado quando o matcher não está disponível; testes de navegador completos continuam via `bun run test:browser` (Vitest + Playwright).
<!-- ci: smoke test 3 -->
## Diagnóstico de sessão da dispositivo (Desktop)
- Quando o portal for aberto via app desktop, use a página `https://seu-app/portal/debug` para validar cookies e contexto:
- `/api/auth/get-session` deve idealmente mostrar `user.role = "machine"` (em alguns ambientes WebView pode retornar `null`, o que não é bloqueante).
- `/api/machines/session` deve retornar `200` com `assignedUserId/assignedUserEmail`.
- O frontend agora preenche `machineContext` mesmo que `get-session` retorne `null`, e deriva o papel efetivo a partir desse contexto.
- Se `machines/session` retornar `401/403`, revise CORS/credenciais e o fluxo de handshake documentados em `docs/OPERACAO-PRODUCAO.md`.
- Usuários e tickets demo são garantidos via `convex/seed.ts`.
- Após iniciar `pnpm convex:dev`, acesse `/dev/seed` uma vez por ambiente local para carregar dados reais de demonstração no banco do Convex.
Os demais colaboradores reais são provisionados via **Convites & acessos**. Caso existam vestígios de dados demo, execute `node scripts/remove-legacy-demo-users.mjs` para limpá-los.
## Setup local rápido
1. `pnpm install`
2. Ajuste `.env` (ou crie a partir do exemplo) e confirme `NEXT_PUBLIC_CONVEX_URL` apontando para o Convex local.
3. `pnpm auth:seed`
4. (Opcional) `pnpm queues:ensure`
5. `pnpm convex:dev`
6. Em outro terminal: `pnpm dev`
> Execute `bun run auth:seed` após configurar `.env` para (re)criar os usuários acima (campos `SEED_USER_*` podem sobrescrever credenciais).
## App Desktop (Agente de Máquinas)
- Código: `apps/desktop` (Tauri v2 + Vite).
- Padrões de URL:
- Produção: usa `https://tickets.esdrasrenan.com.br` por padrão (fallback em release).
- Desenvolvimento: use `apps/desktop/.env` (ver `.env.example`).
- Comandos úteis:
- `pnpm -C apps/desktop tauri dev` — dev completo (abre WebView em 1420 + backend Rust).
- `pnpm -C apps/desktop build` — build do frontend (dist).
- `pnpm -C apps/desktop tauri build` — gera instaladores (bundle) por SO.
- Saída dos pacotes: `apps/desktop/src-tauri/target/release/bundle/`.
2) Provisiona via `POST /api/machines/register` com `MACHINE_PROVISIONING_SECRET`.
3) Envia heartbeats a cada 5 min para `/api/machines/heartbeat` com inventário básico.
4) Abre `APP_URL/machines/handshake?token=...` para autenticar sessão na UI.
- Segurança: token salvo no cofre do SO (Keyring). Store guarda apenas metadados não sensíveis.
- Endpoint extra: `POST /api/machines/inventory` (atualiza inventário por token ou provisioningSecret).
## Backend Convex
- Seeds de usuários/tickets demo: `convex/seed.ts`.
- Para DEV: rode `bun run convex:dev:bun` e acesse `/dev/seed` uma vez para popular dados realistas.
## Desenvolvimento local — boas práticas (atualizado)
- Ambientes separados: mantenha seu `.env.local` só para DEV e o `.env` da VPS só para PROD. Nunca commitar arquivos `.env`.
- Convex em DEV: rode `pnpm convex:dev` e aponte o front para `http://127.0.0.1:3210` via `NEXT_PUBLIC_CONVEX_URL`.
- Banco local: por padrão `DATABASE_URL=file:./prisma/db.sqlite`. Se quiser isolar por projeto, use `db.dev.sqlite`.
- Seeds em DEV: use `pnpm auth:seed` (usuários Better Auth) e acesse `/dev/seed` uma vez para dados de demonstração do Convex.
- Seeds em PROD: só quando realmente necessário; não fazem parte do deploy automático.
## Stack atual (18/12/2025)
- **Next.js**: `16.0.10` (Turbopack por padrão; webpack fica como fallback).
- Whitelist de domínios em `src/config/allowed-hosts.ts` é aplicada pelo `middleware.ts`.
- **React / React DOM**: `19.2.1`.
- **Trilha de testes**: Vitest (`bun test`) sem modo watch por padrão (`--run --passWithNoTests`).
- **CI**: workflow `Quality Checks` (`.github/workflows/quality-checks.yml`) roda `bun install`, `bun run prisma:generate`, `bun run lint`, `bun test`, `bun run build:bun`. Variáveis críticas (`BETTER_AUTH_SECRET`, `NEXT_PUBLIC_APP_URL`, etc.) são definidas apenas no runner — não afetam a VPS.
- **Disciplina pós-mudanças**: sempre que fizer alterações locais, rode **obrigatoriamente**`bun run lint`, `bun run build:bun` e `bun test` antes de entregar ou abrir PR. Esses comandos são mandatórios também para os agentes/automations, garantindo que o projeto continua íntegro.
- **Deploy**: pipeline `ci-cd-web-desktop.yml` (runner self-hosted). Build roda com Bun 1.3 + Node 20. Web é publicado em `/home/renan/apps/sistema` e o Swarm aponta `sistema_web` para essa pasta.
7. Acesse `http://localhost:3000` e valide login com os usuários padrão.
# Banco local (Prisma)
DATABASE_URL=file:./prisma/db.sqlite
### Banco de dados
- Local (DEV): PostgreSQL local (ex.: `postgres:18`) com `DATABASE_URL=postgresql://postgres:dev@localhost:5432/sistema_chamados`.
- Produção: PostgreSQL no Swarm (serviço `postgres` em uso hoje; `postgres18` provisionado para migração). Migrations em PROD devem apontar para o `DATABASE_URL` ativo (ver `docs/OPERATIONS.md`).
- `bun run --cwd apps/desktop tauri dev` — desenvolvimento (porta 1420).
- `bun run --cwd apps/desktop tauri build` — gera instaladores.
- **Fluxo do agente**:
1. Coleta perfil da dispositivo (hostname, OS, MAC, seriais, métricas).
2. Provisiona via `POST /api/machines/register` usando `MACHINE_PROVISIONING_SECRET`, informando perfil de acesso (Colaborador/Gestor) + dados do colaborador.
3. Envia heartbeats periódicos (`/api/machines/heartbeat`) com inventário básico + estendido (discos SMART, GPUs, serviços, softwares, CPU window).
4. Realiza handshake em `APP_URL/machines/handshake?token=...&redirect=...` para receber cookies Better Auth + sessão (colaborador → `/portal`, gestor → `/dashboard`).
5. Token persistido no cofre do SO (Keyring); store guarda apenas metadados.
6. Envio manual de inventário via botão (POST `/api/machines/inventory`).
7. Updates automáticos: plugin `@tauri-apps/plugin-updater` consulta `latest.json` publicado nos releases do GitHub.
- **Admin ▸ Dispositivos**: permite ajustar perfil/email associado, visualizar inventário completo e remover dispositivo.
### Passo a passo local
1) `pnpm install`
2) `pnpm prisma:generate`
3) `pnpm convex:dev` (terminal A)
4) `pnpm dev` (terminal B)
5) (Opcional) `pnpm auth:seed` e visitar `http://localhost:3000/dev/seed`
### Sessão "machine" no frontend
- Ao autenticar como dispositivo, o front chama `/api/machines/session`, popula `machineContext` (assignedUser*, persona) e deriva role/`viewerId`.
- Mesmo quando `get-session` é `null` na WebView, o portal utiliza `machineContext` para saber o colaborador/gestor logado.
- UI remove opção "Sair" no menu do usuário quando detecta sessão de dispositivo.
- `/portal/debug` exibe JSON de `get-session` e `machines/session` (útil para diagnosticar cookies/bearer).
## Deploy via GitHub Actions (produção)
- Fluxo: `git push main` ⇒ runner self‑hosted na VPS sincroniza código e aplica o stack (Traefik/Swarm) sem derrubar o serviço (start-first).
- Disparo do deploy web: apenas quando há mudanças em arquivos do app (src/, public/, prisma/, next.config.ts, package.json, pnpm-lock.yaml, tsconfig.json, middleware.ts, stack.yml).
- Disparo do deploy Convex: apenas quando há mudanças em `convex/**`.
- O `.env` da VPS é preservado; caches do servidor (`node_modules`, `.pnpm-store`) não são tocados.
- Banco Prisma (SQLite) persiste em volume nomeado (`sistema_db`); não é recriado a cada deploy.
### Observações adicionais
- Planejamos usar um cookie `desktop_shell` no futuro para diferenciar acessos do desktop vs navegador (não implementado).
## Bancos e seeds — DEV x PROD
- DEV: use os seeds à vontade (usuários com `pnpm auth:seed`, dados demo do Convex em `/dev/seed`).
- PROD: evite seeds automáticos; para criar um admin use `SEED_USER_*` e `pnpm auth:seed` em um container Node efêmero.
- Alterações de schema: sempre via migrações (`prisma migrate`). O CI aplica `migrate deploy` no start do container web.
## Qualidade e testes
- **Lint**: `bun run lint` (ESLint flat config).
- **Testes unitários/integrados (Vitest)**:
- Cobertura atual inclui utilitários (`tests/*.test.ts`), rotas `/api/machines/*` e `sendSmtpMail`.
- Executar `bun test -- --watch` apenas quando precisar de modo interativo.
- **Build**: `bun run build:bun` (`next build --turbopack`). Quando precisar do fallback oficial, rode `bun run build:webpack`.
- **CI**: falhas mais comuns
- `ERR_BUN_LOCKFILE_OUTDATED`: confirme que o `bun.lock` foi regenerado (`bun install`) após alterar dependências, especialmente do app desktop.
- Falha de host: confira `src/config/allowed-hosts.ts`; o middleware retorna 403 quando o domínio do Traefik não está listado.
## Dicas rápidas
- Imagens em `public/`: trocou o arquivo → push. Para bust de cache, versionar o nome (ex.: `logo.v2.png`) ou usar query (`?v=sha`).
- Problemas de permissão de build: garanta que `.next` pertence ao usuário do runner (se necessário, remover `.next` no host e rebuildar).
- Se precisar inspecionar/backup do SQLite em PROD, prefira um bind dedicado (`/srv/apps/sistema-data:/app/data`) ou use `docker run -v sistema_db:/data` para copiar o arquivo.
## Produção / Deploy
- Runner self-hosted (VPS). Build roda fora de `/srv/apps/sistema` e rsync publica em `/home/renan/apps/sistema`.
- Swarm: `stack.yml` monta `/home/renan/apps/sistema.current` → `/app` (via symlink).
- Menu de usuário (rodapé da sidebar) concentra acesso às configurações ("Meu perfil" → `/settings`) e logout. Removemos o item redundante "Configurações" do menu lateral.
- Formulários de novo ticket (dialog, página e portal) com seleção de responsável, placeholders claros e validação obrigatória de assunto/descrição/categorias.
- **Sessão Dispositivo**: desktop registra heartbeat/inventário e redireciona colaborador/gestor ao portal apropriado com cookies válidos.
### Equipe interna (admin/agent/collaborator)
- Criar tickets com categorias, responsável inicial e anexos.
- Abrir novos tickets diretamente a partir do detalhe via dialog reutilizável.
- Acessar `/settings` para ajustes pessoais e efetuar logout pelo menu.
### Correções recentes
- Temporizador do ticket (atendimento em andamento): a UI passa a aplicar atualização otimista na abertura/pausa da sessão para que o tempo corrente não "salte" para minutos indevidos. O back‑end continua a fonte da verdade (total acumulado é reconciliado ao pausar).
2. Opcional: instale as dependências do Tauri rodando uma vez:
```powershell
pnpm install
pnpm --filter appsdesktop tauri info
bun install
bun install --cwd apps/desktop
bun run --cwd apps/desktop tauri info
```
3. No GitHub → *Settings* → *Actions* → *Runners* → *New self-hosted runner* → escolha Windows x64 e copie URL/token.
4. Em `C:\actions-runner` (recomendado):
@ -267,10 +265,10 @@
.\svc start
```
6. Confirme no GitHub que o runner aparece como `online`.
7. Mantenha a máquina ligada e conectada durante o período em que o workflow precisa rodar:
7. Mantenha a dispositivo ligada e conectada durante o período em que o workflow precisa rodar:
- Para releases desktop, o runner só precisa estar ligado enquanto o job `desktop_release` estiver em execução (crie a tag e aguarde o workflow terminar).
- Após a conclusão, você pode desligar o computador até a próxima release.
8. Observação importante: o runner Windows pode ser sua máquina pessoal. Garanta apenas que:
8. Observação importante: o runner Windows pode ser sua dispositivo pessoal. Garanta apenas que:
- Você confia no código que será executado (o runner processa os jobs do repositório).
- O serviço do runner esteja ativo enquanto o workflow rodar (caso desligue o PC, as releases ficam na fila).
- Há espaço em disco suficiente e nenhuma política corporativa bloqueando a instalação dos pré-requisitos.
@ -326,14 +324,10 @@
steps:
- uses: actions/checkout@v4
- name: Setup pnpm & Node
uses: pnpm/action-setup@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
bun-version: 1.3.1
- name: Deploy stack (Docker Swarm)
working-directory: ${{ env.APP_DIR }}
@ -350,20 +344,16 @@
steps:
- uses: actions/checkout@v4
- name: Setup pnpm & Node
uses: pnpm/action-setup@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
bun-version: 1.3.1
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Install deps
run: pnpm install --frozen-lockfile
run: bun install --frozen-lockfile
- name: Build + Sign + Release (tauri-action)
uses: tauri-apps/tauri-action@v0
@ -389,7 +379,7 @@
target: ${{ env.VPS_UPDATES_DIR }}
overwrite: true
```
2. Ajuste o bloco de deploy conforme seu processo (por exemplo, use `pnpm build && pm2 restart` se não usar Docker ou substitua por chamada à API do Portainer caso faça o deploy por lá).
2. Ajuste o bloco de deploy conforme seu processo (por exemplo, use `bun run build && pm2 restart` se não usar Docker ou substitua por chamada à API do Portainer caso faça o deploy por lá).
3. Faça commit desse arquivo e suba para o GitHub (`git add .github/workflows/ci-cd-web-desktop.yml`, `git commit`, `git push`).
---
@ -429,7 +419,7 @@
- Garanta que o certificado TLS usado pelo Nginx é renovado (p. ex. `certbot renew`).
- Windows: mantenha máquina ligada e atualizada. Se o serviço parar, abra `services.msc` → `GitHub Actions Runner` → Start.
- Windows: mantenha dispositivo ligada e atualizada. Se o serviço parar, abra `services.msc` → `GitHub Actions Runner` → Start.
---
@ -451,7 +441,7 @@
| Job `desktop_release` falha na etapa `tauri-action` | Toolchain incompleto no Windows | Reinstale Rust, WebView2 e componentes C++ do Visual Studio. |
| Artefatos não chegam à VPS | Caminho incorreto ou chave SSH inválida | Verifique `VPS_HOST`, `VPS_USER`, `VPS_SSH_KEY` e se a pasta `/var/www/updates` existe. |
| App não encontra update | URL ou chave pública divergente no `tauri.conf.json` | Confirme que `endpoints` bate com o domínio HTTPS e que `pubkey` é exatamente a chave pública gerada. |
| Runner aparece offline no GitHub | Serviço parado ou máquina desligada | VPS: `sudo ./svc.sh status`; Windows: abra `Services` e reinicie o `GitHub Actions Runner`. |
| Runner aparece offline no GitHub | Serviço parado ou dispositivo desligada | VPS: `sudo ./svc.sh status`; Windows: abra `Services` e reinicie o `GitHub Actions Runner`. |