docs: reorganize and simplify

- 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/
This commit is contained in:
codex-bot 2025-10-20 16:24:16 -03:00
parent 0dd0e67458
commit f5b3abd277
15 changed files with 190 additions and 11 deletions

1
docs/archive/.gitkeep Normal file
View file

@ -0,0 +1 @@

View file

@ -0,0 +1,56 @@
Convex SelfHosted — Configurar env e testar provisionamento (Arquivo)
Nota: este documento foi arquivado. O fluxo atual de deploy/ops está em `docs/operations.md`.
Prérequisitos
- Rodar na VPS com Docker.
- Projeto em `/srv/apps/sistema`.
- Admin Key do Convex (já obtida):
`convex-self-hosted|011c148069bd37e4a3f1c10b41b19459427a20e6d7ba81f53b659861f7658cd4985c8936e9`
1) Exportar variáveis da sessão (URL + Admin Key)
export CONVEX_SELF_HOSTED_URL="https://convex.esdrasrenan.com.br"
export CONVEX_SELF_HOSTED_ADMIN_KEY='convex-self-hosted|011c148069bd37e4a3f1c10b41b19459427a20e6d7ba81f53b659861f7658cd4985c8936e9'
2) Definir MACHINE_PROVISIONING_SECRET no Convex (obrigatório)
docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set MACHINE_PROVISIONING_SECRET '71daa9ef54cb224547e378f8121ca898b614446c142a132f73c2221b4d53d7d6' -y; \
pnpm exec convex env list"
3) (Opcional) Definir MACHINE_TOKEN_TTL_MS (padrão 30 dias)
docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set MACHINE_TOKEN_TTL_MS '2592000000' -y; \
pnpm exec convex env list"
4) (Opcional) Definir FLEET_SYNC_SECRET
docker run --rm -it \
-v /srv/apps/sistema:/app -w /app \
-e CONVEX_SELF_HOSTED_URL -e CONVEX_SELF_HOSTED_ADMIN_KEY \
node:20-bullseye bash -lc "set -euo pipefail; \
corepack enable && corepack prepare pnpm@9 --activate && pnpm i --frozen-lockfile --prod=false; \
unset CONVEX_DEPLOYMENT; \
pnpm exec convex env set FLEET_SYNC_SECRET '' -y; \
pnpm exec convex env list"
5) Testar registro (gera machineToken) — substitua o hostname se quiser
HOST="vm-teste-$(date +%s)"; \
curl -sS -o resp.json -w "%{http_code}\n" -X POST 'https://tickets.esdrasrenan.com.br/api/machines/register' \
-H 'Content-Type: application/json' \
-d '{"provisioningSecret":"71daa9ef54cb224547e378f8121ca898b614446c142a132f73c2221b4d53d7d6","tenantId":"tenant-atlas","hostname":"'"$HOST"'","os":{"name":"Linux","version":"6.1.0","architecture":"x86_64"},"macAddresses":["AA:BB:CC:DD:EE:FF"],"serialNumbers":[],"metadata":{"inventario":{"cpu":"i7","ramGb":16}},"registeredBy":"manual-test"}'; \
echo; tail -c 400 resp.json || true
6) (Opcional) Enviar heartbeat com o token retornado
TOKEN=$(node -e 'try{const j=require("fs").readFileSync("resp.json","utf8");process.stdout.write(JSON.parse(j).machineToken||"");}catch(e){process.stdout.write("")}' ); \
[ -n "$TOKEN" ] && curl -sS -o /dev/null -w "%{http_code}\n" -X POST 'https://tickets.esdrasrenan.com.br/api/machines/heartbeat' \
-H 'Content-Type: application/json' \
-d '{"machineToken":"'"$TOKEN"'","status":"online","metrics":{"cpuPct":12,"memFreePct":61}}'

View file

