User aggregate
# Users
Este documento descreve todas as operações disponíveis para o agregado User e seus sub-recursos, seguindo os padrões de Domain-Driven Design (DDD) e Command Query Responsibility Segregation (CQRS).
Índice
- Users (Usuários)
- UserAddresses (Endereços)
- UserDocuments (Documentos)
- UserFavoriteSkills (Habilidades Favoritas)
- UserFiles (Arquivos)
- UserDiscounts (Descontos)
- UserPaymentMethods (Métodos de Pagamento)
- UserNotifications (Notificações)
- UserRequests (Solicitações)
- UserRatings (Avaliações)
- UserPayments (Pagamentos)
- UserTermAcceptances (Aceites de Termos)
Users (Usuários)
Commands (Comandos)
1. Criação de Usuário (CreateUser)
Contrato: CreateUserCommand
Campos Necessários:
FirstName(string, obrigatório) - Primeiro nome do usuárioLastName(string, obrigatório) - Sobrenome do usuárioEmail(string, opcional) - Email do usuárioIdd(string, obrigatório) - Código de discagem internacional (IDD)Phone(string, obrigatório) - Número de telefoneBirthDate(DateTime, obrigatório) - Data de nascimentoGender(Gender enum, obrigatório) - Gênero do usuárioDocument(string, obrigatório) - Número do documentoDocumentType(DocumentType enum, obrigatório) - Tipo do documentoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
FirstName: Não pode ser vazio; Tamanho máximo: 99 caracteresLastName: Não pode ser vazio; Tamanho máximo: 99 caracteresEmail: Formato de email válido quando fornecido; Tamanho máximo: 100 caracteresIdd: Não pode ser vazio; Tamanho mínimo: 1 caractere; Tamanho máximo: 4 caracteres; Deve conter apenas dígitosPhone: Não pode ser vazio; Tamanho máximo: 15 caracteres; Deve conter apenas dígitos; Deve ser válido conforme validação doIPhoneServiceBirthDate: Não pode ser vazio; Usuário deve ter pelo menos 18 anosDocument: Não pode ser vazioDocumentType: Deve ser um valor válido do enum, (CPF, CNPJ e Unknow)Observation: Tamanho máximo: 500 caracteres quando fornecido
Retorno: CreateUserResponse contendo id do usuário criado.
Eventos de Domínio:
UserCreatedEvent- Disparado quando um usuário é criado
Regras de Negócio: Email e telefone devem ser únicos dentro do sistema, ou seja, não é possível persistir um novo usuário caso email/telefone estejam sendo utilizados.
Fluxo: Ao persistir um usuário na base, o evento UserCreatedEvent é disparado. Para criação de clientes, temos o worker Users-Worker onde é responsável para todo cliente persistido, cadastrá-lo no sistema financeiro, disparando o endpoint [POST] /v1/users/{userId}/financial-system
2. Atualização de Usuário (UpdateUser)
Contrato: UpdateUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do usuário (JsonIgnore)FirstName(string, obrigatório) - Primeiro nome do usuárioLastName(string, obrigatório) - Sobrenome do usuárioEmail(string, opcional) - Email do usuárioIdd(string, obrigatório) - Código de discagem internacionalPhone(string, obrigatório) - Número de telefoneBirthDate(DateTime, obrigatório) - Data de nascimentoGender(Gender enum, obrigatório) - Gênero do usuárioDocument(string, obrigatório) - Número do documentoDocumentType(DocumentType enum, obrigatório) - Tipo do documentoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
- Mesmas validações do
CreateUserCommand Id: Usuário deve existir- Usuário não pode estar com status
Deleted
Retorno: Void
Eventos de Domínio:
UserUpdatedEvent- Disparado quando um usuário é atualizado
Regras de Negócio:
- Não é possível atualizar um usuário deletado
- O perfil do usuário deve existir
3. Ativação de Usuário (ActiveUser)
Contrato: ActiveUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Observation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
Id: Usuário deve existir
Retorno: Void
Eventos de Domínio:
UserActivatedEvent- Disparado quando um usuário é ativadoUserUpdatedEvent- Disparado quando o status é alterado
Regras de Negócio:
- Altera o status do usuário para
Active
4. Atualização de Status (UpdateUserStatus)
Contrato: UpdateUserStatusCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Status(Status enum, obrigatório) - Novo status do usuárioObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
Id: Usuário deve existirStatus: Deve ser um valor válido do enum
Retorno: Void
Eventos de Domínio:
UserActivatedEvent- Disparado quando o status muda paraActiveUserUpdatedEvent- Disparado quando o status é alterado
5. Exclusão por LGPD (DeleteUserByLgpd)
Rota: DELETE /v1/users/{userId}/lgpd
Contrato: DeleteUserByLgpdCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do usuário (JsonIgnore, via rota)Observation(string, opcional) - Motivo da exclusãoAuthor(string, opcional) - Autor da operação
Validações:
Id: Usuário deve existir- Usuário não pode estar com status
Deleted
Retorno: 204 No Content
Eventos de Domínio:
UserDeletedByLgpdEvent- Disparado quando um usuário é deletado por LGPD
Descrição:
Este endpoint implementa a exclusão de dados conforme a Lei Geral de Proteção de Dados (LGPD - Lei nº 13.709/2018). Em vez de excluir fisicamente o registro, os dados pessoais são anonimizados para preservar a integridade referencial e permitir auditoria, cumprindo os requisitos legais de retenção de dados fiscais e comerciais.
Dados Anonimizados:
| Categoria | Campo | Valor Anonimizado |
|---|---|---|
| Perfil | Nome | ANONYMIZED USER |
| Perfil | anonymized_{userId}@deleted.lgpd |
|
| Perfil | Telefone | 00 000000000 |
| Perfil | Data Nascimento | 01/01/1900 |
| Perfil | Gênero | Unknown |
| Endereços | Rua, Cidade, Bairro | ANONYMIZED |
| Endereços | Número | 0 |
| Endereços | CEP | 00000-000 |
| Endereços | Estado | SP |
| Documentos | Código | 000.000.000-00 |
| Documentos | Tipo | Unknown |
| Métodos Pagamento | Nome | ANONYMIZED |
| Métodos Pagamento | Detalhes | { "anonymized": "true" } |
| Financeiro | CustomerId | null |
Regras de Negócio:
- Anonimização do Perfil:
- Nome, email, telefone, data de nascimento e gênero são substituídos por valores padrão
-
Email é gerado com formato único para evitar conflitos
-
Anonimização de Endereços:
- Todos os endereços do usuário são anonimizados
-
Mantém referência à cidade (CityId) para fins estatísticos
-
Anonimização de Documentos:
- CPF/CNPJ são substituídos por valor padrão
-
Tipo de documento alterado para
Unknown -
Anonimização de Métodos de Pagamento:
- Dados de cartão/conta são anonimizados
-
Tokens de pagamento são invalidados
-
Sistema Financeiro:
-
Referência ao sistema financeiro (CustomerId) é removida
-
Status:
- Status do usuário alterado para
Deleted - Impede futuras operações com este usuário
Conformidade Legal (LGPD):
- Art. 18, VI: Direito à eliminação dos dados pessoais
- Art. 16: Dados anonimizados não são considerados dados pessoais
- Art. 7, §5º: Retenção de dados para cumprimento de obrigação legal
- Nota Fiscal: Dados fiscais são preservados em formato anonimizado
Exemplo de Uso:
DELETE /v1/users/123e4567-e89b-12d3-a456-426614174000/lgpd
{
"observation": "Solicitação do titular via SAC - Protocolo #12345",
"author": "dpo@empresa.com"
}
Importante:
- Antes de executar, use o endpoint GET /v1/users/{userId}/deletion-eligibility para verificar se há transações pendentes
- A operação é irreversível - os dados originais não podem ser recuperados
- Registros de transações (pedidos, pagamentos) são mantidos com dados anonimizados para auditoria
6. Exclusão Forçada (ForceDeleteUser)
Contrato: ForceDeleteUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do usuário
Validações:
Id: Usuário deve existir
Retorno: Void
Regras de Negócio:
- Remove permanentemente o usuário do banco de dados
- Operação irreversível
7. Adicionar ao Sistema Financeiro (AddUserInFinancialSystem)
Contrato: AddUserInFinancialSystemCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Author(string, opcional) - Autor da operação
Validações:
UserId: Usuário deve existir
Retorno: AddUserInFinancialSystemResponse (contém o CustomerId gerado)
Regras de Negócio:
- Cria um cliente no sistema financeiro externo
- Armazena o
CustomerIdretornado CustomerIdnão pode exceder 500 caracteres
8. Remover do Sistema Financeiro (RemoveUserFromFinancialSystem)
Contrato: RemoveUserFromFinancialSystemCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Author(string, opcional) - Autor da operação
Validações:
UserId: Usuário deve existir
Retorno: Void
Regras de Negócio:
- Remove o
CustomerIddo usuário - Não remove o cliente do sistema financeiro externo
Queries (Consultas)
1. Buscar Usuário por ID (GetUserById)
Contrato: GetUserByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserByIdResponse
Descrição:
- Retorna todos os dados do usuário especificado
2. Pesquisar Usuários (SearchUsers)
Contrato: SearchUsersQuery
Parâmetros:
CityId(Guid, opcional) - Filtrar por cidadeStatus(Status enum, opcional) - Filtrar por statusName(string, opcional) - Filtrar por nome (busca parcial)Email(string, opcional) - Filtrar por email (busca parcial)Phone(string, opcional) - Filtrar por telefone (busca parcial)PageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da páginaStartDate(DateTime, opcional) - Data inicial de criaçãoEndDate(DateTime, opcional) - Data final de criação
Retorno: SearchUsersResponse (lista paginada de usuários)
Descrição:
- Retorna uma lista paginada de usuários conforme os filtros aplicados
3. Verificar Elegibilidade de Exclusão (CheckUserDeletionEligibility)
Rota: GET /v1/users/{userId}/deletion-eligibility
Contrato: CheckUserDeletionEligibilityQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: CheckUserDeletionEligibilityResponse
- CanBeDeleted (bool) - Indica se o usuário pode ser excluído permanentemente
- Reason (string) - Motivo explicando a recomendação
- TotalOrders (int) - Total de pedidos do usuário
- TotalRequests (int) - Total de solicitações do usuário
- TotalPayments (int) - Total de pagamentos do usuário
- HasPendingTransactions (bool) - Indica se há transações pendentes
Descrição:
Este endpoint valida se um usuário pode ser excluído permanentemente do sistema ou se seus dados devem ser mascarados (anonimizados) para manter a integridade histórica.
Regras de Negócio:
- Pode ser excluído (
CanBeDeleted = true): -
Usuário não possui nenhum histórico de transações (pedidos, solicitações, pagamentos)
-
Deve ser mascarado (
CanBeDeleted = false): - Usuário possui transações pendentes → Aguardar conclusão/cancelamento
- Usuário possui histórico de transações → Dados devem ser mascarados para auditoria
Exemplo de Resposta (pode ser excluído):
{
"canBeDeleted": true,
"reason": "User has no transaction history and can be permanently deleted.",
"totalOrders": 0,
"totalRequests": 0,
"totalPayments": 0,
"hasPendingTransactions": false
}
Exemplo de Resposta (deve ser mascarado):
{
"canBeDeleted": false,
"reason": "User has transaction history. Data must be masked to preserve records.",
"totalOrders": 5,
"totalRequests": 3,
"totalPayments": 2,
"hasPendingTransactions": false
}
Exemplo de Resposta (transações pendentes):
{
"canBeDeleted": false,
"reason": "User has pending transactions. Wait until all are completed or cancelled.",
"totalOrders": 2,
"totalRequests": 1,
"totalPayments": 1,
"hasPendingTransactions": true
}
UserAddresses (Endereços)
Commands (Comandos)
1. Criar Endereço de Usuário (CreateUserAddress)
Contrato: CreateUserAddressCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)CityId(Guid, opcional) - Identificador da cidadeStreet(string, obrigatório) - RuaNumber(string, obrigatório) - NúmeroComplement(string, opcional) - ComplementoCity(string, obrigatório) - CidadeNeighborhood(string, obrigatório) - BairroState(string, obrigatório) - EstadoPostalCode(string, obrigatório) - CEPObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioStreet: Não pode ser vazio; Tamanho máximo: 150 caracteresNumber: Não pode ser vazio; Tamanho máximo: 10 caracteresCity: Não pode ser vazio; Tamanho máximo: 100 caracteresNeighborhood: Não pode ser vazio; Tamanho máximo: 100 caracteresState: Não pode ser vazio; Tamanho máximo: 2 caracteres; Deve ser um estado válido brasileiro (UF) - Estados aceitos: AC, AL, AP, AM, BA, CE, DF, ES, GO, MA, MT, MS, MG, PA, PB, PR, PE, PI, RJ, RN, RS, RO, RR, SC, SP, SE, TOPostalCode: Não pode ser vazio; Deve corresponder ao padrão XXXXX-XXX (formato brasileiro)Observation: Tamanho máximo: 500 caracteres quando fornecido
Retorno: CreateUserAddressResponse
Regras de Negócio:
- Não pode adicionar endereço duplicado
- O primeiro endereço adicionado é automaticamente definido como padrão
- Remove o flag de padrão de outros endereços quando um novo é adicionado
2. Deletar Endereço de Usuário (DeleteUserAddress)
Contrato: DeleteUserAddressCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do endereçoUserId(Guid, obrigatório) - Identificador do usuário
Validações:
- Endereço deve existir para o usuário
Retorno: Void
Regras de Negócio:
- Remove o endereço do usuário
3. Definir Endereço Padrão (SetDefaultAddress)
Contrato: SetDefaultAddressCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioUserAddressId(Guid, obrigatório) - Identificador do endereçoAuthor(string, opcional) - Autor da operação
Validações:
- Endereço deve existir para o usuário
Retorno: Void
Regras de Negócio:
- Remove o flag de padrão de todos os outros endereços
- Define o endereço especificado como padrão
4. Atualizar Endereço de Usuário (UpdateUserAddress)
Contrato: UpdateUserAddressCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)UserAddressId(Guid, obrigatório) - Identificador do endereço (JsonIgnore)CityId(Guid, opcional) - Identificador da cidadeName(string, opcional) - Nome/apelido do endereçoStreet(string, obrigatório) - RuaNumber(string, obrigatório) - NúmeroComplement(string, opcional) - ComplementoCity(string, opcional) - Cidade (obrigatório se CityId não fornecido)Neighborhood(string, obrigatório) - BairroState(string, opcional) - Estado (obrigatório se CityId não fornecido)PostalCode(string, obrigatório) - CEPObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioUserAddressId: Não pode ser vazio; Endereço deve existirStreet: Não pode ser vazio; Tamanho máximo: 150 caracteresNumber: Não pode ser vazio; Tamanho máximo: 10 caracteresCity: Obrigatório seCityIdnão fornecido; Tamanho máximo: 100 caracteresNeighborhood: Não pode ser vazio; Tamanho máximo: 100 caracteresState: Obrigatório seCityIdnão fornecido; Tamanho máximo: 2 caracteres (UF)PostalCode: Não pode ser vazio; Formato: XXXXX-XXX
Retorno: Void
Regras de Negócio:
- Atualiza os dados do endereço especificado
- Se
CityIdfor fornecido,CityeStatesão ignorados - Se
CityIdnão for fornecido,CityeStatesão obrigatórios
Queries (Consultas)
1. Buscar Endereços do Usuário (GetUserAddresses)
Contrato: GetUserAddressesQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserAddressesResponse (lista de endereços)
Descrição:
- Retorna todos os endereços de um usuário
2. Buscar Endereço por ID (GetUserAddressById)
Contrato: GetUserAddressByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do endereçoUserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserAddressByIdResponse
Descrição:
- Retorna um endereço específico do usuário
UserDocuments (Documentos)
Commands (Comandos)
1. Criar Documento de Usuário (CreateUserDocument)
Contrato: CreateUserDocumentCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Document(string, obrigatório) - Número do documentoType(DocumentType enum, obrigatório) - Tipo do documentoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioDocument: Não pode ser vazioType: Deve ser um valor válido do enum
Retorno: CreateUserDocumentResponse
Regras de Negócio:
- Não pode adicionar documento duplicado
- Cada usuário pode ter múltiplos documentos
2. Deletar Documento de Usuário (DeleteUserDocument)
Contrato: DeleteUserDocumentCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do documentoUserId(Guid, obrigatório) - Identificador do usuário
Validações:
- Documento deve existir para o usuário
Retorno: Void
Regras de Negócio:
- Remove o documento do usuário
3. Atualizar Documento de Usuário (UpdateUserDocument)
Contrato: UpdateUserDocumentCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)UserDocumentId(Guid, obrigatório) - Identificador do documento (JsonIgnore)Document(string, obrigatório) - Número do documentoType(DocumentType enum, obrigatório) - Tipo do documentoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioUserDocumentId: Não pode ser vazio; Documento deve existirDocument: Não pode ser vazioType: Deve ser um valor válido do enum
Retorno: Void
Regras de Negócio:
- Atualiza os dados do documento especificado
- Não pode duplicar documento existente
Queries (Consultas)
1. Buscar Documentos do Usuário (GetUserDocuments)
Contrato: GetUserDocumentsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserDocumentsResponse (lista de documentos)
Descrição:
- Retorna todos os documentos de um usuário
2. Buscar Documento por ID (GetUserDocumentById)
Contrato: GetUserDocumentByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do documentoUserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserDocumentByIdResponse
Descrição:
- Retorna um documento específico do usuário
UserFavoriteSkills (Habilidades Favoritas)
Commands (Comandos)
1. Criar Habilidade Favorita (CreateUserFavoriteSkill)
Contrato: CreateUserFavoriteSkillCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)SkillId(Guid, obrigatório) - Identificador da habilidadeScore(int, obrigatório) - Pontuação da preferênciaObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioSkillId: Deve existirScore: Deve estar dentro do intervalo válido
Retorno: CreateUserFavoriteSkillResponse
Regras de Negócio:
- Não pode adicionar habilidade favorita duplicada
- A habilidade deve existir no sistema
2. Atualizar Habilidade Favorita (UpdateUserFavoriteSkill)
Contrato: UpdateUserFavoriteSkillCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)Id(Guid, obrigatório) - Identificador da habilidade favorita (JsonIgnore)Score(int, obrigatório) - Nova pontuaçãoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
- Habilidade favorita deve existir para o usuário
Score: Deve estar dentro do intervalo válido
Retorno: Void
Regras de Negócio:
- Atualiza a pontuação e observação da habilidade favorita
3. Deletar Habilidade Favorita (DeleteUserFavoriteSkill)
Contrato: DeleteUserFavoriteSkillCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioId(Guid, obrigatório) - Identificador da habilidade favorita
Validações:
- Habilidade favorita deve existir para o usuário
Retorno: Void
Regras de Negócio:
- Remove a habilidade favorita do usuário
Queries (Consultas)
1. Buscar Habilidades Favoritas do Usuário (GetUserFavoriteSkills)
Contrato: GetUserFavoriteSkillsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserFavoriteSkillsResponse (lista de habilidades favoritas)
Descrição:
- Retorna todas as habilidades favoritas de um usuário
2. Buscar Habilidade Favorita por ID (GetUserFavoriteSkillById)
Contrato: GetUserFavoriteSkillByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador da habilidade favoritaUserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserFavoriteSkillByIdResponse
Descrição:
- Retorna uma habilidade favorita específica do usuário
UserFiles (Arquivos)
Visão Geral
O recurso UserFile gerencia arquivos associados a usuários, como comprovantes de endereço, imagens de documentos, fotos de perfil, etc. Os arquivos são armazenados em um serviço de storage externo e podem ser vinculados a diferentes origens (endereços, documentos, perfil).
Endpoints
| Método | Rota | Descrição |
|---|---|---|
| POST | /v1/users/{userId}/files/address/{userAddressId} |
Upload de arquivo para endereço |
| POST | /v1/users/{userId}/files/documents/{userDocumentId} |
Upload de arquivo para documento |
| DELETE | /v1/users/{userId}/files/{fileId} |
Deletar arquivo |
| GET | /v1/users/{userId}/files/{fileId} |
Buscar arquivo por ID |
| GET | /v1/users/{userId}/files/search |
Pesquisar arquivos |
Commands (Comandos)
1. Upload de Arquivo para Endereço (CreateAddressFile)
Rota: POST /v1/users/{userId}/files/address/{userAddressId}
Content-Type: multipart/form-data
Parâmetros de Rota:
userId(Guid, obrigatório) - Identificador do usuáriouserAddressId(Guid, obrigatório) - Identificador do endereço
Form Data:
File(IFormFile, obrigatório) - Arquivo a ser enviado (ex: comprovante de endereço)Observation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Retorno: CreateUserFileResponse
- Id (Guid) - Identificador do arquivo criado
Regras de Negócio:
- O endereço deve existir e pertencer ao usuário
- Não pode adicionar arquivo duplicado (mesmo endereço e nome)
- O arquivo é armazenado em serviço de storage externo
- OriginType é automaticamente definido como
UserAddress
Exemplo de Resposta:
{
"id": "123e4567-e89b-12d3-a456-426614174000"
}
2. Upload de Arquivo para Documento (CreateDocumentFile)
Rota: POST /v1/users/{userId}/files/documents/{userDocumentId}
Content-Type: multipart/form-data
Parâmetros de Rota:
userId(Guid, obrigatório) - Identificador do usuáriouserDocumentId(Guid, obrigatório) - Identificador do documento
Form Data:
File(IFormFile, obrigatório) - Arquivo a ser enviado (ex: foto do documento)Observation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Retorno: CreateUserFileResponse
- Id (Guid) - Identificador do arquivo criado
Regras de Negócio:
- O documento deve existir e pertencer ao usuário
- Não pode adicionar arquivo duplicado (mesmo documento e nome)
- O arquivo é armazenado em serviço de storage externo
- OriginType é automaticamente definido como
UserDocument
3. Deletar Arquivo de Usuário (DeleteUserFile)
Rota: DELETE /v1/users/{userId}/files/{fileId}
Parâmetros de Rota:
userId(Guid, obrigatório) - Identificador do usuáriofileId(Guid, obrigatório) - Identificador do arquivo
Retorno: 204 No Content
Regras de Negócio:
- O arquivo deve existir e pertencer ao usuário
- Remove o arquivo do banco de dados e do storage externo
Queries (Consultas)
1. Buscar Arquivo por ID (GetUserFileById)
Rota: GET /v1/users/{userId}/files/{fileId}
Parâmetros de Rota:
userId(Guid, obrigatório) - Identificador do usuáriofileId(Guid, obrigatório) - Identificador do arquivo
Retorno: GetUserFileByIdResponse
- Id (Guid) - Identificador do arquivo
- OriginIdentifier (Guid) - Identificador da origem (endereço, documento, etc.)
- OriginType (FileOriginType) - Tipo de origem
- ContentType (string) - Tipo MIME do arquivo
- Length (long) - Tamanho do arquivo em bytes
- Name (string) - Nome do arquivo
- Path (string) - Caminho no storage
- PublicUrl (string) - URL pública para acesso ao arquivo
- Created (DateTime) - Data de criação
- Updated (DateTime?) - Data de atualização
- Observation (string?) - Observações
- AuthorCreated (string?) - Autor da criação
- AuthorUpdated (string?) - Autor da atualização
Exemplo de Resposta:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"originIdentifier": "456e7890-e12b-34d5-b678-901234567890",
"originType": "UserDocument",
"contentType": "image/jpeg",
"length": 245789,
"name": "documento_frente.jpg",
"path": "users/123/documents/documento_frente.jpg",
"publicUrl": "https://storage.example.com/users/123/documents/documento_frente.jpg",
"created": "2024-12-01T10:30:00Z",
"updated": null,
"observation": "Frente do documento",
"authorCreated": "user@email.com",
"authorUpdated": null
}
2. Pesquisar Arquivos do Usuário (SearchUserFiles)
Rota: GET /v1/users/{userId}/files/search
Parâmetros de Rota:
userId(Guid, obrigatório) - Identificador do usuário
Query Parameters:
OriginIdentifier(Guid?, opcional) - Filtrar por identificador de origemOriginType(FileOriginType?, opcional) - Filtrar por tipo de origemStartDate(DateTime?, opcional) - Data inicial de criaçãoEndDate(DateTime?, opcional) - Data final de criação
Retorno: SearchUserFilesResponse (lista de arquivos)
Exemplo de Uso:
GET /v1/users/123/files/search?originType=UserDocument&startDate=2024-01-01
Tipos e Enums
FileOriginType
public enum FileOriginType
{
Unknown, // Desconhecido
UserAddress, // Arquivo de endereço (comprovante)
UserDocument, // Arquivo de documento (foto, scan)
UserRequest, // Arquivo de solicitação
UserResponse, // Arquivo de resposta
UserProfile // Arquivo de perfil (foto)
}
UserDiscounts (Descontos)
Commands (Comandos)
1. Adicionar Desconto ao Usuário (AddUserDiscount)
Contrato: AddUserDiscountCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioDiscountId(Guid, obrigatório) - Identificador do desconto
Validações:
UserId: Usuário deve existirDiscountId: Desconto deve existir
Retorno: Void
Regras de Negócio:
- Não pode adicionar desconto duplicado
- Valida se o desconto pode ser utilizado (limites, datas, etc.)
2. Deletar Desconto do Usuário (DeleteUserDiscount)
Contrato: DeleteUserDiscountCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioDiscountId(Guid, obrigatório) - Identificador do desconto
Validações:
- Desconto deve estar vinculado ao usuário
Retorno: Void
Regras de Negócio:
- Remove o desconto do usuário
Queries (Consultas)
1. Pesquisar Descontos do Usuário (SearchUserDiscount)
Contrato: SearchUserDiscountQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da página
Retorno: SearchUserDiscountResponse (lista paginada de descontos)
Descrição:
- Retorna uma lista paginada de descontos do usuário
2. Buscar Desconto por ID (GetUserDiscountById)
Contrato: GetUserDiscountByIdQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioDiscountId(Guid, obrigatório) - Identificador do desconto
Retorno: GetUserDiscountByIdResponse
Descrição:
- Retorna um desconto específico do usuário
UserPaymentMethods (Métodos de Pagamento)
Commands (Comandos)
1. Criar Método de Pagamento PIX (CreatePixPaymentMethod)
Contrato: CreatePixPaymentMethodCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioAddressKey(string, obrigatório) - Chave PIXType(PixType enum, obrigatório) - Tipo da chave PIX (CPF, CNPJ, Email, Phone, Random)IsDefault(bool, obrigatório) - Se é o método padrãoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioAddressKey: Não pode ser vazioType: Deve ser um valor válido do enumIsDefault: Não pode ser nulo
Retorno: CreatePixPaymentMethodResponse
Regras de Negócio:
- Usuário pode ter no máximo 5 métodos de pagamento
- Se
IsDefaultfortrue, removes o flag de padrão de outros métodos do mesmo propósito - Se o método já existe, atualiza ao invés de criar
2. Criar Método de Pagamento com Cartão de Crédito (CreateCreditCardPaymentMethod)
Contrato: CreateCreditCardPaymentMethodCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioHolderName(string, obrigatório) - Nome do titular do cartãoNumber(string, obrigatório) - Número do cartãoExpiryMonth(string, obrigatório) - Mês de expiração (MM)ExpiryYear(string, obrigatório) - Ano de expiração (YY ou YYYY)Ccv(string, obrigatório) - Código de segurançaIsDefault(bool, obrigatório) - Se é o método padrãoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioHolderName: Não pode ser vazioNumber: Não pode ser vazio; Deve ter formato válido de cartãoExpiryMonth: Deve ser um mês válido (01-12)ExpiryYear: Deve ser um ano válidoCcv: Não pode ser vazio; Deve ter 3 ou 4 dígitosIsDefault: Não pode ser nulo
Retorno: CreateCreditCardPaymentMethodResponse
Regras de Negócio:
- Mesmas regras do PIX
- Os dados do cartão são armazenados de forma tokenizada no sistema financeiro
3. Criar Método de Pagamento com Transferência Bancária (CreateBankTransferPaymentMethod)
Contrato: CreateBankTransferPaymentMethodCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioBank(string, obrigatório) - Nome do bancoOwnerName(string, obrigatório) - Nome do titular da contaDocument(string, obrigatório) - CPF/CNPJ do titularAgency(string, obrigatório) - AgênciaAccount(string, obrigatório) - Número da contaAccountDigit(string, obrigatório) - Dígito verificador da contaIsDefault(bool, obrigatório) - Se é o método padrãoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioBank: Não pode ser vazioOwnerName: Não pode ser vazioDocument: Não pode ser vazio; Deve ser um CPF ou CNPJ válidoAgency: Não pode ser vazioAccount: Não pode ser vazioAccountDigit: Não pode ser vazioIsDefault: Não pode ser nulo
Retorno: CreateBankTransferPaymentMethodResponse
Regras de Negócio:
- Mesmas regras do PIX
Queries (Consultas)
1. Buscar Métodos de Pagamento do Usuário (GetUserPaymentMethods)
Contrato: GetUserPaymentMethodsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: GetUserPaymentMethodsResponse (lista de métodos de pagamento)
Descrição:
- Retorna todos os métodos de pagamento de um usuário
2. Buscar Método de Pagamento por ID (GetUserPaymentMethodById)
Contrato: GetUserPaymentMethodByIdQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioPaymentMethodId(Guid, obrigatório) - Identificador do método de pagamento
Retorno: GetUserPaymentMethodByIdResponse
Descrição:
- Retorna um método de pagamento específico do usuário
3. Buscar Template de Método de Pagamento (GetUserPaymentMethodTemplate)
Contrato: GetUserPaymentMethodTemplateQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioPaymentType(PaymentType enum, obrigatório) - Tipo do método de pagamento
Retorno: GetUserPaymentMethodTemplateResponse
Descrição:
- Retorna o template/estrutura necessária para criar um método de pagamento específico
UserNotifications (Notificações)
Commands (Comandos)
1. Criar Notificação (CreateNotification)
Contrato: CreateNotificationCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)NotificationType(UserNotificationType enum, obrigatório) - Tipo da notificaçãoParameters(Dictionary, obrigatório) - Parâmetros da notificação CorrelationId(Guid, padrão: Guid.NewGuid()) - Identificador de correlaçãoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazioNotificationType: Deve ser um valor válido do enumParameters: Deve conter os parâmetros necessários para o tipo de notificação
Retorno: CreateNotificationResponse
Eventos de Domínio:
UserNotificationCreatedEvent- Disparado quando uma notificação é criada
Regras de Negócio:
- A notificação é criada com status
Pending - Os parâmetros variam conforme o tipo de notificação
2. Reenviar Notificação (ResendNotification)
Contrato: ResendNotificationCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioNotificationId(Guid, obrigatório) - Identificador da notificação
Validações:
- Notificação deve existir para o usuário
Retorno: ResendNotificationResponse
Regras de Negócio:
- Cancela a notificação antiga
- Cria uma nova notificação com os mesmos parâmetros
- Dispara o evento
UserNotificationCreatedEvent
3. Atualizar Notificação (UpdateNotification)
Contrato: UpdateNotificationCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário (JsonIgnore)NotificationId(Guid, obrigatório) - Identificador da notificação (JsonIgnore)Status(NotificationStatus enum, obrigatório) - Novo status da notificaçãoErrorMessage(string, opcional) - Mensagem de erro (quando status é Failed)
Validações:
- Notificação deve existir para o usuário
Status: Deve ser um valor válido do enumErrorMessage: Obrigatório quando status éFailed
Retorno: Void
Regras de Negócio:
- Atualiza o status da notificação
- Se status for
Sent, marca como enviada - Se status for
Failed, armazena mensagem de erro - Se status for
Cancelled, cancela a notificação
Queries (Consultas)
1. Pesquisar Notificações (SearchNotifications)
Contrato: SearchNotificationsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioNotificationType(UserNotificationType enum, opcional) - Filtrar por tipoStatus(NotificationStatus enum, opcional) - Filtrar por statusPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da páginaStartDate(DateTime, opcional) - Data inicialEndDate(DateTime, opcional) - Data final
Retorno: SearchNotificationsResponse (lista paginada de notificações)
Descrição:
- Retorna uma lista paginada de notificações conforme os filtros aplicados
UserRequests (Solicitações)
Commands (Comandos)
1. Criar Solicitação de Usuário (CreateUserRequest)
Contrato: CreateUserRequestCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioRequestId(Guid, obrigatório) - Identificador da solicitaçãoAuthor(string, opcional) - Autor da operação
Validações:
UserId: Usuário deve existirRequestId: Solicitação deve existir
Retorno: Void
Regras de Negócio:
- Não pode vincular solicitação duplicada
- Vincula uma solicitação (Request) ao usuário
Queries (Consultas)
1. Buscar Solicitação por ID (GetUserRequestById)
Contrato: GetUserRequestByIdQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioRequestId(Guid, obrigatório) - Identificador da solicitação
Retorno: GetUserRequestByIdResponse
Descrição:
- Retorna uma solicitação específica do usuário
2. Pesquisar Solicitações do Usuário (SearchUserRequests)
Contrato: SearchUserRequestsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioStatus(RequestStatus enum, opcional) - Filtrar por statusPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da páginaStartDate(DateTime, opcional) - Data inicialEndDate(DateTime, opcional) - Data final
Retorno: SearchUserRequestsResponse (lista paginada de solicitações)
Descrição:
- Retorna uma lista paginada de solicitações do usuário conforme os filtros aplicados
Eventos de Domínio
User
- UserCreatedEvent - Disparado quando um usuário é criado
- UserUpdatedEvent - Disparado quando um usuário é atualizado
- UserActivatedEvent - Disparado quando um usuário é ativado
- UserDeletedByLgpdEvent - Disparado quando um usuário é deletado por LGPD
UserNotifications
- UserNotificationCreatedEvent - Disparado quando uma notificação é criada
UserRatings (Avaliações de Usuário)
Visão Geral
O recurso UserRating gerencia as avaliações que os usuários fazem sobre os profissionais após a conclusão de um serviço. Cada avaliação está relacionada a um item de pedido (OrderItem) e gera uma performance para o profissional.
Commands (Comandos)
1. Criar Avaliação (CreateUserRating)
Contrato: CreateUserRatingCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário que avaliaOrderItemId(Guid, obrigatório) - Identificador do item do pedidoProfessionalUserId(Guid, obrigatório) - Identificador do profissional avaliadoRating(int, obrigatório) - Nota da avaliação (1 a 5)Comment(string, opcional) - Comentário da avaliaçãoHighlightedSkills(List, opcional) - Habilidades destacadas Author(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazio; Usuário deve existirOrderItemId: Não pode ser vazio; Item do pedido deve existirProfessionalUserId: Não pode ser vazio; Profissional deve existirRating: Deve estar entre 1 e 5
Retorno: CreateUserRatingResponse
- Id (Guid) - Identificador da avaliação criada
- ProfessionalUserPerformanceId (Guid) - Identificador da performance criada
Regras de Negócio:
- Um usuário só pode avaliar um item de pedido uma vez
- A avaliação cria automaticamente uma ProfessionalUserPerformance
- O pedido deve estar concluído para permitir avaliação
Exemplo de Uso:
{
"userId": "123e4567-e89b-12d3-a456-426614174000",
"orderItemId": "456e7890-e12b-34d5-b678-901234567890",
"professionalUserId": "789a0123-b45c-67d8-e901-234567890abc",
"rating": 5,
"comment": "Excelente profissional, muito pontual e cuidadoso!",
"highlightedSkills": [
"skill-id-1",
"skill-id-2"
],
"author": "user@email.com"
}
Queries (Consultas)
1. Buscar Avaliação por ID (GetUserRatingById)
Contrato: GetUserRatingByIdQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioUserRatingId(Guid, obrigatório) - Identificador da avaliação
Retorno: GetUserRatingByIdResponse
- Id (Guid) - Identificador da avaliação
- OrderItemId (Guid) - Identificador do item do pedido
- TaskName (string) - Nome da tarefa avaliada
- ProfessionalUserPerformanceId (Guid) - ID da performance
- ProfessionalUser (object) - Dados do profissional
- Id (Guid) - Identificador do profissional
- Fullname (string) - Nome completo do profissional
- Rating (int) - Nota da avaliação
- Comment (string) - Comentário
- HighlightedSkills (DictionaryCreated (DateTime) - Data de criação
- Updated (DateTime?) - Data de atualização
- AuthorCreated (string) - Autor da criação
- AuthorUpdated (string) - Autor da atualização
Exemplo de Resposta:
{
"id": "rating-id",
"orderItemId": "order-item-id",
"taskName": "Limpeza Residencial",
"professionalUserPerformanceId": "performance-id",
"professionalUser": {
"id": "professional-id",
"fullname": "Carlos Silva"
},
"rating": 5,
"comment": "Excelente profissional!",
"highlightedSkills": {
"skill-id-1": "Pontualidade",
"skill-id-2": "Organização"
},
"created": "2024-12-01T14:30:00Z",
"updated": null,
"authorCreated": "user@email.com",
"authorUpdated": null
}
2. Pesquisar Avaliações (SearchUserRatings)
Contrato: SearchUserRatingsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioProfessionalUserId(Guid?, opcional) - Filtrar por profissionalMinRating(int?, opcional) - Nota mínimaMaxRating(int?, opcional) - Nota máximaPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 10) - Tamanho da página
Retorno: SearchUserRatingsResponse
- Lista paginada de avaliações
UserPayments (Pagamentos de Usuário)
Visão Geral
O recurso UserPayment gerencia os pagamentos realizados pelos usuários, relacionando-os com os pagamentos de pedidos (OrderPayment) e métodos de pagamento (UserPaymentMethod).
Commands (Comandos)
1. Criar Pagamento (CreateUserPayment)
Contrato: CreateUserPaymentCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioOrderPaymentId(Guid, obrigatório) - Identificador do pagamento do pedidoUserPaymentMethodId(Guid?, opcional) - Método de pagamento usadoAmount(decimal, obrigatório) - Valor do pagamentoObservation(string, opcional) - ObservaçõesAuthor(string, opcional) - Autor da operação
Validações:
UserId: Não pode ser vazio; Usuário deve existirOrderPaymentId: Não pode ser vazio; Pagamento do pedido deve existirAmount: Deve ser maior que 0
Retorno: CreateUserPaymentResponse
- Id (Guid) - Identificador do pagamento criado
Regras de Negócio:
- Relaciona o pagamento do usuário com o pagamento do pedido
- Pode estar associado a um método de pagamento salvo
2. Atualizar Pagamento (UpdateUserPayment)
Contrato: UpdateUserPaymentCommand
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioUserPaymentId(Guid, obrigatório) - Identificador do pagamentoStatus(PaymentStatus?, opcional) - Novo statusObservation(string, opcional) - ObservaçõesAuthor(string, opcional) - Autor da operação
Retorno: Void
Queries (Consultas)
1. Buscar Pagamento por ID (GetUserPaymentById)
Contrato: GetUserPaymentByIdQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioUserPaymentId(Guid, obrigatório) - Identificador do pagamento
Retorno: GetUserPaymentByIdResponse
- Id (Guid) - Identificador do pagamento
- OrderPaymentId (Guid) - ID do pagamento do pedido
- UserPaymentMethodId (Guid?) - ID do método de pagamento
- Amount (decimal) - Valor
- Status (string) - Status do pagamento
- Created (DateTime) - Data de criação
- Updated (DateTime?) - Data de atualização
- Observation (string) - Observações
- AuthorCreated (string) - Autor da criação
- AuthorUpdated (string) - Autor da atualização
2. Pesquisar Pagamentos (SearchUserPayments)
Contrato: SearchUserPaymentsQuery
Parâmetros:
UserId(Guid, obrigatório) - Identificador do usuárioOrderPaymentId(Guid?, opcional) - Filtrar por pagamento do pedidoStatus(PaymentStatus?, opcional) - Filtrar por statusStartDate(DateTime?, opcional) - Data inicialEndDate(DateTime?, opcional) - Data finalPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 10) - Tamanho da página
Retorno: SearchUserPaymentsResponse
- Lista paginada de pagamentos
Regras Gerais de Negócio
Usuário (User)
- Um usuário deve ter pelo menos 18 anos
- Email e telefone devem ser únicos no sistema (validação no handler)
- O primeiro documento adicionado é marcado como padrão
- O primeiro endereço adicionado é marcado como padrão
- Um usuário deletado (status
Deleted) não pode ser atualizado - Ao deletar por LGPD, os dados são anonimizados, não removidos
- O CustomerId não pode exceder 500 caracteres
Endereços (UserAddresses)
- Não pode haver endereços duplicados para o mesmo usuário
- Apenas um endereço pode ser marcado como padrão
- O CEP deve seguir o formato brasileiro (XXXXX-XXX)
- Ao excluir um endereço padrão, o mais recente é definido como novo padrão
Documentos (UserDocuments)
- Não pode haver documentos duplicados para o mesmo usuário
- Documentos podem ser validados posteriormente
- Documentos podem ser atualizados
Habilidades Favoritas (UserFavoriteSkills)
- Não pode haver habilidades favoritas duplicadas para o mesmo usuário
- A habilidade deve existir no agregado de Skills
Arquivos (UserFiles)
- Não pode haver arquivos duplicados (mesmo OriginIdentifier e Name)
- Arquivos são armazenados em serviço externo de storage
Descontos (UserDiscounts)
- Não pode haver descontos duplicados para o mesmo usuário
- O desconto deve estar válido (datas, limites de uso, etc.)
Métodos de Pagamento (UserPaymentMethods)
- Usuário pode ter no máximo 5 métodos
- Apenas um método pode ser padrão por propósito (recebimento/pagamento)
- Dados sensíveis de cartão são tokenizados
Notificações (UserNotifications)
- Notificações são criadas com status
Pending - Notificações podem ser reenviadas (cria nova e cancela a antiga)
- Parâmetros variam conforme o tipo de notificação
Solicitações (UserRequests)
- Não pode vincular solicitação duplicada ao mesmo usuário
- A solicitação deve existir no agregado de Requests
Avaliações (UserRatings)
- Um usuário só pode avaliar um item de pedido uma vez
- Avaliação cria automaticamente uma ProfessionalUserPerformance
- Rating deve estar entre 1 e 5
Pagamentos (UserPayments)
- Relaciona pagamentos do usuário com pagamentos de pedidos
- Pode estar associado a um método de pagamento salvo
Padrões Utilizados
CQRS (Command Query Responsibility Segregation)
- Commands: Operações que modificam o estado (Create, Update, Delete)
- Queries: Operações que apenas consultam dados (Get, Search)
DDD (Domain-Driven Design)
- Agregados: User é o agregado raiz
- Entidades: UserAddress, UserDocument, UserFavoriteSkill, UserFile, UserDiscount, UserPaymentMethod, UserNotification, UserRequest, UserRating, UserPayment, UserTermAcceptance
- Value Objects: Name, Email, Phone, BirthDate, Gender, Document, Address, etc.
- Domain Events: Eventos disparados quando ações importantes ocorrem
- Invariantes: Regras de negócio mantidas pelo agregado
Repository Pattern
- Acesso a dados abstraído através de interfaces de repositório
MediatR Pattern
- Commands e Queries implementados como requests do MediatR
- Handlers processam as requisições
FluentValidation
- Validações declarativas para commands e queries
UserTermAcceptances (Aceites de Termos)
Gerenciamento de aceites de termos e políticas pelo usuário.
Commands (Comandos)
1. Aceitar Termo (AcceptUserTerm)
Endpoint: POST /v1/users/{userId}/term-acceptances
Contrato: AcceptUserTermCommand
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termo a ser aceitoIpAddress(string, opcional) - Endereço IP do usuárioUserAgent(string, opcional) - User-Agent do navegador/aplicativoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
TermId: Não pode ser vazio; Termo deve existirIpAddress: Tamanho máximo: 45 caracteresUserAgent: Tamanho máximo: 500 caracteres
Regras de Negócio (DDD - Entidade User):
- O termo deve estar com status Active para ser aceito
- O usuário não pode aceitar o mesmo termo mais de uma vez
- A validação é feita no método
AcceptTermda entidade User
Exceções:
RuleViolationDomainException("Can only accept active terms.")- Termo não está ativoRuleViolationDomainException("User has already accepted this term.")- Termo já aceito
Retorno: AcceptUserTermResponse
- Id (Guid) - Identificador do aceite criado
Queries (Consultas)
1. Verificar Termos Pendentes (HasPendingTerms)
Endpoint: GET /v1/users/{userId}/term-acceptances/has-pending
Contrato: HasPendingTermsQuery
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: HasPendingTermsResponse
- HasPendingTerms (bool) - true se existem termos ativos não aceitos pelo usuário
Lógica (DDD):
1. Busca usuário com seus aceites de termos via GetUserWithTermAcceptancesAsync
2. Busca todos os termos ativos via GetActiveTermsAsync
3. Usa método HasAcceptedAllRequiredTerms da entidade User para verificar
4. Retorna true se existir algum termo ativo não aceito
2. Buscar Aceite por ID (GetUserTermAcceptanceById)
Endpoint: GET /v1/users/{userId}/term-acceptances/{id}
Contrato: GetUserTermAcceptanceByIdQuery
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioTermAcceptanceId(Guid, obrigatório) - Identificador do aceite
Retorno: GetUserTermAcceptanceByIdResponse
- Id (Guid) - Identificador do aceite
- UserId (Guid) - Identificador do usuário
- TermId (Guid) - Identificador do termo
- TermTitle (string) - Título do termo
- TermType (TermType) - Tipo do termo
- TermStatus (TermStatus) - Status atual do termo
- TermVersion (int) - Versão do termo
- AcceptedAt (DateTime) - Data/hora do aceite
- IpAddress (string?) - Endereço IP
- UserAgent (string?) - User-Agent
Lógica (DDD):
- Usa método GetTermAcceptance da entidade User
- Lança NotFoundDomainException se não encontrar
3. Pesquisar Aceites (SearchUserTermAcceptances)
Endpoint: GET /v1/users/{userId}/term-acceptances/search
Contrato: SearchUserTermAcceptancesQuery
Campos de Filtro:
TermStatus(TermStatus?, opcional) - Filtrar por status do termoTermType(TermType?, opcional) - Filtrar por tipo do termoTermTitle(string?, opcional) - Filtrar por título (busca parcial)TermVersion(int?, opcional) - Filtrar por versãoAcceptedFrom(DateTime?, opcional) - Data mínima de aceiteAcceptedTo(DateTime?, opcional) - Data máxima de aceitePageNumber(int, opcional) - Número da página (padrão: 1)PageSize(int, opcional) - Tamanho da página (padrão: 100)
Retorno: SearchUserTermAcceptancesResponse (PagingResult)
Métodos DDD na Entidade User
| Método | Descrição |
|---|---|
AcceptTerm(Term, ipAddress?, userAgent?, author?, observation?) |
Registra aceite de termo. Valida se termo está ativo e não foi aceito |
HasAcceptedTerm(Guid termId) |
Verifica se usuário já aceitou um termo específico |
HasAcceptedAllRequiredTerms(IEnumerable<Guid> activeTermIds) |
Verifica se aceitou todos os termos ativos |
GetTermAcceptance(Guid termAcceptanceId) |
Obtém aceite por ID. Lança exceção se não encontrar |
Observações Finais
- Todos os campos marcados com
[JsonIgnore]não aparecem no contrato JSON da API - Campos opcionais podem ser
null - Enums devem ser valores válidos conforme definição
- Validações de tamanho máximo referem-se aos valores numéricos especificados
- Eventos de domínio são disparados de forma assíncrona
- Operações que modificam estado são transacionais