Módulo Usuário — visão geral
O módulo de usuário implementa o cadastro, o ciclo de vida e os recursos pessoais do usuário do
Portal 2.0: perfil próprio e de terceiros, administração por plataforma e por tenant, diretório de
busca, exportação assintona, códigos internos, identidade visual (foto/assinatura), vínculos com
serviços externos, ativos genéricos do usuário, snippets de texto pessoais e o fluxo de convite que
dá origem a uma conta nova. Ele vive em quatro pacotes do backend (NestJS), todos dentro de
identity/: user, user-asset, snippet e invitation.
Fonte de verdade. Este levantamento foi feito inteiramente a partir do código atual (branch
integration/with-fixlaudo) e dos testes em__test__. Não existe rascunho anterior deste módulo. Cartões de negócio do Bitrix (funil 562) descrevem o sistema legado (mm-pacs-portal-api, rotas/usuario/*, tabelastb_usuario*) e foram usados só como pista de intenção de produto — o campo que mapearia "status vs. código real" está vazio em todos os cartões consultados, então nenhuma regra de negócio foi copiada do Bitrix sem confirmação no código NestJS atual.
Prefixo de rotas e versionamento
Como em authentication, a API usa versionamento por URI (VersioningType.URI, versão padrão
1): toda rota deste módulo é servida sob /v1/... (ex.: /v1/users/me,
/v1/tenants/:tenantId/users), exceto o endpoint de resolução interna de serviço externo, que é
VERSION_NEUTRAL e carrega o v1 no próprio caminho (/internal/v1/external-services/:serviceName/resolve).
Arquitetura
Como os quatro pacotes se relacionam
useré o núcleo: entidade do usuário (IdentityUserEntity), perfil, segurança, atividade, administração por plataforma e por tenant, diretório de busca, exportação, código interno, identidade visual (foto/assinatura) e vínculo com serviço externo. Todos os outros pacotes deste módulo dependem dele (umuser-asset, umsnippete um convite aceito sempre apontam para umuserIdexistente aqui).user-asseté um armazenamento genérico e versionado de arquivos do usuário (hoje usado paraPROFILE_PHOTOeSIGNATURE_IMAGE), com fluxo de upload em duas etapas (sessão assinada + confirmação com hash). Ele coexiste com o caminho de foto/assinatura mais antigo do próprio pacoteuser(PUT /users/:userId/photoe/signature, upload direto multipart) — ver Identidade visual para a distinção confirmada no código.snippeté independente dos demais: textos pré-definidos privados ao dono, sem relação de dados comuser-assetouinvitation. Sua única dependência é a sessão OAuth do próprio usuário (bloqueia token delegado por serviço).invitationé o ponto de entrada de um usuário novo: cria e gerencia um convite por e-mail e, ao ser aceito, chama os serviços deuser(CreateIdentityUserService) e deidentity/authorization(AssignIdentityUserRoleService) para materializar a conta e seus perfis.
Onde este módulo se conecta com authentication/authorization
- Credencial e MFA (authentication): criar um usuário
(
CreateIdentityUserService) cria também suaIdentityCredentialEntity(senha com hash,emailVerified: false, sem TOTP/SafeID). Resetar TOTP, desbloquear conta e verificar e-mail são operações do pacoteauthentication, expostas aqui através deIdentityUserController(POST /users/:userId/totp/reset,POST /users/:userId/unlock,POST /users/me/email-verification). - Permissões e escopo (
identity/authorization): toda rota que não é "sobre mim mesmo" decide acesso por meio deAuthorizationClaimReader(é a conta umplatform-admin?) ou porResolveIdentityEffectivePermissionService/AuthorizationGuardcom permissões nomeadas (user:write,user:read,user:read-sensitive,user:export,user:export-sensitive,role:manage,internal-code:write,internal-code:read,internal-code:delete) escopadas por unidade ou tenant. Cada página de rota abaixo lista a permissão exigida. - Sessão: desativar um usuário (
SetIdentityUserActivityByPlatformAdminService) também revoga todas as sessões ativas dele viaRevokeAllIdentityUserSessionsService(identity/session).
Convenção de erros
Toda exceção de negócio estende BaseError/BusinessError/ValidationError e já carrega seu
statusCode e errorCode fixos no construtor. O filtro global (AllExceptionsFilter) apenas
repassa esses valores — não há uma tabela central de mapeamento status↔erro. Cada página de rota
abaixo lista as classes de erro realmente lançadas por aquele fluxo.
Páginas deste módulo
| Página | Cobre |
|---|---|
| Perfil próprio | GET/PATCH /users/me, PUT /users/me/professional-license, GET /users/me/security, POST /users/me/email-verification, PATCH/DELETE /users/me/recovery-email |
| Gerenciar usuário (plataforma) | POST /users, POST /users/admin, GET/DELETE /users/:userId, PATCH /users/:userId/fields, PATCH /users/:userId/activity, POST /users/:userId/unlock, POST /users/:userId/totp/reset |
| Usuário por tenant | POST/PATCH/DELETE /tenants/:tenantId/users(/:userId), PATCH /tenants/:tenantId/users/:userId/activity |
| Diretório de usuários | GET /users, POST /users/directory-lookups |
| Exportação de usuários | POST /user-exports, GET /user-exports/:exportJobId |
| Código interno | POST /users/internal-codes, GET /users/:userId/internal-codes, PATCH/DELETE /users/internal-codes/:internalCodeId |
| Identidade visual | GET /users/:userId/branding, PUT/DELETE /users/:userId/photo, PUT/DELETE /users/:userId/signature |
| Ativos do usuário | POST /users/:userId/assets/upload-sessions, POST /users/:userId/assets, GET /users/:userId/assets, GET /users/:userId/assets/:assetId/download-session, DELETE /users/:userId/assets/:assetId |
| Serviço externo | GET/PUT /users/:userId/external-services(/:serviceName), GET /internal/v1/external-services/:serviceName/resolve |
| Snippets | POST/GET /me/snippets, GET/PUT/DELETE /me/snippets/:snippetId |
| Convites | POST /invitations, GET/POST /invitations/accept/:token, POST /invitations/:invitationId/resend, DELETE /invitations/:invitationId |
:::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).
:::