chore: add debug comment to diagnose mode

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-12-10 10:58:48 -06:00
parent 2896e2d006
commit 09d87835b8
3 changed files with 157 additions and 105 deletions

View File

@@ -1,154 +1,190 @@
# Especificacion de Arquitectura Cache-First
# Especificacion: Hook de Pre-Evaluacion de Pagina
## 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.
Define un hook que permite a plugins externos evaluar condiciones ANTES de que WordPress sirva una pagina singular. Este hook es util para plugins de control de acceso, rate limiters, membership, etc.
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)
**Alcance del tema:** ROI-Theme SOLO provee el hook. La implementacion de logica de acceso es responsabilidad de cada plugin.
---
### Requirement: Contexto Rico para Plugins Externos
## Requirements
The system MUST provide sufficient context for external plugins to make access decisions.
### Requirement: Hook roi_theme_before_page_serve
#### Scenario: Plugin necesita informacion del post
The system MUST provide a hook that fires before WordPress serves a singular page, allowing external plugins to evaluate conditions and potentially redirect.
#### Scenario: Plugin externo evalua acceso antes de servir pagina
- **GIVEN** un plugin de control de acceso enganchado a `roi_theme_before_page_serve`
- **WHEN** un visitante anonimo 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()` + `exit`, la pagina NO se sirve
#### Scenario: Ningun plugin enganchado
- **GIVEN** ningun plugin esta escuchando `roi_theme_before_page_serve`
- **WHEN** un visitante solicita una pagina
- **THEN** la pagina se sirve normalmente
- **AND** no hay impacto en rendimiento
#### Scenario: Solo 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
#### Scenario: Usuarios logueados excluidos
- **GIVEN** un usuario autenticado (logged in)
- **WHEN** solicita cualquier pagina
- **THEN** el hook NO DEBE dispararse
- **BECAUSE** los plugins de cache no cachean paginas para usuarios logueados
#### Scenario: REST API excluida
- **GIVEN** una peticion REST API (REST_REQUEST === true)
- **WHEN** se procesa la peticion
- **THEN** el hook NO DEBE dispararse
- **BECAUSE** las peticiones REST tienen su propio ciclo de vida y no sirven paginas HTML
---
### Requirement: Contexto para Plugins
The hook MUST provide sufficient context for plugins to make decisions.
#### Scenario: Plugin accede a 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
- **AND** `get_queried_object()` retorna el WP_Post completo
- **AND** funciones como `is_singular()`, `is_single()`, `is_page()` funcionan
#### Scenario: Plugin necesita informacion del visitante
- **GIVEN** un plugin enganchado a `roi_theme_before_page_serve`
#### Scenario: Plugin accede a informacion del visitante
- **GIVEN** un plugin enganchado al hook
- **WHEN** el hook se dispara
- **THEN** `is_user_logged_in()` esta disponible
- **AND** `$_SERVER['REMOTE_ADDR']` esta disponible
- **THEN** `$_SERVER['REMOTE_ADDR']` esta disponible
- **AND** headers HTTP estan disponibles via `$_SERVER`
---
### Requirement: No Bloquear Cache
### Requirement: No Interferir con Cache
The system MUST NOT define DONOTCACHEPAGE or similar constants that prevent caching.
The theme MUST NOT define cache-blocking constants.
#### Scenario: Tema no interfiere con plugins de cache
#### Scenario: Tema no bloquea cache
- **GIVEN** el tema roi-theme instalado
- **WHEN** W3TC, WP Super Cache, o Redis Object Cache estan activos
- **WHEN** plugins de cache (W3TC, WP Super Cache, etc.) 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
#### Scenario: Plugin decide bloquear cache
- **GIVEN** un plugin necesita bloquear cache para una pagina
- **WHEN** el plugin esta enganchado al hook
- **THEN** es responsabilidad del PLUGIN definir `DONOTCACHEPAGE`
- **AND** el tema NO participa en esa decision
---
### Requirement: Ubicacion en Clean Architecture
## Known Limitations
The hook registration MUST follow ROITheme's Clean Architecture patterns.
### Limitation 1: Page Cache Bypass
#### 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
**Severity**: CRITICAL para plugins que requieren evaluacion en cada request
#### 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/`
Cuando Page Cache esta habilitado (W3TC, WP Super Cache, etc.), el hook `roi_theme_before_page_serve` NO SE EJECUTA para paginas cacheadas.
**Razon tecnica:**
```
Request → advanced-cache.php → [Cache HIT] → HTML servido
WordPress NUNCA carga
Hook NUNCA se dispara
```
**Implicacion para plugins:**
- Rate limiters: Los limites no se evaluan en cache hits
- Membership plugins: El acceso no se verifica en cache hits
- Geolocation: Las restricciones no aplican en cache hits
**Solucion:** Los plugins que requieren evaluacion en cada request deben implementar su propia estrategia (JavaScript-First, cookies, edge workers, etc.). Esto esta FUERA del alcance de esta spec.
### Limitation 2: Solo Paginas Singulares
El hook solo dispara para `is_singular() === true`. Archives, taxonomies, search, y home NO disparan el hook.
---
## Implementation Notes
## Implementation
### Hook Priority
### Ubicacion en Clean Architecture
```
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
```
El hook DEBE registrarse en `Shared/Infrastructure/Hooks/`.
### Ejemplo de Plugin Enganchado
### Archivo: CacheFirstHooksRegistrar.php
```php
// 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;
<?php
declare(strict_types=1);
namespace ROITheme\Shared\Infrastructure\Hooks;
final class CacheFirstHooksRegistrar
{
public function register(): void
{
add_action('template_redirect', [$this, 'fireBeforePageServe'], 0);
}
// Si no hay problema, simplemente retornar
// La pagina se servira (con cache si disponible)
}, 10);
public function fireBeforePageServe(): void
{
if (is_user_logged_in()) {
return;
}
if (!is_singular()) {
return;
}
if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
return;
}
if (defined('REST_REQUEST') && REST_REQUEST) {
return;
}
$post_id = get_queried_object_id();
if ($post_id > 0) {
do_action('roi_theme_before_page_serve', $post_id);
}
}
}
```
### Archivos a Crear
### Registro en functions.php
```
Shared/
├── Domain/
│ └── Contracts/
│ └── PageServeHookInterface.php # Interface del hook
└── Infrastructure/
└── Hooks/
└── CacheFirstHooksRegistrar.php # Registro del hook
```php
$cacheFirstHooks = new \ROITheme\Shared\Infrastructure\Hooks\CacheFirstHooksRegistrar();
$cacheFirstHooks->register();
```
---
## 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
1. Hook `roi_theme_before_page_serve` se dispara en `template_redirect` priority 0
2. Solo dispara para `is_singular() === true`
3. NO dispara para usuarios logueados
4. Pasa `$post_id` como parametro
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
6. Plugins pueden enganchar y hacer redirect/exit
7. Sin impacto en rendimiento si ningun plugin engancha
---
## Version History
| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2025-12-07 | Initial spec |
| 2.0 | 2025-12-07 | Simplified: Only defines hook, removed plugin implementation details |