Commit Graph

450 Commits

Author SHA1 Message Date
provisionamento Athletic Map 71f6822e2a feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste-2
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:40:28 +00:00
provisionamento Athletic Map 264a2dcdb6 feat(plataforma): PgBouncer passa a servir o tenant escolinha-de-teste-2
Escrito pela etapa BANCO_CRIADO do provisionamento.
2026-09-24 21:40:11 +00:00
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