# Plano de Desenvolvimento — Sistema de Chamados  

> **Diretriz máxima**: documentação, comunicação e respostas sempre em português brasileiro.

## Contatos
- **Esdras Renan** — monkeyesdras@gmail.com

## Credenciais padrão (Better Auth)
| Papel | Usuário | Senha |
| --- | --- | --- |
| Administrador | `admin@sistema.dev` | `admin123` |
| Painel telão | `suporte@rever.com.br` | `agent123` |

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.

> Execute `bun run auth:seed` após configurar `.env` para (re)criar os usuários acima (campos `SEED_USER_*` podem sobrescrever credenciais).

## 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.

## Stack atual (06/11/2025)
- **Next.js**: `16.0.8` (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.0`.
- **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.

## Setup local (atualizado)
1. `bun install`
2. Copie `.env.example` → `.env.local`.  
   - Principais variáveis para DEV:
     ```
     NODE_ENV=development
     NEXT_PUBLIC_APP_URL=http://localhost:3000
     BETTER_AUTH_URL=http://localhost:3000
     BETTER_AUTH_SECRET=dev-only-long-random-string
     NEXT_PUBLIC_CONVEX_URL=http://127.0.0.1:3210
     DATABASE_URL=file:./prisma/db.dev.sqlite
     ```
3. `bun run auth:seed`
4. (Opcional) `bun run queues:ensure`
5. `bun run convex:dev:bun`
6. Em outro terminal: `bun run dev:bun`
7. Acesse `http://localhost:3000` e valide login com os usuários padrão.

### Banco de dados
- Local (DEV): `DATABASE_URL=file:./prisma/db.dev.sqlite` (guardado em `prisma/prisma/`).  
- Produção: SQLite persistido no volume Swarm `sistema_sistema_db`. Migrations em PROD devem apontar para esse volume (ver `docs/DEPLOY-RUNBOOK.md`).
- Limpeza de legados: `node scripts/remove-legacy-demo-users.mjs` remove contas demo antigas (Cliente Demo, gestores fictícios etc.).

### Verificações antes de PR/deploy
```bash
bun run lint
bun test
bun run build:bun
```

## Aplicativo Desktop (Tauri)
- Código-fonte: `apps/desktop` (Tauri v2 + Vite + React 19).
- URLs:
  - Produção: `https://tickets.esdrasrenan.com.br`
  - DEV: configure `apps/desktop/.env` (exemplo fornecido).
- Comandos:
  - `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.

### 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).

### Observações adicionais
- Planejamos usar um cookie `desktop_shell` no futuro para diferenciar acessos do desktop vs navegador (não implementado).

## 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.
  - Variáveis Better Auth ausentes (`BETTER_AUTH_SECRET`): definidas no workflow (`Quality Checks`).
  - Falha de host: confira `src/config/allowed-hosts.ts`; o middleware retorna 403 quando o domínio do Traefik não está listado.

## 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).  
- Para liberar novo release manualmente:
  ```bash
  ln -sfn /home/renan/apps/sistema.build.<novo> /home/renan/apps/sistema.current
  docker service update --force sistema_web
  ```
- Resolver `P3009` (migration falhou) sempre no volume `sistema_sistema_db`:
  ```bash
  docker service scale sistema_web=0
  docker run --rm -it -e DATABASE_URL=file:/app/data/db.sqlite \
    -v /home/renan/apps/sistema.current:/app \
    -v sistema_sistema_db:/app/data -w /app \
    oven/bun:1 bash -lc "bun install --frozen-lockfile && bun x prisma migrate resolve --rolled-back <migration> && bun x prisma migrate deploy"
  docker service scale sistema_web=1
  ```

## Estado do portal / app web
- Autenticação Better Auth com `AuthGuard`.
- Sidebar inferior agrega avatar, link para `/settings` e logout (oculto em sessões de dispositivo).
- Formulários de ticket (novo/editar/comentários) usam editor rico + anexos; placeholders e validação PT-BR.
- Relatórios e painéis utilizam `AppShell` + `SiteHeader`.
- `usePersistentCompanyFilter` mantém filtro global de empresa em relatórios/admin.
- Exportações CSV: backlog, canais, CSAT, SLA, horas (rotas `/api/reports/*.csv`).
- PDF do ticket (`/api/tickets/[id]/export/pdf`).
- Play interno/externo com métricas por tipo.
- Admin > Empresas: cadastro + “Cliente avulso?”, horas contratadas, vínculos de usuários.
- Admin > Usuários/Equipe:
  - Abas separadas: "Equipe" (administradores e agentes) e "Usuários" (gestores e colaboradores).
  - Multi‑seleção + ações em massa: excluir usuários, remover agentes de dispositivo e revogar convites pendentes.
  - Filtros por papel, empresa e espaço (tenant) quando aplicável; busca unificada.
  - Convites: campo "Espaço (ID interno)" removido da UI de geração.
- Admin > Usuários: vincular colaborador à empresa.
- Alertas enviados: acessível agora em Configurações → Administração do workspace (link direto para /admin/alerts). Removido da sidebar.
- Dashboard: cards por fila e indicadores principais.

## Fluxos suportados
- **Equipe interna** (`admin`, `agent`, `collaborator`): cria/acompanha tickets, comenta, altera status/fila, gera relatórios.
- **Gestores** (`manager`): visualizam tickets da empresa, comentam publicamente, acessam dashboards.
- **Colaboradores** (`collaborator`): portal (`/portal`), tickets próprios, comentários públicos, editor rico, anexos.
- **Sessão Dispositivo**: desktop registra heartbeat/inventário e redireciona colaborador/gestor ao portal apropriado com cookies válidos.

### 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).

## Backlog recomendado
1. E-mails automáticos quando uso de horas ≥ 90% do contratado.
2. Ações rápidas (status/fila) diretamente na lista de tickets.
3. Limites de anexos por tenant + monitoramento.
4. Layout do PDF do ticket alinhado ao visual da aplicação.
5. Experimentos com React Compiler (Next 16).

## Referências rápidas
- **Endpoints agent desktop**:
  - `POST /api/machines/register`
  - `POST /api/machines/heartbeat`
  - `POST /api/machines/inventory`
- **Relatórios XLSX**:
  - Backlog: `/api/reports/backlog.xlsx?range=7d|30d|90d[&companyId=...]`
  - Canais: `/api/reports/tickets-by-channel.xlsx?...`
  - CSAT: `/api/reports/csat.xlsx?...`
  - SLA: `/api/reports/sla.xlsx?...`
  - Horas: `/api/reports/hours-by-client.xlsx?...`
  - Inventário de dispositivos: `/api/reports/machines-inventory.xlsx?[companyId=...]`
- **Docs complementares**:  
  - `docs/DEV.md` — guia diário atualizado.  
  - `docs/STATUS-2025-10-16.md` — snapshot do estado atual e backlog.  
  - `docs/DEPLOY-RUNBOOK.md` — runbook do Swarm.  
  - `docs/admin-inventory-ui.md`, `docs/plano-app-desktop-maquinas.md` — detalhes do inventário/agente.

## Regras de Codigo

### Tooltips Nativos do Navegador

**NAO use o atributo `title` em elementos HTML** (button, span, a, div, etc).

O atributo `title` causa tooltips nativos do navegador que sao inconsistentes visualmente e nao seguem o design system da aplicacao.

```tsx
// ERRADO - causa tooltip nativo do navegador
<button title="Remover item">
  <Trash2 className="size-4" />
</button>

// CORRETO - sem tooltip nativo
<button>
  <Trash2 className="size-4" />
</button>

// CORRETO - se precisar de tooltip, use o componente Tooltip do shadcn/ui
<Tooltip>
  <TooltipTrigger asChild>
    <button>
      <Trash2 className="size-4" />
    </button>
  </TooltipTrigger>
  <TooltipContent>Remover item</TooltipContent>
</Tooltip>
```

**Excecoes:**
- Props `title` de componentes customizados (CardTitle, DialogTitle, etc) sao permitidas pois nao geram tooltips nativos.

### Acessibilidade

Para manter acessibilidade em botoes apenas com icone, prefira usar `aria-label`:

```tsx
<button aria-label="Remover item">
  <Trash2 className="size-4" />
</button>
```

---
_Última atualização: 15/12/2025 (Next.js 16, build padrão com Turbopack e fallback webpack documentado)._ 
