# 🏗️ Arquitectura del Sistema

## Descripción general

Este proyecto es un **backend API REST** construido con **Laravel 12** para un sistema de gestión empresarial de vinos y licores. La arquitectura sigue un patrón **modular orientado a dominios** con separación clara de responsabilidades.

## Stack tecnológico

### Backend
- **Framework:** Laravel 12
- **PHP:** >= 8.2
- **Base de datos:** MySQL 8.0+ / MariaDB 10.3+
- **Autenticación:** Laravel Sanctum + 2FA (TOTP)
- **API Documentation:** Scribe
- **Testing:** Pest (no PHPUnit)

### Frontend assets
- **Build tool:** Vite
- **CSS Framework:** Tailwind CSS 4.0
- **HTTP Client:** Axios

### Librerías principales
- **PDF:** `barryvdh/laravel-dompdf`
- **Excel:** `maatwebsite/excel`
- **2FA:** `spomky-labs/otphp`

## Patrón de arquitectura

### MVC extendido con Repository/Service (parcial)

```
┌─────────────┐
│   Client    │
│ (Frontend)  │
└──────┬──────┘
       │ HTTP/JSON
       ↓
┌─────────────────────────────────────────┐
│           Laravel Router                │
│         (routes/api.php)                │
└──────────────┬──────────────────────────┘
               │
               ↓
┌──────────────────────────────────────────┐
│         Middleware Layer                 │
│  • auth:sanctum                          │
│  • permiso (custom)                      │
│  • temp.token (2FA)                      │
└──────────────┬───────────────────────────┘
               │
               ↓
┌──────────────────────────────────────────┐
│          Controllers                     │
│  • Validación inicial                    │
│  • Orquestación de lógica                │
│  • Retorno de respuestas                 │
└──────────────┬───────────────────────────┘
               │
         ┌─────┴─────┐
         │           │
         ↓           ↓
┌────────────┐  ┌────────────┐
│   Models   │  │  Services  │
│  (Eloquent)│  │ (Optional) │
│            │  │            │
│ • CRUD ops │  │ • Business │
│ • Relations│  │   Logic    │
│ • Queries  │  │ • Complex  │
│            │  │   Ops      │
└──────┬─────┘  └─────┬──────┘
       │              │
       │              ↓
       │      ┌──────────────┐
       │      │ Repositories │
       │      │  (Minimal)   │
       │      └──────┬───────┘
       │             │
       └──────┬──────┘
              │
              ↓
     ┌────────────────┐
     │   Database     │
     │   (MySQL)      │
     └────────────────┘
```

## Estructura de directorios

### Árbol principal

