carlos@cesaints: ~/projects/member-management.md — zsh

Comando: cat projects/member-management.md

projects/member-management.md · 2,7 KB

Sistema de filiados de uma confederação nacional, modernizado com o legado no ar

Uma confederação profissional nacional mantém num sistema PHP legado, em produção, o cadastro dos filiados, a carteira digital com QR, os lotes de pedidos das regionais e a filiação pela internet com contrato e consentimento. Como único engenheiro, conduzo a modernização por dentro, sem parar o sistema: controle de versão, decisões registradas, testes a partir de zero, CI com bancos descartáveis e deploy com backup e rollback automático.

abrir demonstraçãosimulação do sistema com dados fictícios · 6 telas

Papel
Único engenheiro da modernização
Período
jun/2026 – hoje
O que eu fiz

Eu: Arquitetura e plano da modernização, as 16 decisões registradas, o fluxo dos lotes como máquina de estados, a filiação digital reescrita, os relatórios da comissão de finanças, os testes, o CI/CD, o ambiente de homologação e o método de segurança.

Outras pessoas: O sistema original já existia e estava em produção antes do meu trabalho; a base legada não é minha.

Projeto privado, descrito sem identificar cliente, produto ou empresa.

Diagrama

O legado no ar, com o código novo crescendo por dentro

Filiado, regional e sede, a consulta pública por QR e o candidato à filiação chegam pelas mesmas rotas, cada uma com os perfis declarados e fechada por padrão. Atrás delas, o app PHP reúne o legado em produção e o código novo em camadas, que cresce por dentro (strangler fig). Os dados ficam em bancos MySQL separados, o cadastro principal e a filiação digital, conferidos por um reconciliador. A entrega passa pelo GitHub Actions: pré-verificação com bancos descartáveis e deploy com backup, health check e rollback automático.

Contexto

Uma confederação nacional de profissionais mantém num sistema web o cadastro dos filiados e a regularidade de cada registro profissional. As representações estaduais, as regionais, mandam os pedidos de carteira em lotes; a sede confere, cobra, imprime e repassa a parte de cada regional. Qualquer pessoa confere pelo QR da carteira se um profissional está regular. O sistema é antigo, está em produção e guarda dados pessoais reais.

O que eu construí

  • Controle de versão a partir do servidor. O primeiro commit é o retrato do que estava no ar, só código, sem segredos nem dados de usuário. Os dois bancos passaram a ser versionados como schema e migrations, com detecção de segredos no CI.
  • O fluxo do lote como máquina de estados. Em confecção, em análise, aguardando pagamento, em produção, revisão final e finalizado, com prazos em dias úteis que pulam fins de semana e feriados nacionais e da UF, prorrogação com justificativa, pendência em duas etapas (a regional sinaliza, a sede confirma) e ciência registrada dos dois lados.
  • A impressão da carteira presa à regularidade. Só imprime quando todo registro do lote está regular. A tela desabilita o botão e explica o que falta, e o gerador repete a checagem no servidor.
  • A filiação digital reescrita. Pré-cadastro com documentos, contrato eletrônico e consentimento LGPD registrados em separado; roteamento pela UF decidido no servidor; avaliação documento por documento; e o filiado só nasce depois do pagamento.
  • Relatórios para a diretoria. Comparativo ano a ano com duas leituras, financeiro por UF e por lote, e exportação XLSX própria no formato da planilha da secretaria.
  • Entrega com rede de segurança. Pré-verificação no CI com bancos descartáveis e migrations aplicadas duas vezes para provar idempotência; deploy com backup, health check e rollback automático; homologação com envio de e-mail bloqueado, validada pela diretoria antes de publicar mudanças.

Segurança como método

Leitura do código, auditoria dinâmica contra um container local, perguntas de segurança revisadas em cada diff e suítes de red team autenticado no CI. Regra escrita: nenhum scanner contra produção. As categorias trabalhadas seguem o OWASP Top 10: A01 controle de acesso, A02 falhas criptográficas e armazenamento de credenciais, A03 injeção e XSS, A04 design inseguro de upload, A05 configuração insegura e A07 autenticação e sessão. Achados específicos não são publicados.

O que não está aqui

O nome da entidade, a área profissional, números reais e qualquer detalhe que identifique o sistema. A demonstração usa uma confederação fictícia, com pessoas, registros e valores inventados.

Restrições

  • Sistema em produção, com dados pessoais de filiados: o que as pessoas veem não muda sem uma decisão.
  • Uma pessoa, em meio período.
  • No ponto de partida, nenhum teste automatizado, nenhum ambiente de homologação e nenhum controle de versão utilizável.
  • Testes de segurança só em ambiente local; nenhum scanner apontado para produção.

Decisões

Modernizar por dentro, sem reescrever

Contexto
Mais de 100 mil linhas de PHP em produção, sem testes, e uma pessoa em meio período. Reescrever levaria anos; atualizar tudo de uma vez quebraria telas sem que nada avisasse.
Escolha
Strangler fig: o legado continua servindo enquanto cada arquivo tocado sai saneado, o código novo nasce em camadas e a atualização da linguagem espera um catálogo de quebras feito num container paralelo.
Ganhos
  • O sistema nunca parou, e cada melhoria é pequena e reversível.
  • O módulo reescrito virou o padrão para todo código novo.
