Runbook Operacional
Introdução ao documento
Este runbook consolida os procedimentos operacionais que podem ser sustentados por artefatos versionados do repositório: scripts npm, Dockerfile, chart Helm, workflows GitHub Actions e rotas de healthcheck. O objetivo é reduzir tempo de diagnóstico em execução local, build, deploy e incidentes de integração.
Fato observado:
- O repositório versiona scripts de execução/teste/build em
package.json. Evidências:package.json:5-22. - O repositório versiona build containerizado em
Dockerfile. Evidências:Dockerfile:1-78. - O repositório versiona deploy por Helm em GitHub Actions. Evidências:
.github/workflows/ci-cd-pipeline.yml:13-124.
Versionamento
- Documento atualizado em
2026-03-20. - Revisar este runbook sempre que mudarem scripts npm, pipeline CI/CD, Dockerfile, chart Helm ou rotas
/api/health,/api/liveness,/api/readiness. - A aplicação versionada no repositório está em
0.1.4.
Fato observado:
- A versão do pacote é
0.1.4. Evidências:package.json:2-3. - O endpoint de saúde expõe
process.env.NEXT_APP_VERSION, e o container aceitaARG NEXT_APP_VERSIONno build. Evidências:src/app/api/health/route.ts:6-19,Dockerfile:23-35.
Referencial teórico
Este documento usa como base operacional os padrões efetivamente adotados no repositório: ciclo de vida Next.js via scripts npm, build multi-stage em Docker, deploy declarativo por Helm e probes HTTP de liveness/readiness/health.
Fato observado:
- O ciclo principal de execução é
next dev,next buildenext start. Evidências:package.json:6-12. - O deploy é feito com
helm upgrade --install. Evidências:.github/workflows/ci-cd-pipeline.yml:69-74,.github/workflows/ci-cd-pipeline.yml:95-99,.github/workflows/ci-cd-pipeline.yml:119-124. - O chart expõe probes HTTP de liveness e readiness. Evidências:
helm/templates/deployment.yaml:53-64.
Execução local
Pré-requisitos operacionais observados
Fato observado:
- O projeto depende de Node.js e npm. Evidências:
package.json:5-22. - O build local executa
prebuild, que chamanode updateEnvVersion.jsantes denext build. Evidências:package.json:6-10. - Fora de CI,
updateEnvVersion.jslê e sobrescreve.env. Se.envnão existir, o processo encerra com erro. Evidências:updateEnvVersion.js:4-5,updateEnvVersion.js:10-13,updateEnvVersion.js:19-23,updateEnvVersion.js:41-48. - Existe arquivo de referência de variáveis em
.env.example. Evidências:.env.example:1-26.
Inferência operacional:
- Antes de rodar
npm run buildlocalmente, convém garantir que exista um.envderivado de.env.example, porque o prebuild não usa.env.examplediretamente e falha se o.envestiver ausente.
Sequência mínima para subir localmente
npm ci
npm run dev
Validação rápida após o bootstrap:
curl -s http://localhost:3000/api/health
curl -s http://localhost:3000/api/liveness
curl -s http://localhost:3000/api/readiness
Modo E2E local:
npm run dev:e2e
Build e start em modo produção local:
npm run build
npm run start
Fato observado:
- Há script
dev. Evidências:package.json:7. - Há script
dev:e2ecomNEXT_PUBLIC_E2E_TEST_MODE=true. Evidências:package.json:8. - Há scripts
buildestart. Evidências:package.json:9-10. - Os endpoints
/api/health,/api/livenesse/api/readinessexistem. Evidências:src/app/api/health/route.ts:3-31,src/app/api/liveness/route.ts:3-11,src/app/api/readiness/route.ts:3-23. - O workflow de Cypress usa
npm ci,npm run buildenpm run start:e2e -- -p 3000. Evidências:.github/workflows/cypress.yml:29-30,.github/workflows/cypress.yml:52-62.
Variáveis mínimas observadas para execução
Fato observado:
.env.exampletrazNEXTAUTH_URL,NEXTAUTH_SECRET,API_URL,DHEDALOS_PRIVACY_POLICY,SCHEDULE_URL,SCHEDULE_APP_KEY,JITSI_SERVER_URL,DATADOG_*,METADATA_*eANALYTICS_GOOGLE_ID. Evidências:.env.example:3-26.- O chart Helm injeta
NEXTAUTH_URL,NEXTAUTH_SECRET,SCHEDULE_APP_KEY,SCHEDULE_URL,API_URL,NEXT_PUBLIC_API_URL,QUIZ_API_URL,NEXT_PUBLIC_QUIZ_API_URL,NEXT_DHEDALOS_PRIVACY_POLICY,NEXT_DATADOG_*,NOVU_*. Evidências:helm/templates/secret.yaml:11-30.
Pendência operacional relevante:
- Há divergência entre nomes de variáveis do exemplo local (
DHEDALOS_PRIVACY_POLICY,DATADOG_*) e nomes lidos por/api/envs(NEXT_DHEDALOS_PRIVACY_POLICY,NEXT_DATADOG_*). Evidências:.env.example:6,.env.example:16-19,src/app/api/envs/route.ts:8-24,helm/templates/secret.yaml:24-28.
Deploy
Fluxo versionado
Fato observado:
- O job
buildexecuta em todas as branches, PRs e releases publicadas. Evidências:.github/workflows/ci-cd-pipeline.yml:3-16. - O build publica imagem Docker com tag baseada no nome normalizado da branch e também com
github.sha. Evidências:.github/workflows/ci-cd-pipeline.yml:22-29,.github/workflows/ci-cd-pipeline.yml:41-49. - A branch
developaciona deploy no namespacepiloto-dhedalos-ecosystemno clusteroke-we-002. Evidências:.github/workflows/ci-cd-pipeline.yml:51-74. - A branch
mainaciona deploy nos namespacesessencia-ecosystemedhedalos-ecosystemno clusteroke-we-001. Evidências:.github/workflows/ci-cd-pipeline.yml:76-124.
Comando de deploy observado
helm dependency build helm
helm upgrade --install --create-namespace -n <namespace> <release> helm \
-f kubernetes/<cluster>/<namespace>/values.yaml \
--set image.repository=<registry>/<repository>/<app> \
--set image.tag=<git-sha>
Fato observado:
- Este é o padrão exato usado nos três jobs de deploy. Evidências:
.github/workflows/ci-cd-pipeline.yml:69-74,.github/workflows/ci-cd-pipeline.yml:95-99,.github/workflows/ci-cd-pipeline.yml:119-124. - O chart publica a aplicação em
containerPort: 3000, comservice.targetPort: 3000eservice.port: 80. Evidências:helm/templates/deployment.yaml:41-64,helm/values.yaml:29-32.
Rollback
Fato observado:
- O repositório não contém job, script npm ou documento dedicado de rollback. Evidências:
.github/workflows/ci-cd-pipeline.yml:1-124,package.json:5-22. - O deploy Helm é parametrizado apenas por
image.repositoryeimage.tag. Evidências:.github/workflows/ci-cd-pipeline.yml:72-74,.github/workflows/ci-cd-pipeline.yml:97-99,.github/workflows/ci-cd-pipeline.yml:122-124,helm/templates/deployment.yaml:39-40.
Inferência operacional:
- O rollback viável a partir do que está versionado é repetir o mesmo
helm upgrade --installdo ambiente afetado, apontando--set image.tag=<sha_anterior_estável>. - A escolha do
shaestável anterior depende do histórico externo do registry ou do GitHub Actions; essa origem não está documentada no repositório.
Comando base de rollback inferido:
helm dependency build helm
helm upgrade --install --create-namespace -n <namespace> <release> helm \
-f kubernetes/<cluster>/<namespace>/values.yaml \
--set image.repository=<registry>/<repository>/<app> \
--set image.tag=<sha-anterior-estavel>
Comandos úteis
| Comando | Uso | Natureza | Evidências |
|---|---|---|---|
npm ci | Instalar dependências de forma reprodutível | Fato observado | .github/workflows/cypress.yml:29-30, Dockerfile:11-15 |
npm run dev | Subir app em desenvolvimento | Fato observado | package.json:7 |
npm run dev:e2e | Subir app em modo E2E com mocks | Fato observado | package.json:8 |
npm run build | Gerar build Next.js | Fato observado | package.json:6-10, Dockerfile:23-35 |
npm run start | Subir build em produção local | Fato observado | package.json:10 |
npm run start:e2e -- -p 3000 | Subir build em modo E2E | Fato observado | package.json:11, .github/workflows/cypress.yml:58-62 |
npm test | Executar testes Jest | Fato observado | package.json:15 |
npm run lint | Executar lint do Next.js | Fato observado | package.json:12 |
npm run prettier | Conferir formatação em ./src | Fato observado | package.json:13 |
npm run storybook | Subir Storybook | Fato observado | package.json:17 |
curl -s http://localhost:3000/api/health | Validar health detalhado | Fato observado | src/app/api/health/route.ts:3-31, Dockerfile:72-74 |
curl -s http://localhost:3000/api/liveness | Validar resposta do processo | Fato observado | src/app/api/liveness/route.ts:3-11, helm/templates/deployment.yaml:53-58 |
curl -s http://localhost:3000/api/readiness | Validar prontidão para tráfego | Fato observado | src/app/api/readiness/route.ts:3-23, helm/templates/deployment.yaml:59-64 |
helm dependency build helm | Resolver dependências do chart antes de deploy | Fato observado | .github/workflows/ci-cd-pipeline.yml:71, .github/workflows/ci-cd-pipeline.yml:96, .github/workflows/ci-cd-pipeline.yml:121 |
Troubleshooting dos 5 incidentes mais prováveis
1. Build local falha antes do next build
Sintoma provável:
- erro de leitura/escrita do
.envno prebuild.
Checagens:
- Verificar se existe arquivo
.envno diretório raiz. - Confirmar se
npm run buildestá chamandoprebuild. - Se necessário, comparar chaves mínimas com
.env.example.
Ação inicial:
- Criar ou corrigir
.envantes do build. - Reexecutar
npm run build.
Fato observado:
prebuildexecutanode updateEnvVersion.js. Evidências:package.json:6.- Fora de CI,
updateEnvVersion.jslê e grava.env, encerrando com erro em falhas de I/O. Evidências:updateEnvVersion.js:10-13,updateEnvVersion.js:19-23,updateEnvVersion.js:41-48.
2. Usuário não consegue entrar ou é redirecionado para /
Sintoma provável:
- tela protegida redireciona para login ou login retorna
null.
Checagens:
- Validar
NEXTAUTH_URLeNEXTAUTH_SECRET. - Confirmar disponibilidade do backend WordPress em
API_URL. - Inspecionar falha no
POST /api/jwt-auth/v1/tokenchamado peloCredentialsProvider.
Ação inicial:
- Revisar envs de autenticação.
- Testar a obtenção de sessão e repetir o login.
- Confirmar se o backend remoto de autenticação está acessível.
Fato observado:
- O protected layout redireciona para
/quando não há sessão. Evidências:src/app/(protected-routes)/layout.tsx:21-25. - O login usa
fetch(${baseUrl}/api/jwt-auth/v1/token). Evidências:src/utils/authOptions.ts:59-69. NEXTAUTH_URLeNEXTAUTH_SECRETaparecem tanto no.env.examplequanto no secret Helm. Evidências:.env.example:3-4,helm/templates/secret.yaml:13-18.
3. Agendamento retorna 401/500 ou não mostra horários
Sintoma provável:
- erro em
/api/schedule/slotou ausência de horários disponíveis.
Checagens:
- Verificar se o usuário está autenticado.
- Confirmar se o payload contém
class_idedate. - Conferir
SCHEDULE_URLeSCHEDULE_APP_KEY. - Confirmar se a turma possui facilitador resolvido por
getFacilitatorByClass.
Ação inicial:
- Reexecutar a chamada com payload válido.
- Validar credenciais/envs da agenda.
- Verificar se a turma retornada pelo backend possui facilitador.
Fato observado:
- A rota exige sessão e retorna
401sem usuário autenticado. Evidências:src/app/api/schedule/slot/route.ts:7-19. - A rota retorna
401seclass_idoudateestiverem ausentes. Evidências:src/app/api/schedule/slot/route.ts:21-32. - A rota retorna
401se a turma não tiver facilitador. Evidências:src/app/api/schedule/slot/route.ts:34-48. SCHEDULE_URLeSCHEDULE_APP_KEYexistem nos envs observados. Evidências:.env.example:8-9,helm/templates/secret.yaml:12,helm/templates/secret.yaml:19.
4. Upload, listagem ou download de submissões falham
Sintoma provável:
- erro em
POST /api/submissions,GET /api/submissionsouGET /api/submissions/files/....
Checagens:
- Validar
SUBMISSIONS_URL,SUBMISSIONS_APP_KEYeSUBMISSIONS_STORAGE_URL. - Confirmar se o header
Authorizationfoi recebido no upload. - Para download, confirmar se
SUBMISSIONS_STORAGE_URLestá configurada e se o arquivo existe no storage remoto.
Ação inicial:
- Testar
GET /api/submissionscom filtros mínimos. - Refazer upload validando token e conteúdo multipart.
- Testar o caminho completo de arquivo no proxy
/api/submissions/files/....
Fato observado:
POST /api/submissionsenviaAuthorizationrecebido ouSUBMISSIONS_APP_KEY. Evidências:src/app/api/submissions/route.ts:7-19.GET /api/submissionssempre usaSUBMISSIONS_APP_KEYno proxy. Evidências:src/app/api/submissions/route.ts:41-83.- O download de arquivo falha com
500seSUBMISSIONS_STORAGE_URLnão estiver configurada. Evidências:src/app/api/submissions/files/[...path]/route.ts:17-24. - O proxy de arquivo devolve
404ou status remoto quando o storage não encontra o objeto. Evidências:src/app/api/submissions/files/[...path]/route.ts:26-35. SUBMISSIONS_URLeSUBMISSIONS_APP_KEYsão lidos em constantes globais. Evidências:src/utils/consts.ts:10-11.
5. Jitsi, Blip, Quiz ou telemetria de cliente não carregam
Sintoma provável:
- sala não abre com servidor esperado, chat Blip não inicializa, quiz não responde ou Datadog não sobe.
Checagens:
- Testar
GET /api/jitsi/config,GET /api/blip/configeGET /api/envs. - Validar
JITSI_SERVER_URL,BLIP_APP_KEY,QUIZ_API_URLeNEXT_DATADOG_*. - Verificar no navegador se houve erro na chamada de
/api/envs.
Ação inicial:
- Corrigir as envs ausentes.
- Revalidar os endpoints de configuração.
- Recarregar a aplicação e revisar o console do navegador.
Fato observado:
/api/jitsi/configretornaprocess.env.JITSI_SERVER_URLe faz fallback parameet.jit.si. Evidências:src/app/api/jitsi/config/route.ts:3-18./api/blip/configretorna500quandoBLIP_APP_KEYnão está definida. Evidências:src/app/api/blip/config/route.ts:3-9./api/envsexpõeQUIZ_API_URLeNEXT_DATADOG_*ao cliente. Evidências:src/app/api/envs/route.ts:6-26.- O bootstrap do Datadog depende de sucesso em
fetch('/api/envs'). Evidências:src/app/start/DatadogStart.tsx:11-47.
Pendências
- Não existe rollback automatizado versionado no repositório. Evidências:
.github/workflows/ci-cd-pipeline.yml:1-124,package.json:5-22. - Há divergência entre a versão escrita localmente pelo prebuild (
NEXT_PUBLIC_APP_VERSION) e a versão lida pelos endpoints de runtime (NEXT_APP_VERSION). Evidências:updateEnvVersion.js:10-16,src/app/api/health/route.ts:10,src/app/api/envs/route.ts:8,Dockerfile:23-27. - Há divergência entre nomes de envs de Datadog/privacidade em
.env.examplee nomes lidos em/api/envs. Evidências:.env.example:6,.env.example:16-19,src/app/api/envs/route.ts:8-24,helm/templates/secret.yaml:24-28. Dockerfile.awsreferencianpm run startAws, mas esse script não existe empackage.json. Evidências:Dockerfile.aws:23,package.json:5-22.