Código interno do usuário — API
Cria, lista, atualiza e exclui o código interno que identifica um usuário (tipicamente um preparador/operador) dentro de uma unidade organizacional — um identificador curto usado por sistemas e fluxos que não trabalham com UUID. Cada combinação (usuário, unidade) tem no máximo um código interno ativo.
Funcionamento
- Criar: o ator pode criar um código interno para si mesmo em qualquer unidade à qual
pertença, ou para outro usuário se tiver a permissão
internal-code:writenaquela unidade. Em ambos os casos, o usuário alvo precisa efetivamente pertencer à unidade informada (por atribuição de tenant inteiro ou por atribuição direta na própria unidade) — senão a operação é tratada como "usuário não encontrado", não como "acesso negado", para não revelar unidades de terceiros. - Unicidade: só pode existir um código interno não excluído por par (usuário, unidade); tentar criar outro para o mesmo par é conflito.
- Listar: se o ator lista os próprios códigos, vê todas as unidades ativas às quais pertence.
Se lista os códigos de outro usuário, precisa da permissão
internal-code:read, e só vê as unidades que estão simultaneamente no escopo do ator e nas unidades ativas do usuário alvo. - Atualizar/excluir: mesma regra de autorização da criação (dono da unidade ou permissão
internal-code:write/internal-code:delete), reavaliada a partir do registro já existente — umForbiddenActionde escopo é convertido em "não encontrado" para não revelar a existência do código a quem não tem acesso à unidade.
Endpoints
| Método | Rota | Descrição |
|---|---|---|
| POST | /v1/users/internal-codes | Cria um código interno para um usuário em uma unidade |
| GET | /v1/users/:userId/internal-codes | Lista os códigos internos visíveis do usuário |
| PATCH | /v1/users/internal-codes/:internalCodeId | Atualiza o valor de um código interno |
| DELETE | /v1/users/internal-codes/:internalCodeId | Exclui (soft-delete) um código interno |
Versão: v1
Swagger: Identity — User internal codes · Rota (Dev): http://localhost:3000/v1/users/internal-codes
Permissões
| Rota | Guards | Regra de acesso |
|---|---|---|
POST /users/internal-codes (próprio) | IdentityOAuthAccessTokenGuard | ator precisa pertencer à unit_id informada |
POST /users/internal-codes (terceiro) | idem | ator precisa de internal-code:write na unit_id |
GET /users/:userId/internal-codes | idem | próprio: unidades ativas do ator; terceiro: internal-code:read + interseção de unidades |
PATCH .../:internalCodeId | idem | dono da unidade do código, ou internal-code:write |
DELETE .../:internalCodeId | idem | dono da unidade do código, ou internal-code:delete |
Headers
| Header | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Bearer <access_token> |
Content-Type | Sim (POST/PATCH) | application/json |
Path parameters
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
userId | uuid | Sim (GET) | Usuário cujos códigos internos serão listados |
internalCodeId | uuid | Sim (PATCH/DELETE) | Identificador do código interno |
Body
POST /users/internal-codes — IdentityUserInternalCodeCreateRequest:
json{ "internal_code": "OP-014", "unit_id": "0192f3c6-...-fe83b", "user_id": "8f2a...-uuid" }
| Campo | Tipo | Obrigatório | Validação |
|---|---|---|---|
internal_code | string | Sim | 1–20 caracteres |
unit_id | uuid | Sim | — |
user_id | uuid | Sim | — |
PATCH .../:internalCodeId — IdentityUserInternalCodeUpdateRequest:
json{ "internal_code": "OP-015" }
| Campo | Tipo | Obrigatório | Validação |
|---|---|---|---|
internal_code | string | Sim | 1–20 caracteres |
Response
201/200 — IdentityUserInternalCodeResponse:
json{ "id": "...", "internal_code": "OP-014", "unit_id": "0192f3c6-...-fe83b", "user_id": "8f2a...-uuid" }
204 — DELETE: sem corpo.
Erros
| Classe de erro | errorCode | Status | Quando ocorre |
|---|---|---|---|
ForbiddenAction | IDENTITY_USER_INTERNAL_CODE_FORBIDDEN | 403 | ator sem acesso à unidade e sem a permissão nomeada |
IdentityUserNotFoundError | IDENTITY_USER_NOT_FOUND | 404 | usuário alvo não pertence à unidade informada, ou está inativo |
AlreadyExistsError | IDENTITY_USER_INTERNAL_CODE_ALREADY_EXISTS | 409 | já existe código não excluído para (usuário, unidade) |
IdentityUserInternalCodeNotFoundError | IDENTITY_USER_INTERNAL_CODE_NOT_FOUND | 404 | internalCodeId inexistente, excluído, ou fora do escopo do ator |
| ValidationError | IDENTITY_USER_INTERNAL_CODE_INVALID | 400 | internal_code vazio ou com mais de 20 caracteres |
| — | IDENTITY_INVALID_OAUTH_ACCESS_TOKEN | 401 | token ausente, inválido, expirado ou revogado |
Regras de negócio
| ID | Regra | Comportamento esperado |
|---|---|---|
| RN-01 | Unicidade por (usuário, unidade) | uma segunda tentativa de criação para o mesmo par é 409 |
| RN-02 | Criar/editar para si mesmo não exige permissão nomeada | basta o ator pertencer à unidade |
| RN-03 | Criar/editar para terceiro exige permissão explícita | internal-code:write (criar/editar) ou internal-code:delete (excluir), escopada à unidade do código |
| RN-04 | Falta de acesso vira "não encontrado" nas operações sobre um recurso já existente | evita confirmar a existência de um código fora do escopo do ator |
Compliance
| Órgão / norma | Exigência | Como a rota atende |
|---|---|---|
| LGPD | minimização e auditoria de alteração | toda criação/edição/exclusão gera evento com ator, IP e clientId |
| ANVISA (indireto) | rastreabilidade operador↔ação | trilha de auditoria imutável por operação |
Variáveis de ambiente
Nenhuma específica a esta rota.
Requisitos não funcionais
| Requisito | Definição |
|---|---|
| Idempotência | Não — segunda criação para o mesmo par é conflito, não replay |
| Auditoria | Sim — identity.user.internal_code.created/.updated/.deleted |
Relacionado
- 🖥️ Tela:
A confirmar — responsável: time de frontend; data: 24/09/2026. - 📂 Módulo: Usuário
- 🔎 Diretório de usuários — filtro
internal_code