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