```
CL038_BACK/
├── app/
│   ├── Events/              # Eventos del sistema
│   ├── Exports/             # Clases de exportación Excel
│   │   ├── Compras/
│   │   ├── Inventario/
│   │   └── PuntoVenta/
│   ├── Http/
│   │   ├── Controllers/     # Controladores por módulo
│   │   │   ├── Base/
│   │   │   ├── Compras/
│   │   │   ├── Dashboard/
│   │   │   ├── Inventario/
│   │   │   ├── Promociones/
│   │   │   └── PuntoVenta/
│   │   ├── Middleware/      # Middleware personalizado
│   │   ├── Requests/        # Form Requests validación
│   │   │   ├── Base/
│   │   │   ├── Compras/
│   │   │   ├── Inventario/
│   │   │   ├── Promociones/
│   │   │   └── PuntoVenta/
│   │   └── Resources/       # API Resources (transformación)
│   │       ├── Base/
│   │       ├── Compras/
│   │       ├── Inventario/
│   │       ├── Promociones/
│   │       └── PuntoVenta/
│   ├── Imports/             # Clases de importación Excel
│   │   ├── ClientesImport/
│   │   ├── Inventario/
│   │   └── ProveedoresImport/
│   ├── Library/             # Librerías personalizadas
│   │   └── FSG/
│   │       ├── Servicio/    # Servicios custom
│   │       └── Traits/      # Traits reutilizables
│   ├── Mail/                # Clases de correo
│   ├── Models/              # Modelos Eloquent por módulo
│   │   ├── Base/
│   │   ├── Compras/
│   │   ├── Inventario/
│   │   ├── Promociones/
│   │   └── PuntoVenta/
│   ├── Providers/           # Service Providers
│   ├── Repositories/        # Repositorios (mínimo)
│   └── Services/            # Servicios de negocio
│       ├── Dashboard/
│       └── Image/
├── bootstrap/
│   └── app.php              # Configuración de aplicación
├── config/                  # Archivos de configuración
├── database/
│   ├── factories/           # Factories para testing
│   ├── migrations/          # Migraciones de BD
│   └── seeders/             # Seeders de datos iniciales
├── documentacion/           # 📚 Documentación del proyecto
│   ├── Compras/
│   ├── PuntoVenta/
│   └── General/
├── public/
│   ├── docs/                # Documentación API generada
│   └── plantillas/          # Plantillas Excel para importación
├── resources/
│   ├── css/                 # Estilos CSS
│   ├── js/                  # JavaScript
│   └── views/               # Vistas Blade
│       ├── emails/          # Templates de correo
│       ├── Excels/          # Templates Excel
│       ├── Pdfs/            # Templates PDF
│       └── scribe/          # Templates documentación
├── routes/
│   ├── api.php              # Enrutador principal API
│   ├── Base/                # Rutas módulo Base
│   ├── Compras/             # Rutas módulo Compras
│   ├── Dashboard/           # Rutas Dashboard
│   ├── Inventario/          # Rutas Inventario
│   ├── Promociones/         # Rutas Promociones
│   └── PuntoVenta/          # Rutas Punto de Venta
├── storage/
│   ├── app/
│   │   └── public/
│   │       ├── pdfTemporal/     # PDFs generados por usuario
│   │       └── excelTemporal/   # Excels generados por usuario
│   └── logs/                # Logs de aplicación
├── tests/
│   ├── Feature/             # Tests de características
│   └── Unit/                # Tests unitarios
├── .env                     # Variables de entorno
├── composer.json            # Dependencias PHP
├── package.json             # Dependencias Node.js
└── vite.config.js           # Configuración Vite
```

## Organización modular

### Módulos del sistema

El sistema está dividido en **5 módulos funcionales:**

#### 1. Base (Fundacional)
**Propósito:** Gestión de usuarios, autenticación, permisos, estructura organizacional

**Entidades principales:**
- Usuario, Perfil, Ruta, Menu
- Empresa, Sucursal
- Pais, Estado, Delegacion, Colonia
- Banco, Bitacora, Notificacion

**Responsabilidades:**
- Autenticación con Sanctum
- 2FA con TOTP
- Sistema de permisos personalizado
- Gestión de usuarios y roles
- Estructura organizacional
- Auditoría (bitácora)

#### 2. PuntoVenta
**Propósito:** Gestión de clientes, ventas, cotizaciones, operaciones de caja

**Entidades principales:**
- Cliente, CategoriaCliente
- ListaPrecio, ListaPrecioDetalle
- Cotizacion, Operacion
- Caja, CajaHistorial

**Características especiales:**
- Generación automática de folios de cliente
- Sistema de listas de precios
- Gestión de operaciones de venta
- Control de caja

#### 3. Compras
**Propósito:** Gestión de proveedores, requisiciones, cotizaciones de compra

**Entidades principales:**
- Proveedor, CategoriaProveedor
- Requisicion, Pedido
- Cotizacion

**Características especiales:**
- Categorías jerárquicas de proveedores
- Sistema de requisiciones
- Cotizaciones a proveedores

#### 4. Inventario
**Propósito:** Gestión de productos, categorías, movimientos, almacenes

**Entidades principales:**
- Producto, CategoriaProducto
- Unidad, ProveedorProducto
- Inventario, Movimiento
- Almacen, LoteProducto

**Características especiales:**
- Control de existencias
- Movimientos de inventario
- Gestión de lotes y caducidades
- Múltiples almacenes

#### 5. Promociones
**Propósito:** Gestión de combos y promociones

**Entidades principales:**
- Combo, ComboProducto
- Promocion, PromocionProducto

**Características especiales:**
- Combos de productos
- Promociones temporales
- Descuentos y ofertas

### Flujo de datos entre módulos