Custos
  • Dois estilos de código convivem por muito tempo, e a atualização da linguagem fica registrada como dívida.

Autorização declarada na rota, fechada por padrão

Contexto
As checagens de acesso estavam espalhadas pelas telas; um esquecimento bastaria para abrir uma tela a um perfil que não devia vê-la.
Escolha
Cada rota declara quais perfis a acessam (filiado, regional, sede, formulários ou público), e rota sem declaração é recusada. O escopo da regional vem da sessão, nunca da URL.
Ganhos
  • As permissões de 214 rotas ficam num só lugar, fáceis de revisar.
  • Testes de autorização por perfil e por UF rodam contra essa tabela.
Custos
  • Um nível declarado errado só aparece quando alguém usa o menu, o que pediu testes de navegação com sessão real.

O filiado só nasce depois do pagamento

Contexto
Quem envia a filiação pela internet ainda não é filiado: faltam a conferência dos documentos e o pagamento. E os dados ficam em dois bancos, sem chave estrangeira entre eles.
Escolha
O candidato vive num pré-cadastro com área própria. O registro do pagamento cria, numa transação, a pessoa, o registro com o próximo número e a carteira. Baixa e criação são passos separados e repetíveis, com trava idempotente e um reconciliador entre os bancos, em vez de transação distribuída.
Ganhos
  • Nenhum número de registro para quem não pagou.
  • Uma falha na criação pode ser repetida sem baixar o pagamento de novo.
Custos
  • Um estado a mais para explicar ao candidato, e um reconciliador para operar.

Deploy e migration com rede de segurança

Contexto
Publicar era copiar arquivos para o servidor, sem volta fácil, e mudar o banco era um passo manual sem conferência.
Escolha
Deploy incremental com backup do que é substituído, health check e rollback automático; o deploy pausa quando há migration pendente, e o schema sobe antes do código, compatível com a versão anterior.
Ganhos
  • Uma publicação ruim volta sozinha para a versão anterior.
  • Migration nunca roda sem backup e pré-checagem.
Custos
  • Um passo manual por migration, e arquivos órfãos no servidor até uma limpeza com evidência.

Um relatório que não engana quem decide

Contexto
Comparar o ano corrente, ainda aberto, com anos fechados distorcia a variação em várias vezes.
Escolha
O comparativo entrega sempre duas leituras, mesmo período e ano civil, com o corte ancorado no último dia com lançamento e a data do corte escrita no aviso, nos indicadores e na planilha.
Ganhos
  • A comissão de finanças compara trechos iguais do calendário.
Custos
  • Dois números para o mesmo ano, que a tela precisa explicar.

Stack e por quê

PHP com MVC próprio
Legado mantido em produção; código novo em camadas de serviço dentro do mesmo app.
MySQL em dois bancos
Cadastro principal e filiação digital, ligados na aplicação e conferidos por um reconciliador.
Geração de PDF e QR
Carteira, contrato e recibos com QR de validação pública.
Docker
Ambiente local reproduzível e o único alvo dos testes de segurança.
GitHub Actions
Pré-verificação com bancos descartáveis, deploy com rollback e migration com backup.
Design system em CSS
Tokens com contraste AA anotado e verificadores automáticos de contraste e de uso.

Resultados

  • De zero para 47 arquivos de teste automatizado, com cerca de 14,3 mil linhas.

    repositório privado auditadoContagem na branch de trabalho do repositório(Auditoria do repositório privado, set/2026)
  • 214 rotas, cada uma com os perfis de acesso declarados na própria rota.

    repositório privado auditadoContagem na tabela de rotas da branch de trabalho(Auditoria do repositório privado, set/2026)
  • 16 decisões de arquitetura registradas em ADRs, com opções, prós e contras e gatilho de reavaliação.

    repositório privado auditadoRegistro de decisões do projeto(Auditoria do repositório privado, set/2026)
  • 42 migrations versionadas: 27 no banco principal e 15 no da filiação digital.

    repositório privado auditadoContagem no repositório(Auditoria do repositório privado, set/2026)
  • Ponto de partida: mais de 100 mil linhas de PHP, nenhum teste automatizado e nenhum ambiente de homologação.

    declaradoNota de diagnóstico do projeto

Ângulo de segurança

Superfície de ataque

  • Área do filiado, com dados pessoais, documentos e contratos.
  • Consulta pública e validação de carteira, selo e contrato por QR.
  • Envio de documentos na filiação digital.
  • Painéis da regional e da sede, por onde passa o dinheiro dos lotes.

Controles implementados

  • Autorização declarada em cada rota e fechada por padrão; o escopo da regional vem da sessão.
  • Documentos da filiação guardados fora da pasta pública, conferidos pelo conteúdo real e com hash SHA-256.
  • Contrato em PDF com código de integridade SHA-256, e protocolo com sufixo aleatório contra enumeração.
  • Notificações que levam só primeiro nome e protocolo, nunca CPF, e-mail ou endereço.
  • Suítes de red team autenticado no CI, que se recusam a rodar fora do ambiente local.

O que eu testaria hoje

  • Uma regional tentando ler ou alterar filiados de outra UF.
  • Pular etapas da filiação ou do lote com requisições forjadas.
  • Enumeração de protocolos na validação pública de contratos.

Evidências

  • repositório privado auditadoRepositório privado auditado(Auditoria do repositório privado, set/2026)