# Arquitectura: Cliente como HUB Central

**Fecha**: 2026-02-03  
**Versión**: 2.0

---

## Resumen

El módulo **Clientes** actúa como HUB central del sistema. Desde la ficha de un cliente se puede acceder a toda la información relacionada: proyectos, servicios, documentos, cotizaciones, tareas y estado de cuenta.

---

## Modelo de Datos - Relaciones con `clients`

### Tablas con FK RESTRICT (Protegen contra borrado)

| Tabla | Campo | Tipo | Descripción |
|-------|-------|------|-------------|
| `projects` | `client_id` | REQUIRED | Proyectos del cliente |
| `client_services` | `client_id` | REQUIRED | Servicios contratados |
| `hosting_domains` | `client_id` | REQUIRED | Hosting y dominios |
| `quotes` | `client_id` | REQUIRED | Cotizaciones |
| `advances` | `client_id` | REQUIRED | Adelantos/anticipos |

> ⚠️ **No se puede eliminar un cliente** si tiene registros en estas tablas. Usar `is_active = 0` para desactivar.

### Tablas con FK SET NULL (Permiten borrado, pierden relación)

| Tabla | Campo | Tipo | Descripción |
|-------|-------|------|-------------|
| `receivables` | `client_id` | NULLABLE | Cuentas por cobrar |
| `financial_documents` | `client_id` | NULLABLE | Facturas, RH, etc. |
| `cash_movements` | `client_id` | NULLABLE | Movimientos de caja |
| `time_entries` | `client_id` | NULLABLE | Registro de tiempo |
| `tasks` | `client_id` | NULLABLE | Tareas |
| `calendar_events` | `client_id` | NULLABLE | Eventos |
| `vault_credentials` | `client_id` | NULLABLE | Credenciales |

---

## Ficha del Cliente (`client_view.php`)

### Tabs Disponibles

| Tab | Descripción | Datos |
|-----|-------------|-------|
| **Resumen** | KPIs + datos básicos | Proyectos activos, servicios, saldo, última actividad |
| **Proyectos** | Lista de proyectos | `projects WHERE client_id = ?` |
| **Servicios** | Servicios + Hosting/Dominios | `client_services` + `hosting_domains` |
| **Documentos** | Facturas, RH, etc. | `financial_documents WHERE client_id = ?` |
| **Estado de cuenta** | Balance consolidado | `receivables WHERE client_id = ?` |
| **Cotizaciones** | Propuestas enviadas | `quotes WHERE client_id = ?` |
| **Tareas** | Tareas del cliente | `tasks WHERE client_id = ?` |

### KPIs del Resumen

```
┌─────────────────┬─────────────────┬─────────────────┬─────────────────┐
│ Proyectos       │ Servicios       │ Saldo por       │ Última          │
│ activos         │ activos         │ cobrar          │ actividad       │
│                 │                 │                 │                 │
│ [count]         │ [count]         │ S/ [amount]     │ [date]          │
└─────────────────┴─────────────────┴─────────────────┴─────────────────┘
```

---

## Modelo de Adelantos (Anticipos)

### Tabla `advances`

```sql
advances
├── id
├── client_id (FK RESTRICT → clients)
├── project_id (FK SET NULL → projects)
├── amount
├── currency
├── advance_date
├── payment_method
├── bank_account_id
├── reference
├── description
├── status: available | applied | refunded
├── applied_amount
├── proof_url
└── notes
```

### Tabla `advance_allocations`

```sql
advance_allocations
├── id
├── advance_id (FK RESTRICT → advances)
├── document_id (FK SET NULL → financial_documents)
├── receivable_id (FK SET NULL → receivables)
├── amount
├── allocation_date
└── notes
```

### Flujo de Adelantos

1. **Registrar adelanto**: Cliente paga anticipo → `advances.status = 'available'`
2. **Aplicar a documento**: Seleccionar documento/receivable → crear `advance_allocation`
3. **Actualizar saldos**: 
   - `advances.applied_amount += allocation.amount`
   - `advances.status = 'applied'` si `applied_amount >= amount`
   - Actualizar `status` del documento/receivable según saldo

---

## Diagrama de Relaciones

```
                              ┌─────────────────┐
                              │     clients     │
                              │   (HUB CENTRAL) │
                              └────────┬────────┘
                                       │
       ┌───────────────────────────────┼───────────────────────────────┐
       │                               │                               │
       ▼                               ▼                               ▼
┌──────────────┐              ┌──────────────┐              ┌──────────────┐
│   projects   │              │client_services│             │   quotes     │
│ FK RESTRICT  │              │  FK RESTRICT  │             │ FK RESTRICT  │
└──────┬───────┘              └──────────────┘              └──────────────┘
       │
       ▼
┌──────────────┐   ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│    tasks     │   │ receivables  │   │financial_docs│   │   advances   │
│ FK SET NULL  │   │ FK SET NULL  │   │ FK SET NULL  │   │ FK RESTRICT  │
└──────────────┘   └──────┬───────┘   └──────┬───────┘   └──────┬───────┘
                          │                   │                   │
                          └─────────┬─────────┘                   │
                                    │                             │
                                    ▼                             ▼
                          ┌─────────────────────────────────────────┐
                          │        advance_allocations              │
                          │  (Aplica adelantos a docs/receivables)  │
                          └─────────────────────────────────────────┘
```

---

## Reglas de Negocio

1. **No borrar clientes con actividad**: Usar `is_active = 0`
2. **Adelantos protegidos**: FK RESTRICT impide borrar cliente con adelantos
3. **Documentos históricos**: Aunque cliente se borre, documentos mantienen historial (SET NULL)
4. **Un cliente puede tener múltiples proyectos, servicios y adelantos**

---

## Checklist de Validación

- [ ] Crear cliente
- [ ] Crear proyecto ligado al cliente
- [ ] Crear servicio ligado al cliente
- [ ] Ver vencimiento de hosting/dominio
- [ ] Crear cotización ligada al cliente
- [ ] Registrar documento/factura ligada al cliente
- [ ] Registrar adelanto del cliente
- [ ] Aplicar adelanto a un documento
- [ ] Ver "Estado de cuenta" correcto
- [ ] Intentar eliminar cliente con proyectos (debe fallar)
- [ ] Desactivar cliente (`is_active = 0`)

---

## Archivos Relevantes

| Archivo | Descripción |
|---------|-------------|
| `public/clients.php` | Lista de clientes |
| `public/client_view.php` | Ficha del cliente (HUB) |
| `app/db/schema.php` | Definición de tablas |
| `app/services/financial_service.php` | Documentos financieros |
| `app/services/receivables_service.php` | Cuentas por cobrar |
