feat: fecha as lacunas do item 6 -- UI de Automation Discovery, dedup e janela de execução #55

Merged
jhony75 merged 1 commit from feature/automation-discovery-ui into develop 2026-09-10 11:41:06 -03:00
Owner

Auditoria (pedida antes de implementar, seguindo a regra do roadmap de nunca assumir) confirmou que o item 6 (ingestão de automação) já estava arquiteturalmente pronto desde o item 1 — contrato formal, Core agnóstico de formato, separação definição/execução/resultado, ciclo UNMAPPED/MAPPED/IGNORED. Faltavam 3 lacunas reais, todas fechadas aqui (escopo confirmado com o usuário via AskUserQuestion):

1. UI de Automation Discovery

O Sidebar tinha um item "Discovery" desabilitado com badge "Em breve" — o backend sempre teve mapear/criar cenário/ignorar/reabrir prontos, mas só dava pra usar via API/curl. Tela nova (AutomationDiscoveries.tsx, master-detail, mesmo padrão de Library/SharedSteps): filtro por status, vincular a cenário existente, criar cenário novo a partir da discovery (com tags), ignorar/reabrir. CSS morto do placeholder removido.

2. Dedup por (source, external_run_id)

Reenviar a mesma execução (retry de webhook, at-least-once delivery) duplicava Run/cenários/passos e inflava execution_count de novo. Agora, quando external_run_id vem preenchido e já existe um TestRun com o mesmo (source, external_run_id), a chamada é um no-op idempotente — devolve o run já existente (AutomationRunOut.deduplicated=true), sem criar nada nem tocar contadores. Sem external_run_id, comportamento anterior preservado (sem chave estável pra deduplicar) — decisão confirmada com o usuário entre 3 opções (idempotente / rejeitar 409 / não mexer).

3. started_at/finished_at deixam de ser descartados em silêncio

Esses dois campos eram aceitos no payload e nunca gravados em lugar nenhum — bug real encontrado na auditoria. TestRun ganha automation_started_at/automation_finished_at (migração 23f82fbe105b), persistidos e expostos em TestRunOut.

Verificação

  • Backend: pytest -n auto — 176 passed (4 testes novos em test_automation.py: dedup mesmo source/run_id, dedup não aplica com source diferente, sem external_run_id sempre cria novo, started_at/finished_at persistidos).
  • Frontend: tsc --noEmit, eslint, vitest — 125 passed (6 testes novos), build, build-storybook — todos ok.
  • Manual, ponta a ponta contra o dev real: ingestão via curl → dedup confirmado ao vivo (mesmo run_id, deduplicated: true na segunda chamada, execution_count não incrementou de novo) → discovery aparece na tela → vincular a cenário existente → ignorar → reabrir, tudo funcionando e refletindo no backend real.

Fora de escopo (decisão explícita)

Item 7 (orquestração com runner externo) fica pra uma rodada futura — existe inclusive um design diferente e conflitante já documentado (ADR-0012, TestCheck) que precisa ser reconciliado antes de desenhar o item 7.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com

