refactor: Report referencia TestRun em vez de embutir cenários próprios #18

Merged
jhony75 merged 1 commit from refactor/report-run-scenarios into develop 2026-09-03 06:58:15 -03:00
Owner

Resumo

Último item pendente do mapa Motor vs. EEG (docs/ARCHITECTURE.md): Report tinha ReportScenario/ReportScenarioStep próprios, uma cópia quase idêntica de TestRunScenario/TestRunStep (funções de criação praticamente clonadas — add_scenario_to_report vs add_scenario_to_run). Já existia a estrutura certa pra isso (TestRun); faltava Report referenciá-la.

  • TestRun ganha report_id (FK 1:1 pra reports.id, nullable, unique, ondelete=CASCADE) — Report.run é um TestRun "de suporte" exclusivo daquele report.
  • Migration 573520d0fbe5 migra report_scenarios/report_scenario_steps/anexos de step (images.step_id) existentes pra test_run_scenarios/test_run_steps/run_images, com IDs deslocados por offset pra nunca colidir com scenarios/steps de Runs já existentes, e só então dropa as tabelas/coluna antigas.
  • Contrato HTTP não mudou: Report.scenarios virou @property delegando pra Report.run.scenarios — como os schemas Pydantic não declaram os campos extras que só TestRunScenario/TestRunStep têm, o JSON fica idêntico ao de antes. Zero mudança de frontend.
  • GET /api/runs passa a filtrar os runs "de suporte" de Report.
  • Issue (achados) continua embutido em Report — não há equivalente no motor pra reaproveitar (decisão documentada, não pendência).
  • Corrige também o head do Alembic esperado no restore drill do CI (mesmo padrão de manutenção do PR anterior).

Validação

Dado o risco real de mover BLOBs entre tabelas, fui além do padrão usado nas migrations anteriores:

  • pytest no backend: 37/37 passando
  • Migration testada com dados seedados direto no schema antigo (não só banco vazio) incluindo um Run pré-existente, pra garantir que o offset de IDs não colide
  • Round-trip upgrade → downgrade → upgrade comparando BLOBs byte a byte
  • Validação end-to-end via API real (dev server): criar report com cenário/passo/imagem, editar status do passo, duplicar (confirma reset de status + não cópia de anexos), exportar PDF/HTML (cenário aparece corretamente), deletar report e confirmar cascade limpo sem linhas órfãs em test_runs/test_run_scenarios/test_run_steps/run_images
  • Confirmado que GET /api/runs não lista os runs de suporte