@ -0,0 +1,126 @@
# Deploy runbook (Swarm) — Arquivo
Nota: este runbook foi arquivado. Utilize `docs/operations.md` para o fluxo atualizado de deploy.
Este guia documenta o fluxo de deploy atual e os principais passos de diagnóstico/correção que resolveram o problema do front não atualizar mesmo com o CI verde.
## Visão geral (como você trabalha)
- Você dá push na `main` e aguarda o GitHub Actions concluir.
- O pipeline cria um build imutável no servidor em `/home/renan/apps/sistema.build.<release>`.
- Um symlink estável aponta para o release ativo: `/home/renan/apps/sistema.current`.
- O serviço `sistema_web` monta sempre `/home/renan/apps/sistema.current:/app`. Para atualizar, basta mudar o symlink e forçar a task.
Resultado: front/back sobem com o novo código sem editar o stack a cada release.
## Fluxo de release (mínimo)
1. Gerar build em `/home/renan/apps/sistema.build.<stamp-ou-sha>` (CI faz isso).
2. Atualizar symlink: `ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current`.
3. Rollout do serviço web: `docker service update --force sistema_web`.
4. Opcional: se o `stack.yml` mudou, aplicar: `docker stack deploy --with-registry-auth -c /home/renan/apps/sistema.build.<novo>/stack.yml sistema`.
## Stack estável (essência)
- Mount fixo: `/home/renan/apps/sistema.current:/app` (não interpolar APP_DIR).
- Comando inline (sem script), com migrations na subida:
- `command: ["bash","-lc","corepack enable && corepack prepare pnpm@9 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"]`
- **Se você optar por usar `/app/scripts/start-web.sh`** (como no workflow atual), ele já garante `pnpm@9` via Corepack/NPM antes de rodar Prisma/Next. Certifique-se de copiar esse arquivo para o build publicado; sem ele, a task cai com `pnpm: command not found`.
- Env obrigatórias (URLs válidas):
- `DATABASE_URL=file:/app/data/db.sqlite`
- `NEXT_PUBLIC_CONVEX_URL=http://sistema_convex_backend:3210`
- `NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.br`
- `BETTER_AUTH_URL=https://tickets.esdrasrenan.com.br`
- Update com `stop-first` (evita `database is locked` em SQLite) + healthcheck.
## Prisma/SQLite do stack
- O volume do stack é namespaced: `sistema_sistema_db` (não `sistema_db`).
- Ao operar Prisma fora do Swarm, use SEMPRE este volume e a mesma `DATABASE_URL`:
```
APP_DIR=/home/renan/apps/sistema.current
docker run --rm -it \
-e DATABASE_URL=file:/app/data/db.sqlite \
-v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@9 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate status'
```
## Diagnóstico rápido
- Ver a task atual + erros: `docker service ps --no-trunc sistema_web`
- Logs frescos do serviço: `docker service logs --since=2m -f sistema_web`
- Spec aplicado (Args + Mounts):
```
docker service inspect sistema_web \
--format '{{json .Spec.TaskTemplate.ContainerSpec.Args}} {{json .Spec.TaskTemplate.ContainerSpec.Mounts}}'
```
- Envs do serviço: `docker service inspect sistema_web --format '{{json .Spec.TaskTemplate.ContainerSpec.Env}}'`
## O incidente (front não atualizava) — causa e correções
Sintomas:
- Actions verde, mas UI antiga; logs com rollbacks de `docker service update`.
Causas encontradas:
1) Serviço ainda montava build antigo e comando antigo (spec não mudava).
- Inspect mostrava `Source=/home/renan/apps/sistema.build.<antigo> -> /app` e comando inline antigo.
- Correção: redeploy do stack com mount em `/home/renan/apps/sistema.current` + `docker service update --force sistema_web`.
2) Migration P3009 ("failed migrations") no SQLite do stack.
- Motivo: resolver/aplicar migrations no volume errado (`sistema_db`), enquanto o serviço usa `sistema_sistema_db`.
- Correção determinística:
- `docker service scale sistema_web=0`
- `prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code` no volume `sistema_sistema_db` (comando acima em "Prisma/SQLite do stack").
- `pnpm exec prisma migrate deploy`
- `docker service scale sistema_web=1` (ou `update --force`).
3) Rollback por script ausente (`/app/scripts/start-web.sh`).
- Task caía com exit 127 porque o build não continha o script.
- Correção: voltar ao comando inline no stack (sem depender do script) OU garantir o script no build e executável.
4) Falha de env (Invalid URL em `NEXT_PUBLIC_APP_URL`/`BETTER_AUTH_URL`).
- Correção: definir URLs válidas no stack ou via `docker service update --env-add ...`.
## Cheatsheet de correções
- Forçar rollout da task:
- `docker service update --force sistema_web`
- Aplicar build novo (sem tocar stack):
- `ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current`
- `docker service update --force sistema_web`
- Corrigir mount/args no serviço (hotfix):
```
docker service update \
--mount-rm target=/app \
--mount-add type=bind,src=/home/renan/apps/sistema.current,dst=/app \
--args 'bash -lc "corepack enable && corepack prepare pnpm@9 --activate && pnpm exec prisma migrate deploy && pnpm start -p 3000"' \
sistema_web
```
- Resolver P3009 (volume certo) e aplicar migrations:
```
APP_DIR=/home/renan/apps/sistema.current
docker service scale sistema_web=0
docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \
-v "$APP_DIR:/app" -v sistema_sistema_db:/app/data -w /app \
node:20-bullseye bash -lc 'corepack enable; corepack prepare pnpm@9 --activate; pnpm i --no-frozen-lockfile; pnpm exec prisma migrate resolve --rolled-back 20251015223259_add_company_provisioning_code; pnpm exec prisma migrate deploy'
docker service scale sistema_web=1
```
- Criar DB se faltar (P1003):
- `docker run --rm -v sistema_sistema_db:/data busybox sh -lc ': >/data/db.sqlite'`
- Ajustar envs em runtime:
- `docker service update --env-add NEXT_PUBLIC_APP_URL=https://tickets.esdrasrenan.com.br --env-add BETTER_AUTH_URL=https://tickets.esdrasrenan.com.br sistema_web`
## Notas finais
- Como o stack monta `/home/renan/apps/sistema.current`, um novo release exige apenas atualizar o symlink e forçar a task. O `stack.yml` só precisa ser redeployado quando você altera labels/envs/serviços.
- Se a UI parecer não mudar, valide o mount/args via inspect, confira logs da task atual e force hardreload no navegador.