```
┌──────────────────────────────────────────────────────┐
│                      BASE                             │
│  (Usuarios, Permisos, Empresas, Sucursales)          │
└────────────────┬─────────────────────────────────────┘
                 │
                 │ Usa permisos
                 │ Asigna sucursales
                 │
        ┌────────┴────────┬──────────────────┐
        │                 │                  │
        ↓                 ↓                  ↓
┌───────────────┐  ┌─────────────┐  ┌──────────────┐
│  PUNTO VENTA  │  │   COMPRAS   │  │  INVENTARIO  │
│               │  │             │  │              │
│ • Clientes    │  │ • Proveedores│ │ • Productos  │
│ • Operaciones │  │ • Requisiciones│ • Movimientos│
└───────┬───────┘  └──────┬──────┘  └──────┬───────┘
        │                 │                 │
        │                 │                 │
        │        ┌────────┴────────┐        │
        │        │                 │        │
        └────────→  PROMOCIONES   ←─────────┘
                 │                 │
                 │ • Combos        │
                 │ • Ofertas       │
                 └─────────────────┘
```

**Relaciones entre módulos:**
- **PuntoVenta** usa productos de **Inventario**
- **Compras** alimenta el **Inventario**
- **Promociones** combina productos del **Inventario**
- **Base** provee autenticación y permisos a todos

## Capas de la aplicación

### 1. Capa de Rutas (Routes)

**Ubicación:** `routes/`

**Estructura:**
- `api.php`: Punto de entrada principal, importa rutas modulares
- `{Modulo}/{entidad}.php`: Rutas específicas por entidad

**Características:**
- Todas bajo prefijo `/api/v1`
- Agrupadas por módulo
- Middleware: `auth:sanctum` + `permiso:{permission}`
- IDs codificados en base64 en URLs

**Ejemplo:**
```php
// routes/api.php
Route::prefix('v1')->group(function () {
    require base_path('routes/Base/login.php');
    require base_path('routes/Compras/proveedor.php');
    // ...
});

// routes/Compras/proveedor.php
Route::middleware('auth:sanctum')->prefix('compras')->group(function () {
    Route::prefix('proveedor')->group(function () {
        Route::post('/lista', [ProveedorController::class, 'lista'])
            ->middleware('permiso:proveedor.lista');
    });
});
```

### 2. Capa de Middleware

**Ubicación:** `app/Http/Middleware/`

**Middleware personalizados:**
- **Permiso:** Verificación de permisos por ruta
- **ValidateTemporaryToken:** Validación de token temporal para 2FA

**Configuración:** `bootstrap/app.php`

**Flujo:**
```
Request → auth:sanctum → permiso:{permission} → Controller
```

### 3. Capa de Controladores

**Ubicación:** `app/Http/Controllers/{Modulo}/`

**Responsabilidades:**
- Validación inicial (via Form Requests)
- Orquestación de lógica de negocio
- Manejo de transacciones
- Retorno de respuestas JSON estandarizadas

**Patrón común:**
```php
public function accion(EntidadFormRequest $request)
{
    try {
        DB::beginTransaction();

        // Lógica de negocio (delegada al modelo)
        $data = $this->modelo->nuevo($request);

        DB::commit();

        return response()->json([
            'code' => 200,
            'message' => 'Éxito',
            'data' => $data
        ]);
    } catch (Throwable $th) {
        DB::rollBack();
        return response()->json([
            'code' => 500,
            'message' => $th->getMessage()
        ], 500);
    }
}
```

**Características:**
- No contienen lógica de negocio pesada
- Usan inyección de dependencias
- Transacciones explícitas con DB::beginTransaction()
- Documentadas con PHPDoc para Scribe

### 4. Capa de Validación (Form Requests)

**Ubicación:** `app/Http/Requests/{Modulo}/`

**Responsabilidades:**
- Validación de datos de entrada
- Transformación de datos (prepareForValidation)
- Mensajes de error personalizados en español
- Autorización (authorize method)

**Patrón:**
```php
class ProveedorFormRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        return [
            'proveedorNombre' => 'required|string|max:75|unique:...',
            'proveedorEmail' => 'nullable|email:rfc,dns|max:100',
            // ...
        ];
    }

    public function messages(): array
    {
        return [
            'proveedorNombre.required' => 'El nombre es obligatorio.',
            // ...
        ];
    }

    public function failedValidation(Validator $validator)
    {
        throw new HttpResponseException(response()->json([
            'success' => false,
            'status' => 422,
            'message' => 'Errores de validación',
            'errors' => $validator->errors(),
        ]));
    }
}
```

