@hed-hog/contact
v0.0.304
Published
```markdown # @hed-hog/contact
Readme
# @hed-hog/contact
## 1. Visão geral do módulo
O módulo `@hed-hog/contact` gerencia informações relacionadas a contatos, documentos, pessoas e seus tipos, além das relações entre pessoas. Ele oferece funcionalidades completas de CRUD para tipos de contato, tipos de documento, pessoas e suas relações, com suporte a internacionalização (locales), paginação e controle de acesso baseado em roles.
## 2. Escopo e responsabilidades
- Gerenciar tipos de contato (`contact_type`).
- Gerenciar tipos de documento (`document_type`).
- Gerenciar pessoas (`person`), incluindo contatos, documentos, endereços e metadados.
- Gerenciar tipos de relação entre pessoas (`person_relation_type`), que são fixos e imutáveis via API.
- Validar regras específicas de negócio, como unicidade de contatos primários e restrições para registro de empresas.
- Suportar autenticação e autorização baseada em roles (`admin`, `admin-contact`).
- Suportar internacionalização para mensagens e dados localizados.
- Integrar com serviços de paginação, banco de dados Prisma e envio de emails.
## 3. Endpoints
### Person Contact Type (`/person-contact-type`)
| Método | Path | Autenticação | Descrição |
|--------|------------------------|-------------------------------------|----------------------------------|
| GET | `/person-contact-type` | Autenticado (roles: admin, admin-contact) | Lista tipos de contato com paginação e locale. |
| GET | `/person-contact-type/:id` | Autenticado (roles: admin, admin-contact) | Obtém tipo de contato por ID com locale. |
| POST | `/person-contact-type` | Autenticado (roles: admin, admin-contact) | Cria um novo tipo de contato. |
| PATCH | `/person-contact-type/:id` | Autenticado (roles: admin, admin-contact) | Atualiza um tipo de contato existente. |
| DELETE | `/person-contact-type` | Autenticado (roles: admin, admin-contact) | Exclui tipos de contato por IDs. |
**Parâmetros e corpo:**
- `CreateDTO` para criação:
- `code` (string): código do tipo de contato.
- `locale` (objeto): nomes localizados, ex: `{ "pt": { "name": "Telefone" }, "en": { "name": "Phone" } }`.
- `UpdateDTO` para atualização: campos parciais de `CreateDTO`, `locale` opcional.
**Resposta:**
- Listagem paginada ou objeto do tipo criado/atualizado.
- Erros:
- 400 Bad Request: dados inválidos, `locale` vazio, IDs para exclusão não informados.
- 404 Not Found: tipo de contato não encontrado.
---
### Person Document Type (`/person-document-type`)
| Método | Path | Autenticação | Descrição |
|--------|------------------------|-------------------------------------|----------------------------------|
| GET | `/person-document-type` | Autenticado (roles: admin, admin-contact) | Lista tipos de documento com paginação e locale. |
| GET | `/person-document-type/:id` | Autenticado (roles: admin, admin-contact) | Obtém tipo de documento por ID com locale. |
| POST | `/person-document-type` | Autenticado (roles: admin, admin-contact) | Cria um novo tipo de documento. |
| PATCH | `/person-document-type/:id` | Autenticado (roles: admin, admin-contact) | Atualiza um tipo de documento existente. |
| DELETE | `/person-document-type` | Autenticado (roles: admin, admin-contact) | Exclui tipos de documento por IDs. |
**Parâmetros e corpo:**
- `CreateDTO` para criação:
- `code` (string): código do tipo de documento.
- `country_code` (string): código do país.
- `is_unique` (boolean): indica se o documento é único.
- `locale` (objeto): nomes localizados.
- `UpdateDTO` para atualização: campos parciais de `CreateDTO`, `locale` opcional.
**Resposta:**
- Listagem paginada ou objeto do tipo criado/atualizado.
- Erros:
- 400 Bad Request: dados inválidos, `locale` vazio, IDs para exclusão não informados.
- 404 Not Found: tipo de documento não encontrado.
---
### Person (`/person`)
| Método | Path | Autenticação | Descrição |
|--------|------------------------|-------------------------------------|----------------------------------|
| GET | `/person` | Autenticado (roles: admin, admin-contact) | Lista pessoas com filtros e paginação. |
| GET | `/person/stats` | Autenticado (roles: admin, admin-contact) | Estatísticas de pessoas. |
| GET | `/person/owner-options`| Autenticado (roles: admin, admin-contact) | Lista usuários possíveis para atribuição como responsáveis. |
| GET | `/person/:id` | Autenticado (roles: admin, admin-contact) | Obtém pessoa por ID com detalhes. |
| GET | `/person/avatar/:id` | Pública | Abre avatar público pelo ID do arquivo. |
| POST | `/person` | Autenticado (roles: admin, admin-contact) | Cria uma nova pessoa. |
| PATCH | `/person/:id` | Autenticado (roles: admin, admin-contact) | Atualiza pessoa existente. |
| DELETE | `/person` | Autenticado (roles: admin, admin-contact) | Exclui pessoas por IDs. |
**Parâmetros e corpo:**
- `CreateDTO` para criação:
- `name` (string): nome da pessoa.
- `type` (enum: individual, company): tipo da pessoa.
- `status` (enum: active, inactive): status da pessoa.
- Campos opcionais: `avatar_id`, `birth_date`, `gender`, `job_title`, `trade_name`, `foundation_date`, `legal_nature`, `notes`, `employer_company_id`.
- `UpdateAllPersonDTO` para atualização:
- Inclui todos os campos do `CreateDTO`.
- Arrays para `contacts`, `addresses`, `documents` com seus respectivos campos e validações.
- Validação para garantir apenas um contato, endereço ou documento primário por tipo.
- Campos opcionais `branch_ids` (array de números) e `headquarter_id` (número).
**Resposta:**
- Listagem paginada, objeto da pessoa criada/atualizada, ou estatísticas.
- Erros:
- 400 Bad Request: dados inválidos, mais de um primário por tipo, referência inválida, registro de empresa desabilitado, IDs para exclusão não informados.
- 404 Not Found: pessoa não encontrada, avatar não encontrado.
---
### Person Relation Type (`/person-relation-type`)
| Método | Path | Autenticação | Descrição |
|--------|------------------------|-------------------------------------|----------------------------------|
| GET | `/person-relation-type` | Autenticado (roles: admin, admin-contact) | Lista tipos fixos de relação entre pessoas. |
| GET | `/person-relation-type/:id` | Autenticado (roles: admin, admin-contact) | Obtém tipo de relação por ID. |
| POST | `/person-relation-type` | Autenticado (roles: admin, admin-contact) | **Não suportado** (tipos fixos). |
| PATCH | `/person-relation-type/:id` | Autenticado (roles: admin, admin-contact) | **Não suportado** (tipos fixos). |
| DELETE | `/person-relation-type` | Autenticado (roles: admin, admin-contact) | **Não suportado** (tipos fixos). |
**Observação:** Tipos de relação são fixos e não podem ser criados, atualizados ou deletados via API. Tentativas resultam em erro 400.
---
## 4. Regras de autenticação e autorização
- A maioria dos endpoints requer autenticação via JWT.
- Acesso restrito a usuários com roles `admin` ou `admin-contact`.
- O endpoint de avatar (`/person/avatar/:id`) é público.
- Tentativas de criar, atualizar ou deletar tipos de relação entre pessoas resultam em erro 400, pois são fixos.
## 5. Estruturas de request/response
### CreateDTO (Person Contact Type)
```json
{
"code": "string",
"locale": {
"pt": { "name": "string" },
"en": { "name": "string" }
}
}UpdateDTO (Person Contact Type)
Campos parciais de CreateDTO, locale opcional.
CreateDTO (Person Document Type)
{
"code": "string",
"country_code": "string",
"is_unique": true,
"locale": {
"pt": { "name": "string" },
"en": { "name": "string" }
}
}UpdateDTO (Person Document Type)
Campos parciais de CreateDTO, locale opcional.
CreateDTO (Person)
{
"name": "string",
"type": "individual | company",
"status": "active | inactive",
"avatar_id": "number | null",
"birth_date": "string (date) | null",
"gender": "male | female | other | null",
"job_title": "string | null",
"trade_name": "string | null",
"foundation_date": "string (date) | null",
"legal_nature": "string | null",
"notes": "string | null",
"employer_company_id": "number | null"
}UpdateAllPersonDTO (Person)
Inclui todos os campos do CreateDTO e:
contacts: array de objetos comid?,value,is_primary,contact_type_id.addresses: array de objetos comid?,line1,line2?,city,state,country_code?,postal_code?,is_primary,address_type.documents: array de objetos comid?,value,document_type_id.branch_ids?: array de números.headquarter_id?: número opcional para empresa.
6. Erros comuns
400 Bad Request
- Falta de campos obrigatórios (ex:
localevazio). - Tentativa de criar/atualizar tipos de relação (não suportado).
- Mais de um contato, endereço ou documento primário do mesmo tipo.
- Tentativa de registrar empresa quando registro está desabilitado.
- Referência inválida para empresa ou endereço.
- IDs para exclusão não informados.
- Falta de campos obrigatórios (ex:
404 Not Found
- Entidade não encontrada por ID (pessoa, tipo de contato, tipo de documento).
- Pessoa do tipo empresa não encontrada quando registro está desabilitado.
- Avatar não encontrado.
7. Banco de dados (tabelas YAML)
contact
- Finalidade: Armazena contatos associados a pessoas.
- Colunas:
id(PK)person_id(FK paraperson.id)contact_type_id(FK paracontact_type.id)value(string)is_primary(boolean, default: false)created_at,updated_at
- Índices:
- Único em
(person_id, contact_type_id, is_primary)ondeis_primary = true.
- Único em
contact_type
- Finalidade: Define tipos de contato.
- Colunas:
id(PK)name(locale_varchar, com traduções pt/en)code(string)created_at,updated_at
document
- Finalidade: Armazena documentos associados a pessoas.
- Colunas:
id(PK)person_id(FK paraperson.id)document_type_id(FK paradocument_type.id)value(string)created_at,updated_at
document_type
- Finalidade: Define tipos de documento.
- Colunas:
id(PK)name(locale_varchar, pt/en)code(string)country_code(string)is_unique(boolean)created_at,updated_at
person
- Finalidade: Armazena pessoas (indivíduos e empresas).
- Colunas:
id(PK)name(string)type(enum: individual, company)status(enum: active, inactive)avatar_id(FK parafile.id, nullable, onDelete SET NULL)created_at,updated_at
person_address
- Finalidade: Associação entre pessoas e endereços.
- Colunas:
id(PK)person_id(FK paraperson.id)address_id(FK paraaddress.id)created_at,updated_at
- Índices:
- Único em
address_id.
- Único em
person_company
- Finalidade: Dados específicos para pessoas do tipo empresa.
- Colunas:
id(PK, FK paraperson.id)trade_name(string, nullable)foundation_date(date, nullable)legal_nature(string, nullable)headquarter_id(FK paraperson_company.id, nullable, onDelete SET NULL, onUpdate CASCADE)created_at,updated_at
- Índices:
- Em
headquarter_id
- Em
person_individual
- Finalidade: Dados específicos para pessoas do tipo indivíduo.
- Colunas:
id(PK, FK paraperson.id)birth_date(date, nullable)gender(enum: male, female, other, nullable)job_title(string, nullable)created_at,updated_at
person_individual_relation
- Finalidade: Relações entre pessoas do tipo indivíduo.
- Colunas:
id(PK)person_individual_id(FK paraperson_individual.id, onDelete CASCADE, onUpdate CASCADE)related_person_individual_id(FK paraperson_individual.id, onDelete CASCADE, onUpdate CASCADE)relation_type(enum: parent, child, spouse, sibling, guardian, dependent, partner, responsible, emergency_contact, other)created_at,updated_at
- Índices:
- Em
person_individual_id,related_person_individual_id,relation_type - Único em
(person_individual_id, related_person_individual_id, relation_type)
- Em
person_metadata
- Finalidade: Metadados arbitrários associados a pessoas.
- Colunas:
id(PK)person_id(FK paraperson.id)key(string)value(json)created_at,updated_at
8. Regras de negócio relevantes
- Tipos de relação entre pessoas são fixos e não podem ser alterados via API.
- Apenas um contato, endereço ou documento pode ser marcado como primário por tipo para uma pessoa.
- Registro de pessoas do tipo empresa pode ser desabilitado via configuração
contact-allow-company-registration. - Ao criar ou atualizar pessoa, validações garantem integridade das relações e dados.
- Exclusão de pessoas remove em cascata contatos, documentos, endereços, relações e metadados associados.
- Avatar público pode ser acessado via endpoint público, com cache control configurado.
- Ao criar pessoa sem usuário, é enviado email com link para criação de conta, com token JWT válido por 1 dia.
- Metadados como
noteseemployer_company_idsão armazenados separadamente e sincronizados. - Empresas não podem ser vinculadas como sua própria matriz (headquarter).
- Apenas empresas podem ser vinculadas como matriz ou filial.
- Validações específicas impedem inconsistências nas relações de empresas e indivíduos.
- Atualização de pessoa sincroniza contatos, endereços e documentos, criando, atualizando ou removendo conforme necessário.
- Pesquisa de pessoas suporta filtros por nome, tipo, status, e busca por dados normalizados em contatos, documentos e endereços.
9. Guia rápido de uso (exemplos)
Criar tipo de contato
POST /person-contact-type
Authorization: Bearer <token>
Content-Type: application/json
{
"code": "phone",
"locale": {
"pt": { "name": "Telefone" },
"en": { "name": "Phone" }
}
}Atualizar tipo de documento
PATCH /person-document-type/3
Authorization: Bearer <token>
Content-Type: application/json
{
"is_unique": true,
"locale": {
"pt": { "name": "CPF" },
"en": { "name": "CPF" }
}
}Listar pessoas com filtro e paginação
GET /person?search=joao&type=individual&status=active&page=1&pageSize=20
Authorization: Bearer <token>Criar pessoa
POST /person
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "João Silva",
"type": "individual",
"status": "active",
"birth_date": "1980-05-10",
"gender": "male",
"contacts": [
{
"value": "[email protected]",
"is_primary": true,
"contact_type_id": 1
}
],
"addresses": [
{
"line1": "Rua A, 123",
"city": "São Paulo",
"state": "SP",
"country_code": "BRA",
"postal_code": "01000-000",
"is_primary": true,
"address_type": "residential"
}
],
"documents": [
{
"value": "123.456.789-00",
"document_type_id": 1
}
]
}Atualizar pessoa
PATCH /person/10
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "João da Silva",
"status": "active",
"contacts": [
{
"id": 5,
"value": "[email protected]",
"is_primary": true,
"contact_type_id": 1
}
]
}Excluir pessoas
DELETE /person
Authorization: Bearer <token>
Content-Type: application/json
{
"ids": [10, 11, 12]
}Este README documenta as funcionalidades principais do módulo @hed-hog/contact com base no código e definições atuais. Para detalhes adicionais, consulte o código fonte e as definições de DTOs.
