Pular para conteúdo

Contract aggregate

# Contract Aggregate

Este documento descreve todas as operações disponíveis para o agregado Contract e seus recursos, seguindo os padrões de Domain-Driven Design (DDD) e Command Query Responsibility Segregation (CQRS).

Índice


Contracts (Contratos)

Visão Geral

O agregado Contract representa os contratos disponíveis no sistema que podem ser associados a usuários profissionais. Cada contrato possui: - Um tipo de contrato (ContractType) - Múltiplas versões (ContractVersions) - Arquivos anexados por versão (ContractFiles) - Associações com profissionais (ProfessionalUserContracts)

Estrutura Hierárquica:

Contract
├── ContractType (1:1)
├── ContractVersions (1:N)
│   └── ContractFiles (1:N)
└── ProfessionalUserContracts (1:N)

Commands (Comandos)

1. Criação de Contrato (CreateContract)

Endpoint: POST /v1/contracts

Contrato: CreateContractCommand

Campos Necessários:

  • Title (string, obrigatório) - Título do contrato
  • Description (string, obrigatório) - Descrição do contrato
  • ContractTypeId (Guid, obrigatório) - ID do tipo de contrato
  • Status (ContractStatus, obrigatório) - Status do contrato
  • IsProfessionalRequired (bool, opcional) - Se é um contrato obrigatório para profissionais operarem na plataforma (padrão: false)
  • CreateFirstVersion (bool, opcional) - Se deve criar a primeira versão automaticamente (padrão: true)
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações adicionais

Validações:

  • Title: Não pode ser vazio; Tamanho máximo: 200 caracteres
  • Description: Não pode ser vazio; Tamanho máximo: 1000 caracteres
  • ContractTypeId: Não pode ser vazio
  • Status: Deve ser um valor válido do enum ContractStatus

Retorno: CreateContractResponse - Id (Guid) - Identificador do contrato criado - FirstVersionId (Guid?) - Identificador da primeira versão criada (se CreateFirstVersion = true)

Exemplo de Uso:

{
  "title": "Contrato de Prestação de Serviços",
  "description": "Contrato padrão para prestação de serviços residenciais",
  "contractTypeId": "123e4567-e89b-12d3-a456-426614174000",
  "status": 0,
  "isProfessionalRequired": true,
  "createFirstVersion": true,
  "author": "admin@sistema.com",
  "observation": "Versão inicial do contrato"
}

Exemplo de Resposta:

{
  "id": "123e4567-e89b-12d3-a456-426614174001",
  "firstVersionId": "123e4567-e89b-12d3-a456-426614174002"
}

2. Atualização de Contrato (UpdateContract)

Endpoint: PUT /v1/contracts/{contractId}

Contrato: UpdateContractCommand

Campos Necessários:

  • Title (string, obrigatório) - Título do contrato
  • Description (string, obrigatório) - Descrição do contrato
  • TypeId (Guid, obrigatório) - ID do tipo de contrato
  • Status (ContractStatus, obrigatório) - Status do contrato
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações adicionais

Validações:

  • Mesmas validações do CreateContract

Retorno: 204 No Content


3. Exclusão de Contrato (DeleteContract)

Endpoint: DELETE /v1/contracts/{contractId}

Contrato: DeleteContractCommand

Campos Necessários:

  • ContractId (Guid, obrigatório) - Identificador do contrato

Regras de Negócio:

  • Se o contrato possui relacionamentos com usuários profissionais, será feito um soft delete (status alterado para Deleted)
  • Se não possui relacionamentos, será feito um hard delete (remoção física)

Retorno: 204 No Content


4. Exclusão Forçada de Contrato (ForceDeleteContract)

Endpoint: DELETE /v1/contracts/{contractId}/force

Contrato: ForceDeleteContractCommand

Campos Necessários:

  • ContractId (Guid, obrigatório) - Identificador do contrato

Regras de Negócio:

  • Remove fisicamente o contrato do banco de dados
  • Deve ser usado com cautela, pois remove permanentemente o registro

Retorno: 204 No Content


Queries (Consultas)

1. Buscar Contrato por ID (GetContractById)

Endpoint: GET /v1/contracts/{contractId}

Contrato: GetContractByIdQuery

Campos Necessários:

  • Id (Guid, obrigatório) - Identificador do contrato