### 5. Capa de Modelos (Eloquent)

**Ubicación:** `app/Models/{Modulo}/`

**Responsabilidades:**
- Definición de estructura de tabla
- Relaciones Eloquent
- Métodos de negocio (CRUD)
- Scopes y queries personalizados
- Registro en bitácora

**Características importantes:**
- **NO usan timestamps** (`public $timestamps = false`)
- Lógica de negocio dentro del modelo (patrón Active Record)
- Método `lista()` estático para consultas con filtros
- Métodos CRUD: `nuevo()`, `editar()`, `eliminar()`, `activar()`

**Patrón común:**
```php
class Proveedor extends Model
{
    protected $table = 'com_proveedor';
    protected $primaryKey = 'idProveedor';
    public $timestamps = false;

    protected $fillable = [/* campos */];

    // Relaciones
    public function banco()
    {
        return $this->belongsTo(Banco::class, 'idBanco');
    }

    // Método de listado con filtros
    public static function lista($request = [], $with = [])
    {
        $data = self::with($with)->where(function ($query) use ($request) {
            // Filtros dinámicos
        });

        return empty($request['typeData'])
            ? $data->paginate($request['perPage'] ?? 10)
            : $data->get();
    }

    // CRUD
    public function nuevo($request) { /* ... */ }
    public function editar($request) { /* ... */ }
    public function eliminar($id) { /* ... */ }
    public function activar($id) { /* ... */ }
}
```

### 6. Capa de Transformación (Resources)

**Ubicación:** `app/Http/Resources/{Modulo}/`

**Responsabilidades:**
- Transformar modelos Eloquent a JSON
- Ocultar campos sensibles
- Formatear datos para respuesta
- Incluir relaciones calculadas

**Tipos:**
- **ListaResource:** Para listados (datos mínimos)
- **DetalleResource:** Para vistas detalladas (datos completos)
- **ExcelResource:** Para exportaciones Excel
- **SelectResource:** Para dropdowns (id + nombre)

**Patrón:**
```php
class ProveedorListaResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'idProveedor' => base64_encode($this->idProveedor),
            'proveedorNombre' => $this->proveedorNombre,
            'proveedorEstado' => $this->proveedorEstado,
            'banco' => $this->when($this->banco, function () {
                return new BancoListaResource($this->banco);
            }),
        ];
    }
}
```

### 7. Capa de Servicios (Opcional)

**Ubicación:** `app/Services/`

**Uso actual:** Mínimo (solo Dashboard e Image)

**Propósito:**
- Lógica de negocio compleja
- Operaciones que involucran múltiples modelos
- Cálculos y procesamiento de datos

**Ejemplo potencial:**
```php
class OperacionVentaService
{
    public function procesarVenta($datos)
    {
        // 1. Crear operación
        // 2. Descontar inventario
        // 3. Aplicar promociones
        // 4. Generar factura
        // 5. Registrar en bitácora
    }
}
```

### 8. Capa de Repositorios (Mínima)

**Ubicación:** `app/Repositories/`

**Uso actual:** Solo `BaseRepository` con helper de PDF

**Propósito:**
- Encapsular lógica de acceso a datos
- Reutilizar queries complejas
- Abstraer capa de persistencia

**Estado:** Subutilizada. La mayoría de queries están en modelos.

### 9. Capa de Librerías Personalizadas (FSG)

**Ubicación:** `app/Library/FSG/`

**Componentes:**

#### Servicio/Authentication.php
```php
class Authentication
{
    public function user()
    {
        $token = request()->bearerToken();
        return Usuario::where('usuarioToken', $token)->first();
    }
}
```

#### Traits/HasPermission.php
Sistema de permisos con caché:
```php
trait HasPermission
{
    public function hasPermissions(string $permission): bool
    {
        // Actualmente retorna true en desarrollo
        // Implementa verificación contra base_perfilruta
    }

    public function hasAllPermissions(array $permissions): bool
    public function hasAnyPermission(array $permissions): bool
    public function getPermissions(): array
    public function clearPermissionsCache(): void
}
```

## Flujos de datos principales

### Flujo de autenticación

