Estado atual e histórico¶
Foto do que está pronto, do que falta e do que já deu problema. Atualize esta página quando algo mudar: ela é a memória do projeto.
Em produção desde 25/10/2026¶
https://braggo.com.br abre pela internet (testado em rede de fora de casa). Fluxo: Cloudflare → túnel → Nginx → Angular e API → PostgreSQL.
Feito¶
- [x] Domínio
braggo.com.brregistrado e pago no Registro.br - [x] DNS do domínio na Cloudflare (status Ativo)
- [x] Túnel
braggocomo serviço, rotas para a raiz e owww - [x] Swagger e dashboard do Hangfire fora do alcance público (verificação)
- [x] Chave do JWT e
Setup__Secretpróprios de produção, fora do repositório - [x] E-mail pelo Resend com domínio verificado; recuperação de senha testada de ponta a ponta (E-mail)
- [x] Script de backup do banco e teste de restauração com sucesso (14 tabelas) (Backup)
Pendências¶
Marque conforme concluir.
Conferir (já feito, falta confirmar)
- [ ] Reserva de IP no roteador (menu Rede local > LAN > Ligação DHCP,
servidor→192.168.1.14): confirme que está salva na lista e que a VM volta com o mesmo IP depois desudo reboot - [ ] Cron do backup:
systemctl is-active crone, depois da primeira madrugada, uma linhaokemsudo tail /var/log/braggo-backup.log
Segurança da VM
- [ ] Firewall
ufw, nesta ordem:sudo ufw allow OpenSSH,sudo ufw allow 80/tcp,sudo ufw enable. A porta 80 só precisa atender a rede local, porque o túnel é conexão de saída - [ ] SSH por chave e depois desligar login por senha (passo a passo em Servidor base)
- [ ]
sudo apt update && sudo apt upgrade -ye reinício (havia atualização pendente)
Resiliência
- [ ] Cópia do backup para fora da VM (adiada de propósito; hoje o backup morre junto com a VM)
- [ ] Guardar cópia de
/etc/braggo-api.enve dos arquivos de configuração em local seguro (como) - [ ] Snapshot novo, tirado com a VM desligada, depois que tudo acima estiver pronto
Código e dependências
- [ ] Atualizar o pacote
Microsoft.OpenApi2.4.1 (o build avisou vulnerabilidade de severidade alta) - [ ] Tirar do
appsettings.jsonversionado qualquer senha ou chave real (deixar valores fictícios) e trocar essas credenciais onde elas existem - [ ] Opcional: mover a connection string de produção do
appsettings.Production.jsonpara o.env, para a senha do banco não ficar em arquivo junto do build - [ ] Observar os avisos do Hangfire (
server was considered dead) se voltarem com a VM ligada direto
Produto
- [ ] Definir como o cliente final chega ao agendamento de uma barbearia (hoje a página inicial é o login e o cadastro de barbearia)
Decisões¶
| Data | Decisão | Motivo |
|---|---|---|
| 24/10/2026 | Hospedar em VM no PC de casa | custo zero de hospedagem para validar o produto |
| 24/10/2026 | Túnel Cloudflare em vez de IP público | o IP WAN do roteador está em CGNAT (faixa 100.64.0.0/10), então não há port forwarding; a operadora cobra R$ 50/mês por IP público e a escolha foi não contratar |
| 24/10/2026 | Domínio .com.br no Registro.br |
cerca de R$ 40 por ano |
| 25/10/2026 | Cloudflare como DNS do domínio | o túnel cria e serve os registros automaticamente |
| 25/10/2026 | Segredos no /etc/braggo-api.env |
fora do repositório e fora da pasta que o deploy sobrescreve |
| 25/10/2026 | Backup .dump (pg_dump -Fc), 14 dias, às 3h |
formato custom permite restaurar tabelas isoladas e é validado antes de ser aceito |
| 25/10/2026 | Cópia externa do backup adiada | decisão do dono; segue como risco aceito até ser feita |
| 25/10/2026 | DMARC mantido em p=reject |
e-mails legítimos passaram nos testes |
Incidentes e lições¶
Erro 500: relation "barbearia" does not exist
O banco novo estava sem tabelas. Foi achado com journalctl -u braggo-api. Correção: gerar o script com dotnet ef migrations script --idempotent e rodar com psql (Banco).
Migrations falharam no psql
Várias chamadas migrationBuilder.Sql("...") não terminavam com ;. No script idempotente, o EF coloca os comandos dentro de blocos DO $EF$ ... END $EF$, onde cada comando precisa terminar com ;. Aplicando pelo dotnet ef database update isso costuma passar despercebido, mas rodando o .sql no psql quebra. Correção: terminar todo comando SQL das migrations com ;. Regra daqui para frente: toda migrationBuilder.Sql termina com ;.
Erro 500: Resend:ApiKey não configurada
A chave só existia no ambiente de desenvolvimento. Correção: variável Resend__ApiKey no /etc/braggo-api.env, ligado ao serviço com EnvironmentFile. Regra: tudo que a API lê do ambiente e não está no appsettings precisa de linha no .env.
Snapshots do VMware apagados por engano O estado atual da VM não foi afetado (conferidos serviços, tabelas e arquivos), mas se perdeu a rede de segurança. Lição: snapshot não é backup. Ele fica no mesmo disco da VM, depende da cadeia de snapshots e não protege contra falha do disco. Por isso existe o backup do banco.
Cloudflare: "Invalid nameservers" Depois de trocar os servidores DNS no Registro.br, o domínio fica "em transição" por cerca de 1h15 antes de publicar a troca. Nesse período a Cloudflare mostra o status inválido. Não refazer a troca: apenas esperar e clicar em Check nameservers.
/swagger abre a tela inicial do app
Não é falha de segurança: o Nginx devolve o index.html do Angular para qualquer caminho fora de /api/. Para testar a API de verdade, use /api/....
Todos deslogados depois de trocar a chave do JWT Esperado: os tokens antigos foram assinados com a chave anterior. Avisar os usuários antes, quando houver usuários reais.
Permission denied ao listar o backup
A pasta é 700, só o root entra. Use sudo. Para glob (*.dump), rode dentro de sudo bash -c '...', porque o shell expande o * antes do sudo.