Changelog¶
Todas as mudanças relevantes deste projeto são registradas aqui.
O formato segue Keep a Changelog e o projeto adota Versionamento Semântico.
0.10.2 - 2026-10-01¶
Alterado¶
xadm-comum-web0.10.0 → 0.10.2. O 404 de rota inexistente comAuthorization: Basic(scanner de Elasticsearch/Kibana) deixa de abrir issue emERRORno GlitchTip (issue 1360); só o esquemaBearerconta como credencial na regra do 404 autenticado.- Norma X-Adm 2.1.0 e kit 2.0.8. Adota o ADR central 0039 (chamada de app para app pela URL
pública, com o
xadm-dnsdo host): o recurso no Coolify leva--dns 10.0.1.1 --dns 1.1.1.1, já aplicado em produção, registrado emdocs/decisoes/0035-adota-app-a-app-url-publica-dns-local.mde no runbook de deploy. Opipeline.ymlpassa a pôr timeout em todocurl, a rodar o gate quando o próprio workflow muda e a reprovarproxy_passcom host literal.
Migração¶
- Nada a fazer.
0.10.1 - 2026-09-22¶
Alterado¶
- Uma identidade por app (ADR central 0038). O
app_iddodocs/app.jsonpassa a ser o próprioslug(central-backend) e onomede exibição deriva dele. Oapp_iddoPOST /api/ci/deployfica declarado no OpenAPI como oregistry_slugque já era na resolução, com o motivo de não validar contra a tabelaapps: as stacks compose (PowerSync) ancoram por esse campo e não têm linha no catálogo, então a validação quebraria o único caminho que o usa. - Kit X-Adm 2.0.0 → 2.0.1. A skill
/xadm-setupfoi re-derivada — oPOST /api/setup/provisionpassa a levar o bloco de identidade inteiro doapp.json(slug,descricao,stack,toolchainalém dos obrigatórios), porque a tabelaappsé espelho doapp.jsone só essa chamada a escreve. Saíram as references de stack Flutter que o kit antigo copiava para todo repo.
Corrigido¶
- Upsert do catálogo de apps vira merge. Um
/api/setup/provisionsemstack,slugoudescricaozerava o valor que um setup anterior tinha gravado — foi o que esvaziou a stack de três apps do catálogo e deixou um sem slug. Campo ausente (ou string em branco) agora preserva o que está lá;nome,grupoecliente_idseguem obrigatórios pelas guardas, então app novo continua não entrando incompleto.
0.10.0 - 2026-09-16¶
Adicionado¶
POST /api/auth/refresh(decisão local 0034): troca um JWT de app-user vigente por um novo com o status e o papel atuais, sem a senha. Troca de papel e inativação chegam ao app sem logout. Antes, a sessão pAbast perdia a senha no F5 e o papel ficava congelado até o JWT vencer (24 h). Os tokens de app-user ganhamsub_typeeauth_time. O teto de sessãoAUTH_SESSION_MAX_HOURS(default e máximo 168 h, ADR central 0037) recusa o refresh e corta oexp. Oscodede 403 (not_app_user,access_revoked,session_expired,cliente_inactive,auth_method_not_allowed) são contrato com o app.scripts/coolify/limpeza.py: a limpeza das envs sem leitor no Coolify, com gate pelo release servido egit grepda chave antes de apagar, passa a ser versionada no repo dono doCoolifyClient. Roda em dry-run por padrão; o runbook é odocs/operacao/limpeza-envs-coolify.md.
Alterado¶
- O reconcile lê
int-jar.<cli>.xadm.bizcomo a instância<cli>. Na troca para native do app multi-instância, o native fica comint.<cli>e o jar vai paraint-jar.<cli>. Sem isso, o jar de cada cliente entrava no mapa sem instância, na mesma linha(slug, jar), e um recurso sobrescrevia o outro. - Monitor de host:
/system/df?type=build-cache. Sem otype, o daemon calcula também imagens, containers e volumes a cada chamada — percorre os volumes do host inteiro, I/O pesado na VM que o monitor observa, e o timeout de 3 s estoura. Pré-requisito para ligar odocker-socket-proxy(allowlist de 3 rotas GET). - Deploy só native (ADR central 0033, decisão local 0030). O
build.targetsdodocs/app.jsoné sónative, e opipeline.ymlperdeu o jobbuild_jare o step de deploy jar. O recursocentral-backend-jar-pullfica sem imagem nova: medido em 2026-09-11, o domínio principal já servia 100% native. O rollback é o redeploy da tag imutável<sha>-native. - Constituição X-Adm 1.5.0 → 2.0.0, kit 2.0.0.
- O
docs/app.jsonganhaperfilekite perdenativeedeploy; o projeto do GlitchTip passa parafeatures.glitchtip.project. - Foram re-derivados o pipeline, os Dockerfiles, o
mkdocs.yml, as skills e o hook, e o bloco de regras doCLAUDE.mdtroca a linha§6:pela deFeedback:. - O deploy passa a exigir gate verde e, em tag, o
release-check. - O aviso de publicação de docs deriva a URL do
CENTRAL_DEPLOY_URL. - Entra a página
docs/dev/como-rodar.md. xadm-comum-web0.9.1 → 0.10.0 exadm-comum-teste0.3.0 → 0.4.0 (ADR central 0034, decisão local 0031). O DSN do GlitchTip vem só doSENTRY_DSN, e sai o fallbackGLITCHTIP_DSNdologback.xml.- Locale pt-BR no native (
-H:IncludeLocales=pt-BR): no binário, o alerta de silêncio formatava "1.5h" em vez de "1,5h". mavenLocal()no build, depois do registro e só parabr.com.xadm(libs, Consumir): a versão da casa ainda não publicada sai do~/.m2para testar o app contra a lib; a publicada sempre vem do registro, e a/xadm-releaserecusa dependência da casa que não está nele.- Só o
shadowJarproduz obuild/libs/app.jar: o jar base deixou de usar o mesmo nome. - Postgres de teste singleton (
xadm-comum-teste0.4.0). Um container com dados em tmpfs serve a suíte inteira, e o Flyway migra uma vez. Os 26 testes de integração estendem oIntegracaoComPostgresda lib, que esvazia as tabelas antes de cada teste. Sai ojdbc:tc:doapplication-test.yml, que recriava o banco a cada classe, e com ele o overrideTEST_DB_URL. A tasktestcaiu de 148 s para 91 s. - Travas de teste: 2 min por teste, 15 min para a task
teste 5 s para obter conexão. Teste pendurado vira falha em vez de segurar o CI. - Services por feature e fronteiras travadas. Sete controllers injetavam repository e tinham regra
de negócio inline; a regra passou para services da feature, e os controllers só fazem HTTP e
mapeamento. O
ArchitectureTestagora trava controller → repository e dependência de controller (regras daRegrasArquiteturada lib) e config/infra na entidade (regra local). Contratos e códigos de erro ficam iguais. - Fatias do
ArchitectureTestcom o nome completo (br.com.xadm.integracao.central.admin.., não..admin..): a forma curta casaria também um pacote homônimo da lib da casa. A guarda foi provada quebrando de propósito as regras de base, de ciclo e de entidade. POST /test/glitchtipexigexadm_admin(decisão local 0032): sem token responde 401, sem o papel responde 403. OGET /testsegue público e mostra ocurlcom Bearer.- Pool do Hikari nas chaves certas. O
maximum-pool-size: 5estava num blocohikari:aninhado, que o Micronaut ignora — o pool de produção rodava no default de 10. Agora valemaximum-pool-size: 5comminimum-idle: 2, como a norma pede para um Postgres dividido entre os apps. - Job de silêncio com atraso e intervalo por property (
CENTRAL_SILENCIO_ATRASO_INICIAL,CENTRAL_SILENCIO_INTERVALO; default 20 min e 15 min, como antes). Só o e2e native encurta, para ver o alerta sair e afirmar o locale pt-BR no binário. - Status de acesso pAbast não grava para usuário inexistente: o
POST .../statusdo admin procura o usuário antes de atualizar o acesso; antes gravava e respondia 404. - Dois tokens de serviço, um por escopo de rota (decisão local 0033): a separação entre o
CENTRAL_API_TOKENe o shared secret do integrador fica registrada como exceção à regra de um token por app chamado.
Corrigido¶
- Docs do rollback e do monitor no estado atual. O runbook de deploy e a decisão 0027 davam a reversão do smoke como automática; o control-plane recusa a tag imutável (
400 invalid_image), então a reversão é manual até ele aceitá-la. A decisão 0019 e o runbook do monitor trocam o "mount read-only" pela pré-condição não-root: o Directory Mount do Coolify é bind rw.
Migração¶
- Antes do deploy: confira que o recurso
central-backend-native-pullno Coolify temSENTRY_DSN. Se tiver só oGLITCHTIP_DSN, renomeie: sem isso o erro de produção deixa de chegar ao GlitchTip, e a camada do smoke que procura exceção nova passa sem ver nada. - Depois do deploy: a variável de repo
CENTRAL_DOCS_URLno GitHub deixa de ser lida e pode ser apagada; o recursocentral-backend-jar-pullpode ser desligado no Coolify.
0.9.1 - 2026-09-11¶
Alterado¶
xadm-comum-web0.9.0 → 0.9.1: a lib passa a embarcar a hint native doSentryAppender(reflect-configcom as três entradas: appender,SentryOptionseLevel.valueOf). A cópia local registrava só o appender e, no binário native, o<options>dologback.xmlera ignorado em silêncio — o evento chegava ao GlitchTip semenvironment. A cópia local saiu no mesmo commit (§Migração da lib). De carona, o 404 de negócio (rota que casou) volta aDEBUG; o 404 de rota não casada em request autenticado segue emERROR.- Controllers fora do event loop (
micronaut.server.thread-selection: AUTO, default da casa): o default do Micronaut 5 éMANUAL, e sem@ExecuteOntodo método imperativo — JDBC e as chamadas HTTP bloqueantes ao Coolify, Garage, GlitchTip, Metabase e Resend — rodava no event loop do Netty. - Beans opcionais por
@Requires(pattern = ".+")(Resend, SMTP de teste, validador Firebase): a forma que reprova a property ausente e a vazia; onotEquals = ""só barrava a vazia. - Postgres de dev (
docker-compose.dev.yml) monta o volume em/var/lib/postgresql, o layout do Postgres 18 (no caminho antigo o volume nomeado ficava vazio e o dado ia para um volume anônimo), e espera compg_isready -h 127.0.0.1, que não responde "pronto" no servidor temporário do initdb. - Constituição X-Adm 1.4.8 → 1.5.0: guardas do
pipeline.ymlre-derivadas — a defesa anti-vácuo do ArchUnit passa a reconhecerRegrasArquitetura.importNaoVazio(), que oArchitectureTestusa e que dava aviso eterno; a guarda JTE roda no Windows; entra a guarda de destino de proxy do nginx (aqui se pula) — e as skills/xadm-docse/x-documentarre-sincronizadas.
0.9.0 - 2026-09-10¶
Adicionado¶
- Heartbeat do integrador-client, com alerta de silêncio por horas úteis: o
integrador-client roda on-premise, um por cliente, e quando parava ninguém via — o
sintoma chegava dias depois como "a integração parou". O central passa a receber o
heartbeat que o integrador-server de cada cliente repassa
(
POST /api/integrador/heartbeat, token próprioCENTRAL_API_TOKEN), guarda o estado atual por cliente (migração V16,integrador_instancias) e alerta no GlitchTip uma vez por episódio quando uma instalação passa de 6h úteis sem sinal. A aba Deploy do central-ui ganha a lista das instalações, comDELETEidempotente para parar de acompanhar. Verdocs/decisoes/0028-heartbeat-integrador-client.md.
Alterado¶
- Produção recusa subir sem os tokens M2M: o central subia healthy com
/api/ci/**respondendo 401 a tudo, e o sintoma chegava horas depois como "o deploy da frota parou". Emenv=prodo boot passa a ser recusado semCENTRAL_DEPLOY_TOKEN(e semCENTRAL_API_TOKEN, do heartbeat) — o rolling deploy do Coolify mantém o anterior no ar; fora de prod (e2e/staging) segue sem token. Ação de operação: cadastrar os dois envs nos recursos do Coolify antes do deploy. Documentação migrada para a constituição 1.4.8.
Corrigido¶
/healthvolta a provar a identidade da entrega:SOURCE_COMMITé variável predefinida do Coolify, que em recurso pull-only a injeta em runtime com o literalHEADpor cima do ENV da imagem — a v0.8.0 foi ao ar respondendo"commit":"HEAD", e o smoke pós-deploy passava sem provar identidade (e o rollback seguinte miraria uma tag inexistente). O commit passa ao namespace da casa (XADM_COMMIT), comxadm-comum-web0.9.0, que trataHEADcomo ausente.
0.8.0 - 2026-09-09¶
Adicionado¶
- Smoke de produção pós-deploy, com identidade de entrega e rollback: o
/healthpassa a provar QUAL entrega está no ar —SOURCE_COMMITvira ARG/ENV nos dois Dockerfiles (declarado tarde, para não invalidar onativeCompile) e o CI o passa como build-arg. O jobsmokeroda depois do deploy e confere identidade, rotas críticas doapp.jsone ausência de exceção nova no GlitchTip; reprovou, reverte para a tag imutável da entrega anterior. Verdocs/decisoes/0027-adota-smoke-de-producao.md. - Status de usuário pAbast sem exigir papel: barrar um pAbast exigia antes
conceder papel a ele. A rota nova aceita
INATIVO/REJEITADO/PENDENTEsem papel (criando a linha de acesso se faltar) e reserva a exigência aoATIVO, único status de que o token pAbast copia orole— ativar sem papel devolveria sessão sem papel. Inativar preserva o papel.
Alterado¶
CENTRAL_DEPLOY_URLvolta a ser flavor-agnóstica: apontavacentral-backend-jar.xadm.biz— parar o jar numa promoção a native derrubava oPOST /api/ci/deployda frota inteira.xadm-comum-web0.8.0 (ocommitno/health) eArchitectureTestcompondo aRegrasArquiteturadoxadm-comum-teste, mantendo local a guarda anti-vácuo e a regra de N destinos que a fábrica ainda não cobre. Documentação migrada para a constituição 1.4.0.
0.7.1 - 2026-09-06¶
Corrigido¶
- Rotas do catálogo de papéis na doc: a modelagem anunciava
DELETE /api/admin/apps/{app}/rolesquando a rota real éDELETE /api/admin/apps/{app}/roles/{role}, e o runbook de seed conferia o catálogo por uma URL com o slug do app literal no lugar do path param — as duas afirmações que o gatecheca-rotasreprovou contra o OpenAPI gerado. O mesmoDELETEerrado saiu do javadoc deAppRole.
0.7.0 - 2026-09-06¶
Adicionado¶
- Login social com status×role e auto-governança de acesso: o acesso
oauth_firebasepassa a ter dois eixos —status(PENDENTE/REJEITADO/ATIVO, lifecycle) erole(papel data-driven por app, catálogoapp_roles) — emitidos no token para a sync rule do PowerSync consumir. Abre a superfície self-service/api/app/**: o ADMIN do tenant lista os usuários e atribui papel no seu app, com guarda de auto-lockout do último ADMIN; novo pedido pendente notifica os aprovadores por e-mail (fail-open).@xadmé super-admin implícito. Migrações V11 (split + drop dos grants) e V12 (app_roles). Verdocs/decisoes/0023-login-social-status-role-self-service.md. - Acesso unificado pAbast ∪ oauth, com papel por usuário:
oauth_access_requestsevolui paraapp_user_access(migração V13) — o acesso de qualquer usuário, social (oauth) ou staff do ERP (pAbast), numa tabela só, comstatus+role. O login pAbast vira app-user (app_idopcional no login → token comoauth_app_id/role, fail-closed sem papel; o login legado segue inalterado) e o papel é atribuído pela tela unificada de Usuários. Verdocs/decisoes/0024-acesso-unificado-pabast-oauth.mdedocs/decisoes/0025-catalogo-de-papeis-declarado-pelo-app.md. - Apps compose no control-plane, ancorados no slug do git: stacks
build_pack=dockercomposebuild-from-git (ex. PowerSync) não têm imagem de registry e ficavam fora do reconcile-by-image — sem caminho de deploy gateado e sem auditoria. OPOST /api/ci/deployganha um segundo modo de âncora: sem imagem, oapp_idé oregistry_sluge otargeté obrigatório (migração V15 abre o CHECK). O caminho por imagem da frota fica byte-idêntico. Verdocs/decisoes/0026-deploy-compose-ancorado-no-git.md.
Corrigido¶
- Gate de arquitetura ressuscitado: o ArchUnit 1.3.0 não lê bytecode do JDK 25 (class
major 69) e descartava 194 de 388 classes em silêncio — as travas de fronteira passavam
vácuas, verdes, desde o bump do Micronaut 5. Sobe para 1.4.1 (piso da norma) e um teste
novo falha alto quando o import vem vazio. Junto, o
AdminApiCorsFilterTestchamava um construtor que não existe mais, quebrando ocompileTestJavae impedindo qualquer teste do repo de rodar.
Alterado¶
- Os dois transportes de e-mail passam a ser provados dentro do repo:
SmtpEmailSendereResendEmailSender(o de produção, antes com zero cobertura) ganham prova em JVM pura — SMTP de mentira emServerSocketlocal e WireMock —, sem Docker. O endpoint da Resend virou property (RESEND_ENDPOINT, default o de produção) para ter seam de teste. O denominador do JaCoCo deixa de contar código gerado (Serde*,$Intercepted), que escondia os buracos reais.
0.6.1 - 2026-08-31¶
Alterado¶
- CI mais enxuto (GitHub Actions): o
pipeline.ymlparaleliza a liberação de disco do build native (~5min → ~2min), isola o cache gha por flavor (jar/native) e cacheia as ferramentas de docs (pip/npm); os workflows.forgejo/remanescentes foram removidos (CI 100% GitHub). Documentação e skills sincronizadas à constituição X-Adm 1.1.2.
0.6.0 - 2026-08-31¶
Adicionado¶
- Poke de docs publicadas (event-driven):
POST /api/ci/docs-published(protegido peloDeployAuthFilter) recebe o aviso do CI quando um app publica docs e cutuca o listener interno do container docs (/cgi-bin/_sync) — elimina o poll de 90s do Garage. Verdocs/decisoes/0022-self-deploy-do-central.md.
Alterado¶
- CI 100% GitHub Actions: um
pipeline.ymlúnico (decide → gate ∥ docs ∥ build_jar ∥ build_native → release-check → deploy) substitui obuild-deploy.yml, zerando a dependência do Forgejo Actions. Alinha o central ao modelo v1.1.0 da casa (ADRs 0027/0028/0026). - Self-deploy do central pelo próprio control-plane: o deploy do central passa a usar o
mesmo
POST /api/ci/deployda frota, apontando para si; a guardaself_deploy_refusedfoi removida (o central roda dentro da casa e alcança a API do Coolify — a ponte SSH e a API direta do runner saíram). Verdocs/decisoes/0022-self-deploy-do-central.md.
0.5.4 - 2026-08-30¶
Adicionado¶
- Control-plane de deploy (ADR 0026 / constituição §9): o CI dispara o deploy por API M2M
(
POST /api/ci/deploy, token dedicado no filtro/api/ci/**) e o central resolveapp → recurso Coolifypor um mapa auto-curável ancorado na imagem (app_deploy_targets, migração V10, + reconcile-from-Coolify), chamando a API do Coolify — substitui a ponte SSH + allow-list, que ficava órfã a cada cutover blue-green. Verdocs/decisoes/0021-adota-control-plane-deploy.md. - Painel de deploy (read-only):
GET /api/admin/deploy(JWTxadm_admin) que agrega o mapa de deploy + o últimodeploy_auditpor recurso + o estado vivo do Coolify (reuso do monitor, indexado poruuid), agrupado por app — alimenta a aba Deploy do central-ui.
Alterado¶
- Build off-host (jar + native): o jar e o native passam a buildar no CI (GitHub Actions) e o Coolify só puxa a imagem pronta — o build sai do host de produção. Conformidade à constituição 0.37.3.
0.5.3 - 2026-08-28¶
Alterado¶
- Constituição X-Adm sincronizada para 0.36.5: o gate de CI ganha a guarda de
paridade
Dockerfile/Dockerfile.native(dirs app-writable sob/app) e as skills de release/docs são re-derivadas do template.
Corrigido¶
- Deploy native dispara o redeploy sozinho: após publicar a imagem native no
registry, o workflow passa a acionar a atualização do recurso no Coolify via ponte
SSH (a API do Coolify recusa o IP do runner do GitHub) — antes era publish-only e o
recurso só subia a imagem nova num redeploy manual. A leitura da
DEPLOY_SSH_KEYfoi endurecida contra CRLF: o secret gravado no Windows chegava com\re osshfalhava com "error in libcrypto".
0.5.2 - 2026-08-27¶
Corrigido¶
- Build native: título OpenAPI normalizado para ASCII, evitando falha do
micronaut-openapiao criar o arquivo Swagger durante onativeCompile.
0.5.1 - 2026-08-27¶
Corrigido¶
- Dependência publicada: o central passa a consumir
xadm-comum-web:0.6.1, em vez da versão inexistente0.6.1-SNAPSHOT, permitindo os builds JVM e native.
0.5.0 - 2026-08-27¶
Adicionado¶
- Deploy native: imagem GraalVM native do central-backend buildada no GitHub Actions, publicada no registry e preparada para atualização do recurso native no Coolify.
- Monitoramento de infraestrutura: endpoints read-only para saúde do host e das aplicações do Coolify, com métricas de recursos e degradação parcial explícita.
Alterado¶
- Identidade do serviço: o nome interno passa de
authparacentral-backend, mantendoauth.xadm.bizcomo issuer e endpoint JWKS para não quebrar os clientes PowerSync. - Health: resposta
/healthuniformizada para o formato flat{status, versao}, com liveness native explícito.
Corrigido¶
- Native liveness:
/health/livenesspassa a retornarUPtambém na imagem native. - Documentação operacional: rotas do monitor alinhadas ao OpenAPI gerado.
0.4.2 - 2026-08-10¶
Adicionado¶
- Garage — S3 direto para app server: apps server/web (com
production_url) passam a receber a write-key do Garage no recurso Coolify (GARAGE_ACCESS_KEY_ID GARAGE_SECRET_ACCESS_KEY, decifrada desecret_refno ato da injeção), acessando o bucket direto por S3 em vez do round-trip de presign. O presign broker-signed segue valendo para device/mobile (segredo só no auth); o secret entra só no Coolify (mascarado), nunca noapp.json. Habilita o gancho deferido na decisãodocs/decisoes/0012-garage-arquivos-presign-broker.md.
0.4.1 - 2026-08-10¶
Corrigido¶
- Garage: o provisionamento passa a validar
AUTH_CIPHER_KEY(chave AES-256, 32 bytes base64) antes de tocar o broker. Ausente ou inválida, recusa com erro claro em vez de criar bucket + key e só falhar no encrypt final — o que deixava recursos órfãos no Garage e devolvia um 502 opaco ao setup. A chave, antes documentada como legado, volta a ser obrigatória quando a feature de arquivos está ativa (o secret da write-key é cifrado com ela); doc de operação atualizada.
0.4.0 - 2026-07-16¶
Alterado¶
- Central: o DSN de erros é injetado como
SENTRY_DSN, não maisGLITCHTIP_DSN. O broker derivava<PROVIDER>_<KEY>para todo env; agora abre exceção explícita quando o consumidor é um SDK de terceiro com nome canônico próprio (glitchtip.dsn→SENTRY_DSN), que é o nome que o SDK do Sentry lê do ambiente por convenção — o mesmo mapeamento que o build Flutter já fazia no--dart-define. Fora da exceção, a derivação segue igual. Ologback.xmlaceita os dois nomes durante a transição. Ação de operação: após o deploy, renomear o env no Coolify e apagar oGLITCHTIP_DSNórfão à mão — a injeção é upsert e não remove o nome antigo. Verdocs/operacao/injecao-secrets-coolify.md.
Corrigido¶
- Setup:
app_idefeatureausentes no provision passam a devolver um machine-code estável (app_id_obrigatorio/feature_obrigatoria) em vez doBAD_REQUESTgenérico da validação de borda, que a Central não conseguia traduzir em feedback legível. - Setup:
nomeegruposão validados antes do upsert — provision sem esses campos estourava um 500 opaco (violando o contrato problem+json) em vez de400 nome_obrigatorio/400 grupo_invalido.
0.3.10 - 2026-07-10¶
Corrigido¶
- Gate de CI: quebra uma linha longa em
MetabaseProviderque estourava o limite do checkstyle (>120 caracteres), restaurando o gateci.ymlverde.
0.3.9 - 2026-07-10¶
Alterado¶
- Constituição X-Adm atualizada para 0.18.4 e adotada cobertura JaCoCo no gate de qualidade (CI).
Corrigido¶
- Metabase: o embedding assinado passa a ser best-effort e aplicado após os cards, evitando dashboard vazio quando o embed falha.
- Analytics: o
client_configemite oaptabase_hostjunto da key. - Setup: removida a fórmula do token de serviço da documentação e das respostas da API.
0.3.8 - 2026-07-07¶
Adicionado¶
- Central: links contextuais + embedding assinado do Metabase. A central resolve os links
de produção/docs/source por app e embute dashboards do Metabase via signed embedding
(JWT HS256), sem expor credenciais. Ver
docs/decisoes/0017-metabase-embed.md.
Alterado¶
- Contrato de erro único (problem+json): todos os erros do serviço saem em
application/problem+json(RFC 7807) comcode(machine-code estável), via um processor global; a arquitetura package-by-feature passa a ser travada por gate ArchUnit e oAuthControllerfica fino (negócio noAuthLoginService). Verdocs/decisoes/0016-contrato-erro-unico.md.
Corrigido¶
- Provisão de app de cliente estourava 500 opaco ("Unexpected error" no Sentry) quando o
cliente_iddoapp.jsonnão existia emclientes— ex.: o nome de exibição (Vantroba) no lugar da chave do tenant (vantroba): o FKapps_cliente_id_fkeyfalhava no PERSIST sem tratamento. O broker passa a validar ocliente_idantes do upsert e responder400 cliente_desconhecido(problem+json), apontando a chave minúscula esperada.
0.3.7 - 2026-07-04¶
Corrigido¶
- Preflight CORS do admin retornava 401 em produção (Central bloqueada por "No
Access-Control-Allow-Origin"): os filtros de
/api/admin/**usavam a API@Filterlegada, que ordena porgetOrder()e ignora@Order— a ordem entre CORS e autenticação ficava indefinida e divergia entre o classpath (teste verde) e o fat jar (produção), onde o auth respondia oOPTIONScom 401 antes do CORS. Migrados para@ServerFilter(honra@Order); o auth passa a eximirOPTIONS. Verdocs/decisoes/0015-filtros-admin-serverfilter.md.
0.3.6 - 2026-07-04¶
Alterado¶
- Constituição X-Adm atualizada para 0.17.26:
ci.ymlcanônico (o env do dind vai na config do act_runner, org-wide) + passo nav-drift (checa-nav.pyno gate de código); skills de workflow re-sincronizadas; adicionascripts/checa-nav.py.
0.3.5 - 2026-07-03¶
Alterado¶
- Metabase organiza por pasta: cada app ganha uma sub-collection própria
(
X-Adm|cliente → app → dashboard + cards) em vez de tudo solto numa collection compartilhada; os cards voltam ao nome canônico (sem o sufixo· app_id, já isolados).
0.3.4 - 2026-07-03¶
Corrigido¶
- Provisão de
analytics(502 em produção): oAptabaseProviderparseavaapp_key, mas a API serializa em camelCase (appKey) → key nula; e oMetabaseProvidermandava os dashcards comid:-1repetido → o Metabase rejeitava (400). Corrigidos (lêappKey; id negativo único por card). A idempotência passou a reusar/adotar cards órfãos por nome na collection, sem duplicar — re-rodar o setup auto-cura o estado parcial.
0.3.3 - 2026-07-03¶
Corrigido¶
- Publicação de docs (
docs.yml): os links[decisão 00XX](docs/decisoes/…)no CHANGELOG quebravam omkdocs build --strict— o changelog é embutido emdocs/, então o prefixodocs/não resolvia (viravadocs/docs/…). Passam a texto puro (decisão 00XX).
0.3.2 - 2026-07-03¶
Corrigido¶
- Publicação de docs (
docs.yml): a geração do Javadoc falhava por 5 erros de doclint pré-existentes (dois{@link}cross-package sem FQN; três<h3>de topo pulando de H1). Corrigido — o pipeline de docs volta a publicar.
0.3.1 - 2026-07-03¶
Corrigido¶
- Pipeline de CI (Testcontainers no runner dind): o gate ficava vermelho porque o
mount de
/var/run/docker.sockdo template era ignorado no runner (dind isolado, sem socket do host). O job passa a alcançar o daemon do dind pelo gateway (DOCKER_HOST=tcp://172.17.0.1:2375), mantendo o isolamento.
0.3.0 - 2026-07-03¶
Adicionado¶
- Provider Garage (arquivos): provisão de bucket + chave e corretor de presign
broker-signed (
GET /api/apps/garage/presign) com autorização por app (oauth_app_id, 403 cross-app). Ver decisão 0012. - Provider Aptabase (analytics — eventos): auto-provisão do app forjando o token de
sessão (HS256 com o
AUTH_SECRET), sem depender de API de provisão. Ver decisão 0013. - Provider Metabase (analytics — BI): auto-provisão de collection → dashboard → cards
de BI (queries ClickHouse) via API REST; a feature
analyticspassa a provisionar Aptabase e Metabase. Ver decisão 0014.
Alterado¶
- A injeção do client-grade no Coolify reinicia o recurso para aplicar a env recém-criada.
- Constituição X-Adm atualizada para 0.17.10 (pipeline de skills
x-*; CI com Docker-in-Docker para os Testcontainers).
0.2.1 - 2026-07-03¶
Corrigido¶
/test/glitchtipaceitaapplication/x-www-form-urlencoded: o submit do botão (form HTML) dava 415 porque o@Postdo Micronaut assumeapplication/json.
0.2.0 - 2026-07-03¶
Adicionado¶
- Central de Apps — broker build-time:
POST /api/setup/provisionprovisiona features de infra por app, de forma idempotente, autenticado por token de serviçoX-ADM-<código do dia>. Provisão do GlitchTip (DSN) com injeção do client-grade no recurso Coolify do app. Dashboard admin/api/admin/apps(catálogo por app + estado por provider + links). - Observabilidade de erros: SDK Sentry/GlitchTip (
sentry-logback) reporta os erros do serviço ao GlitchTip; endpoint/testcom smoke-tests públicos e inócuos rodáveis em produção (o 1º valida o pipe de erro ponta a ponta). Ver decisão 0011. - Documentação migrada para o padrão da constituição X-Adm (seis níveis): Resumo Executivo, Documentação Completa, modelo de dados, decisões (0001–0011), runbooks de operação e guia de desenvolvimento.
Alterado¶
- Resposta honesta do
/provision: carrega o estado real por provider (state/last_error+ injeçãoinjected/motivo) e responde 502 quando nenhum provider liga — nunca mais um200mudo escondendo falha. GlitchTip nomeado peloapp_id(slug estável, sem duplicata). Ver decisões 0010/0011. - Código reorganizado para package-by-feature (padrão da casa):
comum(transversal) login+admin+centralapps, com dependências acíclicas entre features.- Constituição X-Adm atualizada para 0.17.2 (skills re-sincronizadas,
xadm-setupinstalada,app.jsoncomapp_id/production_url). - Stack migrada para Micronaut 5.0.3 / JDK 25 / Gradle 9.5.1 (decisão 0009).
Serde passa a usar Jackson 3; o JWKS é serializado via nimbus. O JVM do Gradle
precisa ser 25. Imagens de CI/Docker em
ci-java:25/eclipse-temurin:25. - Gate de CI ganhou o checkstyle (
./gradlew check), com o código conformado ao padrão de estilo da casa.
Corrigido¶
/acessosexpõe oiddo pedido e a central tem CORS liberado.gradlewversionado como executável (100755).