# 📋 Documentação de Validação de Clientes

## 🎯 Visão Geral

O sistema de validação de clientes foi aprimorado para garantir a **unicidade** de campos críticos e a **integridade** dos dados. As validações são aplicadas tanto na **criação** quanto na **atualização** de clientes.

## 🔒 Campos Únicos

### 1. **Tax Number** (Número de Contribuinte)
- **Unicidade**: ✅ Obrigatório ser único
- **Formato**: 9 dígitos numéricos
- **Exemplo**: `123456789`
- **Erro**: `DUPLICATE_TAX_NUMBER`

### 2. **Mobile** (Telemóvel)
- **Unicidade**: ✅ Obrigatório ser único
- **Formato**: `+258 8X XXX XXXX` ou `+258 2X XXX XXXX` (espaços opcionais)
- **Exemplo**: `+258 84 123 4567` ou `+258841234567`
- **Erro**: `DUPLICATE_MOBILE`

### 3. **Home Phone** (Telefone Fixo)
- **Unicidade**: ✅ Obrigatório ser único
- **Formato**: `+258 2X XXX XXXX` (espaços opcionais)
- **Exemplo**: `+258 21 987 6543` ou `+258219876543`
- **Erro**: `DUPLICATE_HOME_PHONE`

### 4. **ID Number** (Número de Identificação)
- **Unicidade**: ✅ Obrigatório ser único (se fornecido)
- **Formato**: 5-50 caracteres alfanuméricos
- **Exemplo**: `123456789` ou `ABC123456`
- **Erro**: `DUPLICATE_ID_NUMBER`

## 📱 Formatos de Telefone Válidos

### Telemóveis (Mobile)
| Operadora | Formato | Exemplo (com espaços) | Exemplo (sem espaços) |
|-----------|---------|----------------------|----------------------|
| Vodacom | `+258 84 XXX XXXX` | `+258 84 123 4567` | `+258841234567` |
| MCel | `+258 82 XXX XXXX` | `+258 82 987 6543` | `+258829876543` |
| Movitel | `+258 86 XXX XXXX` | `+258 86 555 1234` | `+258865551234` |
| Movitel | `+258 87 XXX XXXX` | `+258 87 777 8888` | `+258877778888` |
| Movitel | `+258 88 XXX XXXX` | `+258 88 999 0000` | `+258889990000` |
| Movitel | `+258 89 XXX XXXX` | `+258 89 111 2222` | `+258891112222` |

### Telefones Fixos (Home Phone)
| Cidade | Formato | Exemplo (com espaços) | Exemplo (sem espaços) |
|--------|---------|----------------------|----------------------|
| Maputo | `+258 21 XXX XXXX` | `+258 21 123 4567` | `+258211234567` |
| Beira | `+258 23 XXX XXXX` | `+258 23 987 6543` | `+258239876543` |
| Quelimane | `+258 24 XXX XXXX` | `+258 24 555 1234` | `+258245551234` |
| Tete | `+258 25 XXX XXXX` | `+258 25 777 8888` | `+258257778888` |
| Nampula | `+258 26 XXX XXXX` | `+258 26 999 0000` | `+258269990000` |
| Pemba | `+258 27 XXX XXXX` | `+258 27 111 2222` | `+258271112222` |
| Inhambane | `+258 28 XXX XXXX` | `+258 28 333 4444` | `+258283334444` |

## 📅 Validações de Data

### Data de Nascimento
- **Formato**: `YYYY-MM-DD`
- **Idade Mínima**: 16 anos
- **Idade Máxima**: 100 anos
- **Restrição**: Não pode ser no futuro
- **Erros**:
  - `INVALID_DATE_OF_BIRTH`: Data inválida
  - `FUTURE_DATE_OF_BIRTH`: Data no futuro
  - `INSUFFICIENT_AGE`: Menor de 16 anos
  - `EXCESSIVE_AGE`: Maior de 100 anos

## 📞 Validação de Contato

### Regra de Contato
- **Obrigatório**: Pelo menos um contato deve ser fornecido
- **Campos**: `mobile` OU `home_phone`
- **Erro**: `MISSING_CONTACT`

## 🚫 Códigos de Erro

| Código | Descrição | Status |
|--------|-----------|--------|
| `DUPLICATE_TAX_NUMBER` | Tax number já existe | 409 |
| `DUPLICATE_MOBILE` | Mobile já existe | 409 |
| `DUPLICATE_HOME_PHONE` | Home phone já existe | 409 |
| `DUPLICATE_ID_NUMBER` | ID number já existe | 409 |
| `INVALID_PHONE_FORMAT` | Formato de telefone inválido | 400 |
| `INVALID_TAX_NUMBER_FORMAT` | Formato de tax number inválido | 400 |
| `INVALID_ID_NUMBER_FORMAT` | Formato de ID number inválido | 400 |
| `INVALID_DATE_OF_BIRTH` | Data de nascimento inválida | 400 |
| `FUTURE_DATE_OF_BIRTH` | Data no futuro | 400 |
| `INSUFFICIENT_AGE` | Idade menor que 16 anos | 400 |
| `EXCESSIVE_AGE` | Idade maior que 100 anos | 400 |
| `MISSING_CONTACT` | Nenhum contato fornecido | 400 |