## Resumo Último item pendente do mapa Motor vs. EEG (`docs/ARCHITECTURE.md`): `Report` tinha `ReportScenario`/`ReportScenarioStep` próprios, uma cópia quase idêntica de `TestRunScenario`/`TestRunStep` (funções de criação praticamente clonadas — `add_scenario_to_report` vs `add_scenario_to_run`). Já existia a estrutura certa pra isso (`TestRun`); faltava `Report` referenciá-la. - `TestRun` ganha `report_id` (FK 1:1 pra `reports.id`, nullable, unique, `ondelete=CASCADE`) — `Report.run` é um TestRun "de suporte" exclusivo daquele report. - Migration `573520d0fbe5` migra `report_scenarios`/`report_scenario_steps`/anexos de step (`images.step_id`) existentes pra `test_run_scenarios`/`test_run_steps`/`run_images`, com IDs deslocados por offset pra nunca colidir com scenarios/steps de Runs já existentes, e só então dropa as tabelas/coluna antigas. - **Contrato HTTP não mudou**: `Report.scenarios` virou `@property` delegando pra `Report.run.scenarios` — como os schemas Pydantic não declaram os campos extras que só `TestRunScenario`/`TestRunStep` têm, o JSON fica idêntico ao de antes. Zero mudança de frontend. - `GET /api/runs` passa a filtrar os runs "de suporte" de Report. - `Issue` (achados) continua embutido em `Report` — não há equivalente no motor pra reaproveitar (decisão documentada, não pendência). - Corrige também o head do Alembic esperado no restore drill do CI (mesmo padrão de manutenção do PR anterior). ## Validação Dado o risco real de mover BLOBs entre tabelas, fui além do padrão usado nas migrations anteriores: - [x] `pytest` no backend: 37/37 passando - [x] Migration testada com **dados seedados direto no schema antigo** (não só banco vazio) incluindo um Run pré-existente, pra garantir que o offset de IDs não colide - [x] Round-trip upgrade → downgrade → upgrade comparando **BLOBs byte a byte** - [x] Validação end-to-end via API real (dev server): criar report com cenário/passo/imagem, editar status do passo, duplicar (confirma reset de status + não cópia de anexos), exportar PDF/HTML (cenário aparece corretamente), deletar report e confirmar cascade limpo sem linhas órfãs em `test_runs`/`test_run_scenarios`/`test_run_steps`/`run_images` - [x] Confirmado que `GET /api/runs` não lista os runs de suporte
refactor: Report referencia TestRun em vez de embutir ReportScenario/Step
All checks were successful
EEG QA CI / validate-and-build (pull_request) Successful in 2m11s
EEG QA CI / Deploy production (pull_request) Has been skipped
EEG QA CI / Deploy development (pull_request) Has been skipped
bed2408574
Último item pendente do mapa Motor vs. EEG (docs/ARCHITECTURE.md): Report
tinha ReportScenario/ReportScenarioStep próprios, uma cópia quase idêntica
de TestRunScenario/TestRunStep (funções de criação praticamente clonadas —
add_scenario_to_report vs add_scenario_to_run). Já existia a estrutura certa
pra isso; faltava Report referenciá-la.

TestRun ganha report_id (FK 1:1 pra reports.id, nullable, unique,
ondelete=CASCADE) — Report.run é um TestRun "de suporte" exclusivo daquele
report, criado sempre (mesmo sem cenários). Migration 573520d0fbe5 migra
report_scenarios/report_scenario_steps/anexos de step (images.step_id)
existentes pra test_run_scenarios/test_run_steps/run_images, com IDs
deslocados por offset pra nunca colidir com scenarios/steps de Runs "de
verdade" já existentes, e só então dropa as tabelas/coluna antigas.

Validação da migration foi além do padrão usado até aqui, dado o risco real
de mover BLOBs entre tabelas: testada com dados seedados direto no schema
antigo (não só banco vazio) incluindo um Run pré-existente pra garantir que
o offset de IDs não colide, round-trip upgrade->downgrade->upgrade
comparando BLOBs byte a byte, e validação end-to-end via API real (criar
report com cenário/passo/imagem, editar, duplicar, exportar PDF/HTML,
deletar e confirmar cascade limpo sem órfãos).

Contrato HTTP das rotas de cenário/step do Report não mudou: Report.scenarios
virou @property delegando pra Report.run.scenarios — como ReportScenarioOut/
ScenarioStepOut não declaram os campos extras que só TestRunScenario/
TestRunStep têm (template_id, reports), o Pydantic ignora essas colunas na
validação e o JSON fica idêntico ao de antes. add_report_scenario chama
modules.test_execution.router.add_scenario_to_run direto;
services/reports.py::add_scenario_to_report foi removida.
GET /api/runs passa a filtrar os runs de suporte (report_id IS NOT NULL).
Issue (achados) continua embutido em Report, sem equivalente no motor pra
reaproveitar — decisão documentada, não pendência.

Zero mudança de frontend. 37/37 testes de backend passando.

Também corrige o head do Alembic esperado no restore drill do CI (mesmo
padrão de manutenção já visto antes — precisa bump a cada nova migration).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
jhony75 merged commit ebeb847a59 into develop 2026-09-03 06:58:15 -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!18
No description provided.