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>
This commit is contained in:
2026-10-29 22:20:25 -03:00
parent b35e1a7d69
commit 61fde19133
7 changed files with 266 additions and 195 deletions

View File

@@ -2,24 +2,33 @@
Lembretes de retorno do almoço e de fim de jornada pelo Telegram, a partir dos pontos registrados na PontoMais.
- **Backend:** Go (API REST + worker com bot e jobs)
- **Painel:** Next.js (só administradores)
- **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 no servidor;
- [docs/ARQUITETURA.md](docs/ARQUITETURA.md): arquitetura, regras de negócio e decisões.
- [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:** as Sprints 0 a 6 estão implementadas, mas o código **ainda não foi compilado nem testado**. A primeira execução numa máquina com Docker deve revelar ajustes (ver "Primeira validação").
> **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 e admin
├── 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)
@@ -31,21 +40,30 @@ bot-pontos-v2/
│ │ ├── 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 3000 (só o NPM acessa)
├── 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 e problemas comuns) está em **[docs/DEPLOY.md](docs/DEPLOY.md)**. O resumo abaixo serve de referência rápida.
> 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.
@@ -58,8 +76,10 @@ 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_NPM_IP`: IP do Nginx Proxy Manager;
- `BP_HOLIDAY_LOCATION`: código IBGE da cidade dos feriados (padrão `3106200`, Belo Horizonte).
### 2. Segredos
@@ -72,19 +92,19 @@ docker compose up -d --build
```
```bash
docker compose ps
docker compose ps -a
```
`postgres`, `api`, `worker` e `web` devem ficar `healthy`; `migrate` deve terminar com `exited (0)`.
`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 3000.
- No NPM, crie o Proxy Host apontando para `http://IP_DO_SERVIDOR:3000` com o certificado interno, Force SSL, HTTP/2 e HSTS (ARQUITETURA.md, 11.4).
- 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 é pedida no terminal, sem eco):
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
@@ -106,6 +126,8 @@ docker compose ps
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:
@@ -132,26 +154,25 @@ Recifrar as credenciais após trocar a chave (ver secrets/README.md):
docker compose run --rm api admin rotate-key
```
## Primeira validação
## Desenvolvimento e testes
O código foi escrito sem compilação nem testes. Na primeira máquina onde isso for permitido, nesta ordem:
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`.
1. Gerar o `go.sum` e rodar vet e testes do backend:
Backend (`go vet` e testes):
```bash
docker run --rm -v "$PWD/backend:/src" -w /src golang:1.25-alpine sh -c "go mod tidy && go vet ./... && go test ./..."
```
```bash
docker run --rm -v "$PWD/backend:/src" -w /src golang:1.25-alpine sh -c "go vet ./... && go test ./..."
```
2. Gerar o `package-lock.json` e checar os tipos do painel:
Painel (checagem de tipos):
```bash
docker run --rm -v "$PWD/web:/app" -w /app node:22-alpine sh -c "npm install && npx tsc --noEmit"
```
```bash
docker run --rm -v "$PWD/web:/app" -w /app node:22-alpine sh -c "npm ci && npx tsc --noEmit"
```
3. Subir com `docker compose up -d --build` e seguir "Primeiro uso".
4. Piloto com 1 a 3 usuários, medindo o atraso do `last_cached` da PontoMais (log e auditoria mostram quando cada ponto foi detectado).
> 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.
Mantenha o `go.sum` e o `package-lock.json` gerados no projeto, para builds reproduzíveis.
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
@@ -164,3 +185,4 @@ Mantenha o `go.sum` e o `package-lock.json` gerados no projeto, para builds repr
| 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` |