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:
365
_openspec/changes/adsense-auto-ads-toggle/spec.md
Normal file
365
_openspec/changes/adsense-auto-ads-toggle/spec.md
Normal 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
|
||||
Reference in New Issue
Block a user