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
- Contract Aggregate
- Índice
- Contracts (Contratos)
- Visão Geral
- Commands (Comandos)
- 1. Criação de Contrato (CreateContract)
- 2. Atualização de Contrato (UpdateContract)
- 3. Exclusão de Contrato (DeleteContract)
- 4. Exclusão Forçada de Contrato (ForceDeleteContract)
- Queries (Consultas)
- 1. Buscar Contrato por ID (GetContractById)
- 2. Pesquisar Contratos (SearchContracts)
- Contract Versions (Versões de Contrato)
- Contract Types (Tipos de Contrato)
- Commands (Comandos)
- 1. Criação de Tipo de Contrato (CreateContractType)
- 2. Atualização de Tipo de Contrato (UpdateContractType)
- 3. Exclusão de Tipo de Contrato (DeleteContractType)
- Queries (Consultas)
- 1. Buscar Tipo de Contrato por ID (GetContractTypeById)
- 2. Pesquisar Tipos de Contrato (SearchContractTypes)
- Contract Files (Arquivos de Contrato)
- Visão Geral
- Commands (Comandos)
- 1. Upload de Arquivo de Contrato (CreateContractFile)
- 2. Exclusão de Arquivo de Contrato (DeleteContractFile)
- Queries (Consultas)
- 1. Buscar Arquivo de Contrato por ID (GetContractFileById)
- 2. Obter URL Pública do Arquivo (GetContractFilePublicUrl)
- 3. Pesquisar Arquivos de Contrato (SearchContractFiles)
- Professional User Contracts (Contratos de Usuário Profissional)
- Commands (Comandos)
- 1. Associar Contrato ao Profissional (CreateProfessionalUserContract)
- 2. Assinar Contrato (SignProfessionalUserContract)
- 3. Remover Associação de Contrato (DeleteProfessionalUserContract)
- 4. Upload de Arquivo de Contrato do Profissional (CreateContractFile)
- Queries (Consultas)
- 1. Buscar Contrato do Profissional por ID (GetProfessionalUserContractById)
- 2. Pesquisar Contratos do Profissional (SearchProfessionalUserContracts)
- Enums
- Relacionamentos
- Observações Importantes
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 contratoDescription(string, obrigatório) - Descrição do contratoContractTypeId(Guid, obrigatório) - ID do tipo de contratoStatus(ContractStatus, obrigatório) - Status do contratoIsProfessionalRequired(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çãoObservation(string, opcional) - Observações adicionais
Validações:
Title: Não pode ser vazio; Tamanho máximo: 200 caracteresDescription: Não pode ser vazio; Tamanho máximo: 1000 caracteresContractTypeId: Não pode ser vazioStatus: 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 contratoDescription(string, obrigatório) - Descrição do contratoTypeId(Guid, obrigatório) - ID do tipo de contratoStatus(ContractStatus, obrigatório) - Status do contratoAuthor(string, opcional) - Autor da operaçãoObservation(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 contratoStatus(ContractStatus?, opcional) - Filtrar por statusPageNumber(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 contratoDescription(string, obrigatório) - Descrição do tipoIsActive(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çãoObservation(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 contratoDescription(string, obrigatório) - Descrição do tipoIsActive(bool, obrigatório) - Se está ativoNotifiesUsers(bool, obrigatório) - Se notifica usuáriosIsProfessionalOnly(bool, obrigatório) - Se é apenas para profissionaisAuthor(string, opcional) - Autor da operaçãoObservation(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 nomePageNumber(int) - Número da páginaPageSize(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ãoAuthor(string, opcional) - Autor da operaçãoObservation(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 contratoVersionId(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
RuleViolationDomainExceptionse 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 contratocontractVersionId(Guid, obrigatório) - Identificador da versão do contrato
Campos Necessários:
File(IFormFile, obrigatório) - Arquivo a ser enviadoIsDefault(bool, obrigatório) - Se é o arquivo padrão da versãoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações
Regras de Negócio:
- O arquivo é associado a uma versão específica do contrato
- Se
IsDefaultfor true, os outros arquivos da mesma versão terão seu flagIsDefaultremovido - 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 contratocontractVersionId(Guid, obrigatório) - Identificador da versão do contratofileId(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 contratocontractVersionId(Guid, obrigatório) - Identificador da versão do contratofileId(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 contratocontractVersionId(Guid, obrigatório) - Identificador da versão do contratofileId(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ãoPageNumber(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 associadoContractVersion(int, obrigatório) - Versão do contratoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações
Validações:
ContractId: Não pode ser vazioContractVersion: 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
IsSignedcomo true - Registra
SignedAtcom 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 profissionalprofessionalUserContractId(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 contratoIsSigned(bool?, opcional) - Filtrar por status de assinaturaPageNumber(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
-
Soft Delete vs Hard Delete: O
DeleteContractfaz soft delete quando há relacionamentos, preservando a integridade referencial. UseForceDeleteContractapenas quando necessário remover permanentemente. -
Versionamento de Contratos:
- Cada contrato pode ter múltiplas versões gerenciadas através da entidade ContractVersion
- O número da versão é sequencial e automático por contrato
- Versões podem ser ativadas/desativadas e publicadas
- Arquivos são associados a versões específicas, não diretamente ao contrato
-
Não é possível deletar uma versão que possui arquivos - delete os arquivos primeiro
-
Arquivos de Contrato:
- Cada arquivo pertence a uma versão específica do contrato
- Apenas um arquivo pode ser marcado como padrão por versão
-
URLs públicas expiram após aproximadamente 7 dias e são regeneradas automaticamente
-
Tipos de Contrato:
NotifiesUsers: Indica se contratos deste tipo devem gerar notificações para os usuários-
IsProfessionalOnly: Indica se o tipo de contrato é exclusivo para usuários profissionais que trabalham na plataforma -
Assinatura de Contratos: A assinatura é registrada com timestamp UTC e pode ser verificada através do campo
IsSignedeSignedAt. -
Auditoria: Todos os comandos suportam os campos
AuthoreObservationpara rastreabilidade das operações. -
Hierarquia de Endpoints:
- Contratos:
/v1/contracts/{contractId} - Versões:
/v1/contracts/{contractId}/versions/{versionId} - Arquivos (específicos da versão):
/v1/contracts/{contractId}/versions/{versionId}/files/{fileId} - Busca de arquivos (todas versões):
/v1/contracts/{contractId}/files/search