ProfessionalUsers
Este documento descreve todas as operações disponíveis para o agregado ProfessionalUser e seus sub-recursos, seguindo os padrões de Domain-Driven Design (DDD) e Command Query Responsibility Segregation (CQRS).
Índice
- ProfessionalUsers (Usuários Profissionais)
- ProfessionalUserAddresses (Endereços)
- ProfessionalUserDocuments (Documentos)
- ProfessionalUserSkills (Habilidades)
- ProfessionalUserAvailabilities (Disponibilidades)
- ProfessionalUserSchedules (Agendamentos)
- ProfessionalUserPaymentMethods (Métodos de Pagamento)
- ProfessionalUserNotifications (Notificações)
- ProfessionalUserCities (Cidades)
- ProfessionalUserJobs (Trabalhos)
- ProfessionalUserTasks (Tarefas)
- ProfessionalUserResponses (Respostas)
- ProfessionalUserContracts (Contratos)
- ProfessionalUserPerformances (Avaliações)
- ProfessionalUserTermAcceptances (Aceites de Termos)
ProfessionalUsers (Usuários Profissionais)
Commands (Comandos)
1. Criação de Usuário Profissional (CreateProfessionalUser)
Contrato: CreateProfessionalUserCommand
Campos Necessários:
FirstName(string, obrigatório) - Primeiro nome do profissionalLastName(string, obrigatório) - Sobrenome do profissionalEmail(string, opcional) - Email do profissionalIdd(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 profissionalDocument(string, obrigatório) - Número do documentoDocumentType(DocumentType enum, obrigatório) - Tipo do documentoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
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á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; Profissional deve ter pelo menos 18 anosDocument: Não pode ser vazioDocumentType: Deve ser um valor válido do enum
Retorno: CreateProfessionalUserResponse
Eventos de Domínio:
ProfessionalUserCreatedEvent- Disparado quando um profissional é criado
2. Atualização de Usuário Profissional (UpdateProfessionalUser)
Contrato: UpdateProfessionalUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do profissional (JsonIgnore)FirstName(string, obrigatório) - Primeiro nome do profissionalLastName(string, obrigatório) - Sobrenome do profissionalEmail(string, opcional) - Email do profissionalIdd(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 profissionalStatus(Status enum, obrigatório) - Status do profissionalObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
- Mesmas validações do
CreateProfessionalUserCommand Id: Profissional deve existirStatus: Deve ser um valor válido do enum
Retorno: Void
Eventos de Domínio:
ProfessionalUserUpdatedEvent- Disparado quando um profissional é atualizado
Regras de Negócio:
- Não é possível atualizar um profissional deletado
- O perfil do profissional deve existir
3. Exclusão de Usuário Profissional (DeleteProfessionalUser)
Contrato: DeleteProfessionalUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do profissional
Validações:
Id: Profissional deve existir
Retorno: Void
Regras de Negócio:
- Remove permanentemente o profissional do banco de dados
- Operação irreversível
4. Exclusão por LGPD (DeleteProfessionalUserByLgpd)
Rota: DELETE /v1/professional-users/{professionalUserId}/lgpd
Contrato: DeleteProfessionalUserByLgpdCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do profissional (JsonIgnore, via rota)Observation(string, opcional) - Motivo da exclusãoAuthor(string, opcional) - Autor da operação
Validações:
Id: Profissional deve existir- Profissional não pode estar com status
Deleted
Retorno: 204 No Content
Eventos de Domínio:
ProfessionalUserDeletedByLgpdEvent- Disparado quando um profissional é 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 PROFESSIONAL |
| Perfil | anonymized_{professionalUserId}@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 | Detalhes | { "anonymized": "true" } |
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 profissional 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 conta são anonimizados
-
Status:
- Status do profissional alterado para
Deleted - Impede futuras operações com este profissional
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
Exemplo de Uso:
DELETE /v1/professional-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/professional-users/{professionalUserId}/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 (respostas, agendamentos, performances) são mantidos com dados anonimizados para auditoria
5. Exclusão Forçada (ForceDeleteProfessionalUser)
Rota: DELETE /v1/professional-users/{professionalUserId}/force
Contrato: ForceDeleteProfessionalUserCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do profissional
Validações:
Id: Profissional deve existir
Autenticação: Requer autorização de administrador (AdminAuthorize)
Retorno: 204 No Content
Eventos de Domínio:
ProfessionalUserDeletedEvent- Disparado quando um profissional é deletado
Descrição:
Este endpoint permite a exclusão permanente e irreversível de um profissional do sistema. Diferente da exclusão por LGPD, este endpoint remove fisicamente o registro do banco de dados.
Regras de Negócio:
- Requer permissão de administrador
- Remove permanentemente o profissional e todos os dados relacionados
- Operação irreversível - não há como recuperar os dados
Importante: - Use este endpoint apenas quando o profissional não possui histórico de transações - Para profissionais com histórico, utilize o endpoint de exclusão por LGPD
Queries (Consultas)
1. Buscar Usuário Profissional por ID (GetProfessionalUserById)
Contrato: GetProfessionalUserByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do profissional
Retorno: GetProfessionalUserByIdResponse
Descrição:
- Retorna todos os dados do profissional especificado
2. Pesquisar Usuários Profissionais (SearchProfessionalUsers)
Contrato: SearchProfessionalUsersQuery
Parâmetros:
JobId(Guid, opcional) - Filtrar por trabalhoJobTaskId(Guid, opcional) - Filtrar por tarefa de trabalhoCityId(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)StartDate(DateTime, opcional) - Data inicial de criaçãoEndDate(DateTime, opcional) - Data final de criaçãoDocumentType(DocumentType enum, opcional) - Filtrar por tipo de documentoSkills(IEnumerable, opcional) - Filtrar por habilidades PageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da página
Retorno: SearchProfessionalUsersResponse (lista paginada de profissionais)
Descrição:
- Retorna uma lista paginada de profissionais conforme os filtros aplicados
3. Verificar Elegibilidade de Exclusão (CheckProfessionalUserDeletionEligibility)
Rota: GET /v1/professional-users/{professionalUserId}/deletion-eligibility
Contrato: CheckProfessionalUserDeletionEligibilityQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckProfessionalUserDeletionEligibilityResponse
- CanBeDeleted (bool) - Indica se o profissional pode ser excluído permanentemente
- Reason (string) - Motivo explicando a recomendação
- TotalResponses (int) - Total de respostas do profissional
- TotalSchedules (int) - Total de agendamentos do profissional
- TotalPerformances (int) - Total de avaliações de performance do profissional
- HasPendingTransactions (bool) - Indica se há transações pendentes
Descrição:
Este endpoint valida se um profissional 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): -
Profissional não possui nenhum histórico de transações (respostas, agendamentos, performances)
-
Deve ser mascarado (
CanBeDeleted = false): - Profissional possui transações pendentes → Aguardar conclusão/cancelamento
- Profissional possui histórico de transações → Dados devem ser mascarados para auditoria
Exemplo de Resposta (pode ser excluído):
{
"canBeDeleted": true,
"reason": "Professional user has no transaction history and can be permanently deleted.",
"totalResponses": 0,
"totalSchedules": 0,
"totalPerformances": 0,
"hasPendingTransactions": false
}
Exemplo de Resposta (deve ser mascarado):
{
"canBeDeleted": false,
"reason": "Professional user has transaction history. Data must be masked to preserve records.",
"totalResponses": 15,
"totalSchedules": 10,
"totalPerformances": 8,
"hasPendingTransactions": false
}
Exemplo de Resposta (transações pendentes):
{
"canBeDeleted": false,
"reason": "Professional user has pending transactions. Wait until all are completed or cancelled.",
"totalResponses": 5,
"totalSchedules": 2,
"totalPerformances": 0,
"hasPendingTransactions": true
}
ProfessionalUserAddresses (Endereços)
Commands (Comandos)
1. Criar Endereço de Profissional (CreateAddress)
Contrato: CreateAddressCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (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:
ProfessionalUserId: 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)
Retorno: CreateAddressResponse
Regras de Negócio:
- Não pode adicionar endereço duplicado
- Profissional pode ter múltiplos endereços
2. Deletar Endereço de Profissional (DeleteAddress)
Contrato: DeleteAddressCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do endereçoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Endereço deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove o endereço do profissional
3. Validar Endereço de Profissional (ValidateAddress)
Contrato: ValidateAddressCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do endereçoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Endereço deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Marca o endereço como validado
Queries (Consultas)
1. Buscar Endereços do Profissional (GetAddresses)
Contrato: GetAddressesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetAddressesResponse (lista de endereços)
Descrição:
- Retorna todos os endereços de um profissional
2. Buscar Endereço por ID (GetAddressById)
Contrato: GetAddressByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do endereçoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetAddressByIdResponse
Descrição:
- Retorna um endereço específico do profissional
3. Verificar Endereços Válidos (CheckValidAddress)
Rota: GET /v1/professional-users/{professionalUserId}/address/valid
Contrato: CheckValidAddressQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckValidAddressResponse
- HasValidAddress (bool) - Indica se há pelo menos um endereço validado
- TotalAddresses (int) - Total de endereços do profissional
- ValidAddresses (int) - Quantidade de endereços validados
Descrição:
Este endpoint verifica se o profissional possui algum endereço validado no sistema.
Exemplo de Resposta (com endereço válido):
{
"hasValidAddress": true,
"totalAddresses": 3,
"validAddresses": 2
}
Exemplo de Resposta (sem endereço válido):
{
"hasValidAddress": false,
"totalAddresses": 1,
"validAddresses": 0
}
ProfessionalUserDocuments (Documentos)
Commands (Comandos)
1. Criar Documento de Profissional (CreateDocument)
Contrato: CreateDocumentCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (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:
ProfessionalUserId: Não pode ser vazioDocument: Não pode ser vazioType: Deve ser um valor válido do enum
Retorno: CreateDocumentResponse
Regras de Negócio:
- Não pode adicionar documento duplicado
- Cada profissional pode ter múltiplos documentos
2. Deletar Documento de Profissional (DeleteDocument)
Contrato: DeleteDocumentCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do documentoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Documento deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove o documento do profissional
3. Validar Documento de Profissional (ValidateDocument)
Contrato: ValidateDocumentCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do documentoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Documento deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Marca o documento como validado
Queries (Consultas)
1. Buscar Documentos do Profissional (GetDocuments)
Contrato: GetDocumentsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetDocumentsResponse (lista de documentos)
Descrição:
- Retorna todos os documentos de um profissional
2. Buscar Documento por ID (GetDocumentById)
Contrato: GetDocumentByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador do documentoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetDocumentByIdResponse
Descrição:
- Retorna um documento específico do profissional
3. Verificar Documentos Válidos (CheckValidDocument)
Rota: GET /v1/professional-users/{professionalUserId}/documents/valid
Contrato: CheckValidDocumentQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckValidDocumentResponse
- HasValidDocument (bool) - Indica se há pelo menos um documento validado
- TotalDocuments (int) - Total de documentos do profissional
- ValidDocuments (int) - Quantidade de documentos validados
Descrição:
Este endpoint verifica se o profissional possui algum documento validado no sistema.
Exemplo de Resposta (com documento válido):
{
"hasValidDocument": true,
"totalDocuments": 2,
"validDocuments": 1
}
Exemplo de Resposta (sem documento válido):
{
"hasValidDocument": false,
"totalDocuments": 1,
"validDocuments": 0
}
ProfessionalUserSkills (Habilidades)
Commands (Comandos)
1. Criar Habilidade de Profissional (CreateSkill)
Contrato: CreateSkillCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)SkillId(Guid, obrigatório) - Identificador da habilidadeScore(int, obrigatório) - Pontuação da habilidade (0-10)Observation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Não pode ser vazioSkillId: Não pode ser vazio; Habilidade deve existirScore: Deve estar entre 0 e 10Observation: Tamanho máximo: 500 caracteres quando fornecido
Retorno: CreateSkillResponse
Regras de Negócio:
- Não pode adicionar habilidade duplicada
- A habilidade deve existir no sistema
- Score representa o nível de proficiência do profissional
2. Atualizar Habilidade de Profissional (UpdateSkill)
Contrato: UpdateSkillCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)Id(Guid, obrigatório) - Identificador da habilidade (JsonIgnore)Score(int, obrigatório) - Nova pontuaçãoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
- Habilidade deve existir para o profissional
Score: Deve estar entre 0 e 10
Retorno: Void
Regras de Negócio:
- Atualiza a pontuação e observação da habilidade
3. Deletar Habilidade de Profissional (DeleteSkill)
Contrato: DeleteSkillCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalId(Guid, obrigatório) - Identificador da habilidade
Validações:
- Habilidade deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove a habilidade do profissional
Queries (Consultas)
1. Buscar Habilidades do Profissional (GetProfessionalUserSkills)
Contrato: GetProfessionalUserSkillsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetProfessionalUserSkillsResponse (lista de habilidades)
Descrição:
- Retorna todas as habilidades de um profissional com suas pontuações
2. Buscar Habilidade por ID (GetProfessionalUserSkillById)
Contrato: GetProfessionalUserSkillByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador da habilidadeProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetProfessionalUserSkillByIdResponse
Descrição:
- Retorna uma habilidade específica do profissional
ProfessionalUserAvailabilities (Disponibilidades)
Commands (Comandos)
1. Criar Disponibilidade (CreateAvailability)
Contrato: CreateAvailabilityCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)Day(DayOfWeek enum, obrigatório) - Dia da semanaStartDt(TimeSpan, obrigatório) - Hora de inícioEndDt(TimeSpan, obrigatório) - Hora de términoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Não pode ser vazioStartDt: Deve ser menor queEndDt; Deve ser maior ou igual a 00:00EndDt: Deve ser menor ou igual a 24:00- Duração: Mínimo 30 minutos; Máximo 16 horas
Observation: Tamanho máximo: 500 caracteres quando fornecido
Retorno: CreateAvailabilityResponse
Regras de Negócio:
- Não pode ter sobreposição de horários no mesmo dia
- Profissional pode ter múltiplos horários de disponibilidade por dia
2. Atualizar Disponibilidade (UpdateAvailability)
Contrato: UpdateAvailabilityCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)Id(Guid, obrigatório) - Identificador da disponibilidade (JsonIgnore)Day(DayOfWeek enum, obrigatório) - Dia da semanaStartDt(TimeSpan, obrigatório) - Hora de inícioEndDt(TimeSpan, obrigatório) - Hora de términoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
- Mesmas validações do
CreateAvailabilityCommand - Disponibilidade deve existir para o profissional
Retorno: Void
3. Deletar Disponibilidade (DeleteAvailability)
Contrato: DeleteAvailabilityCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador da disponibilidadeProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Disponibilidade deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove a disponibilidade do profissional
Queries (Consultas)
1. Pesquisar Disponibilidades (SearchAvailabilities)
Contrato: SearchAvailabilitiesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalDay(DayOfWeek enum, opcional) - Filtrar por dia da semanaPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da página
Retorno: SearchAvailabilitiesResponse (lista paginada de disponibilidades)
Descrição:
- Retorna uma lista paginada de disponibilidades conforme os filtros aplicados
ProfessionalUserSchedules (Agendamentos)
Commands (Comandos)
1. Criar Schedule (CreateSchedule)
Contrato: CreateScheduleCommand
Campos Necessários:
UserProfessionalId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)OrderItemId(Guid, obrigatório) - Identificador do item do pedido (JsonIgnore)StartDate(DateTime, obrigatório) - Data e hora de inícioHours(double, obrigatório) - Quantidade de horasObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
UserProfessionalId: Não pode ser vazioOrderItemId: Não pode ser vazio; Item do pedido deve existirStartDate: Não pode estar no passadoHours: Deve ser maior que 0
Retorno: CreateScheduleResponse
Regras de Negócio:
- Não pode ter conflito de horários com outros agendamentos
- O agendamento deve estar dentro da disponibilidade do profissional
- O item do pedido deve estar associado ao profissional
2. Deletar Schedule (DeleteSchedule)
Contrato: DeleteScheduleCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador do agendamentoProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Validações:
- Agendamento deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove o agendamento do profissional
- Apenas agendamentos futuros podem ser deletados
Queries (Consultas)
1. Pesquisar Schedules (SearchSchedules)
Contrato: SearchSchedulesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalStartDate(DateTime, opcional) - Data inicialEndDate(DateTime, opcional) - Data finalOrderItemId(Guid, opcional) - Filtrar por item do pedidoPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da página
Retorno: SearchSchedulesResponse (lista paginada de agendamentos)
Descrição:
- Retorna uma lista paginada de agendamentos conforme os filtros aplicados
ProfessionalUserPaymentMethods (Métodos de Pagamento)
Commands (Comandos)
1. Criar Método de Pagamento (CreatePaymentMethod)
Contrato: CreatePaymentMethodCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)PaymentType(PaymentType enum, obrigatório) - Tipo do método de pagamentoPaymentDetails(Dictionary, obrigatório) - Detalhes do pagamento IsDefault(bool, obrigatório) - Se é o método padrãoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Não pode ser vazioPaymentType: Deve ser um valor válido do enumPaymentDetails: Não pode ser vazio; Deve conter os campos necessários conforme o tipoIsDefault: Não pode ser nulo
Retorno: CreatePaymentMethodResponse
Regras de Negócio:
- Profissional pode ter múltiplos métodos de pagamento
- Apenas um método pode ser padrão por vez
- Os campos de
PaymentDetailsvariam conforme oPaymentType
2. Atualizar Método de Pagamento (UpdatePaymentMethod)
Contrato: UpdatePaymentMethodCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)Id(Guid, obrigatório) - Identificador do método de pagamento (JsonIgnore)PaymentDetails(Dictionary, obrigatório) - Detalhes do pagamento IsDefault(bool, obrigatório) - Se é o método padrãoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
- Método de pagamento deve existir para o profissional
PaymentDetails: Não pode ser vazio
Retorno: Void
3. Deletar Método de Pagamento (DeletePaymentMethod)
Contrato: DeletePaymentMethodCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalId(Guid, obrigatório) - Identificador do método de pagamento
Validações:
- Método de pagamento deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove o método de pagamento do profissional
Queries (Consultas)
1. Buscar Métodos de Pagamento (GetPaymentMethods)
Contrato: GetPaymentMethodsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetPaymentMethodsResponse (lista de métodos de pagamento)
Descrição:
- Retorna todos os métodos de pagamento de um profissional
2. Buscar Método de Pagamento por ID (GetPaymentMethodById)
Contrato: GetPaymentMethodByIdQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalPaymentMethodId(Guid, obrigatório) - Identificador do método de pagamento
Retorno: GetPaymentMethodByIdResponse
Descrição:
- Retorna um método de pagamento específico do profissional
ProfessionalUserNotifications (Notificações)
Commands (Comandos)
1. Criar Notificação (CreateNotification)
Contrato: CreateNotificationCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)NotificationType(ProfessionalUserNotificationType enum, obrigatório) - Tipo da notificaçãoParameters(Dictionary, obrigatório) - Parâmetros da notificação CorrelationId(Guid, padrão: Guid.CreateVersion7()) - Identificador de correlaçãoAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: 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:
ProfessionalUserNotificationCreatedEvent- 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:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalNotificationId(Guid, obrigatório) - Identificador da notificação
Validações:
- Notificação deve existir para o profissional
Retorno: ResendNotificationResponse
Regras de Negócio:
- Cancela a notificação antiga
- Cria uma nova notificação com os mesmos parâmetros
3. Atualizar Notificação (UpdateNotification)
Contrato: UpdateNotificationCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (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 profissional
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
Queries (Consultas)
1. Pesquisar Notificações (SearchNotifications)
Contrato: SearchNotificationsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalNotificationType(ProfessionalUserNotificationType 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
ProfessionalUserCities (Cidades)
Commands (Comandos)
1. Associar Cidade (AssociateCity)
Contrato: AssociateCityCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalCityId(Guid, obrigatório) - Identificador da cidade
Validações:
ProfessionalUserId: Profissional deve existirCityId: Cidade deve existir
Retorno: Void
Regras de Negócio:
- Não pode associar cidade duplicada
- Profissional pode atender em múltiplas cidades
2. Desassociar Cidade (DisassociateCity)
Contrato: DisassociateCityCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalCityId(Guid, obrigatório) - Identificador da cidade
Validações:
- Cidade deve estar associada ao profissional
Retorno: Void
Regras de Negócio:
- Remove a associação da cidade com o profissional
Queries (Consultas)
1. Buscar Cidades Associadas (GetAssociatedCities)
Contrato: GetAssociatedCitiesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetAssociatedCitiesResponse (lista de cidades)
Descrição:
- Retorna todas as cidades onde o profissional atende
2. Verificar Cidades Registradas (CheckRegisteredCities)
Rota: GET /v1/professional-users/{professionalUserId}/cities/registered
Contrato: CheckRegisteredCitiesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckRegisteredCitiesResponse
- HasRegisteredCities (bool) - Indica se há pelo menos uma cidade registrada
- TotalCities (int) - Total de cidades associadas ao profissional
Descrição:
Este endpoint verifica se o profissional possui alguma cidade de atuação registrada no sistema.
Exemplo de Resposta (com cidades registradas):
{
"hasRegisteredCities": true,
"totalCities": 5
}
Exemplo de Resposta (sem cidades registradas):
{
"hasRegisteredCities": false,
"totalCities": 0
}
ProfessionalUserJobs (Trabalhos)
Commands (Comandos)
1. Associar Trabalho (AssociateJob)
Contrato: AssociateJobCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalJobId(Guid, obrigatório) - Identificador do trabalho
Validações:
ProfessionalUserId: Profissional deve existirJobId: Trabalho deve existir
Retorno: Void
Regras de Negócio:
- Não pode associar trabalho duplicado
- Profissional pode realizar múltiplos tipos de trabalho
2. Desassociar Trabalho (DisassociateJob)
Contrato: DisassociateJobCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalJobId(Guid, obrigatório) - Identificador do trabalho
Validações:
- Trabalho deve estar associado ao profissional
Retorno: Void
Regras de Negócio:
- Remove a associação do trabalho com o profissional
- Remove também todas as tarefas associadas a esse trabalho
Queries (Consultas)
1. Buscar Trabalhos Associados (GetAssociatedJobs)
Contrato: GetAssociatedJobsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: GetAssociatedJobsResponse (lista de trabalhos)
Descrição:
- Retorna todos os trabalhos que o profissional realiza
2. Verificar Trabalhos Registrados (CheckRegisteredJobs)
Rota: GET /v1/professional-users/{professionalUserId}/jobs/registered
Contrato: CheckRegisteredJobsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckRegisteredJobsResponse
- HasRegisteredJobs (bool) - Indica se há pelo menos um trabalho registrado
- TotalJobs (int) - Total de trabalhos associados ao profissional
Descrição:
Este endpoint verifica se o profissional possui algum trabalho registrado no sistema.
Exemplo de Resposta (com trabalhos registrados):
{
"hasRegisteredJobs": true,
"totalJobs": 3
}
Exemplo de Resposta (sem trabalhos registrados):
{
"hasRegisteredJobs": false,
"totalJobs": 0
}
ProfessionalUserTasks (Tarefas)
Commands (Comandos)
1. Associar Tarefa (AssociateTask)
Contrato: AssociateTaskCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)JobTaskId(Guid, obrigatório) - Identificador da tarefa de trabalho (JsonIgnore)Experience(Experience enum, obrigatório) - Nível de experiênciaObservation(string, opcional) - Observações adicionais
Validações:
ProfessionalUserId: Profissional deve existirJobTaskId: Tarefa deve existirExperience: Deve ser um valor válido do enum (Beginner, Intermediate, Advanced, Expert)
Retorno: AssociateTaskResponse
Regras de Negócio:
- Não pode associar tarefa duplicada
- A tarefa deve pertencer a um trabalho associado ao profissional
- Profissional pode ter diferentes níveis de experiência para diferentes tarefas
2. Desassociar Tarefa (DisassociateTask)
Contrato: DisassociateTaskCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalJobTaskId(Guid, obrigatório) - Identificador da tarefa de trabalho
Validações:
- Tarefa deve estar associada ao profissional
Retorno: Void
Regras de Negócio:
- Remove a associação da tarefa com o profissional
Queries (Consultas)
1. Buscar Tarefas Associadas (GetAssociatedTasks)
Contrato: GetAssociatedTasksQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalJobId(Guid, opcional) - Filtrar por trabalho
Retorno: GetAssociatedTasksResponse (lista de tarefas)
Descrição:
- Retorna todas as tarefas que o profissional realiza com seus níveis de experiência
2. Verificar Tarefas Registradas (CheckRegisteredTasks)
Rota: GET /v1/professional-users/{professionalUserId}/tasks/registered
Contrato: CheckRegisteredTasksQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: CheckRegisteredTasksResponse
- HasRegisteredTasks (bool) - Indica se há pelo menos uma tarefa registrada
- TotalTasks (int) - Total de tarefas associadas ao profissional
Descrição:
Este endpoint verifica se o profissional possui alguma tarefa registrada no sistema.
Exemplo de Resposta (com tarefas registradas):
{
"hasRegisteredTasks": true,
"totalTasks": 8
}
Exemplo de Resposta (sem tarefas registradas):
{
"hasRegisteredTasks": false,
"totalTasks": 0
}
ProfessionalUserResponses (Respostas)
Commands (Comandos)
1. Criar Resposta (CreateResponse)
Contrato: CreateResponseCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)OrderItemId(Guid, obrigatório) - Identificador do item do pedidoAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Profissional deve existirOrderItemId: Item do pedido deve existir
Retorno: CreateResponseResponse
Regras de Negócio:
- Profissional responde a um item de pedido demonstrando interesse
- Não pode criar resposta duplicada para o mesmo item
- O profissional deve ter as habilidades necessárias para o item
2. Aceitar Resposta (AcceptResponse)
Contrato: AcceptResponseCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalResponseId(Guid, obrigatório) - Identificador da respostaAuthor(string, opcional) - Autor da operação
Validações:
- Resposta deve existir para o profissional
- Resposta deve estar com status
Pending
Retorno: Void
Regras de Negócio:
- Aceita a resposta e vincula o profissional ao item do pedido
- Altera status da resposta para
Accepted
3. Rejeitar Resposta (RejectResponse)
Contrato: RejectResponseCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalResponseId(Guid, obrigatório) - Identificador da respostaReason(string, opcional) - Motivo da rejeiçãoAuthor(string, opcional) - Autor da operação
Validações:
- Resposta deve existir para o profissional
- Resposta deve estar com status
Pending
Retorno: Void
Regras de Negócio:
- Rejeita a resposta
- Altera status da resposta para
Rejected
4. Cancelar Resposta (CancelResponse)
Contrato: CancelResponseCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalResponseId(Guid, obrigatório) - Identificador da respostaReason(string, opcional) - Motivo do cancelamentoAuthor(string, opcional) - Autor da operação
Validações:
- Resposta deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Cancela a resposta
- Altera status da resposta para
Cancelled
Queries (Consultas)
1. Pesquisar Respostas (SearchResponses)
Contrato: SearchResponsesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalOrderItemId(Guid, opcional) - Filtrar por item do pedidoStatus(ResponseStatus 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: SearchResponsesResponse (lista paginada de respostas)
Descrição:
- Retorna uma lista paginada de respostas conforme os filtros aplicados
2. Buscar Resposta por ID (GetResponseById)
Contrato: GetResponseByIdQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalResponseId(Guid, obrigatório) - Identificador da resposta
Retorno: GetResponseByIdResponse
Descrição:
- Retorna uma resposta específica do profissional
ProfessionalUserContracts (Contratos)
Commands (Comandos)
1. Associar Contrato ao Profissional (CreateProfessionalUserContract)
Rota: POST /v1/professional-users/{professionalUserId}/contracts
Contrato: CreateProfessionalUserContractCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore, via rota)ContractId(Guid, obrigatório) - Identificador do contratoObservation(string, opcional) - Observações adicionaisAuthor(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Não pode ser vazio; Profissional deve existirContractId: Não pode ser vazio; Contrato deve existir
Retorno: CreateProfessionalUserContractResponse
- Id (Guid) - Identificador da associação
- ProfessionalUserId (Guid) - Identificador do profissional
- ContractId (Guid) - Identificador do contrato
- ContractVersion (int) - Versão do contrato associada
- IsSigned (bool) - Indica se está assinado (sempre false ao criar)
- SignedAt (DateTime?) - Data da assinatura (sempre null ao criar)
Regras de Negócio:
- Não pode associar contrato duplicado ao mesmo profissional
- Ao associar, sempre pega a versão ativa mais recente do contrato
- Contrato é criado como não assinado (
IsSigned = false) - Se o contrato não tiver versão ativa, lança exceção
2. Assinar Contrato (SignProfessionalUserContract)
Rota: POST /v1/professional-users/{professionalUserId}/contracts/{id}/sign
Contrato: SignProfessionalUserContractCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador da associação contrato-profissional (JsonIgnore, via rota)ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore, via rota)Author(string, opcional) - Autor da operação
Validações:
Id: Não pode ser vazio; Associação deve existirProfessionalUserId: Não pode ser vazio; Profissional deve existir
Retorno: 204 No Content
Regras de Negócio:
- Marca o contrato como assinado (
IsSigned = true) - Define
SignedAtcom data/hora atual (UTC) - Profissional só pode assinar contratos associados a ele
3. Desassociar Contrato (DeleteProfessionalUserContract)
Rota: DELETE /v1/professional-users/{professionalUserId}/contracts/{id}
Contrato: DeleteProfessionalUserContractCommand
Campos Necessários:
Id(Guid, obrigatório) - Identificador da associação (via rota)ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (via rota)
Validações:
Id: Não pode ser vazio; Associação deve existirProfessionalUserId: Não pode ser vazio; Profissional deve existir
Retorno: 204 No Content
Regras de Negócio:
- Remove a associação entre profissional e contrato
- Não valida se o contrato foi assinado (permite remover mesmo assinados)
Queries (Consultas)
1. Buscar Contrato por ID (GetProfessionalUserContractById)
Rota: GET /v1/professional-users/{professionalUserId}/contracts/{id}
Contrato: GetProfessionalUserContractByIdQuery
Parâmetros:
Id(Guid, obrigatório) - Identificador da associação (via rota)ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (via rota)
Retorno: GetProfessionalUserContractByIdResponse
- Id (Guid) - Identificador da associação
- ProfessionalUserId (Guid) - Identificador do profissional
- ContractId (Guid) - Identificador do contrato
- ContractTitle (string) - Título do contrato
- ContractVersion (int) - Versão do contrato associada
- IsSigned (bool) - Indica se está assinado
- SignedAt (DateTime?) - Data da assinatura
- 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 última atualização
Descrição:
- Retorna os detalhes de um contrato específico associado ao profissional
2. Pesquisar Contratos do Profissional (SearchProfessionalUserContracts)
Rota: GET /v1/professional-users/{professionalUserId}/contracts/search
Contrato: SearchProfessionalUserContractsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (via rota)ContractId(Guid, opcional) - Filtrar por contrato específicoIsSigned(bool, opcional) - Filtrar por status de assinaturaPageNumber(int, padrão: 1) - Número da páginaPageSize(int, padrão: 100) - Tamanho da página
Retorno: SearchProfessionalUserContractsResponse (lista paginada)
Cada item contém:
- Id (Guid) - Identificador da associação
- ProfessionalUserId (Guid) - Identificador do profissional
- ContractId (Guid) - Identificador do contrato
- ContractTitle (string) - Título do contrato
- ContractVersion (int) - Versão do contrato
- IsSigned (bool) - Indica se está assinado
- SignedAt (DateTime?) - Data da assinatura
- Created (DateTime) - Data de criação
Descrição:
- Retorna lista paginada de contratos associados ao profissional
- Pode filtrar por status de assinatura e contrato específico
3. Verificar Contratos Obrigatórios Não Assinados (CheckUnsignedRequiredContracts)
Rota: GET /v1/professional-users/{professionalUserId}/contracts/check-unsigned-required
Contrato: CheckUnsignedRequiredContractsQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (via rota)
Retorno: CheckUnsignedRequiredContractsResponse
- HasUnsignedRequiredContracts (bool) - Indica se existem contratos obrigatórios pendentes de assinatura
- UnsignedContracts (IEnumerable
Cada item em UnsignedContracts contém:
- Id (Guid) - Identificador da associação contrato-profissional
- ContractId (Guid) - Identificador do contrato
- ContractTitle (string) - Título do contrato
- ContractDescription (string) - Descrição do contrato
- ContractVersion (int) - Versão do contrato
- CreatedAt (DateTime) - Data em que o contrato foi associado ao profissional
Descrição:
Este endpoint valida se o profissional possui contratos obrigatórios (IsProfessionalRequired = true)
que ainda não foram assinados. É útil para:
- Bloquear acesso a funcionalidades até que contratos sejam assinados
- Exibir notificações sobre pendências contratuais
- Validar compliance antes de aceitar trabalhos
Exemplo de Resposta (sem pendências):
{
"hasUnsignedRequiredContracts": false,
"unsignedContracts": []
}
Exemplo de Resposta (com pendências):
{
"hasUnsignedRequiredContracts": true,
"unsignedContracts": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"contractId": "789e4567-e89b-12d3-a456-426614174000",
"contractTitle": "Termo de Uso da Plataforma",
"contractDescription": "Contrato obrigatório para operação na plataforma",
"contractVersion": 2,
"createdAt": "2025-01-15T10:30:00Z"
},
{
"id": "456e4567-e89b-12d3-a456-426614174000",
"contractId": "012e4567-e89b-12d3-a456-426614174000",
"contractTitle": "Termo de Privacidade LGPD",
"contractDescription": "Aceite obrigatório para conformidade com LGPD",
"contractVersion": 1,
"createdAt": "2025-01-15T10:30:00Z"
}
]
}
Casos de Uso:
- Validação de Compliance:
- Verificar antes de permitir que profissional aceite trabalhos
-
Exibir lista de contratos pendentes na tela
-
Bloqueio de Funcionalidades:
csharp var check = await CheckUnsignedRequiredContractsAsync(professionalUserId); if (check.HasUnsignedRequiredContracts) { throw new BusinessRuleViolationException( "Você possui contratos obrigatórios pendentes. " + "Assine todos os contratos para continuar." ); } -
Dashboard de Pendências:
- Exibir notificação no dashboard do profissional
- Listar contratos com link para visualização e assinatura
Regras de Negócio:
- Apenas contratos com
IsProfessionalRequired = truesão considerados - Apenas contratos não assinados (
IsSigned = false) são retornados - Contratos arquivados/inativos não são considerados nesta validação
ProfessionalUserPerformances (Avaliações)
Commands (Comandos)
1. Criar Avaliação (CreatePerformance)
Contrato: CreatePerformanceCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional (JsonIgnore)OrderItemId(Guid, obrigatório) - Identificador do item do pedidoRating(int, obrigatório) - Avaliação (0-5)Comment(string, obrigatório) - Comentário da avaliaçãoHighlightedSkills(List, obrigatório) - Habilidades destacadas Author(string, opcional) - Autor da operação
Validações:
ProfessionalUserId: Não pode ser vazioOrderItemId: Não pode ser vazio; Item do pedido deve existirRating: Deve estar entre 0 e 5Comment: Não pode ser vazio; Tamanho máximo: 500 caracteresHighlightedSkills: Não pode ser vazio; Habilidades devem existir
Retorno: CreatePerformanceResponse
Regras de Negócio:
- Apenas um cliente que recebeu o serviço pode avaliar
- Não pode criar avaliação duplicada para o mesmo item
- As habilidades destacadas devem ser habilidades do profissional
2. Deletar Avaliação (DeletePerformance)
Contrato: DeletePerformanceCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalPerformanceId(Guid, obrigatório) - Identificador da avaliação
Validações:
- Avaliação deve existir para o profissional
Retorno: Void
Regras de Negócio:
- Remove a avaliação do profissional
- Apenas o autor da avaliação pode deletá-la
Queries (Consultas)
1. Pesquisar Avaliações (SearchPerformances)
Contrato: SearchPerformancesQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalMinRating(int, opcional) - Avaliação mínimaMaxRating(int, opcional) - Avaliação máximaPageNumber(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: SearchPerformancesResponse (lista paginada de avaliações)
Descrição:
- Retorna uma lista paginada de avaliações conforme os filtros aplicados
2. Buscar Avaliação por ID (GetPerformanceById)
Contrato: GetPerformanceByIdQuery
Parâmetros:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalPerformanceId(Guid, obrigatório) - Identificador da avaliação
Retorno: GetPerformanceByIdResponse
Descrição:
- Retorna uma avaliação específica do profissional
Eventos de Domínio
ProfessionalUser
- ProfessionalUserCreatedEvent - Disparado quando um profissional é criado
- ProfessionalUserUpdatedEvent - Disparado quando um profissional é atualizado
ProfessionalUserNotifications
- ProfessionalUserNotificationCreatedEvent - Disparado quando uma notificação é criada
Regras Gerais de Negócio
Usuário Profissional (ProfessionalUser)
- Um profissional deve ter pelo menos 18 anos
- Email e telefone devem ser únicos no sistema (validação no handler)
- Um profissional deletado não pode ser atualizado
- Profissional deve ter pelo menos uma habilidade cadastrada para receber solicitações
Endereços (ProfessionalUserAddresses)
- Profissional pode ter múltiplos endereços
- Endereços podem ser validados posteriormente
- O CEP deve seguir o formato brasileiro (XXXXX-XXX)
Documentos (ProfessionalUserDocuments)
- Não pode haver documentos duplicados para o mesmo profissional
- Documentos podem ser validados posteriormente
Habilidades (ProfessionalUserSkills)
- Não pode haver habilidades duplicadas para o mesmo profissional
- A habilidade deve existir no sistema
- Score varia de 0 a 10, representando o nível de proficiência
Disponibilidades (ProfessionalUserAvailabilities)
- Não pode ter sobreposição de horários no mesmo dia
- Duração mínima: 30 minutos
- Duração máxima: 16 horas
- Profissional pode ter múltiplos horários por dia
Agendamentos (ProfessionalUserSchedules)
- Não pode ter conflito de horários
- Deve estar dentro da disponibilidade do profissional
- Apenas agendamentos futuros podem ser deletados
- O agendamento deve estar vinculado a um item de pedido (OrderItem)
Métodos de Pagamento (ProfessionalUserPaymentMethods)
- Profissional pode ter múltiplos métodos de pagamento
- Apenas um método pode ser padrão
- Dados sensíveis são armazenados de forma segura
Notificações (ProfessionalUserNotifications)
- Notificações são criadas com status
Pending - Notificações podem ser reenviadas
- Parâmetros variam conforme o tipo
Cidades (ProfessionalUserCities)
- Não pode associar cidade duplicada
- Profissional pode atender em múltiplas cidades
- Cidade deve existir no sistema
Trabalhos (ProfessionalUserJobs)
- Não pode associar trabalho duplicado
- Ao desassociar trabalho, remove todas as tarefas associadas
- Trabalho deve existir no sistema
Tarefas (ProfessionalUserTasks)
- Tarefa deve pertencer a um trabalho associado ao profissional
- Profissional pode ter diferentes níveis de experiência para diferentes tarefas
- Níveis de experiência: Beginner, Intermediate, Advanced, Expert
Respostas (ProfessionalUserResponses)
- Não pode criar resposta duplicada
- Profissional deve ter habilidades necessárias para o item
- Status possíveis: Pending, Accepted, Rejected, Cancelled
Avaliações (ProfessionalUserPerformances)
- Apenas cliente que recebeu serviço pode avaliar
- Não pode criar avaliação duplicada
- Rating varia de 0 a 5
- Comentário é obrigatório
- Deve destacar pelo menos uma habilidade
Padrões Utilizados
CQRS (Command Query Responsibility Segregation)
- Commands: Operações que modificam o estado (Create, Update, Delete, Associate, etc.)
- Queries: Operações que apenas consultam dados (Get, Search)
DDD (Domain-Driven Design)
- Agregados: ProfessionalUser é o agregado raiz
- Entidades: ProfessionalUserAddress, ProfessionalUserDocument, ProfessionalUserSkill, ProfessionalUserAvailability, ProfessionalUserSchedule, ProfessionalUserPaymentMethod, ProfessionalUserNotification, ProfessionalUserCity, ProfessionalUserJob, ProfessionalUserTask, ProfessionalUserResponse, ProfessionalUserPerformance, ProfessionalUserTermAcceptance
- Value Objects: Name, Email, Phone, BirthDate, Gender, Document, Address, Score, Review, Availability, Schedule, etc.
- Domain Events: Eventos disparados quando ações importantes ocorrem (ProfessionalUserScheduleCreatedEvent, ProfessionalUserScheduleDeletedEvent, ProfessionalUserActivatedEvent, etc.)
- 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
ProfessionalUserTermAcceptances (Aceites de Termos)
Gerenciamento de aceites de termos e políticas pelo profissional.
Commands (Comandos)
1. Aceitar Termo (AcceptProfessionalTerm)
Endpoint: POST /v1/professional-users/{professionalUserId}/term-acceptances
Contrato: AcceptProfessionalTermCommand
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termo a ser aceitoIpAddress(string, opcional) - Endereço IP do profissionalUserAgent(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 ProfessionalUser):
- O profissional não pode aceitar o mesmo termo mais de uma vez
- A validação é feita no método
AcceptTermda entidade ProfessionalUser
Exceções:
RuleViolationDomainException("Professional user has already accepted this term.")- Termo já aceito
Retorno: AcceptProfessionalTermResponse
- Id (Guid) - Identificador do aceite criado
Queries (Consultas)
1. Verificar Termos Pendentes (HasPendingTerms)
Endpoint: GET /v1/professional-users/{professionalUserId}/term-acceptances/has-pending
Contrato: HasPendingTermsQuery
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissional
Retorno: HasPendingTermsResponse
- HasPendingTerms (bool) - true se existem termos ativos não aceitos pelo profissional
Lógica (DDD):
1. Busca profissional com seus aceites de termos via GetProfessionalUserWithTermAcceptancesAsync
2. Busca todos os termos ativos via GetActiveTermsAsync
3. Usa método HasAcceptedAllRequiredTerms da entidade ProfessionalUser para verificar
4. Retorna true se existir algum termo ativo não aceito
2. Buscar Aceite por ID (GetProfessionalUserTermAcceptanceById)
Endpoint: GET /v1/professional-users/{professionalUserId}/term-acceptances/{id}
Contrato: GetProfessionalUserTermAcceptanceByIdQuery
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalTermAcceptanceId(Guid, obrigatório) - Identificador do aceite
Retorno: GetProfessionalUserTermAcceptanceByIdResponse
- Id (Guid) - Identificador do aceite
- ProfessionalUserId (Guid) - Identificador do profissional
- 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 ProfessionalUser
- Lança NotFoundDomainException se não encontrar
3. Pesquisar Aceites (SearchProfessionalUserTermAcceptances)
Endpoint: GET /v1/professional-users/{professionalUserId}/term-acceptances/search
Contrato: SearchProfessionalUserTermAcceptancesQuery
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: SearchProfessionalUserTermAcceptancesResponse (PagingResult)
Métodos DDD na Entidade ProfessionalUser
| Método | Descrição |
|---|---|
AcceptTerm(Term, ipAddress?, userAgent?, author?, observation?) |
Registra aceite de termo. Valida se termo não foi aceito |
HasAcceptedTerm(Guid termId) |
Verifica se profissional 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 |
Ativação de Profissional (Activation)
Visão Geral
Para um profissional ser ativado na plataforma, ele precisa cumprir todos os requisitos obrigatórios. A validação segue o padrão DDD com regras implementadas na entidade.
Command (Comando)
Ativar Profissional (ActivateProfessionalUser)
Endpoint: POST /v1/professional-users/{professionalUserId}/activate
Contrato: ActivateProfessionalUserCommand
Campos Necessários:
ProfessionalUserId(Guid, obrigatório) - Identificador do profissionalAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Requisitos para Ativação:
- Documento ativo e validado - Profissional deve ter pelo menos um documento com
IsDefault = trueeIsValid = true - Endereço ativo e validado - Profissional deve ter pelo menos um endereço com
IsDefault = trueeIsValid = true - Contratos obrigatórios assinados - Todos os contratos com
IsProfessionalRequired = truedevem estar assinados - Termos obrigatórios aceitos - Todos os termos ativos devem ter sido aceitos
Exceções (DDD - RuleViolationDomainException):
"Professional user is already active."- Já está ativo"Cannot activate a deleted professional user."- Profissional deletado"Cannot activate professional user. Pending requirements: ..."- Requisitos pendentes
Retorno: 204 No Content
Eventos de Domínio:
ProfessionalUserActivatedEvent- Disparado quando profissional é ativado
Métodos DDD na Entidade ProfessionalUser (Activation)
| Método | Descrição |
|---|---|
HasValidatedDocument() |
Verifica se tem documento ativo e validado |
HasValidatedAddress() |
Verifica se tem endereço ativo e validado |
HasSignedAllRequiredContracts(IEnumerable<Guid> activeContractIds) |
Verifica se assinou todos contratos obrigatórios |
HasAcceptedAllRequiredTerms(IEnumerable<Guid> activeTermIds) |
Verifica se aceitou todos termos obrigatórios |
GetActivationPendencies(IEnumerable<Guid> activeTermIds, IEnumerable<Guid> activeContractIds) |
Retorna lista de pendências |
Activate(IEnumerable<Guid> activeTermIds, IEnumerable<Guid> activeContractIds, Author?, Observation?) |
Ativa o profissional se todos requisitos forem atendidos |
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
- Score de habilidades: 0 (iniciante) a 10 (expert)
- Rating de avaliações: 0 (péssimo) a 5 (excelente)
- Disponibilidades: 30 minutos a 16 horas por período