# SPA Angular (shell OIDC + admin de catalogos + cadastro de Atleta) consumindo # o BFF. Substitui o stub estatico nginx/configMap. Roteado em / no ingress. --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend-spa namespace: acme-prod labels: app: frontend-spa athleticmap.io/contexto: frontend spec: replicas: 1 selector: { matchLabels: { app: frontend-spa } } template: metadata: labels: app: frontend-spa athleticmap.io/contexto: frontend athleticmap.io/bff-aqui: "true" spec: containers: - name: frontend-spa image: docker.io/library/frontend-spa:2.131-grupos-downloads-110 imagePullPolicy: Never ports: [{ containerPort: 80 }] env: - { name: ATM_KC_URL, value: "https://auth.athleticmap.com" } - { name: ATM_REALM, value: "athleticmap-3" } - { name: ATM_CLIENT, value: "spa" } - { name: ATM_TENANT, value: "acme" } - { name: ATM_PLANO, value: "prata" } # P4.6 — o roteamento interno do nginx, por GRUPO de contextos. # # Medido em 2026-09-22: as tres estavam VAZIAS nos quatro tenants, e # `render-config.sh` faz toda variavel ausente cair em ATM_API_URL, que # por sua vez cai em `http://servico-bff`. Ou seja: o nginx mandaria # `/api/cadastro` para o BFF, que responde **401** em vez da resposta do # contexto. Hoje nada quebra porque o INGRESS atende antes, com uma linha # por contexto — e e justamente essas linhas que P4.6 quer remover. # # Definidas aqui, a remocao do Ingress deixa de ser mudanca arriscada e # vira mudanca sem efeito visivel. Enquanto o Ingress existir, estas # variaveis nao mudam nada: o trafego nem chega a este nginx. - { name: ATM_API_CORE_URL, value: "http://runtime-core.acme-prod.svc.cluster.local" } - { name: ATM_API_OPERACAO_URL, value: "http://runtime-operacao.acme-prod.svc.cluster.local" } - { name: ATM_API_SAUDE_URL, value: "http://runtime-saude.acme-prod.svc.cluster.local" } # P4.6 fechado 2026-09-26: o BFF e o SEGUNDO CONTAINER deste # mesmo pod (ver o container 'servico-bff' abaixo) — sem # Deployment proprio. `127.0.0.1` porque os dois containers # do pod compartilham a rede. O Service `servico-bff` continua # existindo, so com o `selector` mudado para o rotulo # `athleticmap.io/bff-aqui` deste pod — quem aponta direto para ele # (o webhook do Garmin do escolinha, e o Prometheus) nao # precisou de nenhuma edicao. - { name: ATM_BFF_URL, value: "http://127.0.0.1:8083" } - { name: ATM_API_URL, value: "http://servico-bff.acme-prod.svc.cluster.local" } resources: requests: { cpu: 50m, memory: 64Mi } limits: { cpu: 200m, memory: 128Mi } volumeMounts: - name: publico mountPath: /usr/share/nginx/html/publico readOnly: true readinessProbe: httpGet: { path: /, port: 80 } initialDelaySeconds: 5 periodSeconds: 10 - name: servico-bff image: docker.io/library/servico-bff:2.31-dono-metricas-grupos imagePullPolicy: Never ports: [{ containerPort: 8083 }] env: - { name: ATM_CONFIG_URL, value: "http://servico-configuracao" } - { name: ATM_CADASTRO_URL, value: "http://servico-cadastro" } - { name: ATM_ORGANIZACAO_URL, value: "http://servico-organizacao" } - { name: ATM_PLANEJAMENTO_URL, value: "http://servico-planejamento" } - { name: ATM_CAMPEONATO_URL, value: "http://servico-campeonato" } - { name: ATM_SAUDE_URL, value: "http://servico-saude" } - { name: ATM_FINANCEIRO_URL, value: "http://servico-financeiro" } - { name: ATM_DOCUMENTOS_URL, value: "http://servico-documentos" } - { name: ATM_ADMINISTRATIVO_URL, value: "http://servico-administrativo" } - { name: ATM_ASSISTENCIA_SOCIAL_URL, value: "http://servico-assistencia-social" } - { name: ATM_PEDAGOGICO_URL, value: "http://servico-pedagogico" } - { name: ATM_NUTRICAO_URL, value: "http://servico-nutricao" } - { name: ATM_AGENDA_URL, value: "http://servico-agenda" } - { name: ATM_JWK_SET_URI, value: "http://keycloak.plataforma-prod.svc:8080/realms/athleticmap-3/protocol/openid-connect/certs" } - { name: ATM_ISSUER, value: "https://auth.athleticmap.com/realms/athleticmap-3" } - name: ATM_CONSENTIMENTO_SEGREDO valueFrom: { secretKeyRef: { name: consentimento-selo, key: segredo } } - { name: ATM_TENANT, value: "acme" } - { name: ATM_PLANO, value: "prata" } - { name: ATM_TRANSCRICAO_URL, value: "http://servico-voz.plataforma-prod.svc:8091" } # servico de voz (05/10/2026) # App dos pais e aparelhos (06/10/2026): token de MAQUINA do client operacao; o token do responsavel nunca desce. - { name: ATM_MAQUINA_TOKEN_URL, value: "http://keycloak.plataforma-prod.svc:8080/realms/athleticmap-3/protocol/openid-connect/token" } - name: ATM_MAQUINA_SEGREDO valueFrom: secretKeyRef: { name: operacao-credentials, key: client-secret, optional: true } # Push (FCM): vazio = desligado, ate existir o projeto Firebase (Secret fcm-credenciais/json + ATM_FCM_PROJETO). - name: ATM_FCM_CREDENCIAIS valueFrom: secretKeyRef: { name: fcm-credenciais, key: json, optional: true } - { name: ATM_FCM_PROJETO, value: "" } - { name: GARMIN_FRONTEND_REDIRECT, value: "https://acme.athleticmap.com/integracoes/garmin" } resources: requests: { cpu: 50m, memory: 256Mi } limits: { cpu: 500m, memory: 512Mi } readinessProbe: httpGet: { path: /bff/health, port: 8083 } initialDelaySeconds: 20 periodSeconds: 10 failureThreshold: 30 livenessProbe: httpGet: { path: /actuator/health/liveness, port: 8083 } initialDelaySeconds: 50 periodSeconds: 20 failureThreshold: 6 volumes: - name: publico projected: sources: - configMap: name: frontend-publico-texto items: - { key: "_estilo.css", path: "_estilo.css" } - { key: "consentimento.js", path: "consentimento.js" } - { key: "contratar.css", path: "contratar.css" } - { key: "contratar.html", path: "contratar.html" } - { key: "contratar.js", path: "contratar.js" } - { key: "convite.css", path: "convite.css" } - { key: "convite.html", path: "convite.html" } - { key: "convite.js", path: "convite.js" } - { key: "desafio.js", path: "desafio.js" } - { key: "fontes--fontes.css", path: "fontes/fontes.css" } - { key: "lp-escolinhas.css", path: "lp-escolinhas.css" } - { key: "lp-escolinhas.html", path: "lp-escolinhas.html" } - { key: "lp-escolinhas.js", path: "lp-escolinhas.js" } - { key: "minha-conta.css", path: "minha-conta.css" } - { key: "minha-conta.html", path: "minha-conta.html" } - { key: "minha-conta.js", path: "minha-conta.js" } - { key: "painel.css", path: "painel.css" } - { key: "painel.html", path: "painel.html" } - { key: "painel.js", path: "painel.js" } - { key: "planos-modulos.json", path: "planos-modulos.json" } - { key: "preparando.html", path: "preparando.html" } - { key: "preparando.js", path: "preparando.js" } - { key: "privacidade.html", path: "privacidade.html" } - { key: "termos.html", path: "termos.html" } - configMap: name: frontend-publico-binario items: - { key: "fontes--Barlow-400-latin-ext.woff2", path: "fontes/Barlow-400-latin-ext.woff2" } - { key: "fontes--Barlow-400-latin.woff2", path: "fontes/Barlow-400-latin.woff2" } - { key: "fontes--Barlow-500-latin-ext.woff2", path: "fontes/Barlow-500-latin-ext.woff2" } - { key: "fontes--Barlow-500-latin.woff2", path: "fontes/Barlow-500-latin.woff2" } - { key: "fontes--Barlow-600-latin-ext.woff2", path: "fontes/Barlow-600-latin-ext.woff2" } - { key: "fontes--Barlow-600-latin.woff2", path: "fontes/Barlow-600-latin.woff2" } - { key: "fontes--Barlow-700-latin-ext.woff2", path: "fontes/Barlow-700-latin-ext.woff2" } - { key: "fontes--Barlow-700-latin.woff2", path: "fontes/Barlow-700-latin.woff2" } - { key: "fontes--IBMPlexMono-500-latin-ext.woff2", path: "fontes/IBMPlexMono-500-latin-ext.woff2" } - { key: "fontes--IBMPlexMono-500-latin.woff2", path: "fontes/IBMPlexMono-500-latin.woff2" } - { key: "fontes--Poppins-500-latin-ext.woff2", path: "fontes/Poppins-500-latin-ext.woff2" } - { key: "fontes--Poppins-500-latin.woff2", path: "fontes/Poppins-500-latin.woff2" } - { key: "fontes--Poppins-600-latin-ext.woff2", path: "fontes/Poppins-600-latin-ext.woff2" } - { key: "fontes--Poppins-600-latin.woff2", path: "fontes/Poppins-600-latin.woff2" } - { key: "fontes--Poppins-700-latin-ext.woff2", path: "fontes/Poppins-700-latin-ext.woff2" } - { key: "fontes--Poppins-700-latin.woff2", path: "fontes/Poppins-700-latin.woff2" } - { key: "fontes--Poppins-800-latin-ext.woff2", path: "fontes/Poppins-800-latin-ext.woff2" } - { key: "fontes--Poppins-800-latin.woff2", path: "fontes/Poppins-800-latin.woff2" } - { key: "img--hero-escolinha.jpg", path: "img/hero-escolinha.jpg" } - { key: "img--logo-athletic-map.png", path: "img/logo-athletic-map.png" } - { key: "produto-dashboard.webp", path: "produto-dashboard.webp" } --- apiVersion: v1 kind: Service metadata: name: frontend-spa namespace: acme-prod labels: app: frontend-spa spec: selector: { app: frontend-spa } ports: [{ name: http, port: 80, targetPort: 80 }]