Files
bot-pontos/README.md
Bruno Santos 61fde19133 docs: revisa a documentação com base no que a aplicação faz hoje
- README: o que a aplicação faz, migrations, BP_WEB_PORT e testes com
  go.sum/package-lock.json (sem go mod tidy)
- ARQUITETURA: esquema real (00001 a 00003), rotas que faltavam, Compose
  e imagens atuais, cadeia de proxies, retenção, situação dos testes,
  decisões 30 a 33 e estado da implementação
- DEPLOY: cópia por tar, BP_WEB_PORT em todas as etapas e atualização
  para a versão com exclusão de contas
- MANUAL: papéis do owner e navegação por ano nos feriados
- openapi.yaml: DELETE /accounts/{id} e regras da conta restrita
- Dockerfiles: comentários sobre go.sum e package-lock.json

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:20:25 -03:00

189 lines
9.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bot de Pontos v2
Lembretes de retorno do almoço e de fim de jornada pelo Telegram, a partir dos pontos registrados na PontoMais.
- **Backend:** Go 1.25 (API REST + worker com bot e jobs, num binário só)
- **Painel:** Next.js 15 (administradores e contas de leitura)
- **Banco:** PostgreSQL 17
- **Execução:** Docker Compose numa máquina Debian, atrás do Nginx Proxy Manager da rede
Documentação:
- [docs/MANUAL_USUARIO.md](docs/MANUAL_USUARIO.md): manual do usuário do Telegram e do administrador do painel;
- [docs/DEPLOY.md](docs/DEPLOY.md): passo a passo de implantação e atualização no servidor;
- [docs/ARQUITETURA.md](docs/ARQUITETURA.md): arquitetura, regras de negócio e decisões;
- [secrets/README.md](secrets/README.md): segredos e troca da chave de criptografia;
- [backend/api/openapi.yaml](backend/api/openapi.yaml): contrato da API REST.
> **Estado:** Sprints 0 a 6 e as evoluções da tabela [Sprints](#sprints) implementadas. O backend compila e passa em `go vet` e `go test`; o painel passa na checagem de tipos (`tsc`). Ainda faltam testes de integração com Postgres real e a medição do atraso da PontoMais no piloto (ARQUITETURA.md, seção 16).
## O que a aplicação faz
- **Telegram:** cadastro (`/cadastrar`), consulta ao vivo do retorno e da saída previstos (`/entrada2`, `/saida2`), situação (`/status`), ligar e pausar lembretes (`/ativarponto`, `/desativarponto`) e comandos de admin (`/usuarios`, `/ativarusuario`, `/desativarusuario`).
- **Lembretes automáticos:** o worker consulta a PontoMais na janela do dia (padrão 11:30–19:00, com frequência adaptativa por usuário) e avisa alguns minutos antes da volta do almoço e da saída. Fins de semana e feriados (feriadosapi.com + cadastro manual) ficam de fora.
- **Painel:** início com alertas, usuários (credencial, jornada, janela personalizada, consulta ao vivo, admin do bot), lembretes (cancelar/reenviar), auditoria, feriados, configurações da janela global com pré-visualização e contas do painel (criar, papel, vínculo com usuário, redefinir senha, desativar, excluir).
- **Operação:** avisos aos admins do bot pelo Telegram, retenção automática de dados, backup diário, CLI administrativa.
## Estrutura
```text
bot-pontos-v2/
├── backend/ # Go: um binário com api, worker, migrate, admin e healthcheck
│ ├── cmd/botpontos/ # ponto de entrada e comandos administrativos
│ ├── internal/
│ │ ├── domain/ # entidades e erros (sem dependências)
│ │ ├── rules/ # cálculos puros: jornada, janela, frequência adaptativa
│ │ ├── app/ # casos de uso (Telegram, painel, CLI e jobs usam os mesmos)
│ │ ├── bot/ # comandos do Telegram
│ │ ├── httpapi/ # API REST do painel
│ │ ├── worker/ # liderança, bot e ciclos (reconciliação, despacho, manutenção)
│ │ ├── bootstrap/ # montagem dos adapters reais
│ │ ├── config/ # variáveis de ambiente e segredos
│ │ ├── httpx/ # utilitários HTTP
│ │ ├── metrics/ # contadores internos (sem endpoint /metrics)
│ │ └── adapters/ # postgres, pontomais, telegram, feriados, crypto
│ ├── db/migrations/ # SQL (goose), embutido no binário
│ └── api/openapi.yaml # contrato da API
├── web/ # Next.js (App Router, CSS próprio)
├── postgres/init/ # cria o usuário da aplicação na 1ª subida do banco
├── scripts/backup-loop.sh # pg_dump diário com retenção de 14 dias
├── deploy/ # firewall da porta do painel (só o NPM acessa)
├── secrets/ # Docker secrets (não versionar o conteúdo)
├── docker-compose.yml
└── .env.example
```
Migrations existentes:
| Migration | Conteúdo |
| --- | --- |
| `00001_initial_schema` | Esquema inicial e permissões do usuário `botpontos_app` |
| `00002_holiday_source_feriadosapi` | Libera a origem `feriadosapi` em `holidays.source` |
| `00003_web_account_delete` | Permite excluir contas do painel mantendo a auditoria (`audit_logs.actor_account_name`) |
## Implantação
> O passo a passo completo para o servidor Debian (Docker, firewall, NPM, certificado, primeiro admin, backup, atualização e problemas comuns) está em **[docs/DEPLOY.md](docs/DEPLOY.md)**. O resumo abaixo serve de referência rápida.
Pré-requisito: Debian 12 com Docker Engine e plugin Compose (repositório oficial da Docker), NTP ativo e IP fixo. Go e Node **não** precisam estar instalados; o build acontece dentro dos containers.
### 1. Configuração
```bash
cp .env.example .env
```
Ajuste no `.env`:
- `BP_HOST_LAN_IP`: IP fixo do servidor (o NPM aponta para ele);
- `BP_WEB_PORT`: porta do painel no servidor (padrão `3000`; troque se ela já estiver em uso);
- `BP_PUBLIC_URL`: endereço do painel, igual ao nome do certificado no NPM (ex.: `https://botpontos.lan`);
- `BP_NPM_IP`: IP do Nginx Proxy Manager;
- `BP_HOLIDAY_LOCATION`: código IBGE da cidade dos feriados (padrão `3106200`, Belo Horizonte).
### 2. Segredos
Siga [secrets/README.md](secrets/README.md) para criar `pg_password`, `pg_app_password`, `encryption_key`, `telegram_token` e `holiday_api_key`.
### 3. Subir
```bash
docker compose up -d --build
```
```bash
docker compose ps -a
```
`postgres`, `api`, `worker` e `web` devem ficar `healthy`; `migrate` deve terminar com `exited (0)`; `backup` fica `running`.
### 4. Firewall e proxy
- Instale `deploy/botpontos-firewall.service` (instruções no próprio arquivo) para que só o NPM alcance a porta do painel (`BP_WEB_PORT`).
- No NPM, crie o Proxy Host apontando para `http://IP_DO_SERVIDOR:3000` (ou a porta de `BP_WEB_PORT`) com o certificado interno, Force SSL, HTTP/2 e HSTS (ARQUITETURA.md, 11.4).
## Primeiro uso
1. **Criar a conta owner do painel** (a senha, de no mínimo 12 caracteres, é pedida no terminal, sem eco):
```bash
docker compose run --rm api admin create-owner --username admin
```
2. **Entrar no painel** pelo endereço do NPM.
3. **Cadastrar o primeiro admin do Telegram:** no Telegram, a pessoa envia `/cadastrar` ao bot. No painel, em **Usuários**, abra o cadastro, configure a credencial da PontoMais (ela é validada na hora), clique em **Ativar** e depois em **Tornar admin do bot**.
Pela linha de comando, o equivalente é:
```bash
docker compose run --rm api admin set-credentials --user-id 1 --email pessoa@empresa.com
```
```bash
docker compose run --rm api admin bot-admin --user-id 1 --enable
```
4. **Demais usuários:** cada um envia `/cadastrar`; o admin recebe o aviso pelo Telegram, configura a credencial no painel e ativa. O usuário envia `/ativarponto` para ligar os lembretes.
5. **Opcional:** em **Contas**, o owner pode criar uma conta de leitura ligada a um usuário do Telegram, para a pessoa acompanhar só os próprios dados no painel.
## Comandos úteis
Logs de um serviço:
```bash
docker compose logs -f worker
```
Situação das migrations:
```bash
docker compose run --rm migrate migrate status
```
Redefinir a senha de uma conta do painel:
```bash
docker compose run --rm api admin reset-password --username admin
```
Recifrar as credenciais após trocar a chave (ver secrets/README.md):
```bash
docker compose run --rm api admin rotate-key
```
## Desenvolvimento e testes
Os testes não exigem Go nem Node instalados: rodam em containers temporários e usam as versões fixadas em `backend/go.sum` e `web/package-lock.json`.
Backend (`go vet` e testes):
```bash
docker run --rm -v "$PWD/backend:/src" -w /src golang:1.25-alpine sh -c "go vet ./... && go test ./..."
```
Painel (checagem de tipos):
```bash
docker run --rm -v "$PWD/web:/app" -w /app node:22-alpine sh -c "npm ci && npx tsc --noEmit"
```
> Não rode `go mod tidy` com Go 1.25: ele tenta baixar versões que exigem Go 1.26 e quebra o build da imagem. Mantenha o `go.sum` e o `package-lock.json` versionados.
Para rodar localmente pelo Compose, use no `.env` `BP_HOST_LAN_IP=127.0.0.1`, `BP_COOKIE_SECURE=false` e `BP_PUBLIC_URL=http://127.0.0.1:3000`.
## Sprints
| Sprint | Entrega |
| --- | --- |
| 0 — Fundação | Estrutura, Compose, migrations, health, liderança do worker |
| 1 — Núcleo | Domínio e regras puras (com testes), cliente PontoMais, criptografia AES-GCM com rotação de chave |
| 2 — Bot | Comandos do Telegram com ativação unificada e avisos aos admins |
| 3 — Lembretes | Reconciliação na janela com frequência adaptativa, despacho a cada 2 min com `SKIP LOCKED`, tolerância de 10 min, 3 falhas seguidas, detecção de queda, feriados |
| 4 — API | Login com Argon2id e bloqueio, sessões, CSRF, papéis, todos os endpoints do painel |
| 5 — Painel | Dashboard, usuários (jornada, janela personalizada, credencial, consulta ao vivo), lembretes (cancelar/reenviar), auditoria, feriados, configurações com pré-visualização, contas |
| 6 — Operação | Retenção de dados, manutenção, CLI administrativa, backup, firewall, documentação |
| Evoluções | Feriados pela feriadosapi.com (endpoint por cidade, código IBGE em `BP_HOLIDAY_LOCATION`, migration `00002`); conta de leitura ligada a um usuário, restrita aos próprios dados (ARQUITETURA 9.6, MANUAL e DEPLOY 10.4); exclusão de contas do painel (migration `00003`); porta do painel configurável (`BP_WEB_PORT`); dependências fixadas em `go.sum` e `package-lock.json` |