# Histórico de Setup e Decisões — Sistema de Chamados

> Registro das etapas realizadas, problemas encontrados e decisões tomadas para colocar o projeto em produção (Traefik + Swarm + Convex self‑hosted) com CI/CD via runner self‑hosted.

## Arquitetura final
- Frontend Next.js (app) em `tickets.esdrasrenan.com.br`.
- Convex self‑hosted (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 self‑hosted 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 pull‑based 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 self‑hosted, 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 self‑hosted
- 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 self‑hosted `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 self‑hosted.

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 self‑hosted).
- Solução: regularizar billing; opcionalmente usar `scripts/deploy-from-git.sh` até normalizar.

## Checklists de operação
- Deploy manual (pull‑based): `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 self‑hosted (zero minutos GitHub‑hosted).
- Fixar versão do `convex-backend` (ao invés de `latest`) para releases mais controladas.
- Substituir bind‑mount 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 type‑check do Next. Avaliar, em outro momento, ambient d.ts no desktop para editor.
