Guia do código¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-15
Audiência: dev que abriu o repositório e quer passar os olhos e entender como o código do tradutor está organizado, antes de mergulhar classe a classe. Para o porquê das escolhas, veja a arquitetura integrador + tradutor e as demais decisões; para o desenho completo, a Documentação Completa; para rodar e testar, Como rodar.
O retrato em uma frase¶
O tradutor varre a réplica estoque do db_thoms, mapeia cada produto para o contrato da WebStorm e
envia em lotes para POST /sync/erp, gravando cada envio e a resposta para auditoria e reprocesso; ao
lado, recebe o CSV do X-Adm e o repassa ao integrador.
flowchart TB
poke["webhook: POST /api/integrador/produto"] --> sweep["sweep: varre estoque por updated_at"]
agenda["SweepScheduler"] --> sweep
sweep --> mapper["mapper: réplica para item do parceiro"]
mapper --> envio["envio e parceiro: lotes para POST /sync/erp"]
envio --> auditoria["auditoria: webstorm_ecom_request"]
csv["produto: POST /api/csv/processar"] --> integrador["IntegradorClient: PUT e DELETE /api/v1/xadm"]
Como o código é organizado¶
Organização package-by-feature sob br.com.xadm.webstormecom: cada funcionalidade é um pacote de
topo que carrega as próprias camadas, em vez de pastas globais controller//service/.
| Pacote | É | Responsabilidade |
|---|---|---|
sweep |
feature | a varredura da réplica: agenda (SweepScheduler), trava entre instâncias por advisory lock (SweepClusterLock) e uma execução por vez (SingleFlight) |
replica |
feature | leitura da tabela estoque, que é do integrador (só leitura) |
mapper |
feature | o de-para réplica → item do parceiro (ProdutoMapper) |
parceiro |
feature | o cliente HTTP da WebStorm (WebStormClient), o envio em lote e a retentativa em 5xx ou timeout |
envio |
feature | idempotência por versão, classificação da resposta, registro do envio e reprocesso |
auditoria |
feature | a trilha webstorm_ecom_request, a leitura que as telas consomem (AuditoriaService) e a limpeza por retenção (CleanupJob) |
webhook |
feature | o poke do integrador (POST /api/integrador/produto, ROLE_API) |
produto |
feature | a ingestão do CSV do X-Adm (POST /api/csv/processar): extrai o zip, calcula o diff contra o último snapshot e repassa ao integrador; a leitura da trilha de processamentos é do IngestaoService |
arquivo |
feature | a guarda do upload original no Garage (ArquivoStore) |
monitor |
feature | o watchdog do heartbeat do CSV (Monitor) e a tela /admin/monitor |
views |
feature | as telas JTE: a trilha de envios (/) e o admin (/admin), que leem pelo serviço da feature |
security |
base | a regra de acesso das views (ViewSecurityRule, ViewWhitelist) e as respostas de erro de auth |
dev |
base | apoio de desenvolvimento: seed, mock do integrador e gravação de payload |
Os templates JTE ficam em src/main/jte/; o layout padrão X-Adm vem do kit em src/main/jte/kit/.
As migrations do Flyway (src/main/resources/db/migration/) criam só as tabelas webstorm_ecom_*.
As camadas¶
Uma requisição ou um disparo agendado entra por um controller ou scheduler, passa pelo serviço da
feature e chega ao repositório micronaut-data (@JdbcRepository). A tela recebe um view-model, não a
entidade. O que é transversal vem das libs da casa: login e sessão (xadm-seguranca), /health e
GlitchTip (xadm-comum-web), registro das mensagens m2m e a tela /admin/mensageria
(xadm-mensageria) e o S3Client do Garage (xadm-comum-storage).
Travas de arquitetura¶
O ArquiteturaTest, dentro do ./gradlew check, guarda cinco invariantes:
- sem ciclo de dependência entre os pacotes de feature (
RegrasArquitetura.semCiclosEntreFatias); - controller não acessa repositório: a persistência fica atrás do serviço da feature
(
RegrasArquitetura.controllerNaoAcessaRepository); - nada depende de controller — o domínio, o parsing e a infra não conhecem a borda HTTP
(
RegrasArquitetura.nadaDependeDeController); - todo
@Post,@Putou@Patchde controller de view declara@Consumes— sem ele o submit do formulário devolve 415; - o import de classes não pode vir vazio, senão as regras acima passariam sem testar nada.
As guardas estáticas do job gate do pipeline.yml completam a lista (placeholders do Micronaut,
paridade dos Dockerfiles, reflect-config da JTE no native, libs no piso, entre outras).
Por onde começar a ler¶
Application— o entrypoint; inicializa o Sentry antes do contexto, para erro de boot chegar ao GlitchTip.src/main/resources/application.yml— toda a configuração e as envs de cada feature.- Uma feature ponta a ponta:
WebhookController→Sweep→ProdutoMapper→EnvioParceiro→RegistradorEnvio.
Referência completa¶
Este app não publica Javadoc em dev/api/: a referência de classe é o próprio código, e a narrativa
acima é o atalho para achar por onde entrar.