214 lines
11 KiB
Markdown
214 lines
11 KiB
Markdown
# 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 (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.
|
||
|
||
## 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=postgresql://postgres:dev@localhost:5432/sistema_chamados
|
||
```
|
||
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): 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`).
|
||
- 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) no PostgreSQL ativo:
|
||
```bash
|
||
docker service scale sistema_web=0
|
||
docker run --rm -it --network traefik_public \
|
||
--env-file /home/renan/apps/sistema.current/.env \
|
||
-v /home/renan/apps/sistema.current:/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/OPERATIONS.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: 18/12/2025 (Next.js 16, build padrão com Turbopack e fallback webpack documentado)._
|