Docs: document machine-session fixes, desktop handshake, portal UX changes, and Windows osInfo fallback

This commit is contained in:
Esdras Renan 2025-10-15 00:21:11 -03:00
parent 328415d9e9
commit 0fb9bf59b2
5 changed files with 53 additions and 4 deletions

View file

@ -84,3 +84,11 @@ Após executar `pnpm auth:seed`, as credenciais padrão ficam disponíveis confo
Consulte `PROXIMOS_PASSOS.md` para acompanhar o backlog funcional e o progresso das iniciativas planejadas. Consulte `PROXIMOS_PASSOS.md` para acompanhar o backlog funcional e o progresso das iniciativas planejadas.
<!-- ci: smoke test 3 --> <!-- ci: smoke test 3 -->
## Diagnóstico de sessão da máquina (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`.

View file

@ -45,8 +45,9 @@
### Sessão "machine" no frontend ### Sessão "machine" no frontend
- Ao autenticar como `machine`, o frontend consulta `/api/machines/session` e popula `machineContext` (assignedUserId, email, name, persona). - Ao autenticar como `machine`, o frontend consulta `/api/machines/session` e popula `machineContext` (assignedUserId, email, name, persona).
- O Portal usa `machineContext.assignedUserId` como `viewerId` ao abrir chamados, permitindo que o colaborador/gestor abra tickets pelo desktop. - Mesmo quando `/api/auth/get-session` retorna `null` na WebView, o portal passa a derivar a role a partir do `machineContext` e utiliza `assignedUserId` como `viewerId` — assim o colaborador consegue abrir chamados via desktop.
- Na UI interna, o menu do usuário (canto inferior do sidebar) oculta o botão "Encerrar sessão" quando a sessão é de máquina. - Na UI interna, o menu do usuário (canto inferior do sidebar) oculta o botão "Encerrar sessão" quando a sessão é de máquina (ou quando `machineContext` está presente).
- Página de diagnóstico: `/portal/debug` exibe o status/JSON de `get-session` e `machines/session` com os mesmos cookies da aba.
### Sinalizador de desktop (opcional futuro) ### Sinalizador de desktop (opcional futuro)
- Podemos adicionar um cookie (ex.: `desktop_shell=1`) no handshake para diferenciar acessos do app desktop de acessos web convencionais. - Podemos adicionar um cookie (ex.: `desktop_shell=1`) no handshake para diferenciar acessos do app desktop de acessos web convencionais.
@ -147,7 +148,11 @@ Observações:
- Dashboard: cards de filas (Chamados/Laboratório/Visitas) e indicadores principais. - Dashboard: cards de filas (Chamados/Laboratório/Visitas) e indicadores principais.
- Lista de tickets: filtro por Empresa, coluna Empresa, alinhamento vertical e melhor espaçamento entre colunas. - Lista de tickets: filtro por Empresa, coluna Empresa, alinhamento vertical e melhor espaçamento entre colunas.
## Entregas recentes relevantes ## Entregas recentes relevantes
- Sessão de máquina confiável no desktop: CORS com credenciais habilitado, aplicação de múltiplos cookies via `NextResponse.cookies.set(...)`, fallback no portal para usar `machineContext` quando `get-session` for `null`.
- Portal (cliente): esconder Fila/Prioridade, listar apenas tickets do solicitante, editor rico + anexos nos comentários, botão “Sair” oculto no desktop.
- Convex: permissão de comentário para solicitante corrigida (primeiro comentário público após criação do ticket).
- Desktop (Windows): fallback para preencher `extended.windows.osInfo` via `sysinfo` quando o PowerShell retornar vazio.
- Correção do redirecionamento após logout evitando retorno imediato ao dashboard. - Correção do redirecionamento após logout evitando retorno imediato ao dashboard.
- Validações manuais dos formulários de rich text para eliminar `ZodError` durante edição. - Validações manuais dos formulários de rich text para eliminar `ZodError` durante edição.
- Dropdown de responsáveis na criação de tickets com preenchimento automático pelo autor e evento inicial de comentário. - Dropdown de responsáveis na criação de tickets com preenchimento automático pelo autor e evento inicial de comentário.

View file

