# US-MGN005-001: Gestionar Contactos

## Identificacion

| Campo | Valor |
|-------|-------|
| **ID** | US-MGN005-001 |
| **Modulo** | MGN-005 Catalogs |
| **Sprint** | Sprint 3 |
| **Prioridad** | P0 - Critica |
| **Story Points** | 8 |
| **Estado** | Ready |
| **RF Relacionado** | RF-CATALOG-001 |
| **Fecha** | 2025-12-05 |

---

## Historia de Usuario

**Como** usuario del sistema
**Quiero** gestionar contactos (clientes, proveedores, empleados)
**Para** mantener un directorio centralizado de todas las entidades con las que interactua mi organizacion

---

## Descripcion

El sistema debe permitir crear, editar, listar y eliminar contactos. Cada contacto puede ser clasificado como cliente, proveedor, empleado u otro tipo. Los contactos son la base para operaciones comerciales, facturacion, pagos y CRM.

### Contexto

- Base para modulos de ventas, compras y CRM
- Soporta multiple tipos de contacto
- Incluye datos fiscales y de contacto
- Vinculable a usuarios del sistema

---

## Criterios de Aceptacion

### Escenario 1: Listar contactos

```gherkin
Given un usuario autenticado con permiso "catalogs.contacts.read"
When accede a GET /api/v1/catalogs/contacts
Then el sistema responde con status 200
  And retorna lista paginada de contactos del tenant
  And cada contacto incluye: id, name, contactType, email, phone, isActive
  And los resultados estan ordenados por nombre por defecto
```

### Escenario 2: Buscar contactos

```gherkin
Given un usuario con permiso "catalogs.contacts.read"
When envia GET /api/v1/catalogs/contacts?search=acme
Then retorna contactos cuyo nombre, email o tax_id contengan "acme"
  And la busqueda es case-insensitive

When envia GET /api/v1/catalogs/contacts?type=customer
Then retorna solo contactos de tipo "customer"

When envia GET /api/v1/catalogs/contacts?tags=vip,prioritario
Then retorna contactos que tengan cualquiera de esos tags
```

### Escenario 3: Crear contacto

```gherkin
Given un usuario con permiso "catalogs.contacts.create"
When envia POST /api/v1/catalogs/contacts con datos validos:
  | name | "ACME Corporation" |
  | contactType | "customer" |
  | email | "info@acme.com" |
  | taxId | "RFC123456789" |
Then el sistema responde con status 201
  And retorna el contacto creado con id generado
  And el contacto pertenece al tenant actual
```

### Escenario 4: Crear contacto con datos incompletos

```gherkin
Given un usuario con permiso "catalogs.contacts.create"
When envia POST sin el campo "name"
Then el sistema responde con status 400
  And el mensaje indica "name es requerido"

When envia POST con email invalido
Then el sistema responde con status 400
  And el mensaje indica "email no es valido"

When envia POST con contactType no valido
Then el sistema responde con status 400
  And el mensaje indica "contactType debe ser: customer, supplier, employee, other"
```

### Escenario 5: Actualizar contacto

```gherkin
Given un contacto existente con id "uuid-123"
  And un usuario con permiso "catalogs.contacts.update"
When envia PATCH /api/v1/catalogs/contacts/uuid-123
  | phone | "+52 555 123 4567" |
Then el sistema responde con status 200
  And retorna el contacto actualizado
  And updated_at se actualiza
```

### Escenario 6: Eliminar contacto (soft delete)

```gherkin
Given un contacto existente sin referencias en otros modulos
  And un usuario con permiso "catalogs.contacts.delete"
When envia DELETE /api/v1/catalogs/contacts/uuid-123
Then el sistema responde con status 204
  And el contacto se marca como is_active = false
  And el contacto ya no aparece en listados por defecto
```

### Escenario 7: Contacto con referencias

```gherkin
Given un contacto que tiene facturas asociadas
When se intenta eliminar el contacto
Then el sistema responde con status 409
  And el mensaje indica "Contacto tiene registros asociados"
  And sugiere desactivar en lugar de eliminar
```

### Escenario 8: Ver detalle con direcciones

