Skip to content

fix(console): Config de Risco salva com confirmação explícita (M1)#113

Merged
danzeroum merged 1 commit into
masterfrom
claude/criptotrade-onboarding-06pd5p
Jul 21, 2026
Merged

fix(console): Config de Risco salva com confirmação explícita (M1)#113
danzeroum merged 1 commit into
masterfrom
claude/criptotrade-onboarding-06pd5p

Conversation

@danzeroum

Copy link
Copy Markdown
Owner

M1 · Config de Risco salva com confirmação explícita

Primeiro da faixa de manutenção pós-validação VPS. Bug revelado pelo uso real (dividendo do de-mock 5.x — a UI passou a bater na API real). Diff 100% frontend (docs/design/pages/); backend intacto.

Bug

A Config de Risco não salvava. Duas causas em screen_settings:

  1. cada slider/campo disparava PATCH direto no onChange (chatty);
  2. patchRiskConfig não enviava confirm → o backend (risk.py:310) responde 400 confirmation_required a cada arraste.

Fix (padrão do aviso do A5)

As edições dos 3 cards (Sistema, Risco, Guardrails) acumulam num draft local; um botão "Salvar" por card abre um modal de confirmação com resumo before→after; só ao confirmar o PATCH é enviado — e o de risco vai com confirm:true. Fim do PATCH-a-cada-onChange.

Auditoria dos irmãos (pedida)

  • /v1/risk/config tem o gate confirm=true; /v1/config e /v1/alerts/config não têm o gate, mas ganham o mesmo fluxo acumular+confirmar (elimina a chattiness).
  • /v1/agents/{id}/config é editado no drawer de Agentes (fora deste screen, sem gate).
  • Nota: o card de Guardrails hoje não renderiza (alertConfig nunca é buscado no load) — refatorado por consistência/futuro, mas é caminho morto (finding separado, fora do M1).

Fixture (regressão trava para sempre)

PATCH /v1/risk/config passa a exigir confirm===true (400 sem ele), espelhando o backend; +PATCH /v1/config canned. Novo config_save.spec: edição só acumula (0 PATCH no onChange) → Salvar mostra o diff before→after → Confirmar envia 1 PATCH com confirm:true (sucesso; sem confirm o fixture 400 → o teste quebraria); + cancelar não envia PATCH.

Validação

  • config_save 2/2; suíte completa 77 verdes (--retries=1); node build.mjs + mock-guard OK.

🤖 Generated with Claude Code


Generated by Claude Code

Bug revelado pelo uso real na VPS (dividendo do de-mock 5.x — a UI passou a bater na
API real): a Config de Risco não salvava. Duas causas em screen_settings:
(1) cada slider/campo disparava PATCH direto no onChange (chatty), e
(2) patchRiskConfig não enviava confirm → o backend (risk.py:310) responde 400
    confirmation_required a cada arraste.

Fix (padrão do aviso do A5): as edições dos 3 cards (Sistema, Risco, Guardrails)
acumulam num DRAFT local; um botão "Salvar" por card abre um modal de confirmação
com o resumo before→after; só ao confirmar o PATCH é enviado — e o de risco vai com
confirm:true. Nada mais de PATCH-a-cada-onChange.

Auditoria dos irmãos (pedida): só /v1/risk/config tem o gate confirm=true; /v1/config
e /v1/alerts/config não têm o gate, mas ganham o mesmo fluxo acumular+confirmar
(elimina a chattiness). /v1/agents/{id}/config é editado no drawer de Agentes (fora
deste screen, sem gate). Nota: o card de Guardrails hoje não renderiza (alertConfig
nunca é buscado no load) — refatorado por consistência/futuro, mas é caminho morto.

Fixture (regressão trava para sempre): PATCH /v1/risk/config passa a EXIGIR
confirm===true (400 confirmation_required sem ele), espelhando o backend; +PATCH
/v1/config canned. Novo spec config_save.spec: edição só acumula (0 PATCH no
onChange) → Salvar mostra o diff before→after → Confirmar envia 1 PATCH com
confirm:true (sucesso; sem confirm o fixture 400 → o teste quebraria); + cancelar
não envia PATCH.

Validação: config_save 2/2; suíte completa 77 verdes (retries=1); build+guard OK.
Diff 100% frontend (docs/design/pages/); backend intacto.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZ3vLNTHKekjQVtjFVRi5D
@danzeroum
danzeroum merged commit 55083a4 into master Jul 21, 2026
12 checks passed
danzeroum pushed a commit that referenced this pull request Jul 21, 2026
…ona (M4)

reset_paper_state.py estava "inoperável como documentado" na VPS. A exploração
mostrou que o fix é menor que o descrito: --yes JÁ existe e o docstring JÁ usa
`python -m`. Os tropeços reais eram dois:

1. EOFError: sem --yes e sem TTY (`docker compose exec` sem -it), o input() do prompt
   estourava um traceback. Fix: try/except EOFError em main() → aborta limpo
   (return 1, sem traceback) com mensagem apontando --yes.

2. Doc de operação: o fluxo documentado era `stop orchestrator → python -m … → start`,
   mas (a) rodar `python -m` no HOST não tem o ambiente (é dockerizado) e (b)
   `docker compose exec orchestrator` falharia — exec exige container DE PÉ e o
   fluxo para o orchestrator. Fix: a linha não-interativa passa a mirar o container
   `app` (fica de pé, compartilha o mesmo volume ./data / LEDGER_DIR que o
   orchestrator — confirmado no docker-compose.vps.yml), com --yes (sem TTY):
       docker compose -f docker-compose.vps.yml stop orchestrator
       docker compose -f docker-compose.vps.yml exec app python -m scripts.reset_paper_state --yes
       docker compose -f docker-compose.vps.yml start orchestrator
   Reforçado também que a invocação é SEMPRE `python -m` (rodar `python
   scripts/reset_paper_state.py` daria ModuleNotFoundError: src).

NÃO adicionei bootstrap de sys.path: bateria no gate E402 do ruff (select E4) e
fugiria da convenção `python -m` de todos os scripts do repo.

Testes (tests/test_reset_paper_state.py — antes só cobriam a função pura, não o
main() CLI; LEDGER_DIR isola ledger E app db via get_db_path):
- +test_main_yes_resets_without_prompting (--yes pula o prompt e reseta; input()
  não é chamado).
- +test_main_eof_without_yes_aborts_cleanly (EOFError → return 1, sem traceback,
  estado intacto).

Validação: pytest completo verde, cobertura 78.12% ≥ 72%; ruff (gate) limpo.

Fecha a faixa de manutenção M1–M4 (M1 #113, M2+M3 #114, M4 este PR).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZ3vLNTHKekjQVtjFVRi5D
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.

2 participants