Commit Graph

448 Commits

Author SHA1 Message Date
provisionamento Athletic Map 76e11b9aca feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:39:54 +00:00
provisionamento Athletic Map 3f965f07d5 feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:39:03 +00:00
provisionamento Athletic Map 88aab7d17d feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:38:30 +00:00
provisionamento Athletic Map 96888649bc feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:38:09 +00:00
provisionamento Athletic Map bcc7de951b feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:37:53 +00:00
deploy 754475e94d chore(plataforma): servico-captacao:2.6-banco-do-tenant 2026-09-24 21:36:36 +00:00
deploy 85ee182b43 feat(plataforma): infraestrutura da etapa BANCO_CRIADO
RBAC amarrado por resourceNames (db-credentials nos tenants, pgbouncer-userlist
so aqui), netpol do PgBouncer por ROTULO em vez de por nome, e a credencial de
administracao do Postgres compartilhado para o servico-captacao.
2026-09-24 21:36:33 +00:00
deploy 642e091641 chore(plataforma): servico-captacao:2.5-cadastro-do-cliente 2026-09-24 21:15:28 +00:00
provisionamento Athletic Map b51778076f feat(tenant): provisiona escolinha-de-teste
Cliente: Escolinha de Teste
Assinatura: sub_h2dtdvlbt83iq2lg
Plano: (nao informado)
Realm: athleticmap-6

Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
2026-09-24 21:03:10 +00:00
deploy 466c70fb25 chore(plataforma): servico-captacao:2.4-retomar-relogio 2026-09-24 21:01:51 +00:00
deploy 5e5c618273 chore(plataforma): servico-captacao:2.3-retomar 2026-09-24 20:51:32 +00:00
deploy c3e821ba90 chore(plataforma): servico-captacao:2.2-smtp-hostinger 2026-09-24 20:38:12 +00:00
deploy d68cf37493 feat(plataforma): SMTP pela Hostinger, e o molde do realm no repositorio
O dominio athleticmap.com tem MX na Hostinger e SPF que so autoriza a
Hostinger. A credencial foi medida: aceita em smtp.hostinger.com:587,
recusada com 535 no Gmail e no Titan.

O molde do realm nunca tinha sido empurrado — PROVISIONAMENTO_REALM_TEMPLATE
estava vazio, e a etapa REALM_CRIADO teria parado nele logo depois do SMTP.
2026-09-24 20:38:05 +00:00
deploy 5a60e81b1f chore(plataforma): rotaciona o token do Gitea do provisionador
O anterior apareceu num output de printenv em 2026-09-24. A senha do Keycloak
no mesmo Secret nao foi exposta e foi reselada sem mudar.
2026-09-24 20:26:36 +00:00
provisionamento Athletic Map 3e9bc6c370 feat(tenant): provisiona escolinha-de-teste-2
Cliente: (sem nome no pedido)
Assinatura: sub_60id65hukv48tshu
Plano: (nao informado)
Realm: athleticmap-7

Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
2026-09-24 20:05:10 +00:00
deploy fef8108cd7 chore(plataforma): servico-captacao:2.1-plano-opcional 2026-09-24 20:03:54 +00:00
deploy 6733faea2c chore(plataforma): servico-captacao:2.0-nome-por-documento 2026-09-24 19:56:34 +00:00
provisionamento Athletic Map 101fa8108d feat(tenant): provisiona escolinha-de-teste
Cliente: Escolinha de Teste
Assinatura: sub_h2dtdvlbt83iq2lg
Plano: (nao informado)
Realm: athleticmap-6

Gerado pelo provisionamento automatico (P5.2/P5.3) a partir do molde
consolidado de P4.9. O ApplicationSet cria a Application sozinho pelo
gerador de diretorio sobre tenants/*.
2026-09-24 18:58:52 +00:00
deploy e9281b22cd chore(plataforma): servico-captacao:1.9-selar-cert-vazio 2026-09-24 18:56:37 +00:00
deploy 18bae612fe chore(plataforma): servico-captacao:1.8-causa-no-log 2026-09-24 18:41:26 +00:00
deploy 90fbb681c7 chore(plataforma): servico-captacao:1.7-nome-do-lead 2026-09-24 18:09:41 +00:00
ATM Platform a0066235ed chore(teste): preco do bronze em R$ 5 para a venda de prova
Temporario e marcado no proprio arquivo. A venda de teste exercita link,
pagamento, webhook e provisionamento, e nao faz sentido gastar R$ 170 nisso.
Sobreposicao por ambiente: tirar e remover o bloco, sem tocar no codigo.
2026-09-24 17:42:10 +00:00
ATM Platform cb66407c35 fix(plataforma): devolver o que a rodada de imagem apagou do captacao
O publicar_servico_captacao.py escreve o manifesto a partir da copia LOCAL do
athletic-map-deploy, e essa copia esta defasada. Ao subir a tag 1.6 ele levou
junto tudo o que foi ligado hoje no servidor: ASAAS_API_KEY, CAPTACAO_ORIGEM no
dominio novo e as QUATRO credenciais do provisionamento — 56 linhas.

O pod chegou a subir sem elas. E exatamente a divergencia de espelho registrada
hoje de manha, agora com consequencia medida.

Restaurado a partir do commit anterior, com a tag nova aplicada por cima.
2026-09-24 17:37:00 +00:00
deploy c6385f1d61 chore(plataforma): servico-captacao:1.6-assinatura 2026-09-24 17:35:19 +00:00
ATM Platform 2a3558137f feat(P5.8): a chave do Asaas chega ao servico-captacao
E o mesmo Secret que o servico-financeiro ja usa — nao ha credencial nova a
selar, muda so quem a le. Os dois fluxos continuam distintos: o financeiro cobra
o ATLETA, o captacao cobra o TENANT.

optional: true de proposito. Um ambiente sem Asaas sobe do mesmo jeito, e a
venda que precisar da chave recusa nomeando a propriedade. Derrubar o pod
tiraria do ar o provisionamento e a captura de lead, que nao dependem disso.
2026-09-24 17:02:19 +00:00
ATM Platform 2996ca7a92 docs(P3.3): restaurar o cabecalho que a rotacao apagou
O kubeseal devolve YAML limpo, e a rotacao do token levou junto 17 linhas que
diziam por que ha dois segredos, que o AsaasConfig recusa subir se forem iguais,
e que 15 recusas seguidas param a fila da conta no Asaas.

Entra tambem o que mudou hoje: o token do webhook nao precisa mais ser digitado
no painel, porque o script o grava pela API.
2026-09-23 21:45:45 +00:00
ATM Platform 305ad93795 fix(P3.3): token do webhook de cobranca, acertado nos dois lados 2026-09-23 21:30:30 +00:00
ATM Platform 6c6478eea5 fix(P5.9): token do webhook da assinatura 2026-09-23 20:28:21 +00:00
ATM Platform c391dc5aa0 fix(P5.9): token do webhook cadastrado no Asaas 2026-09-23 19:19:51 +00:00
ATM Platform 0693e6cf33 fix(P5.9): rotacao do token do webhook 2026-09-23 19:03:17 +00:00
ATM Platform f5f7939f2c fix(P5.9): rotacao do token do webhook da assinatura 2026-09-23 18:57:34 +00:00
ATM Platform e726702843 feat(P5.9): token do webhook da assinatura, regerado 2026-09-23 18:51:27 +00:00
ATM Platform f168f20ec3 feat(P5.3): o captacao passa a ler as credenciais do provisionamento 2026-09-23 17:14:58 +00:00
ATM Platform 4fc3d5b0e7 feat(P5.3): credenciais do provisionamento, seladas 2026-09-23 16:12:44 +00:00
ATM Platform 82e7b4c9e3 fix(plataforma): cota com folga para rolling update - 10 para 12 CPU 2026-09-23 13:48:25 +00:00
ATM Platform 97e0aeecd4 feat(P0.9): fase issuer - o issuer passa para athleticmap.com 2026-09-23 12:30:41 +00:00
ATM Platform eeda1e90da Revert "feat(P0.9): fase issuer - o issuer passa para athleticmap.com"
This reverts commit f4747712ad.
2026-09-23 12:22:02 +00:00
ATM Platform f4747712ad feat(P0.9): fase issuer - o issuer passa para athleticmap.com 2026-09-23 12:21:47 +00:00
ATM Platform 5e1bf3a00b feat(P0.9): fase realm - o realm passa a aceitar os dois dominios 2026-09-23 12:14:17 +00:00
deploy 440ade90f5 feat(P0.9): fase HOSTS — os cinco tenants passam a atender os DOIS dominios
Aditiva de proposito: nenhum endereco antigo sai. Quem esta usando
<tenant>.athleticmap.influxdigital.com.br continua entrando, e o cert-manager
passa a emitir tambem o certificado de <tenant>.athleticmap.com.

Foi possivel porque o dono criou o curinga hoje: *.athleticmap.com resolve para
187.77.37.184, conferido com um nome ALEATORIO — demo. ou www. responderiam
mesmo sem curinga, e a conferencia passaria por engano.

9 arquivos, 28 trocas, 317 insercoes e 4 remocoes. As 4 sao as linhas de TLS em
fluxo, reescritas com os dois dominios na mesma lista.

Cada regra de Ingress foi DUPLICADA com os mesmos paths, e nao trocada: uma
regra com host: X so atende X.

`platform/` (ArgoCD e Grafana) fica FORA: mexer no Ingress do ArgoCD no meio de
uma migracao de dominio e perder o instrumento de rollback.

Conferido antes de aplicar: YAML valido em todos os Ingress, e ZERO host sem
entrada de TLS.

O que NAO muda aqui: ATM_ISSUER, ATM_KC_URL e as URLs do Garmin. Ninguem e
deslogado nesta fase.
2026-09-23 11:35:48 +00:00
deploy 80489672b0 fix(plataforma): o initContainer entrega a posse da copia de trabalho
O clone e feito como root e o container principal roda como o usuario app
(uid 999). Sem o chown, a copia de trabalho fica so-leitura para ele, e a etapa
MANIFESTOS_GERADOS falharia ao escrever tenants/<nome> — medido de dentro do pod
logo depois do primeiro deploy: "escrita: NEGADA".

chown, e nao fsGroup: fsGroup ajusta o GRUPO e depende de o diretorio ter
permissao de grupo, o que o git nao garante arquivo a arquivo. Entregar a posse
e explicito e nao depende de umask.
2026-09-22 22:13:27 +00:00
deploy 6ca712c619 feat(plataforma): a etapa MANIFESTOS_GERADOS ganha o molde e a copia de trabalho
Era a primeira etapa do provisionamento e a unica bloqueada por algo MEU, nao
por credencial do dono: o pod nao enxergava o molde nem o repositorio GitOps, e
as tres propriedades ficavam vazias. Falhar fechado, nomeando a propriedade, era
o comportamento certo — o que faltava era o material chegar.

Um initContainer clona o repositorio em /gitops na subida. Dentro dele,
moldes/consolidado e o molde e tenants/<nome> e onde a etapa escreve: UM volume
serve aos dois, e por isso o molde foi para o repositorio GitOps no commit
anterior.

Tres decisoes que valem registro:

- CLONE ANONIMO. O Gitea aceita leitura sem credencial neste repositorio, e
  leitura e tudo o que a etapa 1 precisa. Empurrar e a etapa ARGO_SINCRONIZADO,
  que depende de credencial e continua bloqueada — esta mudanca nao a destrava e
  nao tenta;
- emptyDir, e nao PVC. A copia e descartavel por desenho: se o pod morrer no
  meio de um provisionamento, o que ficou pela metade some junto. Melhor do que
  um clone velho e divergente sobrevivendo entre reinicios;
- a imagem e a do act_runner, que JA esta no no e tem git 2.45.2. Nao ha
  registry aqui, entao construir uma imagem so para ter git custaria mais do que
  reusar esta.

O endereco e o interno (gitea-http.gitea.svc:3000), o mesmo do ApplicationSet.
Depende do 19-netpol-gitea.yaml do commit anterior.
2026-09-22 22:10:39 +00:00
deploy efc9d35f94 feat(plataforma): o provisionamento passa a LER o repositorio GitOps
A etapa MANIFESTOS_GERADOS renderiza o molde para tenants/<nome> numa copia de
trabalho, e o pod obtem essa copia clonando o Gitea na subida. Clonar e leitura.

Escrever continua fora de alcance, de proposito: empurrar no ramo padrao E o
deploy, e depende de uma credencial que ainda nao existe.

O Gitea aceita clone ANONIMO deste repositorio (conferido com git ls-remote sem
credencial), entao a etapa 1 funciona antes de a credencial de escrita existir.

A MESMA armadilha de rede, pela TERCEIRA vez. De dentro do pod, antes desta
politica: HTTP 000, exit 7. O ipBlock 10.43.0.0/16 da deny-cross-tenant cobre o
ClusterIP do Gitea e nao adianta — o k3s avalia DEPOIS do DNAT, e ali o destino
ja e o IP do POD.

Aconteceu com a API do Kubernetes em 20/09, com o sealed-secrets hoje mais cedo,
e agora aqui. E regra deste cluster, nao coincidencia.

Estreita: so o servico-captacao, so o POD do Gitea por rotulo (namespaceSelector
sozinho abriria a 3000 do namespace inteiro, onde tambem vivem o Valkey e o
runner de CI), so a 3000, so saida.
2026-09-22 22:08:45 +00:00
deploy f6aeb233a7 feat(moldes): o molde do tenant novo entra no repositorio GitOps
Ate aqui ele vivia SO no monorepo, e o provisionamento roda DENTRO do cluster —
o pod do servico-captacao nao tinha como enxerga-lo. A etapa MANIFESTOS_GERADOS
falhava por configuracao vazia, e falhar fechado era o comportamento certo; o
que faltava era o molde chegar.

Pondo-o aqui, o pod precisa de UM volume em vez de dois: o mesmo clone do GitOps
serve de molde (moldes/consolidado) e de copia de trabalho (tenants/<nome>).

Os tres marcadores — TENANT, REALM e PLANO — batem com o RenderizadorDeMolde. Os
arquivos NAO sao YAML valido antes de renderizados, e isso e de proposito: um
`{{PLANO}}` literal aplicaria sem reclamar e criaria um tenant cujo plano se
chama "{{PLANO}}", com a barreira negando tudo depois.
2026-09-22 22:07:34 +00:00
deploy 713db06a7b fix(plataforma): o frontend tambem precisava de FQDN, e so ele ficou de fora
Os quatro tenants foram corrigidos mais cedo hoje; o plataforma nao. O defeito
so apareceu agora, e por um motivo que vale registrar: ele e o unico SEM
catch-all /api. Nos outros, uma rota sem linha propria era engolida pelo
backend legado; aqui ela cai no frontend — e e ali que o bug estava esperando.

Medido no log do proprio pod:

  servico-bff could not be resolved (3: Host not found)
  request: "POST /api/plataforma/provisionamentos"

O resolver do nginx nao aplica os search do /etc/resolv.conf, entao nome curto
nao resolve. As cinco variaveis estavam vazias, e toda ausente cai em
ATM_API_URL, que cai no nome curto `servico-bff`.

Aqui nao ha runtime consolidado: os destinos apontam para o BFF, que ja era o
padrao — a diferenca e so o FQDN.

Achado ao conferir o PLATAFORMA_ADMIN_TOKEN recem-ligado: a consulta de estado
devolvia 502 em vez de 401, e o 502 era isto.
2026-09-22 21:28:16 +00:00
deploy 4024c27f1b feat(plataforma): o captacao passa a ler os dois tokens
Vai DEPOIS do commit que selou os Secrets, e nao junto: secretKeyRef de Secret
ausente impede o pod de subir. Os dois ja materializaram no cluster.

PLATAFORMA_WEBHOOK_TOKEN destrava a etapa que recebia o aviso de assinatura e
recusava tudo por falta de configuracao. Falta CADASTRAR o mesmo valor no painel
do Asaas, na conta da Athletic Map — quem for cadastrar le uma vez com:

  kubectl -n plataforma-prod get secret plataforma-webhook-token \
    -o jsonpath='{.data.token}' | base64 -d

PLATAFORMA_ADMIN_TOKEN destrava a consulta de estado do provisionamento, que e
interina e vive no cabecalho x-atm-admin-token.
2026-09-22 21:26:14 +00:00
deploy 1bc58f2927 fix(plataforma): os dois tokens regerados, porque os primeiros vazaram
Ao conferir que os Secrets tinham materializado, o comando imprimiu o campo
`.data` inteiro — ou seja, parte do valor em base64 dos dois tokens foi parar na
conversa. Curto, e o bastante para nao dar por confiavel.

Regerados. Custo zero: nada os referenciava ainda (nenhum Deployment, e o
webhook nao estava cadastrado no Asaas), entao nao houve janela de uso.

A licao, que ja valia para senha e vale igual para Secret: conferir existencia
com `-o name`, e nunca com `-o custom-columns=...:.data` nem `-o yaml`. O que se
quer saber e SE existe, nao O QUE e.
2026-09-22 21:25:43 +00:00
deploy 9f3360038a feat(plataforma): os dois tokens que sao NOSSOS, selados
PLATAFORMA_ADMIN_TOKEN e PLATAFORMA_WEBHOOK_TOKEN. Os dois sao gerados aqui, ao
contrario da api-key do Asaas, que vem do painel do provedor.

O valor nasceu, foi selado e morreu dentro de um unico shell no servidor: nao
foi ecoado, nao foi para arquivo, nao entrou no historico e nao apareceu em ps.
O que se commita e o cifrado, que e publico por natureza.

Vao SOZINHOS neste commit, sem a referencia no Deployment: secretKeyRef de
Secret ausente impede o pod de subir. Primeiro o Secret materializa, depois o
env aponta para ele.

O webhook-token precisa ser CADASTRADO no painel do Asaas com o mesmo valor. Ele
pode ser lido uma vez, por quem for cadastrar:

  kubectl -n plataforma-prod get secret plataforma-webhook-token \
    -o jsonpath='{.data.token}' | base64 -d
2026-09-22 21:24:56 +00:00
deploy 4c338c0eda feat(piloto,acme,escolinha): o Ingress simplificado, como no demo (P4.6)
Mesma mudanca do commit anterior, agora nos tres restantes. O demo foi primeiro
e ficou conferido de fora: os 13 contextos em 200, /bff em 200, /inicio e
/lp-escolinhas em 200, e — o que mais importava — /api/nao-mapeado continua
devolvendo 401, como antes. O comportamento visivel nao mudou.

Catorze linhas saem de cada um. O destino do /api passa de backend (o legado)
para frontend-spa; a decisao "401 ou 404" segue aberta e intacta.
2026-09-22 19:54:40 +00:00
deploy d81f45b62c feat(demo): o Ingress para de rotear /bff e os treze /api/<contexto> (P4.6)
Catorze linhas saem. Quem conhece a topologia interna passa a ser o
frontend/nginx.conf.template, que viaja junto com a imagem — antes, cada
mudanca de topologia obrigava a editar o Ingress de todos os tenants.

O destino do /api mudou de backend (o legado) para frontend-spa. O que o
visitante ve NAO muda: caminho nao mapeado continua recebendo 401 — antes do
backend legado, agora do BFF, para onde o nginx manda o /api que sobra. A
decisao "401 ou 404" segue aberta e intacta; isto so tira o legado do caminho
do trafego.

Pre-condicao resolvida hoje: as cinco variaveis de destino do nginx estavam
vazias e, mesmo apontadas, precisavam de FQDN (o resolver do nginx nao aplica os
search do resolv.conf). Sem isso, esta mudanca derrubaria os treze contextos e o
/bff de uma vez.

ORDEM: /api/public e /api/public/webhooks/asaas vivem no
96-ingress-garmin-public.yaml e tem prefixo mais longo, entao vencem o /api — o
Traefik ordena por tamanho.

Primeiro tenant. Os outros tres so depois de conferido.
2026-09-22 19:52:26 +00:00