```gherkin
Given un contacto con multiples direcciones
When envia GET /api/v1/catalogs/contacts/uuid-123?include=addresses
Then retorna el contacto con array de direcciones
  And cada direccion incluye: type, street, city, state, country, postalCode, isDefault
```

---

## Mockup / Wireframe

```
+------------------------------------------------------------------+
|  CONTACTOS                                    [+ Nuevo Contacto] |
+------------------------------------------------------------------+
| [Buscar...]  [Tipo: Todos v] [Tags: v] [Solo activos ✓]          |
+------------------------------------------------------------------+
| □ | NOMBRE          | TIPO      | EMAIL           | TELEFONO    |
+------------------------------------------------------------------+
| □ | ACME Corp       | Cliente   | info@acme.com   | 555-1234    |
| □ | Proveedor XYZ   | Proveedor | ventas@xyz.com  | 555-5678    |
| □ | Juan Perez      | Empleado  | juan@empresa.com| 555-9012    |
+------------------------------------------------------------------+
| < 1 2 3 ... 10 >                      Mostrando 1-20 de 156      |
+------------------------------------------------------------------+

Modal: Nuevo/Editar Contacto
+------------------------------------------------------------------+
| NUEVO CONTACTO                                              [X]  |
+------------------------------------------------------------------+
| Tipo de Contacto*                                                |
| ( ) Cliente  ( ) Proveedor  ( ) Empleado  ( ) Otro              |
|                                                                  |
| Nombre/Razon Social*        | RFC/NIF                           |
| [________________________]  | [________________]                 |
|                                                                  |
| Email                       | Telefono                           |
| [________________________]  | [________________]                 |
|                                                                  |
| [+ Agregar Direccion]                                           |
|                                                                  |
| Tags: [VIP] [x] [Prioritario] [x]  [+ Agregar]                  |
|                                                                  |
|                               [Cancelar]  [=== Guardar ===]     |
+------------------------------------------------------------------+
```

---

## Notas Tecnicas

### API Endpoints

| Metodo | Path | Descripcion |
|--------|------|-------------|
| GET | /catalogs/contacts | Listar con filtros |
| GET | /catalogs/contacts/:id | Obtener detalle |
| POST | /catalogs/contacts | Crear contacto |
| PATCH | /catalogs/contacts/:id | Actualizar |
| DELETE | /catalogs/contacts/:id | Eliminar (soft) |
| POST | /catalogs/contacts/:id/addresses | Agregar direccion |
| DELETE | /catalogs/contacts/:id/addresses/:aid | Eliminar direccion |

### Validaciones

| Campo | Regla | Mensaje Error |
|-------|-------|---------------|
| name | Required, MaxLength(255) | "Nombre es requerido" |
| contactType | Required, Enum | "Tipo de contacto invalido" |
| email | Optional, IsEmail | "Email no es valido" |
| taxId | Optional, MaxLength(50) | - |
| phone | Optional, Pattern | "Formato de telefono invalido" |

---

## Definicion de Done

- [ ] CRUD completo de contactos implementado
- [ ] Busqueda por nombre, email, taxId
- [ ] Filtros por tipo y tags
- [ ] Gestion de direcciones
- [ ] Soft delete implementado
- [ ] Validacion de referencias antes de eliminar
- [ ] RLS aplicado (tenant isolation)
- [ ] Tests unitarios (>80% coverage)
- [ ] Tests e2e pasando
- [ ] UI de listado y formulario
- [ ] Documentacion Swagger

---

## Dependencias

### Requiere

| Item | Descripcion |
|------|-------------|
| MGN-001 Auth | Autenticacion JWT |
| MGN-003 RBAC | Permisos catalogs.contacts.* |
| MGN-004 Tenants | RLS por tenant |
| core_catalogs schema | Tablas contacts, addresses |

### Bloquea

| Item | Descripcion |
|------|-------------|
| Facturacion | Requiere clientes/proveedores |
| CxC/CxP | Requiere contactos |
| CRM | Requiere contactos |

---

## Historial

| Version | Fecha | Autor | Cambios |
|---------|-------|-------|---------|
| 1.0 | 2025-12-05 | Requirements-Analyst | Creacion inicial |
