# Capa de Aplicación (Application Layer)

## 📋 Propósito

La **Capa de Aplicación** contiene los **Use Cases** que orquestan la lógica de negocio de la aplicación. Actúa como punto de entrada coordinando el flujo entre la UI/API y la Capa de Dominio.

Esta capa es el **corazón de la arquitectura limpia**, encapsulando las reglas de negocio específicas de la aplicación sin conocer detalles de implementación.

## 🎯 Responsabilidades

### ✅ QUÉ HACE

- **Orquestar flujo de la aplicación**: Coordina la secuencia de operaciones necesarias para completar un caso de uso
- **Coordinar llamadas entre capas**: Actúa como intermediario entre la presentación y el dominio
- **Transformar datos (DTOs)**: Utiliza Data Transfer Objects para encapsular entrada/salida
- **Manejar transacciones**: Coordina operaciones que deben ejecutarse de forma atómica
- **Validar entrada**: Verifica que los datos de entrada sean válidos antes de procesarlos
- **Gestionar cache**: Coordina estrategias de cache para optimizar rendimiento

### ❌ QUÉ NO HACE

- **NO contiene lógica de negocio**: La lógica de dominio vive en la Capa de Dominio
- **NO conoce detalles de implementación**: Solo depende de interfaces, nunca de implementaciones concretas
- **NO accede directamente a BD**: Usa repositorios a través de interfaces
- **NO maneja detalles de UI**: No conoce si la petición viene de REST, CLI o WordPress Admin

## 📁 Estructura

```
Application/
├── UseCases/
│   ├── SaveComponent/
│   │   ├── SaveComponentUseCase.php      (Orquestador)
│   │   ├── SaveComponentRequest.php      (DTO entrada)
│   │   └── SaveComponentResponse.php     (DTO salida)
│   ├── GetComponent/
│   │   ├── GetComponentUseCase.php
│   │   ├── GetComponentRequest.php
│   │   └── GetComponentResponse.php
│   ├── SyncSchema/
│   │   ├── SyncSchemaUseCase.php
│   │   ├── SyncSchemaRequest.php
│   │   └── SyncSchemaResponse.php
│   └── DeleteComponent/
│       ├── DeleteComponentUseCase.php
│       ├── DeleteComponentRequest.php
│       └── DeleteComponentResponse.php
└── README.md (este archivo)
```

## 🔧 Use Cases Disponibles

### 1. SaveComponent

**Propósito**: Guardar o actualizar la configuración de un componente.

**Flujo**:
1. Validar datos de entrada
2. Crear/actualizar entidad Component
3. Persistir en repositorio
4. Invalidar cache
5. Retornar confirmación

**Ejemplo de uso**:

```php
use ROITheme\Shared\Application\UseCases\SaveComponent\SaveComponentUseCase;
use ROITheme\Shared\Application\UseCases\SaveComponent\SaveComponentRequest;

$useCase = new SaveComponentUseCase($repository, $validator, $cache);
$request = new SaveComponentRequest('top_bar', [
    'background_color' => '#ffffff',
    'text_color' => '#000000',
    'show_logo' => true
]);

$response = $useCase->execute($request);

if ($response->isSuccess()) {
    echo "Componente guardado exitosamente";
} else {
    echo "Error: " . $response->getError();
}
```

### 2. GetComponent

**Propósito**: Obtener la configuración de un componente con cache-first strategy.

**Flujo**:
1. Verificar cache
2. Si existe en cache → retornar
3. Si no → consultar repositorio
4. Guardar en cache
5. Retornar datos

**Ejemplo de uso**:

```php
use ROITheme\Shared\Application\UseCases\GetComponent\GetComponentUseCase;
use ROITheme\Shared\Application\UseCases\GetComponent\GetComponentRequest;

$useCase = new GetComponentUseCase($repository, $cache);
$request = new GetComponentRequest('top_bar');

$response = $useCase->execute($request);

if ($response->isSuccess()) {
    $data = $response->getData();
    // Procesar datos del componente
} else {
    echo "Error: " . $response->getError();
}
```

### 3. SyncSchema