Retorno: GetContractByIdResponse - Id (Guid) - Identificador do contrato - Title (string) - Título do contrato - Description (string) - Descrição do contrato - ContractType (object) - Tipo do contrato - Id (Guid) - ID do tipo - Name (string) - Nome do tipo - Status (ContractStatus) - Status do contrato - CurrentVersion (object) - Versão atual/ativa do contrato - Id (Guid) - ID da versão - VersionNumber (int) - Número da versão - ChangeLog (string?) - Log de mudanças - IsActive (bool) - Se está ativa - PublishedAt (DateTime?) - Data de publicação - FilesCount (int) - Quantidade de arquivos - Versions (array) - Lista de todas as versões do contrato - 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


2. Pesquisar Contratos (SearchContracts)

Endpoint: GET /v1/contracts/search

Contrato: SearchContractsQuery

Campos de Filtro:

  • Title (string, opcional) - Filtrar por título (contains)
  • ContractTypeId (Guid?, opcional) - Filtrar por tipo de contrato
  • Status (ContractStatus?, opcional) - Filtrar por status
  • PageNumber (int) - Número da página (padrão: 1)
  • PageSize (int) - Tamanho da página (padrão: 20)

Retorno: SearchContractsResponse - Data (array) - Lista de contratos - Hits (int) - Total de registros encontrados


Contract Types (Tipos de Contrato)

Commands (Comandos)

1. Criação de Tipo de Contrato (CreateContractType)

Endpoint: POST /v1/contract-types

Contrato: CreateContractTypeCommand

Campos Necessários:

  • Name (string, obrigatório) - Nome do tipo de contrato
  • Description (string, obrigatório) - Descrição do tipo
  • IsActive (bool, opcional) - Se está ativo (padrão: true)
  • NotifiesUsers (bool, opcional) - Se notifica usuários (padrão: false)
  • IsProfessionalOnly (bool, opcional) - Se é apenas para profissionais (padrão: false)
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações adicionais

Retorno: CreateContractTypeResponse - Id (Guid) - Identificador do tipo criado


2. Atualização de Tipo de Contrato (UpdateContractType)

Endpoint: PUT /v1/contract-types/{contractTypeId}

Contrato: UpdateContractTypeCommand

Campos Necessários:

  • Name (string, obrigatório) - Nome do tipo de contrato
  • Description (string, obrigatório) - Descrição do tipo
  • IsActive (bool, obrigatório) - Se está ativo
  • NotifiesUsers (bool, obrigatório) - Se notifica usuários
  • IsProfessionalOnly (bool, obrigatório) - Se é apenas para profissionais
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações adicionais

Retorno: 204 No Content


3. Exclusão de Tipo de Contrato (DeleteContractType)

Endpoint: DELETE /v1/contract-types/{contractTypeId}

Contrato: DeleteContractTypeCommand

Retorno: 204 No Content


Queries (Consultas)

1. Buscar Tipo de Contrato por ID (GetContractTypeById)

Endpoint: GET /v1/contract-types/{contractTypeId}

Retorno: GetContractTypeByIdResponse - Id (Guid) - Identificador do tipo - Name (string) - Nome do tipo - Description (string) - Descrição do tipo - IsActive (bool) - Se está ativo - NotifiesUsers (bool) - Se notifica usuários - IsProfessionalOnly (bool) - Se é apenas para profissionais - 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


2. Pesquisar Tipos de Contrato (SearchContractTypes)

Endpoint: GET /v1/contract-types/search

Campos de Filtro:

  • Name (string, opcional) - Filtrar por nome
  • PageNumber (int) - Número da página
  • PageSize (int) - Tamanho da página

Retorno: SearchContractsResponse


Contract Versions (Versões de Contrato)

Visão Geral

Cada contrato pode ter múltiplas versões, permitindo rastrear mudanças e evoluções do documento ao longo do tempo. Cada versão: - Possui um número sequencial único por contrato - Pode ter múltiplos arquivos anexados - Pode ser marcada como ativa/inativa - Pode ser publicada com data de publicação - Contém um changelog para documentar as mudanças

Commands (Comandos)

1. Criar Versão de Contrato (CreateContractVersion)

Endpoint: POST /v1/contracts/{contractId}/versions

Contrato: CreateContractVersionCommand

Campos Necessários:

  • ChangeLog (string, opcional) - Descrição das mudanças da versão
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações adicionais

