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

9.5 KiB
Raw Permalink Blame History

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:

Estado: Sprints 0 a 6 e as evoluções da tabela 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

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

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 para criar pg_password, pg_app_password, encryption_key, telegram_token e holiday_api_key.

3. Subir

docker compose up -d --build
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):

    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 é:

    docker compose run --rm api admin set-credentials --user-id 1 --email pessoa@empresa.com
    
    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:

docker compose logs -f worker

Situação das migrations:

docker compose run --rm migrate migrate status

Redefinir a senha de uma conta do painel:

docker compose run --rm api admin reset-password --username admin

Recifrar as credenciais após trocar a chave (ver secrets/README.md):

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):

docker run --rm -v "$PWD/backend:/src" -w /src golang:1.25-alpine sh -c "go vet ./... && go test ./..."

Painel (checagem de tipos):

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