Files
roi-theme/openspec/specs/cache-first-architecture/spec.md
FrankZamora eab974d14c docs(config): add cache-first-architecture specification
Define arquitectura cache-first para ROI-Theme:
- Hook roi_theme_before_page_serve en template_redirect p=0
- Solo para páginas singulares y usuarios anónimos
- Permite que plugins externos evalúen acceso antes de servir página
- NO define DONOTCACHEPAGE (permite cache)

Plan 1000.01 - Preparación para integración con IP View Limit.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 12:07:14 -06:00

5.8 KiB

Especificacion de Arquitectura Cache-First

Purpose

Define la arquitectura cache-first para ROITheme que permite que plugins de cache (W3TC, Redis, etc.) funcionen correctamente mientras plugins externos pueden evaluar condiciones ANTES de servir paginas.

Esta arquitectura:

  • Permite que las paginas se sirvan desde cache siempre que sea posible
  • Provee hooks para que plugins externos (rate limiters, access control, etc.) evaluen condiciones
  • Desacopla el tema de plugins especificos de restriccion de acceso
  • Es portable: cualquier sitio con roi-theme tiene esta capacidad

Requirements

Requirement: Hook de Pre-Evaluacion de Pagina

The system MUST provide a hook that fires BEFORE WordPress serves a page, allowing external plugins to evaluate conditions and potentially redirect.

Scenario: Plugin externo necesita evaluar acceso antes de servir pagina

  • GIVEN un plugin de control de acceso (rate limiter, membership, etc.)
  • WHEN un visitante solicita una pagina singular (post, page, CPT)
  • THEN el tema DEBE disparar do_action('roi_theme_before_page_serve', $post_id)
  • AND el hook DEBE ejecutarse en template_redirect con priority 0
  • AND si el plugin llama wp_safe_redirect() y exit, la pagina NO se sirve

Scenario: Ningn plugin enganchado al hook

  • GIVEN ningun plugin esta escuchando roi_theme_before_page_serve
  • WHEN un visitante solicita una pagina
  • THEN la pagina se sirve normalmente (con cache si disponible)
  • AND no hay impacto en rendimiento

Scenario: Hook solo dispara en paginas singulares

  • GIVEN el hook roi_theme_before_page_serve
  • WHEN la solicitud es para archivo, home, search, feed, o admin
  • THEN el hook NO DEBE dispararse
  • AND la pagina se sirve sin evaluacion adicional

Scenario: Hook no dispara para usuarios logueados

  • GIVEN un usuario autenticado (logged in)
  • WHEN solicita cualquier pagina
  • THEN el hook NO DEBE dispararse
  • AND la pagina se sirve directamente sin evaluacion
  • BECAUSE WordPress no cachea paginas para usuarios logueados (cookies de sesion)

Requirement: Contexto Rico para Plugins Externos

The system MUST provide sufficient context for external plugins to make access decisions.

Scenario: Plugin necesita informacion del post

  • GIVEN un plugin enganchado a roi_theme_before_page_serve
  • WHEN el hook se dispara
  • THEN el plugin recibe $post_id como parametro
  • AND get_queried_object() retorna el objeto WP_Post completo
  • AND is_singular(), is_single(), is_page() funcionan correctamente

Scenario: Plugin necesita informacion del visitante

  • GIVEN un plugin enganchado a roi_theme_before_page_serve
  • WHEN el hook se dispara
  • THEN is_user_logged_in() esta disponible
  • AND $_SERVER['REMOTE_ADDR'] esta disponible
  • AND headers HTTP estan disponibles via $_SERVER

Requirement: No Bloquear Cache

The system MUST NOT define DONOTCACHEPAGE or similar constants that prevent caching.

Scenario: Tema no interfiere con plugins de cache

  • GIVEN el tema roi-theme instalado
  • WHEN W3TC, WP Super Cache, o Redis Object Cache estan activos
  • THEN el tema NO DEBE definir DONOTCACHEPAGE
  • AND el tema NO DEBE definir DONOTCACHEOBJECT
  • AND el tema NO DEBE enviar headers Cache-Control: no-cache

Scenario: Plugin externo decide bloquear cache

  • GIVEN un plugin enganchado a roi_theme_before_page_serve
  • WHEN el plugin necesita bloquear cache para una pagina especifica
  • THEN es responsabilidad del PLUGIN definir DONOTCACHEPAGE
  • AND el tema NO participa en esa decision

Requirement: Ubicacion en Clean Architecture

The hook registration MUST follow ROITheme's Clean Architecture patterns.

Scenario: Hook registrado en Infrastructure

  • GIVEN el sistema de hooks del tema
  • WHEN el hook roi_theme_before_page_serve es registrado
  • THEN el registro DEBE estar en Shared/Infrastructure/Hooks/
  • AND DEBE seguir el patron de HooksRegistrar existente

Scenario: Servicio como punto de extension

  • GIVEN la arquitectura del tema
  • WHEN se necesita extender funcionalidad de pre-evaluacion
  • THEN DEBE existir una interfaz en Shared/Domain/Contracts/
  • AND la implementacion DEBE estar en Shared/Infrastructure/Services/

Implementation Notes

Hook Priority

template_redirect priority order:
├─ Priority 0: roi_theme_before_page_serve (tema dispara hook)
│   └─ Plugins externos se enganchan aqui
├─ Priority 1+: Otros plugins
└─ Priority 10 (default): WordPress template loading

Ejemplo de Plugin Enganchado

// En un plugin externo (ej: ip-rate-limiter)
add_action('roi_theme_before_page_serve', function(int $post_id) {
    // Evaluar condicion (ej: limite de IP)
    if ($this->is_limit_exceeded()) {
        wp_safe_redirect('/suscripcion-vip/?reason=limit', 302);
        exit;
    }
    // Si no hay problema, simplemente retornar
    // La pagina se servira (con cache si disponible)
}, 10);

Archivos a Crear

Shared/
├── Domain/
│   └── Contracts/
│       └── PageServeHookInterface.php     # Interface del hook
└── Infrastructure/
    └── Hooks/
        └── CacheFirstHooksRegistrar.php   # Registro del hook

Acceptance Criteria

  1. El hook roi_theme_before_page_serve se dispara en template_redirect priority 0
  2. Solo se dispara para is_singular() === true
  3. NO se dispara para usuarios logueados (is_user_logged_in() === true)
  4. Pasa $post_id como parametro al hook
  5. No define DONOTCACHEPAGE ni headers anti-cache
  6. Plugins externos pueden enganchar y hacer redirect/exit
  7. Si ningun plugin engancha, no hay impacto en rendimiento
  8. Sigue patrones de Clean Architecture del tema