Checklist de Homologação

Roteiro para validar o sistema em ambiente de homolog antes de promover develop para main. Organizado por persona + fluxos transversais. Cada item é um checkbox — marque conforme testar. Anote bugs encontrados na seção final.

0. Pré-requisitos (smoke test)

  • Todos os containers sobem (docker compose ps — 8 serviços healthy)
  • Migrations rodaram sem erro
  • Login com super admin funciona
  • Login com tenant admin funciona
  • Login com médico (usuário regular) funciona
  • Refresh token renova sessão automaticamente sem deslogar o usuário
  • Logout limpa os cookies (pacs_access_token, pacs_refresh_token)
  • GET /api/me retorna flags corretas (is_super_admin, is_tenant_admin, tenant_id, unit_id)

1. Super Admin

Tenants

  • GET /admin/tenants — lista paginada (50/pág)
  • Filtro search funciona (ILIKE em name/slug)
  • Criar tenant novo
  • Tentar criar tenant com nome duplicado (case-insensitive) → 422
  • Tentar criar tenant com slug duplicado → 422
  • Desativar tenant → confirmar cascade: todos os users do tenant ficam is_active=false
  • Reativar tenant → users não são reativados automaticamente (comportamento esperado)

Units

  • Listar units (com filtro tenant_id)
  • Criar unit vinculada a um tenant
  • Tentar criar unit com nome duplicado na mesma clínica → 422

Modalities (DICOM)

  • Listar modalities (filtros tenant_id, unit_id)
  • Criar modality com AET único global
  • AET é normalizado para UPPERCASE
  • Tentar criar com AET duplicado → 422
  • Tentar criar com unit_id de outro tenant → 404
  • Campo vpn_ip aceita IP válido (v4/v6)

Users

  • Listar users (filtros + has_signature exposto, signature oculto)
  • Criar user regular
  • Criar tenant admin (is_tenant_admin=true)
  • Tentar criar com is_super_admin=true → flag é ignorada (sempre false)
  • Email é normalizado para lowercase
  • CRM no formato NNNN/SS é aceito; inválido → 422
  • Signature como data URL base64 é aceita
  • Editar user (PATCH) — password não é aceito
  • Email único ignora o próprio registro no update

2. Tenant Admin

Escopo (isolamento)

  • apenas units, users, templates, presets da própria clínica
  • Tentar acessar recurso de outro tenant → 403/404

Settings do tenant

  • GET /tenant/settings retorna dados da clínica
  • PATCH /tenant/settings atualiza logo e outros campos

Templates de laudo

  • Listar templates ativos
  • Criar template novo
  • Editar template (PATCH)
  • Ativar um template → outros da mesma unit ficam inativos (exclusão mútua)
  • Soft delete (DELETE) → deleted_at preenchido, some da lista
  • GET /tenant/my-template retorna o template ativo da unit do usuário

Report presets

  • Listar presets (filtro is_active=true funciona via $request->boolean())
  • Criar preset
  • Editar preset
  • Deletar preset

Users e units

  • Criar/editar users da própria clínica
  • Criar/editar units da própria clínica

3. Médico (usuário regular)

Escopo

  • apenas estudos da sua unit
  • Não vê estudos de outras units da mesma clínica
  • Tentar acessar estudo de outra unit via URL direta → 403/404

Listagem e busca

  • Lista de estudos carrega com thumbnails
  • Busca por paciente funciona
  • Filtro patient_uuid retorna estudos daquele paciente
  • Paginação funciona

Detalhe do estudo

  • Thumbnail principal carrega
  • Thumbnails de series carregam
  • Modalidades aparecem (fallback a partir de series quando modalities é nulo)
  • Botão “Abrir Viewer” gera token temporário e abre OHIF em nova aba
  • OHIF carrega DICOM via nginx CORS proxy (localhost:8043)
  • Token expira em 10 minutos (testar com aba aberta após 10min)

Laudos — core do MVP

  • Criar rascunho novo
  • Auto-save funciona (intervalo padrão)
  • Editor Tiptap renderiza o template do tenant
  • Aplicar preset no editor funciona
  • Indicador de quebra de página no editor alinha com preview e PDF (fix P2)
  • Preview A4 renderiza igual ao PDF final
  • Finalizar rascunho → gera PDF com logo + assinatura do médico
  • PDF download/open funciona
  • Tentar finalizar sem rascunho prévio → 422
  • Criar correção em laudo finalizado
  • GET /studies/{id}/reports/revisions retorna audit trail completo:
    • draft_created
    • draft_updated (a cada save)
    • finalized
    • correction

Pacientes

  • Listar pacientes da unit
  • Detalhe do paciente mostra estudos relacionados

4. Ingestão DICOM (transversal)

  • Modality cadastrada envia estudo via C-STORE para pacs_orthanc:4242
  • Orthanc estabiliza após ~10s e dispara webhook
  • Webhook valida X-Webhook-Secret (sem ele → 401)
  • ProcessStudyMetadata job é enfileirado em pacs_python_queue
  • Worker Python consome e indexa em PostgreSQL
  • Thumbnail 300×300 gerado em pacs_storage/thumbnails/{study}/preview.jpg
  • Thumbnails de series também gerados
  • Estudo aparece no frontend com thumbnail em ≤30s do envio
  • AET não cadastrado → estudo não indexado (ou tratamento definido)
  • Modalidade aparece corretamente no detalhe do estudo
  • Re-enfileirar via php artisan pacs:requeue --only-missing-modalities funciona

5. Isolamento multi-tenant (transversal)

  • Tenant A não vê estudos do Tenant B na listagem
  • Tenant A não acessa estudo de Tenant B via ID direto → 403
  • Tenant A não abre OHIF de estudo de Tenant B → 401 do nginx
  • Token do viewer é vinculado ao usuário que o gerou
  • Token do viewer expira em exatamente 10 minutos
  • Global scope BelongsToTenant ativo em todos os controllers
  • JWT carrega tenant_id, unit_id, is_super_admin, is_tenant_admin

6. Frontend — navegação e UX

  • Super admin vê rotas /super-admin/*
  • Tenant admin vê rotas /tenant-admin/*
  • Médico não vê rotas admin (redirect)
  • Sidebar mostra links corretos por role
  • Refresh da página mantém sessão (cookie persiste)
  • Logout redireciona para /login
  • Erros 401 em APIs → tenta refresh automaticamente
  • Erros 403/404 mostram tela apropriada

Bugs encontrados

Liste aqui o que falhar durante o teste. Formato sugerido:
- [Persona/Fluxo] Descrição do bug — passos para reproduzir — severidade (P1/P2/P3)

Encontrados


Decisão de merge

  • Todos os P1 resolvidos
  • P2/P3 documentados em issue para pós-merge
  • PR develop → main pode ser aberto