refactor: reorganizar openspec y planificacion con spec recaptcha

- renombrar openspec/ a _openspec/ (carpeta auxiliar)
- mover specs de features a changes/
- crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura
- migrar _planificacion/ con design-system y roi-theme-template
- agregar especificacion recaptcha anti-spam (proposal, tasks, spec)
- corregir rutas y referencias en todas las specs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2026-01-08 15:30:45 -06:00
parent 0d6b6db108
commit 0f6387ab46
58 changed files with 15364 additions and 1171 deletions

View File

@@ -0,0 +1,365 @@
# Especificacion: AdSense Auto Ads Toggle
## Purpose
Define el comportamiento de un interruptor "Auto Ads" que cuando se activa, delega el control de ubicacion de anuncios a Google AdSense Auto Ads, desactivando automaticamente todas las ubicaciones manuales del tema EXCEPTO los anuncios en resultados de busqueda del plugin ROI APU Search.
**Problema que resuelve:** El usuario necesita probar Google Auto Ads sin tener que deshabilitar manualmente cada ubicacion de anuncio. Ademas, Auto Ads tiende a romper el layout de tablas HTML, por lo que se requiere excluirlas automaticamente.
**Beneficio esperado:** Comparar facilmente el rendimiento (RPM, CTR, revenue) entre ubicaciones manuales vs Auto Ads de Google, manteniendo siempre activos los anuncios en el buscador APU.
---
## Requirements
### Requirement: Campo enable_auto_ads en Schema
El schema adsense-placement.json DEBE incluir un nuevo campo para activar Auto Ads.
#### Scenario: Definicion del campo en JSON Schema
- **WHEN** se define el campo `enable_auto_ads`
- **THEN** DEBE ubicarse en el grupo `visibility` con priority 10
- **AND** DEBE tener type `boolean`
- **AND** DEBE tener default `false`
- **AND** DEBE tener label `Activar Google Auto Ads`
- **AND** DEBE tener description `Cuando esta activo, Google controla automaticamente donde mostrar anuncios. Se desactivan las ubicaciones manuales excepto los anuncios en busqueda.`
#### Scenario: Posicion del campo en el formulario
- **WHEN** se renderiza el formulario de configuracion
- **THEN** el campo `enable_auto_ads` DEBE aparecer inmediatamente despues de `is_enabled`
- **AND** DEBE tener un indicador visual destacado (badge o icono) indicando que es modo automatico
---
### Requirement: Desactivacion Automatica de Ubicaciones Manuales
Cuando Auto Ads esta activo, el sistema DEBE ignorar todas las configuraciones de ubicacion manual.
#### Scenario: Grupos afectados por enable_auto_ads
- **GIVEN** `enable_auto_ads === true`
- **WHEN** se evaluan las ubicaciones de anuncios
- **THEN** los siguientes grupos DEBEN comportarse como si estuvieran desactivados:
- `incontent_advanced` (In-Content Ads Avanzado)
- `behavior` (Ubicaciones en Posts) - EXCEPTO `javascript_first_mode`
- `anchor_ads` (Anuncios Fijos)
- `vignette_ads` (Anuncios de Vineta)
- `layout` (Ubicaciones Archivos/Globales)
- **AND** el grupo `search_results` DEBE permanecer activo
- **AND** el grupo `analytics` DEBE permanecer activo
- **AND** el grupo `content` (credenciales) DEBE permanecer activo
#### Scenario: Preservacion de configuracion en base de datos
- **GIVEN** el usuario activa `enable_auto_ads`
- **WHEN** se guardan los settings
- **THEN** los valores de los campos desactivados NO DEBEN modificarse en la BD
- **AND** cuando el usuario desactive `enable_auto_ads`, sus configuraciones previas DEBEN estar intactas
#### Scenario: Evaluacion en PHP (Server-Side)
- **GIVEN** `enable_auto_ads === true` en los settings
- **WHEN** un Renderer evalua si debe insertar un slot de anuncio
- **THEN** DEBE verificar primero si `enable_auto_ads` esta activo
- **AND** si esta activo, DEBE retornar inmediatamente sin insertar el slot manual
- **AND** EXCEPTO para slots del grupo `search_results`
#### Scenario: Evaluacion en JavaScript (Client-Side)
- **GIVEN** JavaScript-First Mode esta activo
- **AND** `enable_auto_ads === true`
- **WHEN** el controller JavaScript evalua visibilidad
- **THEN** DEBE incluir `enable_auto_ads` en el response del endpoint REST
- **AND** el script DEBE ocultar slots manuales marcados con `data-ad-manual`
- **AND** NO DEBE ocultar slots marcados con `data-ad-search`
---
### Requirement: Excepcion para ROI APU Search
Los anuncios en resultados de busqueda DEBEN permanecer activos independientemente del estado de Auto Ads.
#### Scenario: Configuracion de busqueda siempre disponible
- **GIVEN** `enable_auto_ads === true`
- **WHEN** se obtiene la configuracion para el plugin roi-apu-search via `roi_get_adsense_search_config()`
- **THEN** DEBE retornar la configuracion del grupo `search_results`
- **AND** `search_ads_enabled` DEBE evaluarse independientemente de `enable_auto_ads`
#### Scenario: Slots de busqueda con atributo especial
- **WHEN** se renderizan slots de anuncios para resultados de busqueda
- **THEN** DEBEN incluir atributo `data-ad-search="true"`
- **AND** DEBEN incluir clase CSS `roi-ad-search-slot`
- **AND** NO DEBEN incluir atributo `data-ad-manual`
#### Scenario: JavaScript no oculta slots de busqueda
- **GIVEN** el controller JavaScript detecta `enable_auto_ads === true`
- **WHEN** procesa los slots de anuncios
- **THEN** NO DEBE agregar clase `roi-ad-hidden` a elementos con `data-ad-search`
- **AND** DEBE disparar evento `roi-adsense-activate` para slots de busqueda
---
### Requirement: CSS para Excluir Tablas de Auto Ads
El sistema DEBE inyectar CSS que indica a Google Auto Ads que NO inserte anuncios dentro de tablas.
#### Scenario: Inyeccion de CSS google-auto-ads ignore
- **GIVEN** `enable_auto_ads === true`
- **WHEN** se renderiza el header del sitio
- **THEN** DEBE inyectar el siguiente CSS:
```css
table,
.wp-block-table,
.tablepress,
figure.wp-block-table,
.entry-content table {
google-auto-ads: ignore;
}
```
- **AND** el CSS DEBE cargarse ANTES del script de AdSense
#### Scenario: CSS solo cuando Auto Ads esta activo
- **GIVEN** `enable_auto_ads === false`
- **WHEN** se renderiza el header
- **THEN** NO DEBE inyectar el CSS de `google-auto-ads: ignore`
#### Scenario: Selectores adicionales configurables
- **GIVEN** el usuario necesita excluir elementos adicionales
- **WHEN** existe un campo `auto_ads_exclude_selectors` en el schema
- **THEN** DEBE agregar esos selectores al CSS de exclusion
- **AND** el campo DEBE ser de tipo `textarea`
- **AND** DEBE tener default vacio
---
### Requirement: Script de Google Auto Ads
Cuando Auto Ads esta activo, el sistema DEBE insertar el script requerido por Google.
#### Scenario: Insercion del script adsbygoogle
- **GIVEN** `enable_auto_ads === true`
- **AND** `is_enabled === true`
- **WHEN** se renderiza el head del documento
- **THEN** DEBE insertar el script de AdSense:
```html
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXX"
crossorigin="anonymous"></script>
```
- **AND** DEBE usar el `publisher_id` configurado en el grupo `content`
#### Scenario: No duplicar scripts
- **GIVEN** el tema ya encola el script de AdSense para ubicaciones manuales
- **WHEN** `enable_auto_ads === true`
- **THEN** NO DEBE duplicar el script
- **AND** DEBE reutilizar el script existente
#### Scenario: Delay de carga respetado
- **GIVEN** `delay_enabled === true` en el grupo `forms`
- **AND** `enable_auto_ads === true`
- **WHEN** se carga la pagina
- **THEN** el script de AdSense DEBE cargarse con delay
- **AND** DEBE respetar el valor de `delay_timeout`
---
### Requirement: Indicador Visual en Admin UI
El panel de administracion DEBE mostrar claramente cuando Auto Ads esta activo.
#### Scenario: Badge de estado Auto Ads
- **GIVEN** el usuario accede al panel de configuracion de AdSense
- **WHEN** `enable_auto_ads === true`
- **THEN** DEBE mostrar un badge visible "AUTO ADS ACTIVO" en color naranja (#FF8600)
- **AND** los grupos desactivados DEBEN aparecer con opacidad reducida (0.5)
- **AND** los grupos desactivados DEBEN mostrar tooltip "Desactivado por Auto Ads"
#### Scenario: Seccion de grupos no afectados
- **GIVEN** `enable_auto_ads === true`
- **WHEN** se renderiza el formulario
- **THEN** los grupos `search_results`, `analytics`, y `content` DEBEN renderizarse normalmente
- **AND** DEBEN tener indicador "Siempre activo" visible
#### Scenario: Confirmacion al activar
- **GIVEN** el usuario hace click en `enable_auto_ads`
- **WHEN** el campo cambia de false a true
- **THEN** DEBE mostrar dialogo de confirmacion con mensaje:
"Al activar Auto Ads, Google controlara automaticamente donde mostrar anuncios.
Tus configuraciones manuales se mantendran guardadas pero no se usaran.
Los anuncios en resultados de busqueda seguiran funcionando.
Continuar?"
- **AND** DEBE tener botones "Activar Auto Ads" y "Cancelar"
---
### Requirement: Separacion de Capas segun Clean Architecture
La implementacion DEBE seguir Clean Architecture.
#### Scenario: Value Object AutoAdsConfiguration en Domain
- **WHEN** se crea el Value Object AutoAdsConfiguration
- **THEN** DEBE ubicarse en `Shared/Domain/ValueObjects/`
- **AND** DEBE ser inmutable despues de construccion
- **AND** DEBE exponer `isAutoAdsEnabled()`, `getExcludedSelectors()`, `getPublisherId()`
- **AND** NO DEBE contener logica de WordPress
#### Scenario: Interface en Domain
- **WHEN** se define el contrato para verificar si un grupo esta activo
- **THEN** DEBE existir metodo en `AdsenseSettingsInterface`:
`isGroupActiveWithAutoAds(string $groupName): bool`
- **AND** DEBE retornar false para grupos manuales cuando Auto Ads esta activo
- **AND** DEBE retornar true para `search_results`, `analytics`, `content`
#### Scenario: Service en Infrastructure
- **WHEN** se implementa la logica de evaluacion
- **THEN** el `AdsenseSettingsService` DEBE verificar `enable_auto_ads` antes de evaluar ubicaciones
- **AND** DEBE exponer metodo `getActiveGroups(): array` que retorna solo grupos activos
---
### Requirement: Endpoint REST para Estado de Auto Ads
El endpoint de visibilidad DEBE informar el estado de Auto Ads.
#### Scenario: Inclusion en response de visibility
- **GIVEN** el endpoint `/wp-json/roi-theme/v1/adsense-placement/visibility`
- **WHEN** responde exitosamente
- **THEN** DEBE incluir campo `auto_ads_enabled: boolean`
- **AND** DEBE incluir campo `auto_ads_exclude_selectors: string`
#### Scenario: Response cuando Auto Ads esta activo
- **GIVEN** `enable_auto_ads === true`
- **WHEN** se llama al endpoint
- **THEN** el response DEBE incluir:
```json
{
"show_ads": true,
"auto_ads_enabled": true,
"auto_ads_exclude_selectors": "table,.wp-block-table",
"manual_slots_disabled": true,
"search_slots_enabled": true,
"reasons": [],
"cache_seconds": 300,
"timestamp": 1733900000
}
```
---
### Requirement: Migracion y Retrocompatibilidad
La implementacion DEBE mantener compatibilidad con instalaciones existentes.
#### Scenario: Valor default para instalaciones existentes
- **GIVEN** una instalacion existente sin el campo `enable_auto_ads`
- **WHEN** se ejecuta sync-component
- **THEN** DEBE crear el campo con valor `false`
- **AND** el comportamiento existente NO DEBE cambiar
#### Scenario: Sin cambios en logica si Auto Ads esta desactivado
- **GIVEN** `enable_auto_ads === false`
- **WHEN** se evaluan ubicaciones de anuncios
- **THEN** el comportamiento DEBE ser identico al actual
- **AND** NO DEBE haber impacto en rendimiento
---
### Requirement: Logging y Diagnostico
El sistema DEBE proveer informacion de diagnostico para troubleshooting.
#### Scenario: Log cuando Auto Ads ignora ubicacion
- **GIVEN** `enable_auto_ads === true`
- **AND** WP_DEBUG === true
- **WHEN** un Renderer es llamado para ubicacion manual
- **THEN** DEBE loguear mensaje: "AdSense: Skipping manual slot '{slot_name}' - Auto Ads active"
- **AND** el log DEBE ser level DEBUG
#### Scenario: Comentario HTML de diagnostico
- **GIVEN** `enable_auto_ads === true`
- **AND** WP_DEBUG === true
- **WHEN** se renderiza el header
- **THEN** DEBE incluir comentario HTML:
```html
<!-- ROI AdSense: Auto Ads Mode Active | Manual slots: disabled | Search slots: enabled -->
```
---
## Implementation Notes
### Schema Changes (adsense-placement.json)
Agregar al grupo `visibility`:
```json
"enable_auto_ads": {
"type": "boolean",
"label": "Activar Google Auto Ads",
"default": false,
"editable": true,
"description": "Google controla automaticamente la ubicacion de anuncios. Se desactivan ubicaciones manuales excepto busqueda."
}
```
Agregar al grupo `forms` (nuevo campo):
```json
"auto_ads_exclude_selectors": {
"type": "textarea",
"label": "Selectores adicionales a excluir de Auto Ads",
"default": "",
"editable": true,
"description": "Selectores CSS adicionales donde Auto Ads no debe insertar anuncios (uno por linea)"
}
```
### CSS Default Exclusions
```css
/* Elementos que Google Auto Ads debe ignorar */
table,
.wp-block-table,
.tablepress,
figure.wp-block-table,
.entry-content table,
.roi-apu-results,
.roi-apu-result-item,
pre,
code,
.wp-block-code,
.syntax-highlighted {
google-auto-ads: ignore;
}
```
### Grupos y su comportamiento con Auto Ads
| Grupo | Con Auto Ads OFF | Con Auto Ads ON |
|-------|------------------|-----------------|
| visibility | Activo | Activo (controla is_enabled global) |
| analytics | Activo | Activo |
| content | Activo | Activo (provee publisher_id) |
| incontent_advanced | Activo | IGNORADO |
| behavior | Activo | IGNORADO (excepto javascript_first_mode) |
| anchor_ads | Activo | IGNORADO |
| vignette_ads | Activo | IGNORADO |
| search_results | Activo | ACTIVO (excepcion) |
| layout | Activo | IGNORADO |
| forms | Activo | Activo (delay, exclusiones) |
---
## Validation Checklist
Antes de considerar esta especificacion implementada:
- [ ] Campo `enable_auto_ads` existe en schema y BD
- [ ] Campo `auto_ads_exclude_selectors` existe en schema y BD
- [ ] CSS de exclusion se inyecta solo cuando Auto Ads activo
- [ ] Slots manuales no se renderizan cuando Auto Ads activo
- [ ] Slots de busqueda SI se renderizan cuando Auto Ads activo
- [ ] `roi_get_adsense_search_config()` funciona independiente de Auto Ads
- [ ] Admin UI muestra indicador visual de Auto Ads activo
- [ ] Grupos desactivados aparecen con opacidad reducida
- [ ] Endpoint REST incluye `auto_ads_enabled` en response
- [ ] JavaScript oculta slots manuales pero no de busqueda
- [ ] Script de AdSense se carga correctamente
- [ ] No hay duplicacion de scripts
- [ ] Logs de debug funcionan cuando WP_DEBUG activo
- [ ] Sync-component migra correctamente instalaciones existentes