Módulo Comment — visão geral
Este módulo cobre duas capacidades do backend de Diagnóstico (NestJS, mm-pacs-portal-main-api)
que aparecem juntas na tela de exame, mas são recursos independentes na API: comentar um exame
(texto livre, sem efeito clínico) e sinalizar um achado crítico ou uma suspeita técnica no
exame (uma flag booleana com motivo, sem criar comentário). Comentário vive no pacote
diagnosis/clinical-media (que também hospeda anexos, áudio e imagens-chave, documentados por
outros módulos). Achado crítico e suspeita técnica vivem no pacote diagnosis/exam, dentro do
mesmo controller de "flags clínicas" do exame.
Divergência confirmada em relação ao desenho legado. No sistema antigo (
mm-pacs-portal-api,routes/exame.js), marcar um achado crítico ou uma suspeita técnica era um comentário especial: o texto recebia um prefixo fixo ("Achado Critico: "ou"Motivo da remoção do Achado Crítico: ") e a mesma chamada alterava as colunas de flag do exame (is_achado_critico,is_suspeita_tecnica, e propagavais_original/is_duplicado). O código atual separa completamente as duas coisas: um teste do próprio pacote de comentário afirma explicitamente que o comentário "carries no clinical intent, which belongs to the flag routes" (diagnosis-exam-comment.input.spec.ts), e o teste de ponta a pontadiagnosis-exam-comments.e2e.spec.tsconfirma que criar um comentário não alteracritical-findingnemtechnical-suspicion. As flags hoje são alteradas por rotas próprias (PUT/DELETE /exams/:id/critical-findinge/technical-suspicion), recebem um camporeasonlivre (não um texto de comentário) e não criam uma linha emdiagnosis_exam_comments. A regra legada de que marcar achado crítico desliga automaticamente a suspeita técnica (BR-CMT-092 do levantamento do sistema legado) também não existe no código atual — as duas flags são lidas, escritas e auditadas de forma independente (confirmado lendoMaintainDiagnosisExamClinicalFlagsService, sem nenhuma chamada cruzada entre os dois métodos).
Arquitetura
Os dois grupos de rota compartilham a mesma infraestrutura transversal do serviço de Diagnóstico:
autenticação por access token (JwtAuthenticationGuard), autorização granular por permissão e
por unidade (AuthorizationGuard, com escopo enforcement: 'rls' — um usuário sem acesso à
unidade do exame recebe 404, não 403, porque a existência do recurso é ocultada fora do
escopo), auditoria assíncrona via outbox (consultável em Audit) e
reprojeção assíncrona do item de worklist (contadores e flags aparecem em
GET /worklist, não nestas rotas).
Permissões usadas neste módulo
| Permissão | Usada em |
|---|---|
exam:add-comment | POST /exams/:examId/comments |
exam:list-comment | GET /exams/:examId/comments, GET /exam-comments/:id |
exam:delete-comment | DELETE /exam-comments/:id (além de: autor do comentário ou admin de plataforma) |
exam:read | GET /exams/:id/critical-finding, GET /exams/:id/technical-suspicion, GET /exams/:id/capabilities |
exam:flag-critical-finding | PUT/DELETE /exams/:id/critical-finding |
exam:flag-technical-suspicion | PUT/DELETE /exams/:id/technical-suspicion |
Convenção de erros
Toda exceção de negócio estende DomainError (ou ForbiddenAction) e já carrega seu statusCode
e errorCode fixos no próprio construtor. O filtro global de exceções apenas repassa esses
valores. Cada página de rota abaixo lista as classes de erro confirmadas no código.
Páginas deste módulo
| Página | Cobre |
|---|---|
| Comentar exame | POST/GET /exams/:examId/comments, GET/DELETE /exam-comments/:id — comentário de texto livre, sem efeito clínico |
| Achado crítico e suspeita técnica | GET /exams/:id/capabilities, GET/PUT/DELETE /exams/:id/critical-finding e /technical-suspicion — sinalização clínica do exame, independente do comentário |
:::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, tag Diagnosis — Exam comments e
Diagnosis — Exam clinical flags).
:::