Estudos
Endpoints para consultar estudos DICOM ingeridos pelo sistema. Todos são read-only via API — a criação acontece automaticamente via webhook do Orthanc quando um estudo é estabilizado.
Isolamento multi-tenant: aplicado via scopes Eloquent (BelongsToTenantAndUnit). Usuários regulares enxergam só estudos da sua unidade; tenant admins enxergam todas as unidades do tenant; super admins enxergam tudo.
Endpoints de report aninhados em /studies/{id}/reports/* estão documentados em Laudos.
GET /api/studies
Lista paginada de estudos acessíveis ao usuário.
Auth: auth:api
Query params
Busca case-insensitive em patient_name, patient_id e accession_number. Máximo 255 caracteres.
Filtro exato pela FK patient_uuid.
Exclui o estudo com esse id da listagem (útil para “estudos relacionados”).
Response 200
Paginação Laravel padrão (15 itens por página, não customizável).
{
"data": [
{
"id": "uuid",
"tenant_id": "uuid",
"unit_id": "uuid",
"patient_uuid": "uuid",
"orthanc_study_id": "string",
"study_instance_uid": "string",
"patient_id": "string",
"patient_name": "string",
"patient_birth_date": "YYYY-MM-DD | null",
"patient_sex": "M | F | null",
"accession_number": "string | null",
"study_date": "YYYY-MM-DD",
"study_description": "string | null",
"modalities": ["CT", "CR", ...] ,
"report_status": "pending | draft | final | null",
"reported_at": "iso8601 | null",
"reported_by_user_id": "uuid | null",
"created_at": "iso8601",
"updated_at": "iso8601"
}
],
"current_page": 1,
"per_page": 15,
"total": 123,
"last_page": 9
}
Notas
- Ordenação:
study_date DESC, created_at DESC
- O campo
modalities pode vir null no índex se o worker ainda não indexou as séries — nesse caso, use GET /api/studies/{id} que aplica fallback
GET /api/studies/
Retorna o detalhe de um estudo com relacionamentos patient, unit, tenant.
Auth: auth:api
Path params
| Param | Tipo | Descrição |
|---|
id | uuid | ID do estudo |
Response 200
Mesmo shape do index, mais:
{
"...": "campos do estudo",
"patient": {
"id": "uuid",
"tenant_id": "uuid",
"patient_id": "string",
"patient_name": "string",
"patient_birth_date": "YYYY-MM-DD | null",
"patient_sex": "M | F | null",
"created_at": "iso8601",
"updated_at": "iso8601"
},
"unit": {
"id": "uuid",
"tenant_id": "uuid",
"name": "string"
},
"tenant": {
"id": "uuid",
"name": "string"
}
}
Fallback de modalities
Se o campo modalities do model estiver null (worker ainda não atualizou), o controller calcula dinamicamente agrupando series.modality únicos. Garante que o campo sempre venha populado no show (ao contrário do index).
Erros
| Status | Situação |
|---|
| 401 | Token inválido ou ausente |
| 404 | Estudo não encontrado, ou pertence a outro tenant/unit |
GET /api/studies//series
Lista as séries de um estudo.
Auth: auth:api
Response 200
Array (sem paginação):
[
{
"id": "uuid",
"study_id": "uuid",
"orthanc_series_id": "string",
"series_instance_uid": "string",
"modality": "string",
"series_number": 1,
"manufacturer": "string | null",
"instance_count": 256,
"created_at": "iso8601",
"updated_at": "iso8601"
}
]
Ordenação: series_number ASC, created_at ASC.
Erros
| Status | Situação |
|---|
| 404 | Estudo não encontrado ou fora do tenant/unit |
GET /api/series//instances
Lista as instâncias (imagens) de uma série.
Auth: auth:api
Response 200
[
{
"id": "uuid",
"series_id": "uuid",
"orthanc_instance_id": "string",
"sop_instance_uid": "string",
"instance_number": 1,
"rows": 512,
"columns": 512,
"slice_thickness": 1.25,
"created_at": "iso8601",
"updated_at": "iso8601"
}
]
Ordenação: instance_number ASC, created_at ASC.
GET /api/studies//instances//rendered
Retorna a imagem renderizada (JPEG) de uma instância, via proxy para o Orthanc.
Auth: auth:api
Response 200
- Content-Type:
image/jpeg (propagado do Orthanc)
- Body: binário da imagem
- Headers:
Cache-Control: no-cache, private
Erros
| Status | Situação | Body |
|---|
| 404 | Estudo/instância não existe, ou Orthanc retornou erro | {"message": "Image not available"} |
Notas
- Timeout de 20s na chamada ao Orthanc
- Usado pelo frontend para preview de imagens individuais (ex.: seleção de frames para exportar no PDF)
GET /api/studies//thumbnail
Thumbnail do estudo (JPEG 300×300).
Auth: auth:api
Response 200
- Content-Type:
image/jpeg
- Body: binário (arquivo
thumbnails/{orthanc_study_id}/preview.jpg no volume pacs_storage)
- Headers:
Cache-Control: no-cache, private
Erros
| Status | Situação | Body |
|---|
| 404 | Thumbnail ainda não gerado pelo worker | {"message": "Thumbnail not ready"} |
GET /api/studies//series//thumbnail
Thumbnail de uma série específica.
Auth: auth:api
Response 200
- Content-Type:
image/jpeg
- Body: binário
- Headers:
Cache-Control: no-cache, private
- Fallback: se o thumbnail da série (
thumbnails/{orthanc_study_id}/series/{orthanc_series_id}.jpg) não existir, retorna o do estudo (thumbnails/{orthanc_study_id}/preview.jpg)
Erros
| Status | Situação | Body |
|---|
| 404 | Nenhum thumbnail disponível (série nem estudo) | {"message": "Thumbnail not ready"} |