Regras de Negócio:

  • O número da versão é atribuído automaticamente (sequencial por contrato)
  • Nova versão é criada como ativa por padrão
  • A versão ainda não está publicada (PublishedAt = null)

Retorno: CreateContractVersionResponse - Id (Guid) - Identificador da versão criada - VersionNumber (int) - Número da versão

Exemplo de Uso:

{
  "changeLog": "Atualização de cláusulas contratuais e valores",
  "author": "admin@sistema.com",
  "observation": "Revisão anual"
}

Exemplo de Resposta:

{
  "id": "123e4567-e89b-12d3-a456-426614174002",
  "versionNumber": 2
}

2. Deletar Versão de Contrato (DeleteContractVersion)

Endpoint: DELETE /v1/contracts/{contractId}/versions/{versionId}

Contrato: DeleteContractVersionCommand

Campos Necessários:

  • ContractId (Guid, obrigatório) - Identificador do contrato
  • VersionId (Guid, obrigatório) - Identificador da versão

Regras de Negócio:

  • Não é possível deletar uma versão que possua arquivos associados
  • É necessário deletar todos os arquivos da versão antes de deletá-la
  • Lança exceção RuleViolationDomainException se houver arquivos

Retorno: 204 No Content

Erro 400 (Bad Request):

{
  "message": "Cannot delete a contract version that has associated files. Please delete all files first."
}

Contract Files (Arquivos de Contrato)

Visão Geral

Os arquivos de contrato são anexados a versões específicas do contrato. Cada arquivo: - Pertence a uma versão específica do contrato - Pode ser marcado como arquivo padrão da versão - Possui URL pública gerada automaticamente com expiração

Commands (Comandos)

1. Upload de Arquivo de Contrato (CreateContractFile)

Endpoint: POST /v1/contracts/{contractId}/versions/{contractVersionId}/files

Content-Type: multipart/form-data

Contrato: CreateContractFileCommand

Parâmetros de Rota:

  • contractId (Guid, obrigatório) - Identificador do contrato
  • contractVersionId (Guid, obrigatório) - Identificador da versão do contrato

Campos Necessários:

  • File (IFormFile, obrigatório) - Arquivo a ser enviado
  • IsDefault (bool, obrigatório) - Se é o arquivo padrão da versão
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações

Regras de Negócio:

  • O arquivo é associado a uma versão específica do contrato
  • Se IsDefault for true, os outros arquivos da mesma versão terão seu flag IsDefault removido
  • Cada versão pode ter múltiplos arquivos anexados

Retorno: CreateContractFileResponse - Id (Guid) - Identificador do arquivo criado - PublicUrl (string) - URL pública do arquivo


2. Exclusão de Arquivo de Contrato (DeleteContractFile)

Endpoint: DELETE /v1/contracts/{contractId}/versions/{contractVersionId}/files/{fileId}

Parâmetros de Rota:

  • contractId (Guid, obrigatório) - Identificador do contrato
  • contractVersionId (Guid, obrigatório) - Identificador da versão do contrato
  • fileId (Guid, obrigatório) - Identificador do arquivo

Regras de Negócio:

  • Remove o arquivo do storage e do banco de dados
  • Se o arquivo deletado era o padrão e existem outros arquivos, o mais recente se torna o padrão automaticamente

Retorno: 204 No Content


Queries (Consultas)

1. Buscar Arquivo de Contrato por ID (GetContractFileById)

Endpoint: GET /v1/contracts/{contractId}/versions/{contractVersionId}/files/{fileId}

Parâmetros de Rota:

  • contractId (Guid, obrigatório) - Identificador do contrato
  • contractVersionId (Guid, obrigatório) - Identificador da versão do contrato
  • fileId (Guid, obrigatório) - Identificador do arquivo

Retorno: GetContractFileByIdResponse - Id (Guid) - Identificador do arquivo - ContractVersionId (Guid) - ID da versão do contrato - FileName (string) - Nome do arquivo - ContentType (string) - Tipo de conteúdo (MIME type) - Length (long) - Tamanho do arquivo em bytes - IsDefault (bool) - Se é o arquivo padrão - PublicUrl (string?) - URL pública do arquivo - PublicUrlGeneratedAt (DateTime?) - Data de geração da URL - Created (DateTime) - Data de criação - Updated (DateTime?) - Data de atualização - AuthorCreated (string?) - Autor da criação - AuthorUpdated (string?) - Autor da última atualização - Observation (string?) - Observações