```
1. POST /api/v1/acceso
   ↓
2. LoginController::acceso()
   ↓
3. Verificar credenciales
   ↓
4. ¿2FA habilitado?
   ├─ Sí → Generar token temporal
   │        Retornar para flujo 2FA
   └─ No → Generar token Sanctum
           Retornar usuario + token
```

### Flujo de operación CRUD típica

```
1. Cliente envía request
   ↓
2. Middleware: auth:sanctum
   ↓
3. Middleware: permiso:{permission}
   ↓
4. Controller recibe request
   ↓
5. FormRequest valida datos
   ↓
6. DB::beginTransaction()
   ↓
7. Modelo ejecuta lógica
   ├─ Crear/Actualizar registro
   ├─ Registrar en bitácora
   └─ Operaciones relacionadas
   ↓
8. DB::commit()
   ↓
9. Resource transforma datos
   ↓
10. Retornar JSON response
```

### Flujo de exportación Excel

```
1. POST /exportar-excel
   ↓
2. Controller::exportarExcel()
   ↓
3. Obtener datos con filtros
   ↓
4. Transformar con ExcelResource
   ↓
5. Crear instancia de Export class
   ↓
6. Excel::store() en storage/excelTemporal/{idUsuario}/
   ↓
7. Retornar URL pública del archivo
```

### Flujo de importación Excel

```
1. POST /subir-excel (archivo)
   ↓
2. Import class procesa Excel
   ↓
3. Separar válidos/inválidos
   ↓
4. Retornar arrays para revisión
   ↓
5. POST /validar-duplicados
   ↓
6. Validar duplicados internos
   ↓
7. POST /resumen (con FormRequest)
   ↓
8. Validar contra BD
   ↓
9. POST /importar-confirmados
   ↓
10. DB::transaction()
    ├─ Crear registros
    └─ Bitácora
    ↓
11. Retornar resultado
```

## Patrones de diseño utilizados

### 1. Repository Pattern (Parcial)
Implementación mínima. La mayoría de queries en modelos.

### 2. Active Record Pattern
Los modelos Eloquent contienen lógica de negocio.

### 3. Dependency Injection
Controllers reciben dependencias via constructor o method injection.

### 4. Factory Pattern
Para testing con Factories de Eloquent.

### 5. Observer Pattern
Potencial uso con Eloquent Events (no implementado ampliamente).

### 6. Singleton Pattern
Service Providers de Laravel.

### 7. Strategy Pattern
FormRequests como estrategias de validación.

### 8. Decorator Pattern
Middleware como decoradores de requests.

## Decisiones de arquitectura importantes

### 1. ¿Por qué lógica en Modelos y no en Servicios?

**Decisión:** Active Record con lógica en modelos

**Ventajas:**
- Menos archivos y clases
- Código más directo y legible
- Adecuado para CRUD simple

**Desventajas:**
- Modelos pueden crecer mucho
- Dificulta testing unitario
- Lógica compleja mezclada con ORM

**Recomendación:** Migrar lógica compleja a Services conforme crezca.

### 2. ¿Por qué no usar timestamps de Laravel?

**Decisión:** `public $timestamps = false` en todos los modelos

**Razones posibles:**
- Control manual de fechas
- Campos de fecha con nombres específicos
- Legacy de migraciones anteriores

**Impacto:**
- No hay `created_at` ni `updated_at` automático
- Fechas se gestionan manualmente en cada operación

### 3. ¿Por qué IDs en base64 en URLs?

**Decisión:** Codificar IDs con base64 en rutas

**Ventajas:**
- Oculta IDs numéricos secuenciales
- Dificulta enumeración de recursos
- "Seguridad por oscuridad"

**Desventajas:**
- Overhead de codificación/decodificación
- No es verdadera seguridad (fácil de decodificar)
- Complejidad adicional

**Recomendación:** Usar UUIDs si seguridad es crítica.

### 4. ¿Por qué sistema de permisos custom vs paquete?

**Decisión:** Sistema propio con Perfil-Ruta-Menu

**Ventajas:**
- Control total sobre implementación
- Adaptado a necesidades específicas
- Sin dependencias externas

**Desventajas:**
- Más código a mantener
- No hay soporte de comunidad
- Actualmente deshabilitado en desarrollo

**Alternativas:** Spatie Laravel-Permission, Bouncer

