Skip to main content

Comentários do exame

O popover Comentários deixa qualquer pessoa autorizada registrar uma anotação de texto livre sobre um exame — um recado para quem for atender o paciente depois, uma justificativa de contato com o solicitante, uma observação para o histórico clínico. Em alguns status do exame, o mesmo popover também oferece um atalho: gravar o comentário e trocar o status do exame numa única ação (Pendente, Reconvocar ou Retornar para laudar).

Popover de comentários aberto, com o campo de texto preenchido, perfil doctor

Para quem é​

PersonaQuem éO que faz aqui
Médico / radiologistaAcompanha o exame no dia a diaRegistra observações clínicas, justifica um contato, marca o exame como pendente ou reconvoca o paciente
Administrador / gestor da unidadeOpera a unidadeMesmas ações, mais a exclusão de comentários de qualquer autor
Perfis sem exam:add-comment (ex.: read_only neste ambiente)Consulta a worklistNão vê o ícone de comentário na linha

Como acessar​

O comentário não é uma tela — é um popover ancorado a um ícone, com dois pontos de entrada:

OndeÍconeRota
Linha da worklistBalão de comentário (pi-comment), sempre visível quando exam:add-comment/exams
Grade de ícones do laudáriopi-comments/exams/:examId/report

:::info Quem vê o ícone O ícone só aparece — não fica escondido nem no laudário nem na worklist — quando o exame não está excluído e o usuário tem exam:add-comment (ou é platform admin): canCommentExam(exam, user), exam-policy.ts:171-173. Sem a permissão, o comportamento observado neste ambiente foi o ícone desaparecer completamente da linha (perfil read_only, que tem exam:read mas não exam:add-comment) — não uma versão desabilitada com tooltip. :::

Permissões que liberam cada ação​

AçãoElementoO que decideOnde no código
Ver/abrir o popoverÍcone de balão / pi-commentsexam:add-comment em qualquer escopo do IAM, ou platform adminexam-policy.ts:171-173, exam-user-context.factory.ts:42
Listar comentários existentesCorpo do popover, ao abrir (onShow())Nenhuma checagem própria no front — a query roda sempre que o popover abre; o backend aplica exam:list-comment com escopo RLSexam-comments.component.ts:209-211 (front) · Comentar exame — API (back)
Salvar um novo comentárioBotão SalvarHabilita só com texto não vazio (hasText()); a permissão de escrita é checada pelo backendexam-comments.component.ts:221-232
Apagar um comentárioÍcone de lixeira ao lado do comentárioSó aparece para o autor do próprio comentário (comment.userId === currentUserId()) — o front não verifica exam:delete-comment; o backend é quem de fato exige "autor ou platform admin"exam-comments.component.ts:170-173; back: Comentar exame — API
Marcar Pendente / ReconvocarBotões condicionais no rodapéSó aparecem quando o status do exame está em {Novo, Laudando, Digitado, Digitado I.A.} (RN-C4) e há texto digitadoexam-comments.component.ts:38-44,148-151
Retornar para laudarBotão condicional no rodapéSó aparece em exame Pendente com pelo menos um comentário já existente, ou em exame Reconvocadoexam-comments.component.ts:153-158

Passo a passo​

1. Abrir o popover​

Clique no ícone de balão de comentário na linha do exame (worklist) ou no ícone de comentários da grade do laudário.

Ícone Inserir comentário habilitado na linha, perfil administrator

2. Escrever o comentário​

O popover mostra os comentários existentes (mais recentes primeiro, com nome/foto do autor e "há quanto tempo") e um campo de texto no rodapé, limitado a 512 caracteres (EXAM_COMMENT_MAX_LENGTH, exam-comment.ts:19, aplicado com [maxlength] no HTML e Validators.maxLength no formulário). Sem nenhum comentário ainda, a lista mostra "Nenhum comentário.".

Popover vazio, campo de texto em foco, perfil doctor

Pressionar Enter (sem Shift) salva e fecha o popover; Shift+Enter quebra a linha sem enviar (onEnter, exam-comments.component.ts:214-218).

3. Salvar​

Com o campo preenchido, o botão Salvar habilita. Ao confirmar, o comentário é gravado com o autor sendo sempre o usuário autenticado — o cliente não escolhe o autor (mesma regra do backend, RN-01 de Comentar exame — API).

Botões Salvar / Pendente / Reconvocar habilitados após digitar o texto

