docs: update Codigos/notif_ponto
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
title: Notificação de Ponto
|
||||
description: Sistema de notificação ponto
|
||||
published: true
|
||||
date: 2026-08-15T14:34:50.807Z
|
||||
date: 2026-08-19T21:23:08.082Z
|
||||
tags:
|
||||
editor: markdown
|
||||
dateCreated: 2026-08-15T01:00:06.922Z
|
||||
@@ -15,7 +15,6 @@ dateCreated: 2026-08-15T01:00:06.922Z
|
||||
Construir uma aplicação em Go que, por mensagens no Telegram, ajude aproximadamente dez usuários a não esquecerem a marcação de ponto. Cada usuário possui sua própria credencial na API de ponto. O sistema consulta o histórico de marcações, calcula os próximos eventos relevantes e envia lembretes de:
|
||||
|
||||
- retorno do almoço (`entrada2`);
|
||||
|
||||
- encerramento do expediente (`saida2`).
|
||||
|
||||
Nesta primeira fase, o Telegram é a única interface. Uma interface web, destinada a um único administrador, será adicionada posteriormente sem duplicar as regras de negócio.
|
||||
@@ -25,35 +24,22 @@ Nesta primeira fase, o Telegram é a única interface. Uma interface web, destin
|
||||
Incluído:
|
||||
|
||||
- bot Telegram para usuários e administrador;
|
||||
|
||||
- solicitação e aprovação de cadastro pelo Telegram;
|
||||
|
||||
- armazenamento em SQLite;
|
||||
|
||||
- credencial de API individual por usuário, armazenada de forma criptografada;
|
||||
|
||||
- autenticação na API de ponto e renovação automática do token;
|
||||
|
||||
- leitura dos últimos oito apontamentos;
|
||||
|
||||
- validação de pontos do dia atual;
|
||||
|
||||
- criação persistente e envio único de lembretes;
|
||||
|
||||
- execução em um container LXC Linux no Proxmox;
|
||||
|
||||
- logs, auditoria e backup do banco.
|
||||
|
||||
Fora do escopo inicial:
|
||||
|
||||
- painel web administrativo;
|
||||
|
||||
- regras para feriados municipais, estaduais e nacionais;
|
||||
|
||||
- lembretes de `entrada1` e `saida1`;
|
||||
|
||||
- múltiplos administradores;
|
||||
|
||||
- integrações além de Telegram e API de ponto.
|
||||
|
||||
## 3. Arquitetura
|
||||
@@ -61,65 +47,118 @@ Fora do escopo inicial:
|
||||
O projeto será um monólito modular em Go. Para o volume esperado, um único processo, um SQLite e um LXC são suficientes, simples de manter e adequados para estudo.
|
||||
|
||||
```mermaid
|
||||
|
||||
flowchart TD
|
||||
|
||||
T["Usuários e administrador<br/>Telegram"] --> B["Adaptador Telegram"]
|
||||
B --> UC["Casos de uso por comando"]
|
||||
|
||||
B --> S["Serviços de aplicação"]
|
||||
|
||||
S --> U["Usuários e cadastro"]
|
||||
|
||||
S --> P["Cliente da API de ponto"]
|
||||
|
||||
S --> R["Motor de regras"]
|
||||
|
||||
S --> Q["Agendador de notificações"]
|
||||
|
||||
S --> C["Calendário de dias úteis"]
|
||||
UC --> U["Usuários e cadastro"]
|
||||
UC --> P["Consulta de jornada atual"]
|
||||
UC --> R["Motor de regras e cálculos"]
|
||||
UC --> Q["Agendador de notificações"]
|
||||
UC --> C["Calendário de dias úteis"]
|
||||
|
||||
U --> DB[("SQLite")]
|
||||
|
||||
R --> DB
|
||||
|
||||
Q --> DB
|
||||
|
||||
P --> API["API externa de ponto"]
|
||||
|
||||
Q --> TG["API do Telegram"]
|
||||
|
||||
W["Fase 2: painel web do administrador"] -. reutiliza os mesmos serviços .-> S
|
||||
|
||||
W["Fase 2: painel web do administrador"] -. reutiliza os mesmos casos de uso .-> UC
|
||||
```
|
||||
|
||||
### Princípios
|
||||
|
||||
- O bot Telegram não contém cálculo de jornada: ele apenas recebe comandos e envia mensagens.
|
||||
|
||||
- O bot Telegram não contém cálculo de jornada: ele converte cada comando em um caso de uso e envia sua resposta.
|
||||
- A API de ponto fica isolada em um módulo próprio.
|
||||
|
||||
- As regras de horário ficam em serviços testáveis, sem dependência de Telegram, SQLite ou HTTP.
|
||||
|
||||
- O SQLite registra estado suficiente para evitar mensagens duplicadas após reinício.
|
||||
|
||||
- Tokens de API ficam somente em memória; senha e token nunca são escritos em logs.
|
||||
|
||||
### Arquitetura orientada a comandos
|
||||
|
||||
Cada comando do Telegram terá um caso de uso explícito. Isso evita que o arquivo do bot vire um conjunto de regras misturadas e permite que o futuro painel web reaprove exatamente a mesma lógica.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
CMD["/entrada2, /saida2,<br/>/status, /cadastrar"] --> H["Handler Telegram"]
|
||||
H --> U["Caso de uso"]
|
||||
U --> J["Consulta de jornada"]
|
||||
J --> API["API de ponto"]
|
||||
U --> R["Regras de cálculo"]
|
||||
U --> DB[("SQLite")]
|
||||
U --> H
|
||||
H --> MSG["Resposta Telegram"]
|
||||
```
|
||||
|
||||
O agendador é outro consumidor dos mesmos casos de uso. Portanto, o cálculo retornado em `/saida2` será exatamente o mesmo usado para criar uma notificação automática de `saida2`.
|
||||
|
||||
## 3.1 Comandos da fase 1
|
||||
|
||||
| Comando | Quem usa | Atividade | Resposta esperada |
|
||||
| --- | --- | --- | --- |
|
||||
| `/entrada2` | Usuário ativo | Consulta o histórico atual e calcula `saida1 + 55 min` quando houver ao menos dois pontos. | Horário previsto de retorno ou explicação do ponto que ainda falta. |
|
||||
| `/saida2` | Usuário ativo | Consulta o histórico atual e calcula a saída para completar 7h55 quando houver três pontos. | Horário previsto de saída ou explicação do ponto que ainda falta. |
|
||||
| `/status` | Usuário ativo | Consulta e resume os pontos atuais e os agendamentos do dia. | Situação da jornada e próximos lembretes. |
|
||||
| `/iniciar` | Qualquer pessoa | Identifica o `chat_id` e apresenta instruções. | Boas-vindas ou orientação para cadastro. |
|
||||
| `/cadastrar` | Pessoa não cadastrada | Cria solicitação de cadastro para o administrador. | Confirmação de solicitação pendente. |
|
||||
| `/aprovar <id>` | Administrador | Ativa um pedido de cadastro. | Confirmação e orientação ao novo usuário. |
|
||||
| `/usuarios` | Administrador | Lista usuários e solicitações pendentes. | Resumo administrativo. |
|
||||
| `/ajuda` | Todos | Mostra somente os comandos permitidos ao perfil atual. | Guia de uso. |
|
||||
|
||||
### Regras dos comandos de consulta
|
||||
|
||||
`/entrada2` e `/saida2` fazem uma consulta imediata à API do próprio usuário, independentemente do próximo ciclo do agendador. Eles não enviam lembretes nem mudam um agendamento existente; apenas mostram a projeção atual.
|
||||
|
||||
Exemplos de respostas:
|
||||
|
||||
```text
|
||||
/entrada2
|
||||
Você saiu para almoço às 12:00.
|
||||
Seu retorno previsto é às 12:55.
|
||||
```
|
||||
|
||||
```text
|
||||
/saida2
|
||||
Você trabalhou 4h00 antes do almoço e retornou às 13:00.
|
||||
Para completar 7h55, sua saída prevista é às 16:55.
|
||||
```
|
||||
|
||||
Quando não houver pontos suficientes, a mensagem deve ser clara:
|
||||
|
||||
```text
|
||||
Ainda não consigo calcular sua saída: falta registrar a entrada após o almoço.
|
||||
```
|
||||
|
||||
## 3.2 Evolução: comando `/registrar`
|
||||
|
||||
`/registrar` será uma funcionalidade futura e só poderá efetivamente registrar um ponto se a API externa oferecer um endpoint autorizado de criação de apontamento. A API conhecida até agora apenas autentica e consulta o histórico; ela não confirma a existência dessa operação.
|
||||
|
||||
O desenho recomendado é preparar uma abstração sem fingir que o ponto foi registrado:
|
||||
|
||||
```text
|
||||
PointGateway
|
||||
├── Authenticate(user)
|
||||
├── GetHistory(user)
|
||||
└── RegisterPoint(user, instant) // futura implementação, se a API permitir
|
||||
```
|
||||
|
||||
Possíveis comportamentos futuros:
|
||||
|
||||
- Se houver endpoint oficial: `/registrar` pede confirmação, chama a API e mostra o resultado recebido.
|
||||
- Se não houver endpoint oficial: o comando não deve dizer que bateu o ponto; pode abrir orientação, registrar uma solicitação manual ou apenas informar que a marcação deve ser feita no sistema oficial.
|
||||
|
||||
Por segurança, o fluxo com endpoint oficial deve exigir confirmação explícita, por exemplo `/registrar` seguido de botão **Confirmar registro às 16:55**. A auditoria deve gravar intenção, horário, resposta da API e resultado.
|
||||
|
||||
## 4. Integração com a API de ponto
|
||||
|
||||
Cada usuário tem e-mail e senha próprios.
|
||||
|
||||
1. Fazer `POST` de autenticação com e-mail e senha.
|
||||
|
||||
2. Receber `client`, `token` e validade do token.
|
||||
|
||||
3. Manter esses valores em memória, associados ao usuário.
|
||||
|
||||
4. Fazer `GET` do histórico com token, client e e-mail.
|
||||
|
||||
5. A resposta contém os últimos oito apontamentos.
|
||||
|
||||
6. Se o histórico retornar erro de autenticação, autenticar novamente, atualizar `client`, `token` e validade e repetir a consulta uma única vez.
|
||||
|
||||
7. Se o novo teste falhar, registrar erro de auditoria e tentar no próximo ciclo do agendador.
|
||||
|
||||
> As senhas precisam ser criptografadas no SQLite. A chave de criptografia deve ser uma variável de ambiente do LXC, fora do repositório Git.
|
||||
@@ -133,9 +172,7 @@ Antes de consultar agendamentos ou a API, verificar se a data é segunda a sexta
|
||||
Validação de feriados de Belo Horizonte é uma evolução posterior. Desde o início, ela terá uma interface própria (`HolidayProvider`) para que possa ser incluída sem alterar o fluxo central:
|
||||
|
||||
```text
|
||||
|
||||
IsBusinessDay(data, localidade) = segunda a sexta E não é feriado
|
||||
|
||||
```
|
||||
|
||||
Na fase 1, `não é feriado` será considerado verdadeiro; a localidade padrão será `Belo Horizonte/MG`.
|
||||
@@ -145,19 +182,13 @@ Na fase 1, `não é feriado` será considerado verdadeiro; a localidade padrão
|
||||
O histórico vem com até oito registros. A aplicação deve:
|
||||
|
||||
1. Converter horários para `America/Sao_Paulo`.
|
||||
|
||||
2. Manter apenas registros da data atual.
|
||||
|
||||
3. Ordenar por hora crescente.
|
||||
|
||||
4. Considerar, no máximo, quatro pontos do dia.
|
||||
|
||||
5. Interpretar a sequência como:
|
||||
|
||||
```text
|
||||
|
||||
entrada1 → saida1 → entrada2 → saida2
|
||||
|
||||
```
|
||||
|
||||
| Pontos no dia | Situação |
|
||||
@@ -173,9 +204,7 @@ entrada1 → saida1 → entrada2 → saida2
|
||||
Com dois pontos no dia, considerar que eles são `entrada1` e `saida1`.
|
||||
|
||||
```text
|
||||
|
||||
horário do lembrete de entrada2 = saida1 + 55 minutos
|
||||
|
||||
```
|
||||
|
||||
Exemplo: com saída para almoço às 12:00, o lembrete é agendado para 12:55.
|
||||
@@ -185,11 +214,9 @@ Exemplo: com saída para almoço às 12:00, o lembrete é agendado para 12:55.
|
||||
Com três pontos no dia, considerar que eles são `entrada1`, `saida1` e `entrada2`. O objetivo diário é 7h55 de trabalho efetivo.
|
||||
|
||||
```text
|
||||
|
||||
trabalho_antes_do_almoco = saida1 - entrada1
|
||||
tempo_restante = 7h55 - trabalho_antes_do_almoco
|
||||
horario_estimado_saida2 = entrada2 + tempo_restante
|
||||
|
||||
```
|
||||
|
||||
O lembrete deve ser agendado para o horário calculado menos uma antecedência configurável. Inicialmente, sugerido: cinco minutos.
|
||||
@@ -218,9 +245,7 @@ bruno14082026saida2
|
||||
A garantia técnica deve ser a restrição única:
|
||||
|
||||
```text
|
||||
|
||||
UNIQUE(user_id, reference_date, notification_type)
|
||||
|
||||
```
|
||||
|
||||
Isso evita colisões se nome de usuário mudar ou dois nomes forem semelhantes.
|
||||
@@ -246,15 +271,18 @@ flowchart TD
|
||||
I["Ciclo do agendador, por usuário"] --> D{"É dia útil?<br/>Segunda a sexta"}
|
||||
D -->|Não| X["Encerrar ciclo"]
|
||||
D -->|Sim| A{"Existe agendamento vencido<br/>com execute_send = true?"}
|
||||
|
||||
A -->|Sim| T["Enviar mensagem Telegram"]
|
||||
T --> M["Registrar status sent e sent_at"]
|
||||
M --> X
|
||||
|
||||
A -->|Não| H["Consultar histórico de pontos"]
|
||||
H --> E{"Erro de autenticação?"}
|
||||
E -->|Sim| L["Autenticar novamente"]
|
||||
L --> R["Atualizar client, token e validade"]
|
||||
R --> H
|
||||
E -->|Não| V["Filtrar pontos de hoje e ordenar"]
|
||||
|
||||
V --> P{"Quantidade de pontos"}
|
||||
P -->|0 ou 1| X
|
||||
P -->|2| EN["Criar, se inexistente:<br/>entrada2 = saida1 + 55 min"]
|
||||
@@ -268,115 +296,71 @@ flowchart TD
|
||||
## 8. Estrutura de pastas e arquivos
|
||||
|
||||
```text
|
||||
|
||||
bot-pontos/
|
||||
|
||||
├── cmd/
|
||||
|
||||
│ └── bot/
|
||||
|
||||
│ └── main.go
|
||||
|
||||
├── internal/
|
||||
|
||||
│ ├── app/
|
||||
|
||||
│ │ └── application.go
|
||||
|
||||
│ ├── config/
|
||||
|
||||
│ │ └── config.go
|
||||
|
||||
│ ├── domain/
|
||||
|
||||
│ │ ├── user.go
|
||||
|
||||
│ │ ├── workday.go
|
||||
|
||||
│ │ ├── notification.go
|
||||
|
||||
│ │ └── point.go
|
||||
|
||||
│ ├── usecase/
|
||||
│ │ ├── get_entrada2.go
|
||||
│ │ ├── get_saida2.go
|
||||
│ │ ├── get_status.go
|
||||
│ │ ├── register_user.go
|
||||
│ │ ├── approve_user.go
|
||||
│ │ └── register_point.go # contrato futuro
|
||||
│ ├── pointsapi/
|
||||
|
||||
│ │ ├── client.go
|
||||
|
||||
│ │ ├── auth.go
|
||||
|
||||
│ │ └── models.go
|
||||
|
||||
│ ├── rules/
|
||||
|
||||
│ │ ├── point_validator.go
|
||||
|
||||
│ │ ├── schedule_calculator.go
|
||||
|
||||
│ │ └── business_day.go
|
||||
|
||||
│ ├── scheduler/
|
||||
|
||||
│ │ └── scheduler.go
|
||||
|
||||
│ ├── telegram/
|
||||
|
||||
│ │ ├── bot.go
|
||||
|
||||
│ │ ├── commands.go
|
||||
|
||||
│ │ ├── command_router.go
|
||||
│ │ ├── entrada2_handler.go
|
||||
│ │ ├── saida2_handler.go
|
||||
│ │ ├── status_handler.go
|
||||
│ │ ├── admin_handler.go
|
||||
│ │ └── messages.go
|
||||
|
||||
│ ├── repository/
|
||||
|
||||
│ │ ├── sqlite.go
|
||||
|
||||
│ │ ├── users.go
|
||||
|
||||
│ │ ├── notifications.go
|
||||
|
||||
│ │ └── audit.go
|
||||
|
||||
│ ├── security/
|
||||
|
||||
│ │ └── credentials.go
|
||||
|
||||
│ └── audit/
|
||||
|
||||
│ └── logger.go
|
||||
|
||||
├── migrations/
|
||||
|
||||
│ ├── 001_initial_schema.sql
|
||||
|
||||
│ └── 002_indexes.sql
|
||||
|
||||
├── configs/
|
||||
|
||||
│ └── config.example.yaml
|
||||
|
||||
├── deploy/
|
||||
|
||||
│ ├── bot-pontos.service
|
||||
|
||||
│ └── backup-sqlite.sh
|
||||
|
||||
├── tests/
|
||||
|
||||
│ ├── rules_test.go
|
||||
|
||||
│ └── scheduler_test.go
|
||||
|
||||
├── .env.example
|
||||
|
||||
├── .gitignore
|
||||
|
||||
├── go.mod
|
||||
|
||||
├── go.sum
|
||||
|
||||
├── README.md
|
||||
|
||||
└── PLANO_PROJETO_BOT_PONTOS.md
|
||||
|
||||
```
|
||||
|
||||
### Responsabilidade de cada arquivo
|
||||
@@ -387,6 +371,12 @@ bot-pontos/
|
||||
| `internal/app/application.go` | Conecta dependências e descreve os casos de uso principais. |
|
||||
| `internal/config/config.go` | Lê variáveis de ambiente e parâmetros: Telegram, banco, criptografia, fuso e intervalo do ciclo. |
|
||||
| `internal/domain/*.go` | Entidades puras: usuário, ponto, jornada e notificação; sem HTTP ou SQLite. |
|
||||
| `internal/usecase/get_entrada2.go` | Orquestra a consulta imediata e retorna o horário previsto de `entrada2`. |
|
||||
| `internal/usecase/get_saida2.go` | Orquestra a consulta imediata e retorna o cálculo de `saida2` para completar 7h55. |
|
||||
| `internal/usecase/get_status.go` | Resume os pontos atuais e os agendamentos do usuário. |
|
||||
| `internal/usecase/register_user.go` | Cria e consulta solicitações de cadastro. |
|
||||
| `internal/usecase/approve_user.go` | Aprova cadastro e ativa o usuário. |
|
||||
| `internal/usecase/register_point.go` | Reserva o contrato do futuro `/registrar`; não registra nada enquanto a API não oferecer suporte oficial. |
|
||||
| `internal/pointsapi/client.go` | Requisições HTTP à API; consulta o histórico. |
|
||||
| `internal/pointsapi/auth.go` | Login, cache em memória e renovação de token por usuário. |
|
||||
| `internal/pointsapi/models.go` | Estruturas de request/response da API externa e conversão para o domínio. |
|
||||
@@ -395,7 +385,8 @@ bot-pontos/
|
||||
| `internal/rules/business_day.go` | Verifica segunda a sexta; depois receberá o provedor de feriados de Belo Horizonte. |
|
||||
| `internal/scheduler/scheduler.go` | Executa o ciclo periódico: envia vencidos ou consulta a API/cria agendamentos. |
|
||||
| `internal/telegram/bot.go` | Mantém conexão e atualização do bot Telegram. |
|
||||
| `internal/telegram/commands.go` | Trata `/iniciar`, `/status`, `/cadastrar`, `/aprovar` e comandos administrativos. |
|
||||
| `internal/telegram/command_router.go` | Autoriza o perfil e encaminha cada comando ao respectivo handler. |
|
||||
| `internal/telegram/*_handler.go` | Converte o comando Telegram em chamada de caso de uso e formata a resposta. |
|
||||
| `internal/telegram/messages.go` | Centraliza textos das notificações e respostas do bot. |
|
||||
| `internal/repository/sqlite.go` | Abre SQLite, aplica migrations e configura modo WAL. |
|
||||
| `internal/repository/users.go` | CRUD de usuários, pedidos de cadastro e permissões. |
|
||||
@@ -410,81 +401,46 @@ bot-pontos/
|
||||
## 9. Modelo inicial de banco
|
||||
|
||||
```text
|
||||
|
||||
users
|
||||
|
||||
- id
|
||||
|
||||
- telegram_chat_id (único)
|
||||
|
||||
- display_name
|
||||
|
||||
- api_email
|
||||
|
||||
- encrypted_api_password
|
||||
|
||||
- role (user | admin)
|
||||
|
||||
- status (pending | active | disabled)
|
||||
|
||||
- created_at
|
||||
|
||||
- updated_at
|
||||
|
||||
work_rules
|
||||
|
||||
- id
|
||||
|
||||
- user_id (único)
|
||||
|
||||
- lunch_reminder_after_minutes (padrão 55)
|
||||
|
||||
- daily_work_minutes (padrão 475 = 7h55)
|
||||
|
||||
- exit_reminder_lead_minutes (padrão 5)
|
||||
|
||||
- timezone (America/Sao_Paulo)
|
||||
|
||||
- active
|
||||
|
||||
scheduled_notifications
|
||||
|
||||
- id
|
||||
|
||||
- notification_key
|
||||
|
||||
- user_id
|
||||
|
||||
- reference_date
|
||||
|
||||
- notification_type (entrada2 | saida2)
|
||||
|
||||
- scheduled_at
|
||||
|
||||
- execute_send
|
||||
|
||||
- status
|
||||
|
||||
- sent_at
|
||||
|
||||
- telegram_message_id
|
||||
|
||||
- created_at
|
||||
|
||||
- updated_at
|
||||
|
||||
audit_logs
|
||||
|
||||
- id
|
||||
|
||||
- user_id (opcional)
|
||||
|
||||
- event_type
|
||||
|
||||
- details
|
||||
|
||||
- created_at
|
||||
|
||||
```
|
||||
|
||||
## 10. Ambiente LXC no Proxmox
|
||||
@@ -492,21 +448,13 @@ audit_logs
|
||||
Recomendação inicial:
|
||||
|
||||
- Debian 12;
|
||||
|
||||
- 1 vCPU;
|
||||
|
||||
- 1 GB de RAM;
|
||||
|
||||
- 8 a 16 GB de disco;
|
||||
|
||||
- fuso horário `America/Sao_Paulo`;
|
||||
|
||||
- saída HTTPS para a API de ponto e para o Telegram;
|
||||
|
||||
- serviço Go controlado por `systemd`;
|
||||
|
||||
- banco em `/var/lib/bot-pontos/app.db`;
|
||||
|
||||
- backup diário do SQLite e backup periódico do próprio LXC pelo Proxmox.
|
||||
|
||||
Em produção, o LXC precisa apenas do binário Go compilado, certificados CA, dados de fuso horário e SQLite. O compilador Go pode ficar apenas no ambiente de desenvolvimento ou CI.
|
||||
@@ -514,58 +462,36 @@ Em produção, o LXC precisa apenas do binário Go compilado, certificados CA, d
|
||||
## 11. Sequência de implementação para estudo
|
||||
|
||||
1. Criar repositório, estrutura de pastas e projeto Go (`go mod init`).
|
||||
|
||||
2. Implementar configuração, logs e SQLite com migrations.
|
||||
|
||||
3. Criar entidades de domínio e testes dos cálculos de 55 minutos e 7h55.
|
||||
|
||||
4. Implementar o cliente da API com mocks e teste de reautenticação.
|
||||
|
||||
5. Implementar persistência de usuários e agendamentos com a chave única.
|
||||
|
||||
6. Construir o ciclo do agendador usando dados simulados.
|
||||
|
||||
7. Integrar o Telegram: cadastro, aprovação e mensagens.
|
||||
|
||||
8. Fazer testes de ponta a ponta com um único usuário de teste.
|
||||
|
||||
9. Criar LXC, instalar o serviço e configurar backup.
|
||||
|
||||
10. Cadastrar os demais usuários gradualmente.
|
||||
|
||||
## 12. Casos de teste mínimos
|
||||
|
||||
- Sábado ou domingo: nenhuma consulta e nenhuma notificação.
|
||||
|
||||
- Dois pontos: cria apenas um agendamento de `entrada2` para `saida1 + 55 min`.
|
||||
|
||||
- Três pontos: cria apenas um agendamento de `saida2` para completar 7h55.
|
||||
|
||||
- Quatro pontos: não cria lembrete.
|
||||
|
||||
- Mesmo ciclo rodado duas vezes: não duplica a mesma chave de agendamento.
|
||||
|
||||
- Reinício da aplicação: agendamento persiste e é enviado uma vez.
|
||||
|
||||
- Token expirado: autentica novamente e repete a consulta.
|
||||
|
||||
- Falha contínua na API ou Telegram: registra auditoria sem travar os demais usuários.
|
||||
|
||||
## 13. Evoluções posteriores
|
||||
|
||||
- Feriados de Belo Horizonte/MG e feriados nacionais por um `HolidayProvider` (API ou calendário local com atualização controlada).
|
||||
|
||||
- Painel web para o administrador com autenticação.
|
||||
|
||||
- Tela de usuários, regras, agendamentos, auditoria e erros.
|
||||
|
||||
- Revalidação da API antes de cada envio para eliminar lembretes obsoletos.
|
||||
|
||||
- Painel de saúde da aplicação e alertas para falhas repetidas.
|
||||
|
||||
- Migração para PostgreSQL apenas se o número de usuários, concorrência ou necessidade de relatórios crescer substancialmente.
|
||||
|
||||
## 14. Resultado esperado
|
||||
|
||||
O projeto é viável para uso diário: o volume é baixo, as regras são objetivas e SQLite atende bem. Também é um bom projeto de estudo porque exercita Go, HTTP, autenticação, persistência, criptografia, agendamento, testes, operações Linux e integração com Telegram, sem introduzir complexidade de microserviços cedo demais.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user