Pular para o conteúdo principal

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 aceita ARG NEXT_APP_VERSION no 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 build e next 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 chama node updateEnvVersion.js antes de next build. Evidências: package.json:6-10.
  • Fora de CI, updateEnvVersion.js lê e sobrescreve .env. Se .env nã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 build localmente, convém garantir que exista um .env derivado de .env.example, porque o prebuild não usa .env.example diretamente e falha se o .env estiver 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:e2e com NEXT_PUBLIC_E2E_TEST_MODE=true. Evidências: package.json:8.
  • Há scripts build e start. Evidências: package.json:9-10.
  • Os endpoints /api/health, /api/liveness e /api/readiness existem. 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 build e npm 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.example traz NEXTAUTH_URL, NEXTAUTH_SECRET, API_URL, DHEDALOS_PRIVACY_POLICY, SCHEDULE_URL, SCHEDULE_APP_KEY, JITSI_SERVER_URL, DATADOG_*, METADATA_* e ANALYTICS_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 build executa 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 develop aciona deploy no namespace piloto-dhedalos-ecosystem no cluster oke-we-002. Evidências: .github/workflows/ci-cd-pipeline.yml:51-74.
  • A branch main aciona deploy nos namespaces essencia-ecosystem e dhedalos-ecosystem no cluster oke-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, com service.targetPort: 3000 e service.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.repository e image.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 --install do ambiente afetado, apontando --set image.tag=<sha_anterior_estável>.
  • A escolha do sha está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

ComandoUsoNaturezaEvidências
npm ciInstalar dependências de forma reprodutívelFato observado.github/workflows/cypress.yml:29-30, Dockerfile:11-15
npm run devSubir app em desenvolvimentoFato observadopackage.json:7
npm run dev:e2eSubir app em modo E2E com mocksFato observadopackage.json:8
npm run buildGerar build Next.jsFato observadopackage.json:6-10, Dockerfile:23-35
npm run startSubir build em produção localFato observadopackage.json:10
npm run start:e2e -- -p 3000Subir build em modo E2EFato observadopackage.json:11, .github/workflows/cypress.yml:58-62
npm testExecutar testes JestFato observadopackage.json:15
npm run lintExecutar lint do Next.jsFato observadopackage.json:12
npm run prettierConferir formatação em ./srcFato observadopackage.json:13
npm run storybookSubir StorybookFato observadopackage.json:17
curl -s http://localhost:3000/api/healthValidar health detalhadoFato observadosrc/app/api/health/route.ts:3-31, Dockerfile:72-74
curl -s http://localhost:3000/api/livenessValidar resposta do processoFato observadosrc/app/api/liveness/route.ts:3-11, helm/templates/deployment.yaml:53-58
curl -s http://localhost:3000/api/readinessValidar prontidão para tráfegoFato observadosrc/app/api/readiness/route.ts:3-23, helm/templates/deployment.yaml:59-64
helm dependency build helmResolver dependências do chart antes de deployFato 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 .env no prebuild.

Checagens:

  1. Verificar se existe arquivo .env no diretório raiz.
  2. Confirmar se npm run build está chamando prebuild.
  3. Se necessário, comparar chaves mínimas com .env.example.

Ação inicial:

  1. Criar ou corrigir .env antes do build.
  2. Reexecutar npm run build.

Fato observado:

  • prebuild executa node updateEnvVersion.js. Evidências: package.json:6.
  • Fora de CI, updateEnvVersion.js lê 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:

  1. Validar NEXTAUTH_URL e NEXTAUTH_SECRET.
  2. Confirmar disponibilidade do backend WordPress em API_URL.
  3. Inspecionar falha no POST /api/jwt-auth/v1/token chamado pelo CredentialsProvider.

Ação inicial:

  1. Revisar envs de autenticação.
  2. Testar a obtenção de sessão e repetir o login.
  3. 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_URL e NEXTAUTH_SECRET aparecem tanto no .env.example quanto 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/slot ou ausência de horários disponíveis.

Checagens:

  1. Verificar se o usuário está autenticado.
  2. Confirmar se o payload contém class_id e date.
  3. Conferir SCHEDULE_URL e SCHEDULE_APP_KEY.
  4. Confirmar se a turma possui facilitador resolvido por getFacilitatorByClass.

Ação inicial:

  1. Reexecutar a chamada com payload válido.
  2. Validar credenciais/envs da agenda.
  3. Verificar se a turma retornada pelo backend possui facilitador.

Fato observado:

  • A rota exige sessão e retorna 401 sem usuário autenticado. Evidências: src/app/api/schedule/slot/route.ts:7-19.
  • A rota retorna 401 se class_id ou date estiverem ausentes. Evidências: src/app/api/schedule/slot/route.ts:21-32.
  • A rota retorna 401 se a turma não tiver facilitador. Evidências: src/app/api/schedule/slot/route.ts:34-48.
  • SCHEDULE_URL e SCHEDULE_APP_KEY existem 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/submissions ou GET /api/submissions/files/....

Checagens:

  1. Validar SUBMISSIONS_URL, SUBMISSIONS_APP_KEY e SUBMISSIONS_STORAGE_URL.
  2. Confirmar se o header Authorization foi recebido no upload.
  3. Para download, confirmar se SUBMISSIONS_STORAGE_URL está configurada e se o arquivo existe no storage remoto.

Ação inicial:

  1. Testar GET /api/submissions com filtros mínimos.
  2. Refazer upload validando token e conteúdo multipart.
  3. Testar o caminho completo de arquivo no proxy /api/submissions/files/....

Fato observado:

  • POST /api/submissions envia Authorization recebido ou SUBMISSIONS_APP_KEY. Evidências: src/app/api/submissions/route.ts:7-19.
  • GET /api/submissions sempre usa SUBMISSIONS_APP_KEY no proxy. Evidências: src/app/api/submissions/route.ts:41-83.
  • O download de arquivo falha com 500 se SUBMISSIONS_STORAGE_URL não estiver configurada. Evidências: src/app/api/submissions/files/[...path]/route.ts:17-24.
  • O proxy de arquivo devolve 404 ou status remoto quando o storage não encontra o objeto. Evidências: src/app/api/submissions/files/[...path]/route.ts:26-35.
  • SUBMISSIONS_URL e SUBMISSIONS_APP_KEY sã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:

  1. Testar GET /api/jitsi/config, GET /api/blip/config e GET /api/envs.
  2. Validar JITSI_SERVER_URL, BLIP_APP_KEY, QUIZ_API_URL e NEXT_DATADOG_*.
  3. Verificar no navegador se houve erro na chamada de /api/envs.

Ação inicial:

  1. Corrigir as envs ausentes.
  2. Revalidar os endpoints de configuração.
  3. Recarregar a aplicação e revisar o console do navegador.

Fato observado:

  • /api/jitsi/config retorna process.env.JITSI_SERVER_URL e faz fallback para meet.jit.si. Evidências: src/app/api/jitsi/config/route.ts:3-18.
  • /api/blip/config retorna 500 quando BLIP_APP_KEY não está definida. Evidências: src/app/api/blip/config/route.ts:3-9.
  • /api/envs expõe QUIZ_API_URL e NEXT_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.example e 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.aws referencia npm run startAws, mas esse script não existe em package.json. Evidências: Dockerfile.aws:23, package.json:5-22.