View file

@ -0,0 +1,101 @@
# Plano Integrado App Desktop & Inventário por Máquina (Arquivo)
> Documento vivo. Atualize após cada marco relevante.
## Contexto
- **Objetivo:** Expandir o Sistema de Chamados (Next.js + Convex + Better Auth) para suportar:
- Cliente desktop nativo (Tauri) mantendo UI web e realtime.
- Autenticação máquina-a-máquina usando tokens derivados do inventário.
- Integração com agente de inventário (osquery/FleetDM) para registrar hardware, software e heartbeats.
- Pipeline de distribuição para Windows/macOS/Linux.
- **Escopo inicial:** Focar no fluxo mínimo viável com inventário básico (hostname, OS, identificadores, carga resumida). Métricas avançadas e distribuição automatizada ficam para iteração seguinte.
## Estado Geral
- Web atual permanece operacional com login por usuário/senha.
- Novas features serão adições compatíveis (machine login opcional).
- Melhor abordagem para inventário: usar **osquery + FleetDM** (stack pronta) integrando registros no Convex.
- Agente desktop coleta inventário básico + estendido por SO (Linux: dpkg/rpm + systemd + lsblk/lspci/lsusb/smartctl; Windows: WMI/registry via PowerShell; macOS: system_profiler/pkgutil/launchctl) e envia via heartbeat e/ou `/api/machines/inventory`.
## Marcos & Progresso
| Macro-entrega | Status | Observações |
| --- | --- | --- |
| Documento de arquitetura e roadmap | 🔄 Em andamento | Estrutura criada, aguardando detalhamento incremental a cada etapa. |
| Projeto Tauri inicial apontando para UI Next | 🔄 Em andamento | Estrutura `apps/desktop` criada; pendente testar build após instalar toolchain Rust. |
| Schema Convex + tokens de máquina | ✅ Concluído | Tabelas `machines` / `machineTokens` criadas com TTL e fingerprint. |
| API de registro/heartbeat e exchange Better Auth | 🔄 Em andamento | Endpoints `/api/machines/*` disponíveis; falta testar fluxo end-to-end com app desktop. |
| Endpoint upsert de inventário dedicado | ✅ Concluído | `POST /api/machines/inventory` (modo por token ou provisioningSecret). |
| Integração FleetDM → Convex (inventário básico) | 🔄 Em andamento | Endpoint `/api/integrations/fleet/hosts` criado; falta validar payload real e ajustes de métricas/empresa. |
| Admin > Máquinas (listagem, detalhes, métricas) | ✅ Concluído | Página `/admin/machines` exibe parque completo com status ao vivo, inventário e métricas. |
| Ajustes na UI/Next para sessão por máquina | ⏳ A fazer | Detectar token e exibir info da máquina em tickets. |
| Pipeline de build/distribuição Tauri | ⏳ A fazer | Definir estratégia CI/CD + auto-update. |
| Guia operacional (instalação, uso, suporte) | ⏳ A fazer | Gerar instruções finais com casos de uso. |
Legenda: ✅ concluído · 🔄 em andamento · ⏳ a fazer.
## Dependências Técnicas
- **Tauri Desktop:** Rust + toolchain específico por SO, libwebkit2gtk (Linux), WebView2 (Windows), Xcode (macOS).
- **FleetDM/osquery:** Servidor Fleet (Docker ou VM), enrollment secret por tenant, agentes osquery instalados.
- **Better Auth:** Mechanismo para criar sessões usando subject `machine:*` com escopos restritos.
- **Convex:** Novas tabelas `machines` e `machineTokens`, mutações para registro/heartbeat/exchange.
- **Infra extra:** Endpoints públicos para updater do Tauri, armazenamento de inventário seguro, certificados para assinatura de builds.
## Próximos Passos Imediatos
1. Desktop: finalizar UX das abas (mais detalhes em Diagnóstico e Configurações) e gráficos leves.
2. Coletores Windows/macOS: normalizar campos de software/serviços (nome/versão/fonte/status) e whitelists.
3. Regras: janela temporal real para CPU (dados de 5 min), whitelists por tenant, mais sinais SMART (temperatura e contadores).
4. Admin UI: diálogo “Inventário completo” com busca em JSON, export CSV de softwares/serviços, badges no grid com contagens.
5. Release: ativar secrets de assinatura e publicar binários por SO.
## Notas de Implementação (Atual)
- Criada pasta `apps/desktop` via `create-tauri-app` com template `vanilla-ts`.
- O agente desktop agora possui fluxo próprio: coleta inventário local via comandos Rust, solicita o código de provisionamento, registra a máquina e inicia heartbeats periódicos (`src-tauri/src/agent.rs` + `src/main.ts`).
- Formulário inicial exibe resumo de hardware/OS e salva o token em `~/.config/Sistema de Chamados Desktop/machine-agent.json` (ou equivalente por SO) para reaproveitamento em relançamentos.
- 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_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. 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.
- Novas tabelas Convex: `machines` (fingerprint, heartbeat, vínculo com AuthUser) e `machineTokens` (hash + TTL).
- Novos endpoints Next:
- `POST /api/machines/register` — provisiona máquina, gera token e usuário Better Auth (role `machine`).
- `POST /api/machines/heartbeat` — atualiza estado, métricas e renova TTL.
- `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`).
- 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`.
- 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á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).
### Checklist de dependências Tauri (Linux)
```bash
sudo apt update
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file \
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
# reinicie o terminal e confirme: rustc --version
```
> Ajuste conforme seu sistema operacional (ver https://tauri.app/start/prerequisites/).
---
> Histórico de atualizações:
> - 2025-02-20 — Fluxo completo do agente desktop, heartbeats e rota `/machines/handshake` documentados (assistente).
> - 2025-02-14 — Documento criado com visão geral e plano macro (assistente).

View file

@ -0,0 +1,104 @@
# Histórico de Setup e Decisões — Sistema de Chamados (Arquivo)
Conteúdo mantido como registro. Para operação e deploy atuais, ver `docs/operations.md`.
> Registro das etapas realizadas, problemas encontrados e decisões tomadas para colocar o projeto em produção (Traefik + Swarm + Convex selfhosted) com CI/CD via runner selfhosted.
## Arquitetura final
- Frontend Next.js (app) em `tickets.esdrasrenan.com.br`.
- Convex selfhosted (backend realtime) em `convex.esdrasrenan.com.br`.
- Traefik no Docker Swarm (rede `traefik_public`) roteando por hostname (HTTPS/LE).
- Banco Prisma (SQLite) persistente via volume `sistema_db`.
- Estado do Convex persistente via volume `convex_data`.
- Runner GitHub Actions selfhosted na VPS (usuário `renan`).
## Mudanças no repositório
- `stack.yml` — Stack Swarm (web + convex_backend + convex_dashboard opcional).
- `.env.example` e `apps/desktop/.env.example` — exemplos de ambiente.
- `.github/workflows/ci-cd-web-desktop.yml` — pipeline de deploy web + desktop + deploy do Convex.
- `docs/OPERACAO-PRODUCAO.md` — runbook de operação (deploy, seeds, CI/CD, troubleshooting).
- `docs/SETUP-HISTORICO.md` — este histórico.
- `pnpm-workspace.yaml` — inclui `packages: ['.', 'apps/desktop']` para permitir comandos e builds do desktop. No deploy do web usamos filtros/paths; se preferir isolar, volte para apenas `'.'`.
- `scripts/deploy-from-git.sh` — fallback de deploy pullbased na VPS (sem Actions).
## Gestão de .env
- `.env` não é commitado; usamos o arquivo local na VPS: `/srv/apps/sistema/.env`.
- Workflow atualizado para NÃO apagar `.env` no destino (rsync com filtros `protect`).
- Valor com espaços deve ter aspas: `MAILER_SENDER_EMAIL="Nome <no-reply@dominio>"`.
- Em selfhosted, comentar `CONVEX_DEPLOYMENT`, e usar `NEXT_PUBLIC_CONVEX_URL=https://convex...`.
## Stack (Traefik/Swarm)
- Binds absolutos (Portainer/Swarm exigem): `/srv/apps/sistema:/app`.
- Volumes: `sistema_db``/app/data` (SQLite), `convex_data``/convex/data`.
- Labels Traefik por hostname; WebSocket do Convex funciona via TLS.
## Convex selfhosted
- Evitamos `convex dev` no Swarm (CLI interativo). Adotada imagem oficial `ghcr.io/get-convex/convex-backend`.
- Geração de Admin Key dentro do container: `./generate_admin_key.sh`.
- Publicação de functions com `pnpm exec convex deploy` via container Node (`CONVEX_SELF_HOSTED_URL` + `CONVEX_SELF_HOSTED_ADMIN_KEY`).
- Adicionado `convex_dashboard` opcional (DNS `convex-admin.*`).
## CI/CD (GitHub Actions)
- Runner selfhosted `vps-sistema` com labels `self-hosted, linux, vps`.
- Job Deploy (web) roda sempre em push para `main`.
- Job Deploy Convex functions roda apenas quando arquivos em `convex/**` mudam (paths-filter).
- rsync com `--filter='protect .env*'` para preservar `.env` local.
- Secrets no repositório: `CONVEX_SELF_HOSTED_URL`, `CONVEX_SELF_HOSTED_ADMIN_KEY` (e secrets do desktop se usados).
## Problemas e soluções (pitfalls)
1) WebSocket 1006 no front
- Causa: Convex não rodando corretamente (CLI interativo) → migração para imagem oficial selfhosted.
2) `.env` sendo apagado pelo rsync
- Causa: `--delete` no rsync no job de deploy.
- Solução: adicionar filtros `protect` e `exclude` para `.env*` (raiz/desktop/convex).
3) `MAILER_SENDER_EMAIL` com erro de parsing
- Causa: valor com espaços sem aspas quando foi "sourced" por shell.
- Solução: sempre usar aspas. Depois, com backend oficial, não foi mais necessário `source`.
4) `prisma: not found` no build
- Causa: instalar só prod deps.
- Solução: `NPM_CONFIG_PRODUCTION=false` e `pnpm install --prod=false` no container de build.
5) Lockfile/Workspace quebrando CI
- Causa: conflito de versões quando o desktop entrou no workspace.
- Solução: hoje mantemos `['.', 'apps/desktop']` e usamos filtros no CI/deploy. Alternativa: isolar o desktop fora do workspace.
6) Bind relativo no Swarm/Portainer
- Causa: `./:/app` vira path inválido.
- Solução: usar path absoluto: `/srv/apps/sistema:/app`.
7) Flags `--port/--hostname` no `convex dev`
- Causa: versão do CLI.
- Solução: remover flags, e posteriormente substituir por backend oficial.
8) Billing do GitHub bloqueado
- Causa: cobrança travada bloqueia todos workflows (mesmo selfhosted).
- Solução: regularizar billing; opcionalmente usar `scripts/deploy-from-git.sh` até normalizar.
## Checklists de operação
- Deploy manual (pullbased): `bash /srv/apps/sistema/scripts/deploy-from-git.sh`.
- Deploy via Actions: commit em `main`.
- Seeds: `https://tickets.../dev/seed` e `docker exec ... pnpm auth:seed`.
- Verificação: `docker stack services sistema` e logs dos serviços.
## Melhorias futuras
- Rodar job de "Detect changes" também em runner selfhosted (zero minutos GitHubhosted).
- Fixar versão do `convex-backend` (ao invés de `latest`) para releases mais controladas.
- Substituir bindmount por imagens construídas no CI (tempo de deploy menor, reprodutibilidade).
- Adicionar cache de dependências pnpm no container de build.
## TODOs (próximos técnicos)
- Prisma Client desatualizado x schema (Company.isAvulso/contractedHoursPerMonth)
- Sintoma: Tipos gerados do Prisma não exibem os campos `isAvulso` e `contractedHoursPerMonth` em `CompanyCreateInput`/`CompanyUpdateInput`.
- Temporário: rotas `src/app/api/admin/companies/[id]/route.ts` e mapeamento em `src/app/admin/companies/page.tsx` possuem guardas/casts para compilar.
- Ação:
1. Rodar `pnpm prisma:generate` no mesmo ambiente de build/execução (VPS e local) para regenerar o client.
2. Confirmar que os campos aparecem nos tipos gerados.
3. Remover casts e `eslint-disable` do update; reintroduzir campos no `create` se desejado (com tipagem estrita).
4. Se ainda não existirem fisicamente na base, aplicar migração que adicione os campos ao modelo `Company`.
- Next TS x Desktop (plugin Keyring)
- Mantido `apps/desktop/**` no `tsconfig.exclude` para o typecheck do Next. Avaliar, em outro momento, ambient d.ts no desktop para editor.

