Skip to main content

Foto e assinatura do usuário — API

Lê, substitui e remove a foto de perfil e a imagem de assinatura de um usuário. É o caminho direto de upload (multipart, um arquivo por vez, sem sessão prévia) mantido pelo pacote user. Existe também um caminho versionado e mais recente para os mesmos dois tipos de imagem — ver Ativos do usuário — que convive com este no código atual; nenhuma migração entre os dois foi encontrada neste levantamento.

Funcionamento​

  1. Toda operação passa primeiro por IdentityUserBrandingAccessService.assertActorCanManageUserBranding: o próprio usuário sempre pode gerenciar sua identidade visual; para gerenciar a de um terceiro, o ator precisa ser um administrador de plataforma (isPlatformAdmin: true) — não há permissão nomeada intermediária nesta checagem.
  2. Substituir (PUT .../photo ou .../signature): o arquivo é obrigatório (multipart/form-data, campo file); o backend inspeciona os bytes reais (assinatura de arquivo PNG/JPEG/WebP) e valida contra o tipo declarado — um Content-Type que não bate com o conteúdo real é rejeitado. Faz upload para o armazenamento antes de trocar a referência no banco; se a gravação no banco falhar depois do upload, o arquivo recém-enviado é removido.
  3. Depois de trocar a referência com sucesso, o arquivo anterior (se havia um) é apagado do armazenamento — nunca fica órfão.
  4. Ler (GET .../branding): gera uma URL de download assinada e de curta duração (5 minutos) para cada imagem configurada; se não há foto/assinatura, o campo correspondente vem null.
  5. Remover (DELETE .../photo ou .../signature): zera a referência no banco e depois apaga o arquivo do armazenamento; não falha se já não havia imagem configurada.

Endpoints​

MétodoRotaDescrição
GET/v1/users/:userId/brandingLê as URLs atuais de foto e assinatura
PUT/v1/users/:userId/photoSubstitui a foto do usuário
PUT/v1/users/:userId/signatureSubstitui a assinatura do usuário
DELETE/v1/users/:userId/photoRemove a foto do usuário
DELETE/v1/users/:userId/signatureRemove a assinatura do usuário

Versão: v1

Swagger: Identity — User administration and profile · Rota (Dev): http://localhost:3000/v1/users/:userId/photo

Permissões​

RotaGuardsRegra de acesso
GET/PUT/DELETE .../photo, .../signature, GET .../brandingIdentityOAuthAccessTokenGuardo próprio usuário, ou um administrador de plataforma (isPlatformAdmin: true) para gerenciar a de terceiros

Headers​

HeaderObrigatórioDescrição
AuthorizationSimBearer <access_token>
Content-TypeSim (PUT)multipart/form-data

Path parameters​

NomeTipoObrigatórioDescrição
userIduuidSimUsuário dono da imagem

Body​

PUT .../photo / .../signature: formulário multipart com um único campo:

CampoTipoObrigatórioValidação
filebinárioSimaté 5 MB (foto) / 2 MB (assinatura); PNG/JPEG/WebP com bytes reais coerentes com o Content-Type declarado

Response​

200 — GET .../branding (IdentityUserBrandingResponse):

json
{ "photo_url": "https://storage.exemplo.com/users/photo.jpg", "signature_url": null }

200 — demais operações (IdentityUserChangeResponse):

json
{ "message": "User photo updated." }

Erros​

Classe de erroerrorCodeStatusQuando ocorre
ForbiddenActionIDENTITY_USER_BRANDING_FORBIDDEN403ator sem permissão para gerenciar/ler a identidade visual do alvo
IdentityUserNotFoundErrorIDENTITY_USER_NOT_FOUND404usuário alvo inexistente, excluído ou inativo
ValidationErrorIDENTITY_USER_BRANDING_FILE_REQUIRED400file ausente ou vazio
— (validação de imagem)—400arquivo não reconhecido como PNG/JPEG/WebP válido, ou Content-Type não corresponde aos bytes
—IDENTITY_INVALID_OAUTH_ACCESS_TOKEN401token ausente, inválido, expirado ou revogado

Regras de negócio​

IDRegraComportamento esperado
RN-01Substituir nunca deixa arquivo órfãoupload primeiro; se a troca de referência falhar, o novo arquivo é removido; se tiver sucesso, o arquivo antigo é removido
RN-02Limites de tamanho por tipo5 MB para foto, 2 MB para assinatura, aplicados tanto no FileInterceptor do NestJS quanto na validação de domínio
RN-03Download nunca expõe URL permanentetoda leitura gera uma URL assinada nova, válida por 5 minutos
RN-04Remover é idempotenteremover uma imagem que já não existe não falha

Compliance​

Órgão / normaExigênciaComo a rota atende
LGPDarmazenamento seguro e acesso restritodownload só via URL assinada de curta duração, nunca link direto e permanente
HIPAA (parcial)transmissão segura e trilha de trocaupload via multipart/form-data sobre TLS; toda troca/remoção gera evento de auditoria
ANVISAintegridade da assinatura associada ao laudoevento de auditoria registra a troca; a associação da assinatura ao laudo em si pertence ao domínio de Laudo, fora deste módulo

Variáveis de ambiente​

Nenhuma específica a esta rota (usa a configuração geral de armazenamento do módulo identity).

Requisitos não funcionais​

RequisitoDefinição
IdempotênciaDELETE é idempotente; PUT sempre gera uma nova versão do arquivo
AuditoriaSim — identity.user.photo.updated/.removed, identity.user.signature.updated/.removed

Relacionado​

  • 🖥️ Tela: A confirmar — responsável: time de frontend; data: 24/09/2026.
  • 📂 Módulo: Usuário
  • 🖼️ Ativos do usuário — caminho versionado que também cobre PROFILE_PHOTO/SIGNATURE_IMAGE