Laudos e Presets
Endpoints para gerenciar laudos médicos dos estudos e presets de texto pré-preenchido. Ciclo de vida do laudo:pending → draft → final. Uma vez finalizado, o conteúdo só pode mudar via correção, que cria uma nova ReportRevision imutável no histórico.
RBAC (importante): apenas usuários “doutores” (não tenant_admin, não super_admin) podem criar, editar ou corrigir laudos. Tentativas por admins retornam 403.
Audit trail: toda ação em um laudo — criação de rascunho, atualização, finalização, correção — gera uma ReportRevision imutável, retornada por GET /studies/{id}/reports/revisions.
GET /api/studies//reports
Retorna o laudo do estudo (ounull se não existir).
Auth: auth:api
Path params
| Param | Tipo | Descrição |
|---|---|---|
id | uuid | ID do estudo |
Response 200
report vem null e report_status também.
O campo signature do autor é normalmente hidden no model User, mas é exposto via makeVisible() aqui porque é usado na geração do PDF.
Erros
| Status | Situação |
|---|---|
| 401 | Token inválido |
| 404 | Estudo não encontrado ou fora do tenant/unit |
POST /api/studies//reports
Cria ou atualiza o laudo do estudo (upsert). Usado tanto para salvar rascunho quanto para finalizar. Auth:auth:api — apenas doutores (não tenant_admin, não super_admin)
Request body
Conteúdo do laudo em HTML (saída do editor Tiptap).
draft para salvar rascunho, final para finalizar.ID do template usado. Deve pertencer ao tenant/unidade do estudo.
ID do preset aplicado. Deve pertencer ao tenant do estudo.
Response 200
Erros
| Status | Situação | Body |
|---|---|---|
| 403 | Usuário é tenant_admin ou super_admin | {"message": "Apenas doutores podem criar e editar laudos."} |
| 404 | Estudo não pertence ao tenant/unit | |
| 422 | Laudo já está final — use correção | {"message": "Laudo já finalizado. Correções devem usar fluxo específico."} |
| 422 | template_id/preset_id inválidos | {"message": "Template inválido para o tenant/unidade do estudo."} |
| 422 | Validação de campos | {"message": "...", "errors": {...}} |
Efeitos colaterais
- Cria
ReportRevisioncomaction=draft_created(primeiro),draft_updatedoufinalized - Atualiza
study.report_status - Se
status=final: atualizastudy.reported_atestudy.reported_by_user_id
POST /api/studies//reports/corrections
Registra uma correção num laudo já finalizado. O conteúdo anterior é preservado no histórico de revisões. Auth:auth:api — apenas doutores
Request body
Novo conteúdo do laudo em HTML.
Motivo da correção (opcional, até 2000 caracteres).
Response 200
Erros
| Status | Situação | Body |
|---|---|---|
| 403 | Usuário é admin | {"message": "Apenas doutores podem criar e editar laudos."} |
| 404 | Estudo ou laudo não existe | |
| 422 | Laudo não está final | {"message": "Correção só é permitida para laudo finalizado."} |
Efeitos colaterais
- Cria
ReportRevisioncomaction = "correction", preservandoprevious_content,new_contentereason - Atualiza
report.content,report.author_user_id,report.finalized_at = now() - Atualiza
study.reported_atestudy.reported_by_user_id
GET /api/studies//reports/revisions
Retorna o histórico completo de revisões do laudo (audit trail imutável). Auth:auth:api
Response 200
Array ordenado porcreated_at DESC (mais recente primeiro):
[] (array vazio, não 404).
Erros
| Status | Situação |
|---|---|
| 404 | Estudo não existe ou fora do tenant/unit |
Presets de Laudo
Textos pré-preenchidos que o médico pode aplicar ao laudo com um clique. Escopados por tenant, opcionalmente por unidade e/ou modalidade.GET /api/tenant/report-presets
Lista paginada de presets do tenant. Auth:auth:api (qualquer usuário autenticado)
Query params
Filtra por unidade (presets com
unit_id = null são “globais” do tenant).Filtra por modalidade (
CT, CR, MG, US, etc.). Normalizado para maiúsculas.Busca
ILIKE em name.Filtra por ativo/inativo. Aceita
true/false/1/0 (o backend usa $request->boolean()).Response 200
Paginação de 50 itens por página:GET /api/tenant/report-presets/
Detalhe de um preset. Auth:auth:api
Response 200
Erros
| Status | Situação |
|---|---|
| 404 | Preset não encontrado ou fora do tenant |
POST /api/tenant/report-presets
Cria um novo preset. Auth:auth:api + tenant_admin
Request body
Nome do preset (máximo 255 caracteres).
Unidade à qual o preset pertence. Deve ser do mesmo tenant.
null = preset global do tenant.Modalidade associada (máximo 16 caracteres, salvo em maiúsculas).
Substring usada para sugestão automática no editor (match em
study.study_description).Conteúdo HTML pré-preenchido que é aplicado ao laudo quando o preset é selecionado.
Se
false, o preset não aparece na seleção do editor.Ordem de exibição na UI.
Response 201
Mesmo shape deGET /api/tenant/report-presets/{id}.
Erros
| Status | Situação |
|---|---|
| 403 | Usuário não é tenant_admin |
| 422 | unit_id não pertence ao tenant, ou validação de campos |
PATCH /api/tenant/report-presets/
Atualiza um preset existente. Todos os campos são opcionais. Auth:auth:api + tenant_admin
Request body
Mesmos campos dePOST, todos opcionais (validação sometimes).
Response 200
Preset atualizado (mesmo shape deGET).
Erros
| Status | Situação |
|---|---|
| 403 | Usuário não é tenant_admin |
| 404 | Preset não existe ou fora do tenant |
| 422 | Validação |
DELETE /api/tenant/report-presets/
Remove um preset. Auth:auth:api + tenant_admin
Response 200
Erros
| Status | Situação |
|---|---|
| 403 | Usuário não é tenant_admin |
| 404 | Preset não existe ou fora do tenant |