2. Obter URL Pública do Arquivo (GetContractFilePublicUrl)

Endpoint: GET /v1/contracts/{contractId}/versions/{contractVersionId}/files/{fileId}/public-url

Parâmetros de Rota:

  • contractId (Guid, obrigatório) - Identificador do contrato
  • contractVersionId (Guid, obrigatório) - Identificador da versão do contrato
  • fileId (Guid, obrigatório) - Identificador do arquivo

Retorno: GetContractFilePublicUrlResponse - PublicUrl (string) - URL pública do arquivo - GeneratedAt (DateTime) - Data de geração da URL - ExpiresAt (DateTime) - Data de expiração da URL

Regras de Negócio:

  • Se a URL expirou (após 6 dias, 23 horas, 59 minutos), uma nova URL é gerada automaticamente
  • A URL é armazenada no registro do arquivo para reutilização

3. Pesquisar Arquivos de Contrato (SearchContractFiles)

Endpoint: GET /v1/contracts/{contractId}/files/search

Observação: Este endpoint busca arquivos em todas as versões do contrato, não requer contractVersionId na rota.

Parâmetros de Rota:

  • contractId (Guid, obrigatório) - Identificador do contrato

Campos de Filtro:

  • IsDefault (bool?, opcional) - Filtrar por arquivo padrão
  • PageNumber (int) - Número da página (padrão: 1)
  • PageSize (int) - Tamanho da página (padrão: 100)

Retorno: SearchContractFilesResponse - Data (array) - Lista de arquivos - Id (Guid) - Identificador do arquivo - ContractVersionId (Guid) - ID da versão do contrato - FileName (string) - Nome do arquivo - ContentType (string) - Tipo de conteúdo - Length (long) - Tamanho do arquivo - IsDefault (bool) - Se é o arquivo padrão - Created (DateTime) - Data de criação - Updated (DateTime?) - Data de atualização - AuthorCreated (string?) - Autor da criação - AuthorUpdated (string?) - Autor da última atualização - Observation (string?) - Observações - Hits (int) - Total de registros encontrados


Professional User Contracts (Contratos de Usuário Profissional)

Commands (Comandos)

1. Associar Contrato ao Profissional (CreateProfessionalUserContract)

Endpoint: POST /v1/professional-users/{professionalUserId}/contracts

Contrato: CreateProfessionalUserContractCommand

Campos Necessários:

  • ContractId (Guid, obrigatório) - ID do contrato a ser associado
  • ContractVersion (int, obrigatório) - Versão do contrato
  • Author (string, opcional) - Autor da operação
  • Observation (string, opcional) - Observações

Validações:

  • ContractId: Não pode ser vazio
  • ContractVersion: Deve ser maior que 0
  • O contrato não pode já estar associado ao profissional

Retorno: CreateProfessionalUserContractResponse - Id (Guid) - Identificador da associação criada

Exemplo de Uso:

{
  "contractId": "123e4567-e89b-12d3-a456-426614174000",
  "contractVersion": 1,
  "author": "admin@sistema.com",
  "observation": "Primeira versão do contrato"
}

2. Assinar Contrato (SignProfessionalUserContract)

Endpoint: POST /v1/professional-users/{professionalUserId}/contracts/{id}/sign

Contrato: SignProfessionalUserContractCommand

Campos Necessários:

  • Author (string, opcional) - Autor da assinatura

Regras de Negócio:

  • Define IsSigned como true
  • Registra SignedAt com a data/hora atual (UTC)

Retorno: 204 No Content

Exemplo de Uso:

{
  "author": "profissional@email.com"
}

3. Remover Associação de Contrato (DeleteProfessionalUserContract)

Endpoint: DELETE /v1/professional-users/{professionalUserId}/contracts/{id}

Retorno: 204 No Content


4. Upload de Arquivo de Contrato do Profissional (CreateContractFile)

Endpoint: POST /v1/professional-users/{professionalUserId}/files/contracts/{professionalUserContractId}

Content-Type: multipart/form-data

Parâmetros de Rota:

  • professionalUserId (Guid, obrigatório) - ID do usuário profissional
  • professionalUserContractId (Guid, obrigatório) - ID do contrato do profissional

Campos do Formulário:

  • File (IFormFile, obrigatório) - Arquivo a ser enviado (ex: contrato assinado, anexo)
  • Observation (string, opcional) - Observações sobre o arquivo