## 📝 Exemplos de Respostas de Erro

### Tax Number Duplicado
```json
{
  "success": false,
  "error": "Este número de contribuinte já está sendo usado por outro cliente. Por favor, use um número diferente.",
  "code": "DUPLICATE_TAX_NUMBER",
  "details": {
    "field": "tax_number",
    "value": "123456789",
    "existing_customer": {
      "customer_id": 5,
      "name": "João Silva"
    }
  }
}
```

### Formato de Telefone Inválido
```json
{
  "success": false,
  "error": "Formato de telefone inválido",
  "code": "INVALID_PHONE_FORMAT",
  "details": {
    "errors": [
      {
        "field": "mobile",
        "message": "Formato de telemóvel inválido. Use o formato: +258 8X XXX XXXX ou +258 2X XXX XXXX",
        "value": "123456789",
        "expected_format": "+258 8X XXX XXXX (Vodacom/MCel/Movitel) ou +258 2X XXX XXXX (fixo)"
      }
    ],
    "valid_formats": {
      "mobile": [
        "+258 84 XXX XXXX (Vodacom)",
        "+258 82 XXX XXXX (MCel)",
        "+258 86 XXX XXXX (Movitel)"
      ]
    }
  }
}
```

### Cliente Sem Contato
```json
{
  "success": false,
  "error": "Pelo menos um número de contato (telemóvel ou telefone fixo) deve ser fornecido.",
  "code": "MISSING_CONTACT",
  "details": {
    "required_fields": ["mobile", "home_phone"],
    "message": "Forneça pelo menos um dos campos: mobile ou home_phone"
  }
}
```

## 🔧 Middlewares de Validação

### Ordem de Execução
1. `validateIdNumberFormat` - Valida formato do ID
2. `validateTaxNumberFormat` - Valida formato do tax number
3. `validatePhoneFormat` - Valida formato dos telefones
4. `validateDateOfBirth` - Valida data de nascimento
5. `validateCustomerUniqueness` - Valida unicidade dos campos

### Aplicação
- **Criação**: Todos os middlewares são aplicados
- **Atualização**: Todos os middlewares são aplicados (com exclusão do ID atual)

## 🧪 Testes

### Script de Teste
Execute o arquivo `test-customer-validation.js` para testar todas as validações:

```bash
node test-customer-validation.js
```

### Cenários Testados
1. ✅ Tax number duplicado
2. ✅ Mobile duplicado
3. ✅ Home phone duplicado
4. ✅ Formato de telefone inválido
5. ✅ Formato de tax number inválido
6. ✅ Data de nascimento no futuro
7. ✅ Idade menor que 16 anos
8. ✅ Cliente sem contato
9. ✅ Cliente válido

## 📊 Logs

### Informações Registradas
- **Criação**: ID do cliente, tax_number, mobile, home_phone, created_by
- **Atualização**: ID do cliente, campos alterados, tax_number, mobile, home_phone, updated_by

### Exemplo de Log
```json
{
  "level": "info",
  "message": "Cliente criado: João Silva (ID: 15) por usuário admin",
  "customer_id": 15,
  "tax_number": "123456789",
  "mobile": "+258 84 123 4567",
  "home_phone": "+258 21 987 6543",
  "created_by": 1
}
```

## 🎯 Benefícios

1. **Integridade de Dados**: Garante que não há duplicatas
2. **Validação Robusta**: Múltiplas camadas de validação
3. **Mensagens Amigáveis**: Erros claros e informativos
4. **Logs Detalhados**: Rastreamento completo das operações
5. **Flexibilidade**: Suporte a criação e atualização
6. **Padrões Moçambicanos**: Formatos específicos do país

## 🔄 Atualizações

### Comportamento em Updates
- **Exclusão**: O cliente atual é excluído das verificações de unicidade
- **Validação**: Apenas campos alterados são validados
- **Logs**: Registra quais campos foram alterados

### Exemplo de Update
```javascript
// Atualizando apenas o mobile
PUT /api/customers/5
{
  "mobile": "+258 84 999 9999"
}

// Validação: Verifica se o novo mobile já existe (excluindo o cliente 5)
```

---

**📅 Última Atualização**: 2025-01-11  
**👨‍💻 Desenvolvido por**: Sistema de Microcrédito  
**🔧 Versão**: 1.0.0