Auditoria (pedida antes de implementar, seguindo a regra do roadmap de nunca assumir) confirmou que o item 6 (ingestão de automação) já estava arquiteturalmente pronto desde o item 1 — contrato formal, Core agnóstico de formato, separação definição/execução/resultado, ciclo UNMAPPED/MAPPED/IGNORED. Faltavam 3 lacunas reais, todas fechadas aqui (escopo confirmado com o usuário via AskUserQuestion): ## 1. UI de Automation Discovery O Sidebar tinha um item "Discovery" desabilitado com badge "Em breve" — o backend sempre teve mapear/criar cenário/ignorar/reabrir prontos, mas só dava pra usar via API/curl. Tela nova (`AutomationDiscoveries.tsx`, master-detail, mesmo padrão de Library/SharedSteps): filtro por status, vincular a cenário existente, criar cenário novo a partir da discovery (com tags), ignorar/reabrir. CSS morto do placeholder removido. ## 2. Dedup por (source, external_run_id) Reenviar a mesma execução (retry de webhook, at-least-once delivery) duplicava Run/cenários/passos e inflava `execution_count` de novo. Agora, quando `external_run_id` vem preenchido e já existe um `TestRun` com o mesmo `(source, external_run_id)`, a chamada é um **no-op idempotente** — devolve o run já existente (`AutomationRunOut.deduplicated=true`), sem criar nada nem tocar contadores. Sem `external_run_id`, comportamento anterior preservado (sem chave estável pra deduplicar) — decisão confirmada com o usuário entre 3 opções (idempotente / rejeitar 409 / não mexer). ## 3. started_at/finished_at deixam de ser descartados em silêncio Esses dois campos eram aceitos no payload e nunca gravados em lugar nenhum — bug real encontrado na auditoria. `TestRun` ganha `automation_started_at`/`automation_finished_at` (migração `23f82fbe105b`), persistidos e expostos em `TestRunOut`. ## Verificação - Backend: `pytest -n auto` — 176 passed (4 testes novos em `test_automation.py`: dedup mesmo source/run_id, dedup não aplica com source diferente, sem external_run_id sempre cria novo, started_at/finished_at persistidos). - Frontend: `tsc --noEmit`, `eslint`, `vitest` — 125 passed (6 testes novos), `build`, `build-storybook` — todos ok. - Manual, ponta a ponta contra o dev real: ingestão via curl → **dedup confirmado ao vivo** (mesmo `run_id`, `deduplicated: true` na segunda chamada, `execution_count` não incrementou de novo) → discovery aparece na tela → vincular a cenário existente → ignorar → reabrir, tudo funcionando e refletindo no backend real. ## Fora de escopo (decisão explícita) Item 7 (orquestração com runner externo) fica pra uma rodada futura — existe inclusive um design diferente e conflitante já documentado (ADR-0012, `TestCheck`) que precisa ser reconciliado antes de desenhar o item 7. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
feat: fecha as lacunas do item 6 -- UI de Automation Discovery, dedup e janela de execucao
All checks were successful
EEG QA CI / validate-and-build (pull_request) Successful in 4m57s
EEG QA CI / Deploy production (pull_request) Has been skipped
EEG QA CI / Deploy development (pull_request) Has been skipped
ce7a68f4ff
Auditoria confirmou que o item 6 do roadmap (ingestao de automacao) ja
estava arquiteturalmente pronto desde o item 1 (contrato formal, Core
agnostico de formato, separacao definicao/execucao/resultado, ciclo
UNMAPPED/MAPPED/IGNORED) -- faltavam 3 lacunas reais, todas fechadas
aqui:

1. UI de Automation Discovery (frontend/src/components/AutomationDiscoveries.tsx)
   O Sidebar tinha um item "Discovery" desabilitado com badge "Em breve"
   ha tempos -- o backend sempre teve mapear/criar cenario/ignorar/
   designorar prontos, mas so dava pra usar via API/curl. Tela nova
   (master-detail, mesmo padrao de Library/SharedSteps) com filtro por
   status, vincular a cenario existente, criar cenario novo a partir da
   discovery (com tags), ignorar/reabrir. CSS morto do placeholder
   removido (.sidebar__link--disabled, .sidebar__link-soon).

2. Dedup por (source, external_run_id) em POST /api/automation/runs
   Reenviar a mesma execucao (retry de webhook, at-least-once delivery)
   duplicava Run/cenarios/passos e inflava execution_count de novo. Agora,
   quando external_run_id vem preenchido e ja existe um TestRun com o
   mesmo (source, external_run_id), a chamada e um no-op idempotente --
   devolve o run ja existente (AutomationRunOut.deduplicated=true), sem
   criar nada nem tocar contadores. Sem external_run_id, comportamento
   anterior preservado (sem chave estavel pra deduplicar).

3. started_at/finished_at deixam de ser descartados em silencio
   Esses dois campos eram aceitos no payload e nunca gravados em lugar
   nenhum. TestRun ganha automation_started_at/automation_finished_at
   (migracao 23f82fbe105b), agora persistidos e expostos em TestRunOut.

Verificacao: backend pytest -n auto (176 passed, 4 testes novos em
test_automation.py cobrindo dedup + started_at/finished_at), frontend
tsc/lint/vitest (125 passed, 6 testes novos)/build/build-storybook --
todos ok. Testado manualmente ponta a ponta contra o dev real: ingestao
real via curl -> dedup confirmado ao vivo (mesmo run_id, deduplicated
true na segunda chamada) -> discovery aparece na tela -> vincular a
cenario existente -> ignorar -> reabrir, todos funcionando e refletindo
no backend real.

Item 7 (orquestracao com runner externo) fica pra uma rodada futura, por
decisao explicita -- ha inclusive um design diferente e conflitante ja
documentado (ADR-0012, TestCheck) que precisa ser reconciliado antes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jhony75 merged commit 906d4994bf into develop 2026-09-10 11:41:06 -03:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jhony75/eeg-qa!55
No description provided.