Terms & Privacy Aggregate
Este documento descreve todas as operações disponíveis para o agregado TermsPrivacy e seus recursos, seguindo os padrões de Domain-Driven Design (DDD) e Command Query Responsibility Segregation (CQRS).
Índice
- Terms & Privacy Aggregate
- Índice
- Terms (Termos)
- Visão Geral
- Commands (Comandos)
- 1. Criação de Termo (CreateTerm)
- 2. Atualização de Termo (UpdateTerm)
- 3. Ativação de Termo (ActivateTerm)
- 4. Arquivamento de Termo (ArchiveTerm)
- Queries (Consultas)
- 1. Buscar Termo por ID (GetTermById)
- 2. Pesquisar Termos (SearchTerms)
- 3. Buscar Termos Ativos (GetActiveTerms)
- User Term Acceptances (Aceites de Termos do Usuário)
- Professional User Term Acceptances (Aceites de Termos do Profissional)
- Enums
- Relacionamentos
- Regras de Negócio
Terms (Termos)
Visão Geral
O agregado Term representa os termos e políticas disponíveis no sistema que podem ser aceitos por usuários e profissionais. Cada termo possui: - Um tipo (TermType) que define a natureza do termo - Um status (TermStatus) que controla seu ciclo de vida - Uma versão numérica para controle de atualizações - Data de vigência (EffectiveDate)
Estrutura Hierárquica:
Term
├── UserTermAcceptances (1:N)
└── ProfessionalUserTermAcceptances (1:N)
Commands (Comandos)
1. Criação de Termo (CreateTerm)
Endpoint: POST /v1/terms
Contrato: CreateTermCommand
Campos Necessários:
Title(string, obrigatório) - Título do termoContent(string, obrigatório) - Conteúdo completo do termoType(TermType, obrigatório) - Tipo do termoStatus(TermStatus, opcional) - Status inicial (padrão: Draft)EffectiveDate(DateTime?, opcional) - Data de vigênciaAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
Title: Não pode ser vazio; Tamanho máximo: 200 caracteresContent: Não pode ser vazio; Tamanho máximo: 100.000 caracteresType: Deve ser um valor válido do enum TermType
Regras de Negócio:
- Versionamento automático - A versão é calculada automaticamente com base no próximo número disponível para o tipo (
GetNextVersionAsync) - Apenas um termo ativo por tipo - Se o termo for criado com status
Active, o termo ativo anterior do mesmoTermTypeé automaticamente arquivado
Retorno: CreateTermResponse
- Id (Guid) - Identificador do termo criado
- Version (int) - Versão atribuída ao termo
Exemplo de Uso:
{
"title": "Termos de Uso",
"content": "Lorem ipsum dolor sit amet...",
"type": 1,
"status": 1,
"effectiveDate": "2025-01-01T00:00:00Z",
"author": "admin@sistema.com"
}
2. Atualização de Termo (UpdateTerm)
Endpoint: PUT /v1/terms/{termId}
Contrato: UpdateTermCommand
Campos Necessários:
Title(string, obrigatório) - Título do termoContent(string, obrigatório) - Conteúdo completo do termoEffectiveDate(DateTime?, opcional) - Data de vigênciaAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
- Mesmas validações do CreateTerm para Title e Content
Retorno: 204 No Content
3. Ativação de Termo (ActivateTerm)
Endpoint: POST /v1/terms/{termId}/activate
Contrato: ActivateTermCommand
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termoAuthor(string, opcional) - Autor da operação
Validações:
- Termo deve existir
- Termo deve estar com status
Draft
Regras de Negócio:
- Apenas termos em status Draft podem ser ativados - Lança
BusinessRuleExceptionse o termo não estiver em Draft - Apenas um termo ativo por tipo - Ao ativar um termo, o termo ativo anterior do mesmo
TermTypeé automaticamente arquivado - A versão do termo ativado se torna a versão vigente para aquele tipo
Exceções:
NotFoundException("Term not found")- Termo não existeBusinessRuleException("Only terms with Draft status can be activated.")- Termo não está em Draft
Retorno: 204 No Content
4. Arquivamento de Termo (ArchiveTerm)
Endpoint: POST /v1/terms/{termId}/archive
Contrato: ArchiveTermCommand
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termo
Regras de Negócio:
- Apenas termos em status Active podem ser arquivados
- Termos arquivados são mantidos para histórico de aceites
Retorno: 204 No Content
Queries (Consultas)
1. Buscar Termo por ID (GetTermById)
Endpoint: GET /v1/terms/{termId}
Contrato: GetTermByIdQuery
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termo
Retorno: GetTermByIdResponse
- Id (Guid) - Identificador do termo
- Title (string) - Título do termo
- Content (string) - Conteúdo do termo
- Type (TermType) - Tipo do termo
- Version (int) - Versão do termo
- Status (TermStatus) - Status do termo
- EffectiveDate (DateTime) - Data de vigência
2. Pesquisar Termos (SearchTerms)
Endpoint: GET /v1/terms/search
Contrato: SearchTermsQuery
Campos de Filtro:
Type(TermType?, opcional) - Filtrar por tipoStatus(TermStatus?, opcional) - Filtrar por statusTitle(string?, opcional) - Filtrar por título (busca parcial)PageNumber(int, opcional) - Número da página (padrão: 1)PageSize(int, opcional) - Tamanho da página (padrão: 100)
Retorno: SearchTermsResponse (PagingResult)
3. Buscar Termos Ativos (GetActiveTerms)
Endpoint: GET /v1/terms/active
Contrato: GetActiveTermsQuery
Retorno: Lista de termos com status Active
User Term Acceptances (Aceites de Termos do Usuário)
Visão Geral
Representa o registro de aceite de termos por usuários. Cada aceite contém: - Referência ao termo aceito - Referência ao usuário - Informações de rastreamento (IP, User-Agent) - Data/hora do aceite
Commands (Comandos)
1. Aceitar Termo (AcceptUserTerm)
Endpoint: POST /v1/users/{userId}/term-acceptances
Contrato: AcceptUserTermCommand
Campos Necessários:
TermId(Guid, obrigatório) - Identificador do termo a ser aceitoIpAddress(string, opcional) - Endereço IP do usuárioUserAgent(string, opcional) - User-Agent do navegador/aplicativoAuthor(string, opcional) - Autor da operaçãoObservation(string, opcional) - Observações adicionais
Validações:
TermId: Não pode ser vazio; Termo deve existirIpAddress: Tamanho máximo: 45 caracteresUserAgent: Tamanho máximo: 500 caracteres
Regras de Negócio (DDD - Entidade User):
- O termo deve estar com status Active para ser aceito
- O usuário não pode aceitar o mesmo termo mais de uma vez
- A validação é feita no método
AcceptTermda entidade User
Exceções:
RuleViolationDomainException("Can only accept active terms.")- Termo não está ativoRuleViolationDomainException("User has already accepted this term.")- Termo já aceito
Retorno: AcceptUserTermResponse
- Id (Guid) - Identificador do aceite criado
Exemplo de Uso:
{
"termId": "123e4567-e89b-12d3-a456-426614174000",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}
Queries (Consultas)
1. Verificar Termos Pendentes (HasPendingTerms)
Endpoint: GET /v1/users/{userId}/term-acceptances/has-pending
Contrato: HasPendingTermsQuery
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuário
Retorno: HasPendingTermsResponse
- HasPendingTerms (bool) - true se existem termos ativos não aceitos pelo usuário
Exemplo de Resposta:
{
"hasPendingTerms": true
}
Lógica:
1. Busca todos os termos com status Active
2. Verifica quais termos o usuário já aceitou
3. Retorna true se existir algum termo ativo não aceito
2. Buscar Aceite por ID (GetUserTermAcceptanceById)
Endpoint: GET /v1/users/{userId}/term-acceptances/{id}
Contrato: GetUserTermAcceptanceByIdQuery
Campos Necessários:
UserId(Guid, obrigatório) - Identificador do usuárioTermAcceptanceId(Guid, obrigatório) - Identificador do aceite
Retorno: GetUserTermAcceptanceByIdResponse
- Id (Guid) - Identificador do aceite
- UserId (Guid) - Identificador do usuário
- TermId (Guid) - Identificador do termo
- TermTitle (string) - Título do termo
- TermType (TermType) - Tipo do termo
- TermStatus (TermStatus) - Status atual do termo
- TermVersion (int) - Versão do termo
- AcceptedAt (DateTime) - Data/hora do aceite
- IpAddress (string?) - Endereço IP
- UserAgent (string?) - User-Agent
3. Pesquisar Aceites (SearchUserTermAcceptances)
Endpoint: GET /v1/users/{userId}/term-acceptances/search
Contrato: SearchUserTermAcceptancesQuery
Campos de Filtro:
TermStatus(TermStatus?, opcional) - Filtrar por status do termoTermType(TermType?, opcional) - Filtrar por tipo do termoTermTitle(string?, opcional) - Filtrar por título (busca parcial)TermVersion(int?, opcional) - Filtrar por versãoAcceptedFrom(DateTime?, opcional) - Data mínima de aceiteAcceptedTo(DateTime?, opcional) - Data máxima de aceitePageNumber(int, opcional) - Número da página (padrão: 1)PageSize(int, opcional) - Tamanho da página (padrão: 100)
Retorno: SearchUserTermAcceptancesResponse (PagingResult)
Professional User Term Acceptances (Aceites de Termos do Profissional)
Visão Geral
Representa o registro de aceite de termos por usuários profissionais. Estrutura similar ao UserTermAcceptance, mas vinculado ao ProfessionalUser.
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
Exemplo de Resposta:
{
"hasPendingTerms": false
}
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
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)
Enums
TermStatus
| Valor | Nome | Descrição |
|---|---|---|
| 1 | Draft | Rascunho - ainda em edição |
| 2 | Active | Ativo - versão atual em vigor |
| 3 | Archived | Arquivado - versão anterior mantida para histórico |
TermType
| Valor | Nome | Descrição |
|---|---|---|
| 1 | TermsOfUse | Termos de Uso |
| 2 | PrivacyPolicy | Política de Privacidade |
| 3 | CookiePolicy | Política de Cookies |
| 4 | ProfessionalTerms | Termos do Profissional |
| 5 | CancellationPolicy | Política de Cancelamento |
Relacionamentos
Term (1) ──────────────── (N) UserTermAcceptance ──── (1) User
│
└───────────────────── (N) ProfessionalUserTermAcceptance ──── (1) ProfessionalUser
Tabelas:
- terms - Armazena os termos e políticas
- user_term_acceptances - Registro de aceites de usuários
- professional_user_term_acceptances - Registro de aceites de profissionais
Índices:
- user_term_acceptances: índice único em (user_id, term_id)
- professional_user_term_acceptances: índice único em (professional_user_id, term_id)
Regras de Negócio
Gestão de Termos
- Apenas um termo ativo por tipo - Para cada
TermType, apenas um termo pode estar com statusActivepor vez - Versionamento automático - A versão é calculada automaticamente ao criar um novo termo
- Arquivamento automático - Ao ativar um termo ou criar um termo já como
Active, o termo ativo anterior do mesmo tipo é automaticamente arquivado - Apenas Draft pode ser ativado - Termos só podem ser ativados se estiverem em status
Draft
Aceite de Termos
- Unicidade: Um usuário/profissional só pode aceitar cada termo uma única vez
- Status Ativo: Apenas termos com status
Activepodem ser aceitos - Rastreabilidade: IP e User-Agent são armazenados para auditoria
- Histórico: Mesmo após arquivamento do termo, os aceites são mantidos
Ativação de Profissional
Para um profissional ser ativado na plataforma, ele deve ter aceito todos os termos ativos. Esta verificação é feita através do método HasAcceptedAllRequiredTerms na entidade ProfessionalUser.
Verificação de Pendências
O endpoint has-pending permite verificar rapidamente se existem termos que precisam ser aceitos, útil para:
- Exibir avisos no frontend
- Bloquear ações que requerem aceite de termos
- Fluxos de onboarding