- Para quem é (personas)
- Antes de começar
- Como acessar
- Permissões que liberam cada ação
- Caminho principal — gravar um ditado no laudário
- Caminho principal — ouvir os áudios já gravados
- Caminho principal — excluir um áudio (só no laudário)
- Fluxo técnico — exclusão
- Rotas e contratos relacionados
- Validações
- Caminhos alternativos e falhas
- Observações de negócio
- Relacionado
Gravar, ouvir e excluir áudio do exame
Grave um ditado de voz durante o laudo, ou ouça e exclua os áudios já anexados a um exame — pela grade de exames ou de dentro do próprio laudário.
:::caution Prints reais só para o estado "sem imagem" — gravação e exclusão seguem pendentes
Capturamos ao vivo o acesso à grade de exames e o estado do botão de áudio para um exame sem
imagem (ver visão geral do módulo para o motivo e as capturas). O único exame do
tenant de teste está nesse estado: Exibir áudio simplesmente não aparece (confirmado depois de
corrigir o ambiente de teste — ver caixa "Quem vê o botão na grade" abaixo), e Abrir Laudário
aparece habilitado mas falha ao abrir por um bug de schema GraphQL da própria branch develop (ver
Laudário) — não há, hoje, como abrir o modal de áudio nem o laudário neste
ambiente. Por isso os passos de gravar, ouvir um item real e excluir (seções abaixo) continuam sem
print, substituídos pelos diagramas Mermaid
(A confirmar — responsável: time de frontend; data: 24/09/2026, pendente de um exame de teste com
imagem e do bug de laudário corrigido). Todo texto desta página foi verificado no código-fonte e nos
testes unitários, não inventado a partir do wireframe legado.
:::
Para quem é (personas)
| Persona | Quem é | O que faz aqui |
|---|---|---|
| Médico laudista | Assina laudos (exam:sign) | Grava o ditado de voz durante o laudo, ouve e exclui os próprios áudios ou os de outros laudistas no mesmo exame |
| Gestor / administrador de plataforma | isPlatformAdmin, ou exam:update+exam:delete | Também pode excluir áudio no laudário, mesmo sem assinar laudo |
Qualquer perfil com exam:list-audio | Operação, digitação, auditoria do exame | Ouve os áudios já gravados pela grade de exames (sem poder excluir) |
Perfil sem exam:read | Confirmado com financial neste ambiente | Nem chega à grade de exames — redirecionado silenciosamente para /admin/tenant antes de qualquer botão de áudio existir |
Perfil sem exam:list-audio, mas com exam:read | Papéis operacionais sem acesso clínico completo | Chega à grade, mas a lista mostraria o estado de permissão negada ao abrir o modal — ver "Caminhos alternativos" (não confirmado por falta de um exame com imagem para testar) |
Confirmamos navegando que administrator, doctor e read_only chegam à grade de exames
(financial é redirecionado antes, sem exam:read — ver visão geral).
A confirmar — responsável: time de frontend; data: 24/09/2026. Como o único exame disponível não
tem imagem (o botão de áudio não aparece nesse estado) e abrir o laudário falha pelo bug de schema
GraphQL da branch develop (ver aviso acima), não foi possível abrir o modal/laudário para medir
quem realmente tem exam:sign, exam:list-audio ou exam:add-audio neste ambiente; a tabela acima
descreve a regra do código (exam-policy.ts:429-431), não uma medição por perfil.
Antes de começar
- Você precisa de um exame já cadastrado. Para o gravador, é preciso estar no laudário
(
/exams/:examId/report) — abrir o laudo muda o status do exame, então essa tela não é acessada só para ouvir áudio (para isso, use o botão na grade, abaixo). - O microfone do navegador precisa estar liberado para o domínio do Portal. Sem essa permissão do sistema operacional/navegador, a gravação não funciona (ver "Caminhos alternativos").
- Backend correspondente: Módulo Áudio — visão geral.
Como acessar
| Caminho na tela | Rota | O que abre |
|---|---|---|
| Grade de exames › ícone 🎤 na linha do exame (só quando o exame já tem áudio) | /exams | Modal "Áudios do exame", somente leitura |
| Laudário › painel de ferramentas à direita, seção "Gravador de voz" | /exams/:examId/report | Gravador + lista de áudios do exame, com exclusão se você tiver permissão |
:::info Quem vê o botão na grade
O ícone 🎤 "Exibir áudio", com o badge do número de gravações, só aparece na linha de um exame
que já tem audioCount > 0. Um exame sem áudio nenhum não mostra nem um botão desabilitado — a
ausência do botão já é a informação (exam-worklist.component.html:604-622).
Atualização 24/09/2026: a primeira rodada deste levantamento (ambiente task4 desatualizado)
via o botão aparecer desabilitado com o tooltip "Disponível em breve" para um exame sem imagem
— uma divergência em relação ao código, que não tem nenhum binding de [disabled] para esse botão.
Depois de atualizar o task4 para develop, repetimos o teste: o botão simplesmente não
aparece nesse caso, exatamente como o código sempre disse (exam.audioCount > 0). Era mesmo um
artefato do ambiente de teste desatualizado — não uma pendência do produto. O print abaixo é do
ambiente antigo (mantido como registro histórico); ver a nota completa em
visão geral do módulo.
:::
Permissões que liberam cada ação
| Ação | Onde aparece | O que decide se aparece/funciona |
|---|---|---|
| Ver o botão 🎤 na grade | Linha do exame | exam.audioCount > 0 (não é permissão — é o exame já ter áudio) |
| Abrir a lista (grade ou laudário) e ver os players | Modal da grade / laudário | Nenhuma checagem prévia no frontend; se a API recusar (exam:list-audio ausente), a tela mostra o estado "negado" — ver abaixo |
| Gravar e guardar um áudio | Laudário | Nenhuma permissão de IAM checada no frontend — só suporte do navegador e permissão de microfone do SO. A permissão real (exam:add-audio) só é aplicada no backend, no momento de salvar |
| Excluir um áudio | Só no laudário (nunca no modal da grade) | exam:sign ou (isPlatformAdmin ou exam:update e exam:delete) — calculado em canDeleteExamAudio(), exam-policy.ts:429 |
Caminho principal — gravar um ditado no laudário
1. Abrir o laudário e localizar o gravador
No laudário, o painel de ferramentas à direita tem a seção "Gravador de voz", logo abaixo do bloco de I.A. (que fica sempre desabilitado — ver nota no fim desta página) e acima da categoria BI-RADS.
2. Gravar
Clique no botão de microfone ("Gravar áudio"). Se houver mais de um microfone disponível, um seletor "Microfone" aparece antes do botão — com um só dispositivo, o seletor não é mostrado (escolher entre um item só não é escolha).
A gravação, nesse ponto, existe só no navegador (um Blob), sem nenhuma chamada ao servidor — dá para ouvir de novo antes de decidir guardar.
3. Guardar no exame
Só depois de haver ao menos uma tomada aparecem dois botões largos:
| Botão | O que faz |
|---|---|
| Guardar áudio e fechar a janela | Envia cada tomada ao exame (uma chamada por tomada — ver Gravar áudio — API); ao concluir todas com sucesso, mostra o toast "Áudio guardado no exame.", limpa as tomadas locais e avisa a lista de áudios do exame para recarregar |
| Criar laudo com I.A. | Sempre desabilitado, com tooltip "Ação indisponível" — depende de um endpoint de IA que ainda não existe no backend |
Se o envio falhar (por exemplo, sem exam:add-audio no backend, ou a rede cair), a tomada
permanece na lista local para uma nova tentativa — o componente não limpa nada em caso de erro.
Caminho principal — ouvir os áudios já gravados
A mesma lista (app-exam-audio-list) aparece nas duas superfícies. Ela busca os áudios do exame ao
ser montada e os ordena do mais recente para o mais antigo.
Cada item mostra a data (dd/MM/yy HH:mm) e o player nativo do navegador. O nome do arquivo
não aparece — é um caminho de armazenamento, não uma prova de quem gravou (ver nota abaixo).
Atalhos com o player em foco
| Tecla | Ação |
|---|---|
Espaço | Play/pausa |
← / → | Volta/avança 2 segundos |
r | Reinicia do zero e toca |
Os atalhos operam sobre o player em foco ou, se o foco saiu, sobre o último que entrou em reprodução — não sobre uma seleção explícita.
Caminho principal — excluir um áudio (só no laudário)
Disponível apenas quando canDelete é verdadeiro (ver tabela de permissões acima) — e só a versão
da lista embutida no laudário recebe esse parâmetro; a do modal da grade nunca oferece exclusão.
- Clique no ícone de lixeira ao lado do player.
- Confirme no diálogo: "Excluir áudio" — "Tem certeza de que deseja excluir o áudio "‹nome›"? Ele deixa de aparecer na lista e a exclusão fica registrada no histórico do exame."
- Ao confirmar, a exclusão é enviada e a lista inteira é recarregada (não um recorte local da linha) — toast "Áudio excluído com sucesso.", ou "Não foi possível excluir o áudio." em caso de falha, mantendo o item na lista.
Enquanto uma exclusão está em andamento, o botão de excluir de todos os itens fica desabilitado (guarda contra duplo clique / exclusões simultâneas).
Fluxo técnico — exclusão
Rotas e contratos relacionados
| Uso na tela | Rota de API |
|---|---|
| Carregar a lista (grade ou laudário) | Ouvir e listar áudios — GET /exams/{examId}/audios |
| Guardar uma tomada gravada no laudário | Gravar áudio — POST /exams/{examId}/audios |
| Excluir um áudio | Excluir áudio — DELETE /exams/{examId}/audios/{audioId} |
O upload (gravar) usa uma chamada REST direta ao BFF (POST bff/exams/{examId}/audios,
exam-actions.service.ts:298-322) em vez de GraphQL, pelo mesmo motivo dos anexos: GraphQL não
carrega arquivo binário. Listagem e exclusão usam GraphQL (examAudios / deleteExamAudio).
Validações
Frontend
| Situação | Momento | Comportamento |
|---|---|---|
| Gravação com blob vazio (0 bytes) | Ao parar de gravar | A tomada não é criada — nada aparece na lista de tomadas locais |
Navegador sem MediaRecorder | Ao montar o gravador | Botão de gravar nasce desabilitado, com o selo "Simulação" e o aviso de falta de suporte |
| Permissão de microfone negada pelo usuário/SO | Ao clicar em Gravar | Mensagem "Permissão de microfone negada" + dica de como liberar; distinta da mensagem de "sem suporte" |
Excluir sem canDelete | Ao tentar chamar confirmDelete | Não faz nada — o método verifica canDelete() antes de abrir a confirmação (o botão, de todo modo, nem é renderizado) |
Excluir sem examId resolvido | Ao confirmar exclusão | Toast de erro imediato, sem chamar o backend |
Backend
Ver as páginas de API já linkadas acima — em especial os limites de tamanho (10 MB) e formato
(assinatura binária, não extensão) da rota de gravação,
e a distinção 403/404 por escopo (RLS) descrita na
visão geral do módulo (back).
Caminhos alternativos e falhas
| Situação | O que acontece | Como se recupera |
|---|---|---|
| Exame sem áudio nenhum | Botão 🎤 nem aparece na grade | Grave um áudio pelo laudário primeiro |
| Exame sem imagem (confirmado ao vivo, ambiente atualizado) | Botão Exibir áudio não aparece; Abrir Laudário aparece habilitado mas falha por um bug de schema GraphQL da branch develop (ver Laudário) | Aguardar o exame receber imagem e o bug de laudário ser corrigido (fora desta documentação) |
Sem exam:list-audio | Lista mostra "Você não tem permissão para ouvir os áudios deste exame. Fale com o gestor da unidade." — sem botão de tentar de novo (insistir num 403 não resolve) | Pedir a permissão a quem administra a unidade |
| Falha transitória ao carregar (rede, 5xx) | "Não foi possível carregar os áudios deste exame." com botão Tentar de novo | Clicar em tentar de novo |
| Link de reprodução expirado/objeto removido | Item mostra "Este áudio não está mais disponível." em vez de um player quebrado | Não há recuperação pela tela — o link pré-assinado tem 300s de validade e é regerado a cada consulta; recarregar a lista gera um link novo |
Navegador sem suporte a MediaRecorder | Selo "Simulação — nenhum áudio é gravado" + botão de gravar desabilitado | Usar outro navegador |
| Microfone bloqueado pelo usuário/SO | "Permissão de microfone negada" + dica de liberação | Liberar o microfone para o site nas configurações do navegador e tentar de novo |
Guardar áudio falha no backend (ex.: sem exam:add-audio, ou erro de rede) | A tomada permanece na lista local; nenhum toast de sucesso aparece | Tentar Guardar áudio e fechar a janela de novo; se persistir, verificar a permissão com quem administra a unidade |
| Excluir falha no backend | Toast "Não foi possível excluir o áudio."; o item continua na lista | Tentar excluir de novo |
Observações de negócio
- O nome do arquivo não aparece na lista.
audioNameé o caminho salvo no armazenamento, não uma prova de quem gravou — o contrato de API não devolve o nome de quem gravou o áudio (lacuna registrada também no comentário do componente,exam-audio-list.component.ts:36-40), então a tela evita rotular a gravação com um dado que pareceria autoria sem ser. - Delete não é simétrico com gravar/ouvir. Gravar não tem checagem de IAM no frontend; ouvir
reage a um 403 do backend; excluir é a única ação com uma regra de permissão calculada
antecipadamente no frontend (
canDeleteExamAudio) — e só existe no laudário, nunca no modal da grade de exames. - "Criar laudo com I.A." é uma casca desabilitada por decisão de produto, não um defeito — o
endpoint de que dependeria (
uploadExamAudiopara IA) não existe ainda no BFF.
Relacionado
- ⚙️ API: Gravar áudio, Ouvir e listar áudios, Excluir áudio
- 📂 Módulo: Áudio — visão geral