View file

@ -0,0 +1,52 @@
# Status do Projeto — 16/10/2025 (Arquivo)
Documento de referência sobre o estado atual do sistema (web + desktop), melhorias recentes e pontos de atenção.
## 1. Panorama
- **Web (Next.js 15 + Convex)**: build limpo (`pnpm build`), lint sem avisos e testes estáveis (Vitest em modo não interativo).
- **Desktop (Tauri)**: fluxo de provisionamento e heartbeat operacional; inventário consolidado com coleta multi-plataforma; atualizações OTA suportadas.
- **CI**: workflow `Quality Checks` roda lint/test/build em todo push/PR na `main`; pipeline de deploy (`ci-cd-web-desktop.yml`) permanece responsável por sincronizar com a VPS.
- **Infra**: deploy documentado no runbook (Swarm com symlink `sistema.current`). Migrações Prisma e variáveis críticas mapeadas.
## 2. Melhorias concluídas em 16/10/2025
| Item | Descrição | Impacto |
| --- | --- | --- |
| **Centralização Convex** | Helpers `createConvexClient` e normalização do cookie da máquina (`src/server/convex-client.ts`, `src/server/machines/context.ts`). | Código das rotas `/api/machines/*` ficou mais enxuto e resiliente a erros de configuração. |
| **Auth/Login redirect** | Redirecionamento baseado em role/persona sem uso de `any`, com dependências explícitas (`src/app/login/login-page-client.tsx`). | Evita warnings de hooks e garante rota correta para máquinas/colaboradores. |
| **Ticket header** | Sincronização do responsável com dependências completas (`ticket-summary-header.tsx`). | Removeu warning do lint e previne estados inconsistentes. |
| **Upgrade para Next.js 16 beta** | Dependências atualizadas (`next@16.0.0-beta.0`, `eslint-config-next@16.0.0-beta.0`), cache de filesystem do Turbopack habilitado, scripts de lint/test/build ajustados ao novo fluxo. | Projeto pronto para validar as novidades do Next 16 (React Compiler opcional, prefetch incremental, etc.); builds e testes já rodando com sucesso. |
| **Posture / inventário** | Type guards e normalização de métricas SMART/serviços (`convex/machines.ts`). | Reduziu `any`, melhorou detecção de alertas e consistência do metadata. |
| **Docs** | Revisão completa de `docs/DEV.md`, novo `STATUS-2025-10-16.md`, estrutura uniforme e casos de erro registrados. | Documentação enxuta e atualizada, com trilhas claras para DEV/CI/Deploy. |
| **Testes no CI** | Novo workflow `.github/workflows/quality-checks.yml` e script `pnpm test` em modo não-interativo. | Previne “travamentos” e garante checagens de qualidade automáticas. |
## 3. Pontos de atenção (curto prazo)
- **Migrações Prisma em produção**: qualquer mudança requer executar no volume `sistema_sistema_db` (ver `docs/DEPLOY-RUNBOOK.md`). Atenção para evitar regressões P3009.
- **Atualização dos artefatos Tauri**: releases exigem `latest.json` atualizado e assinatura (`*.sig`). Automação via GitHub Actions já preparada, mas depende de manter as chaves seguras.
- **Seeds Better Auth**: se novos perfis/roles forem adicionados, atualizar `scripts/seed-auth.mjs` e o seed do Convex.
- **Variáveis críticas**: `NEXT_PUBLIC_APP_URL`, `BETTER_AUTH_URL`, `MACHINE_PROVISIONING_SECRET` e `NEXT_PUBLIC_CONVEX_URL` devem ser válidas no stack — qualquer alteração de domínio implica revisar `.env` e `stack.yml`.
## 4. Backlog recomendado
1. **Testes end-to-end**: cobrir fluxo de provisionamento (desktop ↔ API) com smoke automatizado (pode rodar condicional no CI).
2. **Autenticação agnóstica**: avaliar suporte para Clerk/Auth0 conforme docs do Convex (custom JWTs).
3. **Observabilidade**: adicionar métricas/alertas para heartbeats em atraso (Convex + dashboards).
4. **Documentação do Desktop Installer**: guias por SO sobre instalação/assinatura e troubleshooting do updater.
## 5. Casos de erro conhecidos
| Cenário | Sintoma | Como resolver |
| --- | --- | --- |
| Token de máquina revogado | POST `/api/machines/sessions` retorna 401 e desktop volta ao onboarding | Reprovisionar pela UI do agente; garantir que `machineToken` foi atualizado. |
| Falha de heartbeat | Logs com `Falha ao registrar heartbeat` + status 500 | Verificar `NEXT_PUBLIC_CONVEX_URL` e conectividade. Roda `pnpm convext:dev` em DEV para confirmar schema. |
| Updater sem atualização | Desktop fica em “Procurando atualização” indefinidamente | Confirmar release publicado com `latest.json` apontando para URLs públicas do bundle e assinaturas válidas. |
## 6. Próximos passos imediatos
- Monitorar execução do novo workflow de qualidade em PRs.
- Garantir que a equipe esteja ciente do procedimento atualizado de deploy (symlink + service update).
- Revisar backlog acima e priorizar smoke tests para o fluxo da máquina.
_Última atualização: 16/10/2025 (UTC-3)._