Exames — API Pública
Permite que uma aplicação parceira liste e leia exames de diagnóstico dentro do alcance
organizacional autorizado à sua integração — nunca fora dele. É uma leitura pura: não há rota de
escrita de exame na API pública hoje (public-api.exam.update existe no catálogo de capabilities,
mas não tem rota implementada).
Funcionamento
PublicApiMachineAuthGuardePublicApiRateProfileGuardjá rodaram (ver Autenticação e autorização de máquina) — o controller recebe umPublicApiMachineContextpronto, com a instância de integração e a capability já resolvidas.- O controller pergunta a
IntegrationPlatformPublicApi.listAuthorizedUnitIdsquais unidades essa instância pode ver. Se a chamada informarunitIdna query, o resultado é filtrado para conter só esse id — nunca amplia o alcance: pedir a unidade de outra integração devolve uma lista vazia (e portanto nenhum exame), silenciosamente. - Busca os exames (
DiagnosisPublicApi.listExamsInUnits/findExamInUnits) restritos a essas unidades autorizadas. Um exame de outra unidade — mesmo existindo — responde404, nunca403: a API pública não revela que o exame existe fora do alcance da integração. - Se o grant da capability tiver um de-para declarativo de resposta, ele é aplicado ao item (ou a cada item da lista) antes de responder.
Endpoints
| Método | Rota | Descrição |
|---|---|---|
| GET | /v1/exams | Lista exames dentro das unidades autorizadas, com filtro e paginação |
| GET | /v1/exams/:examId | Lê um exame específico, se estiver dentro do alcance autorizado |
Versão: v1
Swagger: Diagnosis (tag) · Rota (Dev):
http://localhost:3002/v1/exams
Lógica de decisão de GET /v1/exams/:examId:
Permissões
| Rota | Guards | Capability exigida |
|---|---|---|
GET /v1/exams | PublicApiMachineAuthGuard, PublicApiRateProfileGuard | public-api.exam.read |
GET /v1/exams/:examId | idem | public-api.exam.read |
Headers
| Header | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Bearer <token de máquina> |
Path parameters
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
examId | uuid | Sim (na leitura de um exame) | Identificador do exame |
Query parameters
| Nome | Tipo | Obrigatório | Default | Descrição |
|---|---|---|---|---|
limit | int | Não | 50 | Máximo 200; abaixo de 1 ou fracionário é 400 |
cursor | string | Não | — | Cursor opaco (base64url do último examId da página anterior) |
accessionNumber | string | Não | — | Até 128 caracteres |
orderCode | string | Não | — | Até 128 caracteres |
studyInstanceUid | string | Não | — | Até 128 caracteres |
unitId | uuid | Não | — | Restringe ainda mais o alcance autorizado; nunca amplia |
Um campo de query não declarado (unexpected=true, por exemplo) é 400 —
o ValidationPipe da API pública é whitelist/forbidNonWhitelisted.
Response
200 — página de PublicApiExamResponse:
json{"items": [{"exam_id": "0198f3a4-...-uuid","accession_number": "ACC-0001","order_code": "ORD-0001","study_instance_uid": "1.2.840...","study_description": "Tórax PA","unit_id": "0198f3a4-...-uuid","patient": { "code": "PAC-0001", "name": "Fulano de Tal" }}],"page": { "limit": 50, "nextCursor": null }}
200 — um exame (GET /v1/exams/:examId): o mesmo formato de item, sem envelope de página.
Quando o grant tem um de-para declarativo, os nomes de campo e a presença de patient podem mudar
conforme a especificação configurada — ver
Concessões de rota.
Erros
| Classe de erro | errorCode | Status | Quando ocorre |
|---|---|---|---|
| (validação de query/path) | PUBLIC_API_REQUEST_REJECTED | 400 | limit/cursor/filtros fora do formato aceito, ou campo de query não declarado |
| (cursor não decodifica um UUID) | PUBLIC_API_PAGE_CURSOR_INVALID | 400 | cursor não é um examId válido em base64url |
PublicApiExamNotFoundError | PUBLIC_API_EXAM_NOT_FOUND | 404 | exame inexistente, excluído (soft delete) ou fora do alcance autorizado |
Ver também os erros de autenticação/autorização transversais em Autenticação e autorização de máquina.
Regras de negócio
| ID | Regra | Comportamento esperado |
|---|---|---|
| RN-01 | unitId da query só restringe, nunca amplia | pedir a unidade de outra integração devolve lista vazia, não erro |
| RN-02 | Exame fora do alcance é 404, nunca 403 | a API pública não confirma nem nega a existência de um exame de outra unidade |
| RN-03 | Exame excluído (soft delete) é invisível | não aparece na lista nem na leitura direta por id |
| RN-04 | Paginação é por cursor de identificador, ordem estável | a página seguinte nunca repete nem pula um item entre chamadas consecutivas |
| RN-05 | Vínculo PLATFORM nunca lista exames | sem política de seleção de tenant, listAuthorizedUnitIds devolve lista vazia para essa instância |
| RN-06 | Vínculo TENANT com ALL_ACTIVE_UNITS acompanha o estado atual | uma unidade ativada/inativada no tenant depois da concessão muda o alcance na próxima chamada, sem nova configuração |
Compliance
| Órgão / norma | Exigência | Como a rota atende |
|---|---|---|
| LGPD | minimização de dados de paciente expostos a terceiro | o de-para declarativo permite omitir o bloco patient por parceiro; resposta nunca inclui campo clínico além do necessário ao contrato |
| HIPAA | controle de acesso mínimo necessário (164.312(a)) | alcance de unidade resolvido a cada requisição, nunca cacheado no token além do vínculo original |
Variáveis de ambiente
Nenhuma específica desta rota.
Tempo médio de resposta
A confirmar — responsável: time de Integration Platform; data: 24/09/2026. Não há medição
publicada; não foi executado neste levantamento.
Requisitos não funcionais
| Requisito | Definição |
|---|---|
| Idempotência | Sim (GET) |
| Paginação | Cursor opaco, limit até 200, default 50 |
| Rate limit | Perfil da concessão (STANDARD/INTERACTIVE/BULK) — ver Autenticação e autorização |
| Cache | Não |
| Auditoria | Log estruturado por requisição (sem persistência de evento de auditoria próprio desta rota) |
Relacionado
- 🖥️ Tela: Não se aplica — consumida por aplicação externa, não pelo frontend do Portal.
- 📂 Módulo: API Pública (Integrações)
- 🔑 Autenticação: Autenticação e autorização de máquina
- 🔗 Concessão da capability: Concessões de rota