@ -17,6 +17,21 @@
- Com esse contexto, o Portal exibe corretamente o nome/email do colaborador/gestor no cabeçalho e permite abrir chamados em nome do usuário vinculado. - Com esse contexto, o Portal exibe corretamente o nome/email do colaborador/gestor no cabeçalho e permite abrir chamados em nome do usuário vinculado.
- Em sessões de máquina, o botão "Encerrar sessão" no menu do usuário é ocultado por padrão na UI interna. - Em sessões de máquina, o botão "Encerrar sessão" no menu do usuário é ocultado por padrão na UI interna.
#### Detalhes importantes (aprendidos em produção)
- CORS com credenciais: as rotas `POST /api/machines/sessions` e `GET /machines/handshake` precisam enviar `Access-Control-Allow-Credentials: true` para que os cookies do Better Auth sejam aceitos na WebView.
- Vários `Set-Cookie`: alguns navegadores/ambientes colapsam cabeçalhos. Para confiabilidade, usamos `NextResponse.cookies.set(...)` para cada cookie, em vez de repassar o cabeçalho bruto.
- Top-level navigation: mesmo tentando criar a sessão via `POST /api/machines/sessions`, mantemos a navegação final pelo `GET /machines/handshake` (primeira parte) para maximizar a aceitação de cookies no WebView.
- Front tolerante: o portal preenche `machineContext` mesmo quando `/api/auth/get-session` retorna `null` na WebView e deriva a role "machine" do contexto — assim o colaborador consegue abrir tickets normalmente.
- Página de diagnóstico: `GET /portal/debug` exibe o status/JSON de `/api/auth/get-session` e `/api/machines/session` com os mesmos cookies da aba.
#### Troubleshooting rápido
1. Abra o app desktop e deixe ele redirecionar para `/portal/debug`.
2. Se `machines/session` for 200 e `get-session` for `null`, está OK — o portal usa `machineContext` assim mesmo.
3. Se `machines/session` for 401/403:
- Verifique CORS/credenciais (`Access-Control-Allow-Credentials: true`).
- Garante que estamos usando `cookies.set` para aplicar todos os cookies da Better Auth.
- Refaça o handshake (feche reabra o desktop). Opcional: renomeie `EBWebView` para limpar cookies no Windows.
## Requisitos ## Requisitos
- VPS com Docker/Swarm e Traefik já em execução na rede externa `traefik_public`. - VPS com Docker/Swarm e Traefik já em execução na rede externa `traefik_public`.
- Portainer opcional (para gerenciar a stack “sistema”). - Portainer opcional (para gerenciar a stack “sistema”).

View file

@ -44,3 +44,9 @@ Saída de artefatos: `apps/desktop/src-tauri/target/release/bundle/`.
``` ```
- Para logs detalhados em dev, rode `pnpm -C apps/desktop tauri dev`. - Para logs detalhados em dev, rode `pnpm -C apps/desktop tauri dev`.
## Diagnóstico de sessão (Desktop → Portal)
- Durante testes, navegue até `/portal/debug` (o desktop pode redirecionar automaticamente) para ver:
- `/api/auth/get-session` — pode ser `null` na WebView; não é bloqueante.
- `/api/machines/session` — precisa retornar `200` com `assignedUserId/email`.
- Produção: as rotas de sessão/handshake enviam `Access-Control-Allow-Credentials: true` e aplicam cookies com `NextResponse.cookies.set(...)` para confiabilidade em navegadores/embeds.
- O desktop mantém a navegação toplevel via `/machines/handshake` para maximizar a aceitação de cookies.

View file

