Files
roi-theme/Shared/Application/README.md
FrankZamora 90863cd8f5 fix(structure): Correct case-sensitivity for Linux compatibility
Rename folders to match PHP PSR-4 autoloading conventions:
- schemas → Schemas
- shared → Shared
- Wordpress → WordPress (in all locations)

Fixes deployment issues on Linux servers where filesystem is case-sensitive.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 22:53:34 -06:00

428 lines
11 KiB
Markdown

# 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