### 5. ¿Por qué estructura modular en lugar de por tipo?

**Decisión:** Organizar por dominio/módulo en lugar de por tipo de archivo

**Ventajas:**
- Alta cohesión (archivos relacionados juntos)
- Fácil de navegar por funcionalidad
- Escalable para equipos grandes

**Desventajas:**
- Rompe convención estándar de Laravel
- Puede confundir a nuevos developers

**Justificación:** Mejor para proyectos grandes y multi-módulo.

## Consideraciones de escalabilidad

### Cuellos de botella potenciales

1. **Listados sin paginación:** Método `lista()` con `typeData='todos'`
2. **Exportaciones grandes:** Sin procesamiento en cola
3. **Importaciones masivas:** Sin batching ni progress tracking
4. **Caché mínima:** Solo en permisos (5 min)
5. **Transacciones largas:** Locks de BD en operaciones complejas

### Mejoras recomendadas

1. **Implementar Jobs:**
```php
// Para exportaciones grandes
dispatch(new ExportarProveedoresJob($filtros, $idUsuario));
```

2. **Añadir caché agresiva:**
```php
// Cachear catálogos estáticos
Cache::remember('categorias_activas', 3600, function() {
    return CategoriaProducto::where('estado', 'Activo')->get();
});
```

3. **Implementar CQRS parcial:**
- Separar queries de lectura de escritura
- Usar vistas materializadas para reportes

4. **Añadir índices en BD:**
- Ver sección de Base de Datos

5. **Microservicios potenciales:**
- Módulo Inventario como servicio separado
- Módulo Promociones como servicio separado

## Testing

### Framework: Pest

**Configuración:** `tests/Pest.php`

**Tipos de tests:**
- Feature: `tests/Feature/`
- Unit: `tests/Unit/`

**Base de datos de testing:**
- SQLite en memoria (`:memory:`)
- Configurado en `phpunit.xml`

**Ejecutar tests:**
```bash
composer test
# o
php artisan test
```

### Estrategia de testing recomendada

1. **Feature tests:** Para flujos completos de API
2. **Unit tests:** Para lógica de negocio en Services
3. **Browser tests:** Con Laravel Dusk (si hay frontend)

**Ejemplo:**
```php
// tests/Feature/ProveedorTest.php
test('puede crear un proveedor', function () {
    $response = $this->post('/api/v1/compras/proveedor/accion', [
        'proveedorNombre' => 'Test Proveedor',
        // ...
    ]);

    $response->assertStatus(200);
    $this->assertDatabaseHas('com_proveedor', [
        'proveedorNombre' => 'Test Proveedor'
    ]);
});
```

## Documentación de API

### Herramienta: Scribe

**Generación:**
```bash
php artisan scribe:generate
```

**Ubicación:** `public/docs/index.html`

**Documentación en código:**
```php
/**
 * @group Compras
 * @subgroup Proveedor
 * @bodyParam proveedorNombre string required Nombre. Example: VIP
 */
public function accion(ProveedorFormRequest $request)
```

## Próximos pasos de arquitectura

### Refactorings sugeridos

1. **Extraer lógica a Services:**
   - Operaciones de venta complejas
   - Cálculos de precios y descuentos
   - Generación de reportes

2. **Implementar Event Sourcing:**
   - Para auditoría completa
   - Reconstruir estados históricos
   - Deshacer operaciones

3. **API versioning:**
   - Actualmente solo `/v1`
   - Preparar para `/v2` con breaking changes

4. **GraphQL endpoint:**
   - Para clientes que necesiten consultas flexibles
   - Complementar REST existente

5. **WebSockets:**
   - Para notificaciones en tiempo real
   - Actualización de inventario en vivo

## Conclusión

Esta arquitectura modular orientada a dominios proporciona:
- ✅ Separación clara de responsabilidades
- ✅ Alta cohesión y bajo acoplamiento
- ✅ Fácil de navegar y mantener
- ✅ Escalable para equipos y funcionalidad

Sin embargo, tiene áreas de mejora:
- ⚠️ Lógica pesada en modelos (migrar a Services)
- ⚠️ Testing limitado
- ⚠️ Caché mínima
- ⚠️ Sin procesamiento asíncrono robusto

Para más detalles, consultar documentación específica de cada módulo.