**Propósito**: Sincronizar múltiples componentes desde un archivo JSON de schemas.

**Flujo**:
1. Leer archivo JSON
2. Validar formato
3. Procesar cada componente del schema
4. Identificar cambios (agregados/actualizados/eliminados)
5. Retornar resumen de cambios

**Ejemplo de uso**:

```php
use ROITheme\Shared\Application\UseCases\SyncSchema\SyncSchemaUseCase;
use ROITheme\Shared\Application\UseCases\SyncSchema\SyncSchemaRequest;

$useCase = new SyncSchemaUseCase($componentRepo, $defaultsRepo);
$request = new SyncSchemaRequest('/path/to/schemas.json');

$response = $useCase->execute($request);

if ($response->isSuccess()) {
    echo $response->getSummary();
    // Output: "Added: 2, Updated: 3, Deleted: 1"
} else {
    foreach ($response->getErrors() as $error) {
        echo "Error: {$error}\n";
    }
}
```

### 4. DeleteComponent

**Propósito**: Eliminar un componente del sistema.

**Flujo**:
1. Verificar que el componente existe
2. Eliminar de repositorio
3. Invalidar cache
4. Retornar confirmación

**Ejemplo de uso**:

```php
use ROITheme\Shared\Application\UseCases\DeleteComponent\DeleteComponentUseCase;
use ROITheme\Shared\Application\UseCases\DeleteComponent\DeleteComponentRequest;

$useCase = new DeleteComponentUseCase($repository, $cache);
$request = new DeleteComponentRequest('old_component');

$response = $useCase->execute($request);

if ($response->isSuccess()) {
    echo $response->getMessage();
} else {
    echo "Error: " . $response->getError();
}
```

## 🏛️ Principios Arquitectónicos

### Regla de Dependencias

```
Application Layer
       ↓ (depende de)
Domain Layer (solo interfaces)
       ↑
NO depende de Infrastructure Layer
```

La capa de aplicación **solo** puede depender de la capa de dominio, y únicamente de sus **interfaces**, nunca de implementaciones concretas.

### Dependency Inversion Principle

**✅ CORRECTO**:

```php
namespace ROITheme\Shared\Application\UseCases\SaveComponent;

use ROITheme\Shared\Domain\Contracts\ComponentRepositoryInterface;
use ROITheme\Shared\Domain\Contracts\ValidationServiceInterface;

final class SaveComponentUseCase
{
    public function __construct(
        private ComponentRepositoryInterface $repository,    // ✅ Interfaz
        private ValidationServiceInterface $validator,       // ✅ Interfaz
        private CacheServiceInterface $cache                 // ✅ Interfaz
    ) {}
}
```

**❌ INCORRECTO**:

```php
use ROITheme\Infrastructure\Persistence\WordPress\WordPressComponentRepository;

final class SaveComponentUseCase
{
    public function __construct(
        private WordPressComponentRepository $repository  // ❌ Implementación concreta
    ) {}
}
```

### DTOs Inmutables

Todos los Request y Response utilizan `readonly class` para garantizar inmutabilidad:

```php
final readonly class SaveComponentRequest
{
    public function __construct(
        private string $componentName,
        private array $data
    ) {}

    // Solo getters, sin setters
    public function getComponentName(): string
    {
        return $this->componentName;
    }
}
```

### Factory Methods en Responses

Los responses utilizan factory methods para encapsular lógica de creación:

```php
final readonly class SaveComponentResponse
{
    // Constructor privado
    private function __construct(
        private bool $success,
        private ?string $error
    ) {}

    // Factory methods públicos
    public static function success(): self
    {
        return new self(true, null);
    }

    public static function failure(string $error): self
    {
        return new self(false, $error);
    }
}
```

## 🧪 Testing

### Estrategia de Testing

Todos los Use Cases tienen tests unitarios con mocks de dependencias:

