Files
roi-theme/Shared/Domain
FrankZamora 4f25297f14 feat(pagespeed): implementar campo is_critical para CSS crítico dinámico (Phase 4.2)
Implementación completa del sistema de Critical CSS dinámico según plan 13.01:

Domain Layer:
- Crear CriticalCSSCollectorInterface para DIP compliance

Infrastructure Layer:
- Implementar CriticalCSSCollector (singleton via DIContainer)
- Crear CriticalCSSHooksRegistrar para inyección en wp_head
- Actualizar DIContainer con getCriticalCSSCollector()

Schemas:
- Agregar campo is_critical a navbar, top-notification-bar, hero
- Sincronizar con BD (18+39+31 campos)

Renderers (navbar, top-notification-bar, hero):
- Inyectar CriticalCSSCollectorInterface via constructor
- Lógica condicional: si is_critical=true → CSS a <head>

Admin (FormBuilders + FieldMappers):
- Toggle "CSS Crítico" en sección visibility
- Mapeo AJAX para persistencia

Beneficios:
- LCP optimizado: CSS crítico inline en <head>
- Above-the-fold rendering sin FOUC
- Componentes configurables desde admin panel

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 09:29:45 -06:00
..

Capa de Dominio - Shared (Fundación)

Propósito

La capa de Dominio de shared/ contiene la lógica de negocio compartida que utilizan todos los contextos (admin y public). Es la fundación del proyecto y no debe tener dependencias de frameworks, librerías externas, o capas superiores.

Principios

  1. Sin dependencias externas: No depende de WordPress, plugins, o librerías
  2. Lógica pura: Solo reglas de negocio y objetos de dominio
  3. Inmutabilidad: Los Value Objects son inmutables
  4. Validación: Los objetos se validan a sí mismos

Estructura

shared/Domain/
├── ValueObjects/        # Value Objects compartidos (ComponentID, SettingValue, etc.)
├── Exceptions/          # Excepciones de dominio (InvalidComponentException, etc.)
└── Contracts/           # Interfaces de repositorios y servicios de dominio

Ejemplos de Uso

Value Objects

Value Objects que representan conceptos del dominio:

namespace ROITheme\Shared\Domain\ValueObjects;

final class ComponentID
{
    private int $value;

    public function __construct(int $value)
    {
        if ($value <= 0) {
            throw new \InvalidArgumentException('Component ID must be positive');
        }

        $this->value = $value;
    }

    public function value(): int
    {
        return $this->value;
    }

    public function equals(ComponentID $other): bool
    {
        return $this->value === $other->value;
    }
}

Excepciones

Excepciones específicas del dominio:

namespace ROITheme\Shared\Domain\Exceptions;

class InvalidComponentException extends \DomainException
{
    public static function withId(int $id): self
    {
        return new self("Component with ID {$id} is invalid");
    }
}

Contracts (Interfaces)

Interfaces que definen comportamientos:

namespace ROITheme\Shared\Domain\Contracts;

interface ComponentRepositoryInterface
{
    public function findById(ComponentID $id): ?Component;
    public function save(Component $component): void;
}

Reglas de Dependencia

PUEDE depender de:

  • Otros objetos dentro de shared/Domain/
  • SPL (Standard PHP Library)
  • Nada más

NO PUEDE depender de:

  • shared/Application/
  • shared/Infrastructure/
  • admin/ o public/
  • WordPress functions
  • Librerías externas

Testing

Los objetos de esta capa se testean con tests unitarios puros, sin necesidad de WordPress:

// tests/Unit/Shared/Domain/ValueObjects/ComponentIDTest.php
public function test_creates_valid_component_id()
{
    $id = new ComponentID(123);
    $this->assertEquals(123, $id->value());
}

Cuándo Agregar Código Aquí

Agrega código a shared/Domain/ cuando:

  • Es lógica de negocio pura (sin WordPress)
  • Es compartido por admin/ y public/
  • Es un concepto fundamental del dominio
  • Necesita alta cohesión y bajo acoplamiento

No agregues aquí:

  • Código que depende de WordPress
  • Lógica específica de un solo contexto
  • Implementaciones concretas de servicios