Regras de Negócio:

  • O arquivo é associado ao contrato específico do profissional
  • Útil para upload de contratos assinados digitalmente ou anexos relacionados
  • O arquivo é armazenado no serviço de storage e uma URL pública é gerada

Retorno: CreateProfessionalUserFileResponse - Id (Guid) - Identificador do arquivo criado

Exemplo de Uso (multipart/form-data):

POST /v1/professional-users/{professionalUserId}/files/contracts/{professionalUserContractId}
Content-Type: multipart/form-data

file: [binary content]
observation: "Contrato assinado pelo profissional"

Exemplo de Resposta:

{
  "id": "123e4567-e89b-12d3-a456-426614174000"
}

Queries (Consultas)

1. Buscar Contrato do Profissional por ID (GetProfessionalUserContractById)

Endpoint: GET /v1/professional-users/{professionalUserId}/contracts/{id}

Retorno: GetProfessionalUserContractByIdResponse - Id (Guid) - Identificador da associação - ProfessionalUserId (Guid) - ID do profissional - ContractId (Guid) - ID do contrato - ContractTitle (string) - Título do contrato - ContractVersion (int) - Versão do contrato - IsSigned (bool) - Se foi 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


2. Pesquisar Contratos do Profissional (SearchProfessionalUserContracts)

Endpoint: GET /v1/professional-users/{professionalUserId}/contracts/search

Campos de Filtro:

  • ContractId (Guid?, opcional) - Filtrar por contrato
  • IsSigned (bool?, opcional) - Filtrar por status de assinatura
  • PageNumber (int) - Número da página (padrão: 1)
  • PageSize (int) - Tamanho da página (padrão: 20)

Retorno: SearchProfessionalUserContractsResponse - Data (array) - Lista de contratos do profissional - Hits (int) - Total de registros encontrados


Enums

ContractStatus

Valor Nome Descrição
0 Active Contrato ativo
1 Inactive Contrato inativo
2 Deleted Contrato excluído (soft delete)

Relacionamentos

ContractType (1) ──────< (N) Contract
Contract (1) ──────< (N) ContractVersion
ContractVersion (1) ──────< (N) ContractFile
Contract (1) ──────< (N) ProfessionalUserContract
ProfessionalUser (1) ──────< (N) ProfessionalUserContract

Explicação da Estrutura:

  • Um ContractType pode ter múltiplos Contracts
  • Um Contract pode ter múltiplas ContractVersions
  • Uma ContractVersion pode ter múltiplos ContractFiles
  • Um Contract pode ter múltiplos ProfessionalUserContracts (associações com profissionais)
  • Um ProfessionalUser pode ter múltiplos ProfessionalUserContracts

Observações Importantes

  1. Soft Delete vs Hard Delete: O DeleteContract faz soft delete quando há relacionamentos, preservando a integridade referencial. Use ForceDeleteContract apenas quando necessário remover permanentemente.

  2. Versionamento de Contratos:

  3. Cada contrato pode ter múltiplas versões gerenciadas através da entidade ContractVersion
  4. O número da versão é sequencial e automático por contrato
  5. Versões podem ser ativadas/desativadas e publicadas
  6. Arquivos são associados a versões específicas, não diretamente ao contrato
  7. Não é possível deletar uma versão que possui arquivos - delete os arquivos primeiro

  8. Arquivos de Contrato:

  9. Cada arquivo pertence a uma versão específica do contrato
  10. Apenas um arquivo pode ser marcado como padrão por versão
  11. URLs públicas expiram após aproximadamente 7 dias e são regeneradas automaticamente

  12. Tipos de Contrato:

  13. NotifiesUsers: Indica se contratos deste tipo devem gerar notificações para os usuários
  14. IsProfessionalOnly: Indica se o tipo de contrato é exclusivo para usuários profissionais que trabalham na plataforma

  15. Assinatura de Contratos: A assinatura é registrada com timestamp UTC e pode ser verificada através do campo IsSigned e SignedAt.

  16. Auditoria: Todos os comandos suportam os campos Author e Observation para rastreabilidade das operações.

  17. Hierarquia de Endpoints:

  18. Contratos: /v1/contracts/{contractId}
  19. Versões: /v1/contracts/{contractId}/versions/{versionId}
  20. Arquivos (específicos da versão): /v1/contracts/{contractId}/versions/{versionId}/files/{fileId}
  21. Busca de arquivos (todas versões): /v1/contracts/{contractId}/files/search