@ -53,7 +53,7 @@ Legenda: ✅ concluído · 🔄 em andamento · ⏳ a fazer.
- URLs configuráveis via `.env` do app desktop: - URLs configuráveis via `.env` do app desktop:
- `VITE_APP_URL` → aponta para a interface Next (padrao produção: `https://tickets.esdrasrenan.com.br`). - `VITE_APP_URL` → aponta para a interface Next (padrao produção: `https://tickets.esdrasrenan.com.br`).
- `VITE_API_BASE_URL` → base usada nas chamadas REST (`/api/machines/*`), normalmente igual ao `APP_URL`. - `VITE_API_BASE_URL` → base usada nas chamadas REST (`/api/machines/*`), normalmente igual ao `APP_URL`.
- Após provisionar ou encontrar token válido, o agente dispara `/machines/handshake?token=...` que autentica a máquina no Better Auth, devolve cookies e redireciona para a UI. - Após provisionar ou encontrar token válido, o agente dispara `/machines/handshake?token=...` que autentica a máquina no Better Auth, devolve cookies e redireciona para a UI. Em produção, mantemos a navegação toplevel pelo handshake para garantir a aceitação de cookies na WebView (mesmo quando `POST /api/machines/sessions` é tentado antes).
- `apps/desktop/src-tauri/tauri.conf.json` ajustado para rodar `pnpm run dev/build`, servir `dist/` e abrir janela 1100x720. - `apps/desktop/src-tauri/tauri.conf.json` ajustado para rodar `pnpm run dev/build`, servir `dist/` e abrir janela 1100x720.
- Novas tabelas Convex: `machines` (fingerprint, heartbeat, vínculo com AuthUser) e `machineTokens` (hash + TTL). - Novas tabelas Convex: `machines` (fingerprint, heartbeat, vínculo com AuthUser) e `machineTokens` (hash + TTL).
- Novos endpoints Next: - Novos endpoints Next:
@ -62,8 +62,23 @@ Legenda: ✅ concluído · 🔄 em andamento · ⏳ a fazer.
- `POST /api/machines/sessions` — troca `machineToken` por sessão Better Auth e devolve cookies. - `POST /api/machines/sessions` — troca `machineToken` por sessão Better Auth e devolve cookies.
- As rotas `/api/machines/*` respondem a preflight `OPTIONS` com CORS liberado para o agente (`https://tickets.esdrasrenan.com.br`, `tauri://localhost`, `http://localhost:1420`). - As rotas `/api/machines/*` respondem a preflight `OPTIONS` com CORS liberado para o agente (`https://tickets.esdrasrenan.com.br`, `tauri://localhost`, `http://localhost:1420`).
- Rota `GET /machines/handshake` realiza o login automático da máquina (seta cookies e redireciona). - Rota `GET /machines/handshake` realiza o login automático da máquina (seta cookies e redireciona).
- As rotas `sessions/handshake` foram ajustadas para usar `NextResponse.cookies.set(...)`, aplicando cada cookie da Better Auth (sessão e assinatura) individualmente.
- CORS: as respostas incluem `Access-Control-Allow-Credentials: true` para origens permitidas (Tauri WebView e app).
- Página de diagnóstico: `/portal/debug` exibe `get-session` e `machines/session` com os mesmos cookies da aba — útil para validar se o desktop está autenticado como máquina.
- O desktop pode redirecionar automaticamente para essa página durante os testes.
- Webhook FleetDM: `POST /api/integrations/fleet/hosts` (header `x-fleet-secret`) sincroniza inventário/métricas utilizando `machines.upsertInventory`. - Webhook FleetDM: `POST /api/integrations/fleet/hosts` (header `x-fleet-secret`) sincroniza inventário/métricas utilizando `machines.upsertInventory`.
- Script `ensureMachineAccount` garante usuário `AuthUser` e senha sincronizada com o token atual. - Script `ensureMachineAccount` garante usuário `AuthUser` e senha sincronizada com o token atual.
### Inventário — Windows (fallback)
- O agente coleta `extended.windows.osInfo` via PowerShell/WMI. Caso o script falhe (política ou permissão), aplicamos um fallback com `sysinfo` para preencher ao menos `ProductName`, `Version` e `BuildNumber` — evitando bloco vazio no inventário exibido.
### Portal do Cliente (UX)
- Quando autenticado como máquina (colaborador/gestor):
- O portal deriva o papel a partir do `machineContext` (mesmo se `/api/auth/get-session` vier `null`).
- A listagem exibe apenas os tickets onde o colaborador é o solicitante.
- Informações internas (Fila, Prioridade) são ocultadas; o responsável aparece quando definido.
- A descrição do chamado vira o primeiro comentário (editor rico + anexos). A permissão de comentar pelo solicitante foi ajustada no Convex.
- O botão “Sair” é ocultado no desktop (faz sentido apenas fechar o app).
- Variáveis `.env` novas: `MACHINE_PROVISIONING_SECRET` (obrigatória) e `MACHINE_TOKEN_TTL_MS` (opcional, padrão 30 dias). - Variáveis `.env` novas: `MACHINE_PROVISIONING_SECRET` (obrigatória) e `MACHINE_TOKEN_TTL_MS` (opcional, padrão 30 dias).
- Variável adicional `FLEET_SYNC_SECRET` (opcional) para autenticar webhook do Fleet; se ausente, reutiliza `MACHINE_PROVISIONING_SECRET`. - Variável adicional `FLEET_SYNC_SECRET` (opcional) para autenticar webhook do Fleet; se ausente, reutiliza `MACHINE_PROVISIONING_SECRET`.
- Dashboard administrativo: `/admin/machines` usa `AdminMachinesOverview` com dados em tempo real (status, heartbeat, token, inventário enviado pelo agente/Fleet). - Dashboard administrativo: `/admin/machines` usa `AdminMachinesOverview` com dados em tempo real (status, heartbeat, token, inventário enviado pelo agente/Fleet).