Skip to main content

Módulo Áudio — visão geral

O módulo de áudio cobre a gravação, a consulta e a exclusão de áudios de ditado anexados a um exame — o recurso que permite a um médico laudista gravar a própria voz (pelo microfone do navegador) durante o laudo ou a visualização de imagens, em vez de digitar. Ele vive em um único controller do backend (NestJS), DiagnosisExamAudioController, dentro do pacote diagnosis/clinical-media.

Escopo deste levantamento. O pacote diagnosis/clinical-media também implementa anexos genéricos (DiagnosisExamAttachmentController), comentários (DiagnosisExamCommentController) e marcação de imagens-chave (DiagnosisExamKeyImageController). Esta página e as páginas abaixo cobrem apenas a capacidade de áudio; as demais capacidades do pacote são documentadas em páginas próprias, fora deste módulo.

Prefixo de rotas e versionamento​

Assim como o módulo Authentication, a API usa versionamento nativo do NestJS por URI (VersioningType.URI, versão padrão 1), então toda rota deste módulo é servida sob /v1/... (ex.: /v1/exams/{examId}/audios). 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, sob a tag "Diagnosis — Exam audios".

Arquitetura​

Autorização e RLS​

Todas as rotas exigem um access token válido (JwtAuthenticationGuard) e uma permissão específica por operação, avaliada pelo AuthorizationGuard com escopo resource (kind: 'resource', resource: 'exam', enforcement: 'rls'), identificado pelo examId do path. Isso soma duas camadas de controle, confirmadas no código:

  1. RBAC/ABAC no guard — decide se o ator tem a permissão exigida (exam:add-audio, exam:list-audio ou exam:delete-audio) no escopo (unidade/tenant) resolvido para aquele exame. Sem a permissão, a resposta é 403 FORBIDDEN_ACTION.
  2. RLS no banco — DiagnosisAuthorizationTransactionInterceptor executa toda a requisição dentro de uma transação com o contexto de RLS aplicado (RlsContextApplier, a partir das unidades/tenants liberados pelo guard). Um exame fora do escopo do ator fica invisível para as consultas, mesmo que exista — a rota devolve 404, não 403, para não revelar a existência do recurso.

Os detalhes de como o RBAC/ABAC resolve papéis, políticas e escopos efetivos pertencem ao módulo Authorization; esta página assume esse comportamento e documenta apenas a permissão exigida por rota.

Formato de áudio aceito​

O formato do arquivo enviado não é confiado pelo Content-Type declarado pelo cliente nem pela extensão do nome do arquivo. O AudioContentTypeDetector lê os primeiros bytes do conteúdo (assinatura binária) e só aceita seis formatos canônicos:

FormatoAssinatura verificada
audio/webmEBML (0x1A 0x45 0xDF 0xA3)
audio/oggOggS
audio/wavRIFF...WAVE
audio/mp4 (m4a)ftyp no offset 4
audio/mpeg (mp3)ID3 ou frame sync MPEG (0xFF + 0xEx)
audio/aacframe sync ADTS (0xFF + 0xFx)

Qualquer outro conteúdo (incluindo um arquivo vazio) é rejeitado com 415 Unsupported Media Type antes de qualquer gravação.

Cobertura de testes automatizados​

A confirmar — responsável: time de Diagnosis; data: 24/09/2026. A busca no diretório __test__ do pacote encontrou apenas testes unitários para o detector de formato (audio-content-type-detector.spec.ts) e para a validação do input de domínio (uploaded-audio.input.spec.ts). Não há teste automatizado (unitário ou e2e) cobrindo o DiagnosisExamAudioController nem o MaintainDiagnosisExamAudiosService — upload completo, listagem, busca por id e exclusão não têm cobertura própria confirmada neste levantamento.

Páginas deste módulo​

PáginaCobre
Gravar áudioPOST /exams/{examId}/audios — envio de um áudio de ditado para o exame
Ouvir e listar áudiosGET /exams/{examId}/audios e GET /exams/{examId}/audios/{audioId}
Excluir áudioDELETE /exams/{examId}/audios/{audioId} — exclusão lógica

:::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 audios"). :::