```php
namespace ROITheme\Tests\Unit\Application\UseCases;

use PHPUnit\Framework\TestCase;
use ROITheme\Shared\Application\UseCases\SaveComponent\SaveComponentUseCase;
use ROITheme\Shared\Domain\Contracts\ComponentRepositoryInterface;
use ROITheme\Shared\Domain\Contracts\ValidationServiceInterface;

class SaveComponentUseCaseTest extends TestCase
{
    private ComponentRepositoryInterface $repository;
    private ValidationServiceInterface $validator;
    private SaveComponentUseCase $useCase;

    protected function setUp(): void
    {
        $this->repository = $this->createMock(ComponentRepositoryInterface::class);
        $this->validator = $this->createMock(ValidationServiceInterface::class);

        $this->useCase = new SaveComponentUseCase(
            $this->repository,
            $this->validator,
            $this->cache
        );
    }

    public function test_saves_component_successfully(): void
    {
        // Test implementation
    }
}
```

### Ubicación de Tests

```
tests/Unit/Application/UseCases/
├── SaveComponentUseCaseTest.php
├── GetComponentUseCaseTest.php
├── SyncSchemaUseCaseTest.php
└── DeleteComponentUseCaseTest.php
```

### Cobertura Esperada

- **Objetivo**: 95%
- **Mínimo aceptable**: 90%

### Ejecutar Tests

```bash
# Todos los tests de Application
cd _planeacion/roi-theme/_testing-suite
vendor/bin/phpunit tests/Unit/Application

# Test específico
vendor/bin/phpunit tests/Unit/Application/UseCases/SaveComponentUseCaseTest.php

# Con cobertura
vendor/bin/phpunit tests/Unit/Application --coverage-text

# Reporte HTML de cobertura
vendor/bin/phpunit tests/Unit/Application --coverage-html coverage
```

## 🔍 Requisitos Técnicos

Todos los archivos de la capa de aplicación deben cumplir:

### 1. Strict Types

```php
<?php
declare(strict_types=1);  // ✅ Obligatorio en todos los archivos
```

### 2. Namespace Correcto

```php
namespace ROITheme\Shared\Application\UseCases\{UseCase};
```

Patrón: **Context-First** → `ROITheme\Shared\Application\...`

### 3. PHPDoc Completo

```php
/**
 * SaveComponentUseCase - Guardar/actualizar componente
 *
 * RESPONSABILIDAD: Orquestar guardado de componente
 * ...
 *
 * @package ROITheme\Shared\Application\UseCases\SaveComponent
 */
final class SaveComponentUseCase
{
    // ...
}
```

### 4. Type Hints Estrictos

```php
// ✅ CORRECTO
public function execute(SaveComponentRequest $request): SaveComponentResponse
{
    // ...
}

// ❌ INCORRECTO
public function execute($request)  // Sin type hints
{
    // ...
}
```

## 📚 Referencias

- **Documentación de Fase**: `_planeacion/roi-theme/_MIGRACION-CLEAN-ARCHITECTURE/Fase-05/FASE-05-PLAN-IMPLEMENTACION.md`
- **Clean Architecture**: Robert C. Martin
- **Dependency Inversion Principle**: SOLID Principles

## ✅ Checklist de Validación

Para validar que un Use Case cumple con los estándares:

- [ ] Usa `declare(strict_types=1)`
- [ ] Namespace correcto: `ROITheme\Shared\Application\UseCases\{UseCase}`
- [ ] PHPDoc completo en clase
- [ ] Solo depende de interfaces del Domain
- [ ] Request es `final readonly class`
- [ ] Response es `final readonly class` con factory methods
- [ ] UseCase es `final class`
- [ ] Constructor injection de dependencias
- [ ] Método `execute()` con type hints
- [ ] Tests unitarios con >= 90% cobertura
- [ ] Sin dependencias de Infrastructure

## 🚀 Próximos Pasos

Después de completar la Capa de Aplicación:

1. **Fase 6**: Infrastructure Layer (Repositorios, Adaptadores)
2. **Fase 7**: API Layer (REST Endpoints)
3. **Fase 8**: Integration Tests
4. **Fase 9**: Migración gradual del código legacy

---

**Mantenedor**: ROI Theme Development Team
**Última actualización**: 2025-01-19
**Versión**: 1.0.0