:::caution Falha ao salvar — print abaixo é do ambiente desatualizado; erro mudou depois do fix O print abaixo (HTTP 400 / "The GraphQL operation is invalid.") veio de um build antigo do ambiente de teste — confirmado depois como bug de bundle desatualizado, já resolvido (ver a nota completa em Comentários — visão geral). Repetindo o teste já com o ambiente corrigido (perfil administrator), o erro de schema não ocorre mais, mas salvar ainda falha por um motivo diferente: a mutation responde 200 com um erro GraphQL UPSTREAM_UNAVAILABLE ("A required service is temporarily unavailable."). Ou seja, salvar um comentário continua não funcionando neste ambiente, mas por uma causa nova e distinta da retratada no print. Isso impediu capturar a tela com um comentário efetivamente salvo e listado. :::

Diálogo de erro ao tentar salvar (ambiente desatualizado, já corrigido — ver aviso acima): "The GraphQL operation is invalid."

Estados da tela​

EstadoQuando aparecePrint
VazioExame sem nenhum comentário ativo
Preenchido, pronto para salvarTexto digitado, botões habilitados
Erro ao salvarFalha na chamada ao servidor (ver caixa acima)
Ícone ausenteUsuário sem exam:add-comment (ex.: read_only)

Regras de negócio​

IDRegraO que a tela faz / impede
RN-C1Ícone só aparece para quem pode comentar e em exame não excluídocanCommentExam; sem a permissão, o ícone some da linha (não fica desabilitado)
RN-C2Comentário limitado a 512 caracteres, texto em branco não conta como preenchidoValidators.maxLength(512) + hasText() (trim) habilitam/desabilitam os botões
RN-C3Exame assinado bloqueia a troca de status combinada com o comentárioAntes de aplicar Pendente/Reconvocar/Retornar, o componente busca o detalhe do exame no servidor; se já está concluído, cancela a cadeia e mostra o aviso EXAM.COMMENTS.ASSINADO_BLOQUEADO — o comentário isolado (botão Salvar) não passa por essa checagem
RN-C4Pendente/Reconvocar só aparecem em exame nos status Novo/Laudando/Digitado/Digitado I.A.; Retornar para laudar só em Pendente (com comentário) ou ReconvocadocanFlagPendingOrRecall / canReturnToReport, exam-comments.component.ts:148-158
RN-C5 (divergência assumida)O legado tinha um catálogo de motivos configurável por empresa (exigir_motivo); o BFF atual não expõe esse catálogo, então Pendente/Reconvocar sempre seguem o caminho direto (comentário + status, sem seleção de motivo)Documentado como SPEC_DEVIATION no próprio componente (exam-comments.component.ts:74-78)
RN-C6 (divergência assumida)O legado escolhia o status de retorno (Novo ou Laudando) conforme já existir um laudo em rascunho; o BFF não expõe essa consulta, então Retornar para laudar sempre volta para o status Novoexam-comments.component.ts:80-82,243-245
RN-C7Salvar ou apagar um comentário atualiza o contador da linha (badge no ícone) sem esperar o próximo carregamento da worklistcommentAdded (output) → onCommentAdded, incremento otimista em exam-worklist.component.ts:1030-1035
RN-A10Só o autor apaga o próprio comentário no front; o backend também aceita platform adminexam-comments.component.ts:170-173; back: RN-04 de Comentar exame — API

Rotas e contratos relacionados​

O front fala GraphQL com o BFF, não a rota REST descrita como contrato público do backend — o comentário do próprio serviço é explícito: "a regra do projeto é falar GraphQL com o BFF" (exam-actions.service.ts:190-199). O BFF traduz essas mutations/queries para as rotas REST documentadas em Comentar exame — API.

Operação GraphQLEquivale à rota REST (back)Quando é chamada
query ExamComments($examId)GET /v1/exams/:examId/commentsToda vez que o popover abre (onShow)
mutation AddExamComment($examId, $description)POST /v1/exams/:examId/commentsBotão Salvar, e também no primeiro passo de Pendente/Reconvocar/Retornar
mutation DeleteExamComment($commentId)DELETE /v1/exam-comments/:idÍcone de lixeira no próprio comentário

Compliance​

Órgão / normaExigênciaComo a tela atende
LGPDminimização; nunca reexibir conteúdo sensível fora de contextoO campo aceita só texto livre; nenhuma mensagem de erro do front repete o conteúdo digitado
HIPAAtrilha de quem escreveu/apagou o quê e quandoDelegada ao backend (diagnosis.exam.comment-added/comment-removed), consultável via Audit

Relacionado​