Skip to content

Fase 9: smoke externo do staging e fechamento - #4

Merged
LuanTrindade95 merged 10 commits into
mainfrom
feature/phase-9-external-smoke
Sep 20, 2026
Merged

LuanTrindade95 merged 10 commits into
mainfrom
feature/phase-9-external-smoke

Conversation

@LuanTrindade95

Copy link
Copy Markdown
Owner

Fecha a Fase 9 com o staging externo validado de fora.

Superfícies públicas

Smoke externo (19/09, reproduzido em auditoria independente em 20/09)

Passo Resultado
GET /health 200
GET /config.json (Netlify) 200, com as URLs públicas
Login demo 200
GET /api/v1/runtime/workflows/1 200, schema amount/supplier/cost_center
POST /api/v1/requests 201, step dinâmico resolvido para o aprovador
Payload fora do schema 422
GET /api/v1/inbox 200, com a pendência
POST .../decide 200, avanço para a aprovação financeira
Realtime runtime.workflow.updated recebido em canal privado, sem refresh

Mudanças

  • docs/DEMO_E2E_SCRIPT.md: seção "Roteiro Externo (Staging)" com payloads e códigos reais.
  • docs/DEPLOYMENT_READINESS.md e docs/STAGING_PLAN.md: alinhados ao render.yaml e ao netlify.toml reais (sem Horizon, sem scheduler, fila sync).
  • render.yaml: LOG_CHANNEL=stderr e LOG_LEVEL=error, sem os quais a exceção fica invisível nos Logs do Render — o que cegou o diagnóstico durante a tarefa.
  • docs/env/staging.backend.env.example: QUEUE_CONNECTION=sync.
  • docs/PROGRESS.md: Fase 9 como DONE, com URLs, códigos HTTP e data.
  • Brain: limitações de staging no KNOWN_ISSUES, aceite das advisories do Angular (DECISIONS.md + ADR-020), estado canônico e próximas ações atualizados, pendências processadas.

Ressalvas para divulgar o link

  1. Plano free hiberna: primeira resposta medida em 14,6 s, 24,6 s e 84,5 s. Aquecer antes de enviar para avaliadores.
  2. O MySQL Aiven desliga sozinho; enquanto isso, /health responde 200 e o login quebra com 500.
  3. Escalonamento de SLA não roda em staging.
  4. Recarregar a página desloga (token só em memória).
  5. Base demo compartilhada e gravável com credenciais públicas.

Gates

  • guard:migrations, check:enforcement, build:staging: verdes.
  • npm run fitness: vermelho apenas no passo audit, pelas advisories de @angular/* 19.2.25 aceitas em ADR-020.

Nenhum segredo versionado: os campos sensíveis do render.yaml seguem sync: false.

🤖 Generated with Claude Code

LuanTrindade95 and others added 10 commits September 18, 2026 22:58
Adds a "Roteiro Externo (Staging)" section to DEMO_E2E_SCRIPT.md covering
the public Netlify/Render/Reverb smoke path with real endpoints, payloads,
expected HTTP codes, and stop criteria. SLA escalation is documented as
not applicable to staging since Render free tier has no worker/scheduler.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ence

DEPLOYMENT_READINESS.md and STAGING_PLAN.md described a Horizon worker
and a scheduler worker on Render, and a Netlify publish path of
dist/frontend/browser; render.yaml only runs flowcore-api/flowcore-reverb
web services with QUEUE_CONNECTION=sync (no SLA escalation in staging),
and netlify.toml publishes frontend/dist/frontend/browser. Status is
updated to the real, verified state: Netlify and Render are live and
reachable, but external smoke is currently blocked by a 500 on login
isolated to database/Redis access, pending human diagnosis.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
LOG_CHANNEL=stack writes to a file inside the container, so exceptions
never reach the Render Logs tab. Set LOG_CHANNEL=stderr and
LOG_LEVEL=error on flowcore-api and the shared staging group.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The example file still documented QUEUE_CONNECTION=redis while
render.yaml runs staging with QUEUE_CONNECTION=sync (no dedicated
worker on the free plan). Align the example to match reality.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Correct the documented status code for request creation (Laravel
auto-assigns 201 to a JsonResource on POST, not 200), and record the
staging finding: POST /api/v1/requests reproducibly returns 500 and
persists nothing for the "Aprovacao de Compra" workflow, whose first
step uses a dynamic assignee (AssigneeResolver::resolveDynamic). The
same endpoint works for "Pedido de Ferias" (role-based assignee),
which was used to validate inbox/decide/realtime end to end. Phase 9
stays IN_PROGRESS until the bug is fixed and the full script re-runs
against the real purchase-request flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The reported AssigneeResolver::resolveDynamic() 500 blocker did not
reproduce: the prior payload used field names outside the published
form schema, which correctly returns 422. Re-ran the full purchase
approval flow against staging with the real schema (amount, supplier,
cost_center) and it works end to end: 201 create (instances #17/#18),
inbox listing, 200 decide advancing the instance, and
runtime.workflow.updated delivered over the private channel without
refresh when the request is created. Phase 9 closes as DONE.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The 500 did not reproduce: the failing payload carried fields outside the
published form schema. Record the post-power-on transient instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LuanTrindade95
LuanTrindade95 merged commit 5b0a362 into main Sep 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant