Skip to main content

Módulo Exame — visão geral

O módulo de Exame é o núcleo do domínio de diagnóstico do Portal 2.0: cria e mantém o registro do exame (ingestão assíncrona, edição de dados do paciente/pedido, exclusão e restauração), controla o ciclo de vida clínico (status, prioridade, modalidade, SLA, unidade), atribui a equipe responsável (radiologista, digitador, residente, médico solicitante), relaciona exames entre si (prévios, complementares, conjugados, duplicados) e compartilha exames entre unidades. Ele vive em quatro pacotes do backend (NestJS), todos dentro de diagnosis/: exam (o agregado central), workflow-policy (as regras de negócio configuráveis que o exame consulta), status-reason (o catálogo de motivos de mudança de status) e medical-catalog (especialidades, subespecialidades e modalidades usadas para classificar o exame).

Fonte de verdade. Este levantamento foi feito inteiramente a partir do código atual (branch integration/with-fixlaudo) e dos testes em __test__. Não existe rascunho anterior deste módulo. Cartões de negócio do Bitrix (funil 562, features F-001 a F-014 e F-S01/F-S04) descrevem o sistema legado (mm-pacs-portal-api, rotas routes/exame.js, routes/marcacaoClinica.js, routes/motivo.js, routes/especialidade.js, tabelas tb_exame*) e foram usados só como pista de intenção de produto — o campo que mapearia "status vs. código real" (ufCrm110_1782750927) está vazio em todos os 13 cartões consultados, então nenhuma regra de negócio foi copiada do Bitrix sem confirmação direta no código NestJS atual. Divergências notáveis em relação ao legado (confirmadas no código, não presumidas): não existe mais uma máquina de estados fechada para o status do exame — qualquer status do catálogo pode suceder qualquer outro, desde que a permissão e o motivo (quando exigido pela política da unidade) sejam satisfeitos; e o achado crítico/suspeita técnica não é mais um comentário com prefixo fixo (ver Achado crítico e suspeita técnica, no módulo Comment).

Prefixo de rotas e versionamento​

Como no restante da API, o versionamento é nativo do NestJS por URI (VersioningType.URI, versão padrão 1): toda rota deste módulo é servida sob /v1/... (ex.: /v1/exams/:id, /v1/exam-ingestions, /v1/units/:unitId/status-reasons, /v1/medical-catalog/specialties). Em desenvolvimento local, o serviço sobe na porta 3000 (MAIN_API_PORT, default 3000) e expõe o Swagger em http://localhost:3000/docs.

Arquitetura​

Módulos irmãos — fora do escopo desta documentação​

Este levantamento cobre apenas exam, workflow-policy, status-reason e medical-catalog. Dois pacotes vizinhos do domínio de diagnóstico têm documentação própria e não são repetidos aqui:

  • Busca, contagem, exportação e favoritos da worklist (diagnosis/worklist) — ver módulo Busca. A busca lê o mesmo read model que este módulo projeta a cada mudança de exame, mas a lógica de filtro/paginação/favoritos pertence àquele módulo.
  • SLA (diagnosis/sla-policy) — ver módulo SLA. O prazo de laudo por prioridade/modalidade, o cap por protocolo clínico (AVC/Trauma) e o motor de cálculo do prazo são documentados lá; este módulo apenas consome ResolveDiagnosisSlaDeadlineService sempre que cria, muda prioridade/modalidade/unidade, duplica ou restaura um exame.
  • Comentário e achado crítico/suspeita técnica (diagnosis/clinical-media para comentário; flags dentro do próprio diagnosis/exam) — ver módulo Comentários e achado crítico. As rotas GET /exams/:id/capabilities e GET/PUT/DELETE /exams/:id/critical-finding/technical-suspicion já estão documentadas lá em detalhe e não são repetidas neste levantamento.

O ciclo de vida do exame​

O status do exame (ExamStatus) tem doze valores: NEW, TO_PREPARE, PENDING, REPORTING, TYPING, DRAFTED, DRAFTED_AI, PRE_REPORTED, SIGNED, RESIGNED, REEVALUATE, RECALL. Cada um espelha um ReportStatus do domínio de laudo (documentado à parte, no domínio de Laudo/Exam Report) — por exemplo SIGNED ⇄ SIGNED, REEVALUATE ⇄ SECOND_OPINION, DRAFTED ⇄ TYPED. Ver o mapa completo em Transição de status.

Não existe mais uma máquina de estados fechada. Diferente do que um desenho de fluxo sugeriria, o código atual (ChangeDiagnosisExamAttributesService.changeStatus) permite qualquer transição entre dois status do catálogo, exceto quando o exame já está SIGNED ou RESIGNED (protegido contra mudança manual — EXAME_JA_ASSINADO), contanto que a política de motivo da unidade seja respeitada. O único outro travamento é o gate de preparação: sair de TO_PREPARE ou PENDING exige que os campos obrigatórios da política de preparo da unidade estejam preenchidos.

Onde este módulo se conecta com workflow-policy, status-reason e medical-catalog​

  • workflow-policy resolve, por unidade, a política efetiva (unidade → tenant → default) que controla: quais prioridades a unidade aceita e qual é a prioridade default; quais modalidades entram automaticamente em preparação; se duplicar um exame assinado o joga de volta em preparação e se renova o SLA; se a mudança manual de status exige motivo; se a data de preparo é atualizada ao sair de TO_PREPARE; e (por unidade) qual médico é automaticamente associado a todo exame novo. Tem ainda uma política de preparo por unidade (preparation-policy) com os campos exigidos para sair de TO_PREPARE/PENDING, e preferências de tela/impressão por unidade (exam-preferences) usadas pelo frontend. Ver Política de fluxo de trabalho, Política de preparo e Preferências de exame da unidade.
  • status-reason é o catálogo de motivos de mudança de status, dono por unidade e compartilhável com outras unidades do mesmo tenant. ChangeDiagnosisExamAttributesService consulta esse catálogo sempre que a política da unidade exige motivo para a transição. Ver Motivos de status por unidade.
  • medical-catalog fornece o vocabulário clínico (especialidade → subespecialidade → apelido DICOM) usado para classificar automaticamente o exame pela descrição do estudo DICOM, na ingestão e sempre que a modalidade ou a descrição do estudo mudam. Ver Opções do catálogo médico, Especialidades, Subespecialidades e Catálogo por unidade e modalidade.

Convenção de erros​

Toda exceção de negócio estende BaseError/DomainError/BusinessError/ValidationError e já carrega seu statusCode e errorCode fixos no construtor. O filtro global (AllExceptionsFilter) apenas repassa esses valores. As páginas abaixo listam os erros confirmados por rota.

Rate limiting​

Nenhum controller deste módulo declara um guard de rate limit próprio. O RateLimitGuard global (RateLimitModule.forRoot, via APP_GUARD) se aplica a todas as rotas daqui: 100 requisições por 60000 ms por padrão, configurável por RATE_LIMIT_LIMIT/RATE_LIMIT_TTL_MS/RATE_LIMIT_ENABLED.

Páginas deste módulo​

Exame — ciclo de vida e atributos​

PáginaCobre
Ciclo de vida do exameGET/PATCH /exams/:id, PUT/DELETE /exams/:id/release, PUT/DELETE /exams/:id/exclusion
Ingestão de examePOST /exam-ingestions, GET /exam-ingestions/:trackingId e o consumidor de fila
Transição de statusPATCH /exams/:id/status
Motivos de status por unidadeGET/POST/PATCH/DELETE /units/:unitId/status-reasons(/:reasonId), associações entre unidades
Prioridade, modalidade e SLAPATCH /exams/:id/priority, /modality, /sla
Mudança de unidadePATCH /exams/:id/unit, GET /exams/:id/unit-history

Equipe e relacionamentos entre exames​

PáginaCobre
Atribuição de equipeGET/PUT/DELETE /exams/:id/assignments(/:responsibility), GET /team-change-reasons
Relacionamentos do exameprévios, complementares e conjugados (/exams/:id/prior-exams, /complements, /conjugates), GET /exams/:id/prior-exam-candidates
Duplicação de examePOST/GET/DELETE /exams/:id/duplicates(/relation)
Compartilhamento entre unidadesGET/POST/DELETE /exams/:id/shares(/:unitId)

Metadados, registros e utilitários do exame​

PáginaCobre
Caso interessanteGET/PUT/DELETE /exams/:id/interesting-case
Registros técnicos e impressãoGET /exams/:id/logs/integration, /logs/messaging, POST /exams/:id/printouts
Replicação de código de pacientePOST /exams/patient-code-replications

Catálogo médico​

PáginaCobre
Opções do catálogo médicoGET /medical-catalog/clinical-markings, /form-types
EspecialidadesGET/POST/PATCH/DELETE /medical-catalog/specialties(/:id), vínculo com unidade
SubespecialidadesGET/POST/PATCH/DELETE /medical-catalog/subspecialties(/:id), apelidos DICOM
Catálogo por unidade e modalidadeGET /medical-catalog/units/:unitId/modalities/:modality/subspecialties

Políticas de workflow​

PáginaCobre
Política de fluxo de trabalhoGET/PUT/DELETE /tenants/:tenantId/diagnosis-workflow-policy, /units/:unitId/diagnosis-workflow-policy
Política de preparoGET/PUT/DELETE /units/:unitId/preparation-policy
Preferências de exame da unidadeGET/PATCH /units/:unitId/exam-preferences

:::tip OpenAPI A documentação interativa (schemas + "Try it out") está disponível em /docs no ambiente onde a API está rodando (local: http://localhost:3000/docs). :::