# Central Click Defender — Arquitectura de producto

**Estado:** Propuesta para revisión  
**Versión:** 0.1.0  
**Fecha:** 2026-07-12  
**Decisión vigente:** no iniciar implementación hasta aprobar este documento.

## 1. Resumen ejecutivo

Central Click Defender (CCD) será un SaaS B2B multiempresa que captura eventos de visitas atribuibles a publicidad, enriquece señales, calcula un puntaje de riesgo explicable, genera detecciones y sincroniza exclusiones de IP con Google Ads. La primera versión será un monolito modular en PHP 8.3, acompañado por workers asíncronos y un tracker JavaScript independiente.

El monolito modular es una decisión deliberada: conserva límites de dominio, transacciones y despliegue sencillo sin el coste operativo prematuro de microservicios. Los módulos se comunican mediante contratos y eventos internos, por lo que los componentes de mayor carga —ingesta, enriquecimiento, detección y conectores— podrán extraerse más adelante sin rediseñar el negocio.

El producto no prometerá eliminar todo fraude. Google Ads aplica límites, políticas y latencia a las exclusiones; además, IP, fingerprint y geolocalización son señales probabilísticas. CCD entregará reducción de riesgo, automatización, trazabilidad y evidencia explicable.

## 2. Alcance y principios

### 2.1 Alcance inicial

- Alta y administración de tenants, usuarios, roles y licencias.
- Registro y verificación de dominios.
- Tracker asíncrono y API pública de ingesta.
- Normalización, enriquecimiento y evaluación por reglas.
- Dashboard e historial explicable.
- Integración OAuth con Google Ads y exclusiones automatizadas.
- Alertas por correo y webhook; otros canales se incorporarán después.
- Auditoría, observabilidad, exportación CSV y operación administrativa global.

### 2.2 Fuera de la primera versión

- Modelos de aprendizaje automático en producción.
- Facturación/cobro automático, PDF/Excel y todos los canales de mensajería.
- Microservicios, Kubernetes y multi-región activa-activa.
- Bloqueo a nivel firewall del sitio del cliente.

### 2.3 Principios obligatorios

1. Aislamiento de tenant en todas las capas, con denegación por defecto.
2. Privacidad y minimización desde el diseño.
3. Procesamiento asíncrono en toda operación no necesaria para aceptar un evento.
4. Reglas explicables y versionadas; ninguna acción automática sin evidencia auditable.
5. Idempotencia en ingesta, jobs y llamadas externas.
6. Contratos versionados y compatibilidad hacia atrás.
7. Secretos fuera del código y datos sensibles cifrados.
8. Modularidad antes que distribución física.

## 3. Requisitos no funcionales y SLO iniciales

| Área | Objetivo inicial | Evolución |
|---|---:|---:|
| Disponibilidad API de ingesta | 99,9% mensual | 99,95% |
| Disponibilidad panel | 99,5% mensual | 99,9% |
| Latencia de aceptación p95 | < 250 ms | < 150 ms |
| Evaluación desde ingesta p95 | < 60 s | < 10 s |
| RPO | 15 min | 5 min |
| RTO | 4 h | 1 h |
| Tracker comprimido | objetivo < 35 KB | controlar por budget CI |
| Retención eventos raw | 90 días configurable | por plan/contrato |
| Auditoría | mínimo 24 meses | por regulación/contrato |

Los SLO se validarán con carga real antes de convertirlos en SLA comercial.

## 4. Arquitectura general

```mermaid
flowchart LR
  B[Visitante] --> T[tracker.js CDN]
  T -->|HTTPS sendBeacon/fetch| E[API Ingesta v1]
  U[Usuario tenant] --> W[Panel web]
  A[Administrador global] --> W
  W --> C[Aplicación PHP / REST]
  E --> C
  C --> DB[(MySQL primario)]
  C --> R[(Redis: rate limit, cache, cola)]
  R --> WK[Workers PHP]
  WK --> P[Proveedores IP/Geo]
  WK --> G[Google Ads API]
  WK --> N[Email/Webhooks]
  C --> O[Logs métricas trazas]
  WK --> O
  DB --> RR[(Réplica lectura)]
  DB --> BK[(Backups cifrados)]
```

### 4.1 Capas internas

```mermaid
flowchart TB
  UI[Interfaces: HTTP REST CLI Workers] --> APP[Aplicación: casos de uso y DTO]
  APP --> DOM[Dominio: entidades value objects políticas eventos]
  APP --> PORT[Puertos: repositorios colas reloj cifrado proveedores]
  INF[Infraestructura: MySQL Redis Google Ads mail] --> PORT
```

- **Dominio:** PHP puro, sin dependencia de framework, HTTP o persistencia.
- **Aplicación:** orquesta casos de uso, transacciones, autorización y eventos.
- **Interfaces:** controladores REST, comandos y consumidores de cola.
- **Infraestructura:** implementaciones de repositorios, cache, proveedores y telemetría.

Repository Pattern se utilizará sólo en agregados con comportamiento; consultas analíticas usarán query services/read models para evitar repositorios genéricos artificiales. Dependency Injection será explícita mediante interfaces y un contenedor PSR-11.

### 4.2 Módulos

```mermaid
flowchart TB
  IAM[IAM] --> TEN[Tenant y licencias]
  TEN --> DOM[Dominios]
  DOM --> ING[Ingesta]
  ING --> SIG[Señales y enriquecimiento]
  SIG --> DET[Detección]
  DET --> BLK[Bloqueos]
  BLK --> ADS[Google Ads]
  DET --> ALT[Alertas]
  ING --> ANA[Analítica y reportes]
  BILL[Facturación futura] --> TEN
  AUD[Auditoría] -. transversal .-> IAM
  AUD -.-> DET
  AUD -.-> ADS
```

| Módulo | Responsabilidad | No debe conocer |
|---|---|---|
| IAM | identidades, autenticación, RBAC, MFA futuro | clicks y Google Ads |
| Tenancy | tenants, planes, licencias, cuotas, estado | detalles del tracker |
| Domains | dominios, propiedad, claves públicas, configuración | credenciales Ads |
| Ingestion | aceptar, validar, deduplicar y encolar eventos | lógica de fraude |
| Signals | catálogo, normalización, proveedores y evidencia | acciones de bloqueo |
| Detection | reglas, versiones, scoring y decisiones | HTTP/proveedores directos |
| Blocking | ciclo de vida, aprobación y deshacer | OAuth directo |
| Google Ads | conexiones, cuentas, campañas y sincronización | reglas internas |
| Analytics | proyecciones agregadas y consultas | mutaciones operativas |
| Alerts | plantillas, canales, reintentos | detección concreta |
| Billing | suscripciones, facturas y eventos de pago futuros | autorización IAM |
| Audit | registro inmutable lógico de acciones | decisiones de negocio |

## 5. Flujo completo

```mermaid
sequenceDiagram
  participant V as Navegador
  participant CDN as CDN
  participant API as Ingesta
  participant Q as Cola
  participant W as Worker
  participant D as Motor detección
  participant G as Google Ads
  V->>CDN: GET tracker.js
  CDN-->>V: JS cacheado + SRI/versionado
  V->>API: POST /v1/events (license public key, event_id)
  API->>API: origen, esquema, cuota, rate limit, deduplicación
  API-->>V: 202 Accepted
  API->>Q: EventAccepted
  Q->>W: enriquecer señales
  W->>D: evaluar snapshot de regla
  D-->>W: score + razones + acción
  W->>Q: DetectionCreated
  Q->>G: reconciliar exclusión idempotente
  G-->>Q: resultado/provider reference
```

1. El tracker genera un `event_id` UUID y un identificador pseudónimo de navegador.
2. Captura sólo señales permitidas por configuración/consentimiento. No intenta eludir controles del navegador.
3. La API valida licencia activa, dominio/origen, tamaño, versión y cuotas. La clave del tracker es pública y no se considera secreto.
4. Responde `202` rápidamente y deriva el trabajo pesado a cola.
5. Los workers normalizan datos y consultan proveedores con cache/circuit breaker.
6. El motor evalúa un snapshot versionado y crea una detección explicable.
7. La política decide observar, alertar, bloquear o requerir aprobación.
8. El conector Google Ads reconcilia estado deseado versus remoto, registra cada intento y revierte cuando corresponde.

Si Redis/cola no está disponible, la API puede persistir un outbox transaccional y responder sólo tras confirmar almacenamiento durable. Nunca se pierde silenciosamente un evento.

## 6. Multi-tenancy

Se usará una base compartida y esquema compartido en la etapa inicial. Todas las entidades propiedad del cliente contienen `tenant_id`; las claves únicas incluyen `tenant_id`, y toda consulta se ejecuta dentro de un `TenantContext` resuelto desde identidad/licencia, nunca desde un parámetro confiado del cliente.

Defensas:

- Middleware obligatorio establece `TenantContext`.
- Repositorios exigen tenant de forma no opcional.
- Policies verifican tenant y permiso sobre el recurso.
- Foreign keys compuestas cuando ayudan a impedir referencias cruzadas.
- Tests automatizados de aislamiento para cada endpoint.
- Jobs contienen tenant y revalidan su estado al ejecutarse.
- Cache, paths de objetos y métricas usan namespace por tenant.
- El administrador global emplea un contexto y permisos separados, con motivo auditable para impersonación.

MySQL no ofrece Row Level Security equivalente a PostgreSQL; por tanto el aislamiento depende de aplicación y constraints. Para clientes regulados se podrá ofrecer base dedicada mediante la misma interfaz de conexión y routing por tenant. Antes de implementar, se debe reevaluar PostgreSQL si RLS es un requisito comercial fuerte.

## 7. Modelo de datos

### 7.1 Convenciones

- Identificadores internos `BIGINT UNSIGNED`; identificadores públicos UUIDv7/ULID para evitar enumeración.
- UTC en almacenamiento; zona horaria IANA por tenant para presentación.
- `created_at`, `updated_at` donde corresponda; borrado lógico sólo donde tenga significado legal/operativo.
- Importes en unidad menor + moneda ISO 4217; nunca `FLOAT`.
- IP cifrada para recuperación operativa y `ip_hash` HMAC para correlación; claves con rotación.
- JSON sólo para payloads variables/evidencia, no para relaciones o campos consultados habitualmente.
- Tablas de alto volumen particionables por fecha y con política de retención.

### 7.2 Entidades principales

| Área | Tabla | Campos/relaciones esenciales |
|---|---|---|
| Tenant | `tenants` | public_id, name, status, timezone, data_region |
| Tenant | `plans` | code, limits_json, active |
| Tenant | `licenses` | tenant_id, plan_id, key_hash, period, starts_at, ends_at, status |
| Tenant | `license_usage` | license_id, metric, period_start, quantity |
| IAM | `users` | public_id, email canonical, password_hash, status, last_login_at |
| IAM | `tenant_users` | tenant_id, user_id, status; membresía N:M |
| IAM | `roles`, `permissions` | roles tenant/global; permisos con código estable |
| IAM | `role_permissions`, `tenant_user_roles` | asignaciones normalizadas |
| IAM | `refresh_tokens` | user_id, family_id, token_hash, expires/revoked; rotación |
| Domains | `domains` | tenant_id, host canonical, status, verification_token_hash |
| Domains | `domain_settings` | domain_id, tracker config version, consent mode |
| Ads | `google_ads_connections` | tenant_id, customer/manager IDs, encrypted OAuth material, status |
| Ads | `ad_accounts` | tenant_id, connection_id, external_id, currency, timezone |
| Ads | `campaigns` | tenant_id, ad_account_id, external_id, name, status, synced_at |
| Tracking | `visitors` | tenant_id, pseudonymous_id_hash, first/last_seen_at |
| Tracking | `click_events` | tenant/domain/campaign/visitor, event_id, occurred/received_at, gclid hash/encrypted, attribution |
| Tracking | `event_signals` | tenant_id, click_event_id, signal_definition_id, typed value/evidence |
| Signals | `signal_definitions` | key, type, sensitivity, schema_version, active |
| Signals | `ip_observations` | tenant/click, ip_hash, encrypted IP, ASN/geo/network classification |
| Rules | `rules` | tenant nullable for templates, name, status, priority |
| Rules | `rule_versions` | rule_id, version, condition_ast, weight, action, checksum, published_at |
| Detection | `evaluations` | tenant/click, ruleset_version, score, verdict, evaluated_at |
| Detection | `rule_matches` | evaluation_id, rule_version_id, contribution, evidence_json |
| Detection | `detections` | tenant/evaluation, severity, status, reason summary |
| Blocking | `block_requests` | tenant, detection, target type/value hash, desired state, expiry |
| Blocking | `block_operations` | request/account/campaign, idempotency_key, attempt, provider ref/status/error |
| Alerts | `alert_rules` | tenant, event type, threshold, channel/template, status |
| Alerts | `alert_deliveries` | tenant, alert rule, event ref, attempt/status/provider ref |
| Settings | `settings` | scope_type/scope_id, key, typed encrypted value, version |
| Audit | `audit_events` | tenant nullable, actor, action, resource, before/after hashes, request_id, timestamp |
| System | `outbox_messages` | aggregate/event, payload, available/published_at, attempts |
| System | `inbox_messages` | consumer, message_id, processed_at; idempotencia |
| System | `api_clients` | tenant, name, key hash, scopes, status |
| System | `webhook_endpoints` | tenant, URL, secret encrypted, subscribed events, status |
| Billing | `billing_customers` | tenant, provider, external id |
| Billing | `subscriptions` | tenant, plan, period, status, provider id |
| Billing | `invoices`, `invoice_lines` | importes, impuestos, estado, periodo |

No se crea una tabla genérica `history`: el historial de negocio vive en versiones y eventos de auditoría. Tampoco se duplica `clients` y `tenants`; una empresa cliente es un tenant. `IPs` y `fingerprints` se modelan como observaciones/identificadores pseudónimos, no como identidades humanas confiables.

### 7.3 Relaciones resumidas

```mermaid
erDiagram
  TENANTS ||--o{ LICENSES : owns
  PLANS ||--o{ LICENSES : defines
  TENANTS ||--o{ TENANT_USERS : has
  USERS ||--o{ TENANT_USERS : joins
  TENANTS ||--o{ DOMAINS : owns
  TENANTS ||--o{ GOOGLE_ADS_CONNECTIONS : owns
  GOOGLE_ADS_CONNECTIONS ||--o{ AD_ACCOUNTS : exposes
  AD_ACCOUNTS ||--o{ CAMPAIGNS : contains
  DOMAINS ||--o{ CLICK_EVENTS : receives
  CAMPAIGNS o|--o{ CLICK_EVENTS : attributes
  CLICK_EVENTS ||--o{ EVENT_SIGNALS : carries
  CLICK_EVENTS ||--o{ EVALUATIONS : evaluated
  RULES ||--o{ RULE_VERSIONS : versions
  EVALUATIONS ||--o{ RULE_MATCHES : explains
  RULE_VERSIONS ||--o{ RULE_MATCHES : matched
  EVALUATIONS ||--o| DETECTIONS : produces
  DETECTIONS ||--o{ BLOCK_REQUESTS : requests
  BLOCK_REQUESTS ||--o{ BLOCK_OPERATIONS : executes
```

### 7.4 Índices y volumen

- `click_events`: unique `(tenant_id,event_id)`; índices `(tenant_id,occurred_at)`, `(tenant_id,domain_id,occurred_at)`, campaña y hash IP según consultas reales.
- `event_signals`: `(tenant_id,click_event_id,signal_definition_id)`; señales calientes podrán proyectarse a columnas/read models.
- `evaluations/detections`: `(tenant_id,evaluated_at)`, `(tenant_id,verdict,evaluated_at)`.
- `block_operations`: unique `(tenant_id,idempotency_key)`.
- `audit_events`: append-only, índice `(tenant_id,occurred_at)` y `(actor_id,occurred_at)`.

Los índices definitivos se validarán con `EXPLAIN` y datos representativos. Agregar índices indiscriminadamente penaliza ingesta.

## 8. Motor de señales y reglas

### 8.1 Señales extensibles

Cada señal implementa un contrato conceptual: `key`, versión de esquema, fuente, tipo, sensibilidad, validador, normalizador y extractor opcional. Los providers externos se adaptan tras puertos. Agregar una señal no modifica el motor; se registra su definición y un extractor.

Las señales del navegador tendrán niveles:

- Esenciales: timestamp, URL normalizada, referrer, UTM, GCLID cuando exista.
- Técnicas: user agent/client hints, viewport, idioma, timezone.
- Conductuales: agregados de movimiento, scroll, foco y permanencia; no secuencias crudas innecesarias.
- Fingerprinting avanzado: desactivado por defecto hasta completar evaluación legal y mecanismo de consentimiento.

### 8.2 Reglas

Las condiciones se almacenan como AST JSON validado contra esquema, no como PHP/SQL evaluable. Operadores permitidos: comparación tipada, pertenencia, ventana temporal, agregación y combinadores booleanos. No se admite código arbitrario.

Una publicación crea `rule_version` inmutable y un `ruleset_version`. Cada evaluación conserva versión, señales, contribuciones y razones. La puntuación inicial será determinística (por ejemplo 0–100), con umbrales configurables y límites para evitar que una señal débil bloquee sola.

Acciones: `observe`, `alert`, `challenge_future`, `block`, `manual_review`. En el lanzamiento, reglas nuevas operarán en shadow mode; el bloqueo automático se habilitará sólo tras medir falsos positivos y disponer de rollback/expiración.

### 8.3 IA futura

`RiskScorer` será un puerto con implementaciones `RuleBasedScorer` y futura `MlScorer`. La IA consumirá features versionadas y devolverá score, versión de modelo y explicaciones; nunca realizará llamadas Google Ads. Un policy engine combinará resultados y aplicará límites. Se requieren dataset governance, control de drift, evaluación offline, canary y fallback determinístico.

## 9. API REST v1

Base: `/api/v1`. JSON UTF-8, timestamps RFC 3339 UTC, IDs públicos opacos. Errores mediante `application/problem+json`. OpenAPI 3.1 será el contrato fuente y CI verificará compatibilidad.

### 9.1 Autenticación

- Panel: access token corto en cookie `HttpOnly`, `Secure`, `SameSite=Lax/Strict` y refresh token rotatorio; protección CSRF para mutaciones. JWT no elimina CSRF ni permite revocación por sí mismo.
- API servidor a servidor: API keys con scopes, almacenadas como hash; OAuth client credentials podrá añadirse.
- Tracker: clave pública de licencia + allowlist de origen + rate limit + validación heurística. No existe secreto seguro en JavaScript público.
- Tokens incluyen `sub`, tenant activo, scopes, `jti`, `iat`, `exp`, issuer y audience; claves asimétricas rotables.

### 9.2 Endpoints principales

| Método | Ruta | Propósito |
|---|---|---|
| POST | `/auth/login` | autenticar y emitir sesión |
| POST | `/auth/refresh` | rotar refresh token |
| POST | `/auth/logout` | revocar familia/token |
| GET/POST | `/tenants/{tenant}/users` | listar/invitar usuarios |
| PATCH | `/tenants/{tenant}/users/{user}` | estado/roles |
| GET/POST | `/domains` | listar/registrar dominio |
| POST | `/domains/{id}/verify` | verificar propiedad |
| POST | `/events` | aceptar evento tracker; `202` |
| POST | `/events/batch` | lote acotado e idempotente |
| GET | `/clicks` | búsqueda paginada |
| GET | `/clicks/{id}` | señales y evaluación autorizadas |
| GET/POST | `/rules` | administrar reglas |
| POST | `/rules/{id}/versions` | crear borrador/versionar |
| POST | `/rules/{id}/publish` | publicar versión |
| GET | `/detections` | historial y filtros |
| POST | `/detections/{id}/review` | decisión humana |
| GET/POST | `/google-ads/connections` | iniciar/listar conexión OAuth |
| GET | `/google-ads/oauth/callback` | callback con state/PKCE |
| POST | `/google-ads/connections/{id}/sync` | solicitar reconciliación |
| GET | `/blocks` | estado de bloqueos |
| POST | `/blocks/{id}/revoke` | solicitar deshacer |
| GET | `/analytics/overview` | métricas agregadas |
| POST | `/exports` | exportación asíncrona |
| GET | `/exports/{id}` | consultar resultado temporal |
| GET/POST | `/webhooks` | administrar endpoints |
| GET | `/license` | estado, límites y consumo |

Administración global vive bajo `/api/v1/admin/*`, requiere audiencia/rol global, MFA futuro obligatorio, red o política adicional y auditoría reforzada.

### 9.3 Semántica

- Paginación cursor-based en datos grandes; filtros con allowlist.
- `Idempotency-Key` en ingesta, exportaciones, bloqueos y operaciones repetibles.
- ETag/`If-Match` para edición concurrente de reglas/configuración.
- Límites por IP, licencia, tenant y endpoint, con headers estándar y `429`.
- Webhooks firmados HMAC con timestamp, replay window, identificador y reintentos con backoff/DLQ.

## 10. Tracker JavaScript

El snippet público propuesto es válido, pero `data-license` identifica la instalación y no autentica secretos. El script tendrá carga `defer/async`, versionado estable, CDN multi-PoP, cache immutable para archivos con hash y fallback seguro.

Diseño:

- API mínima, sin jQuery ni dependencias; Fetch/`sendBeacon` con fallback compatible.
- Presupuesto estricto de bytes, CPU y memoria; captura diferida mediante `requestIdleCallback` cuando exista.
- Cola corta en memoria y opcionalmente almacenamiento local sólo con consentimiento.
- Batching, compresión soportada por navegador/servidor, timeouts y abandono silencioso sin afectar al sitio.
- Normalización de URL para no recolectar parámetros sensibles no permitidos.
- Consent mode configurable y API para que el CMP del cliente habilite categorías.
- CSP documentada; CORS restringido por dominios verificados.
- `tracker_version` y `schema_version` en cada evento; compatibilidad N-1 definida.

Canvas, WebGL, fonts y fingerprint persistente tienen implicaciones legales y de estabilidad; no se habilitarán globalmente hasta una evaluación de privacidad por región. Nunca se usarán técnicas invasivas para evadir el consentimiento.

## 11. Google Ads

La integración usará OAuth 2.0 con `state`, PKCE cuando aplique, scopes mínimos, refresh token cifrado mediante envelope encryption y rotación/revocación. Customer y Manager IDs se validan contra las cuentas accesibles.

El conector implementará:

- Adaptador aislado por versión de Google Ads API.
- Reconciliación de estado deseado/remoto, no llamadas sueltas desde controladores.
- Cola por cuenta con rate limiting, backoff con jitter y respeto por errores retryable.
- Idempotencia lógica, registros de operación, dead-letter queue y reparación manual.
- Límites de exclusiones, campañas compatibles, validación de IPv4/IPv6/rangos conforme a la API vigente.
- Expiración y deshacer automático de bloqueos temporales.
- Circuit breaker y estado visible del proveedor.

Antes de implementar este módulo se verificará la documentación oficial vigente, acceso al developer token, políticas, versiones soportadas y límites. Es un riesgo externo crítico.

## 12. Seguridad y privacidad

### 12.1 Controles

- OWASP ASVS como checklist; threat modeling STRIDE por flujo crítico.
- Contraseñas con Argon2id y parámetros calibrados; MFA para admins en fase temprana.
- Prepared statements, validación de esquema, output encoding contextual y CSP estricta.
- CSRF token de patrón synchronizer/double-submit según implementación de cookies.
- CORS con allowlist exacta; nunca wildcard con credenciales.
- Rate limit distribuido, retraso progresivo, credential stuffing detection y lockout seguro.
- Headers HSTS, CSP, `X-Content-Type-Options`, Referrer-Policy y Permissions-Policy.
- Uploads/exportaciones fuera del web root, con URLs firmadas y expiración.
- Secret manager en producción; nunca `.env` versionado ni tokens en logs.
- TLS en tránsito; cifrado de backups y campos sensibles; claves separadas y rotables.
- Dependencias bloqueadas, SBOM, auditoría de Composer/npm, SAST y secret scanning.
- Separación de funciones y principio de mínimo privilegio en DB/cloud/API.

### 12.2 Privacidad

CCD será potencialmente encargado del tratamiento y cada cliente responsable, sujeto a contrato y jurisdicción. Antes del lanzamiento se requieren DPA, inventario de datos, base legal/consentimiento, política de retención, proceso de derechos del titular, subprocesadores y transferencias internacionales.

IP y fingerprints se consideran datos personales/pseudónimos en muchas jurisdicciones. Se minimizan, se separan de usuarios identificados, se cifran y se retienen sólo lo necesario. La eliminación de tenant será un workflow verificable que cubra DB, objetos, cache, réplicas y expiración documentada de backups.

### 12.3 Auditoría

Eventos append-only con actor, tenant, acción, recurso, request/correlation ID, resultado, timestamp y hashes de cambios. Los payloads excluyen secretos. Para elevar resistencia a manipulación se podrá encadenar hashes por partición y exportar checkpoints a almacenamiento WORM.

## 13. Rendimiento, disponibilidad y escalabilidad

### 13.1 Evolución

1. Una región, aplicación PHP stateless detrás de load balancer, MySQL gestionado/replicado y Redis.
2. Escala horizontal de web/workers; read replica para analítica; CDN para tracker/assets.
3. Particionado temporal de eventos, almacenamiento de objetos para raw/exports y proyecciones analíticas.
4. Extraer servicio de ingesta sólo cuando métricas de carga/equipo lo justifiquen.
5. Motor OLAP (p. ej. ClickHouse) cuando MySQL deje de satisfacer consultas, mediante eventos/outbox, no dual writes.

### 13.2 Resiliencia

- Timeouts explícitos, retries sólo en operaciones seguras/idempotentes y jitter.
- Circuit breakers por proveedor y bulkheads por tenant para evitar noisy neighbor.
- Cola con DLQ, visibility timeout y métricas de edad/backlog.
- Backups PITR, pruebas trimestrales de restauración y runbooks.
- Deploy blue/green o rolling, migraciones expand/contract y feature flags.
- Graceful degradation: ingesta durable continúa aunque analítica o proveedores fallen.

## 14. Observabilidad y operación

- Logs JSON estructurados con `request_id`, `trace_id`, tenant pseudonimizado, versión y resultado; sin secretos/IP en claro.
- Métricas RED para APIs, USE para infraestructura y métricas de negocio (aceptados, evaluados, falsos positivos, operaciones Ads).
- Trazas OpenTelemetry a través de HTTP, cola y proveedores.
- Health endpoints separados: liveness, readiness y diagnóstico autenticado.
- Alertas basadas en SLO/burn rate, backlog, DLQ, expiración OAuth, fallos Ads y consumo de cuotas.
- Runbooks para caída de DB/Redis/proveedor, fuga de secreto, backlog y restauración.

## 15. Frontend y paneles

Bootstrap 5, JavaScript modular vanilla y Chart.js son suficientes para la primera versión. jQuery no se incluirá: no aporta valor al tracker ni al panel moderno y aumenta superficie/peso. Si existe un widget legado que lo necesite, quedará aislado.

El backend entrega HTML inicial seguro y la UI consume endpoints REST para módulos interactivos. Se implementan accesibilidad WCAG 2.1 AA, responsive, estados vacíos/error/carga, protección de rutas y permisos también en servidor.

El mapa requiere elegir proveedor y revisar licencia/costos. Las visualizaciones usan datos agregados, muestreo/rollups para periodos largos y zona horaria del tenant. El ahorro será una **estimación** con fórmula visible y moneda de la cuenta, no una cifra financiera garantizada.

## 16. Reportes y alertas

Exportaciones y reportes se generan como jobs, se guardan cifrados en object storage y se entregan mediante enlace firmado temporal. CSV se protege contra formula injection. PDF/Excel se incorporan tras evaluar librerías, memoria y licencias.

Alertas consumen eventos de dominio, aplican deduplicación, ventanas/silencios y límites por tenant. Email y webhooks primero; Slack/Telegram/WhatsApp serán adaptadores. WhatsApp exige proveedor, plantillas y costos, por lo que no debe considerarse un canal gratuito o inmediato.

## 17. Despliegue y entornos

- `local`, `test`, `staging` y `production` con cuentas/credenciales aisladas.
- Runtime PHP 8.3 administrado y reproducible mediante versiones bloqueadas; XAMPP sólo para desarrollo local. El despliegue directo y la configuración externa se rigen por ADR-0005.
- Configuración por entorno validada al arrancar.
- Pipeline: lint, estándares PSR-12, análisis estático, unit/integration/security/contract tests, build tracker, SBOM e imagen firmada.
- Migraciones versionadas, compatibles con rolling deploy y con procedimiento de rollback/forward fix.
- Versionado semántico para paquetes/servicios; API con versión mayor en URL y política de deprecación.

Estructura futura orientativa (no creada hasta aprobación):

```text
apps/api-public/      apps/backoffice/      apps/worker/
packages/domain/      packages/application/ packages/infrastructure/
public/               tracker/              config/
database/migrations/  tests/                docs/
```

## 18. Estrategia de pruebas

| Nivel | Cobertura |
|---|---|
| Unitarias | value objects, reglas, scoring, cuotas y policies |
| Integración | MySQL/Redis, repositorios, outbox, cifrado y adapters simulados |
| Contrato | OpenAPI, tracker/API, Google Ads adapter y webhooks |
| E2E | alta tenant → evento → detección → operación Ads simulada |
| Aislamiento | acceso cruzado a cada recurso, cache, export y job |
| Seguridad | SAST/DAST, dependencias, secretos, auth, CSRF, SSRF, IDOR |
| Rendimiento | ingesta sostenida/picos, reglas, cola, dashboard |
| Resiliencia | timeouts, duplicados, proveedor/Redis caído, reintentos y restore |

Google Ads se prueba mediante puertos/fakes y un entorno controlado; ninguna suite debe modificar campañas productivas.

## 19. Casos de uso principales

1. Administrador global crea tenant, plan y licencia; toda acción queda auditada.
2. Owner acepta invitación, registra/verifica dominio e instala tracker.
3. Sistema recibe evento, lo deduplica, enriquece y evalúa sin bloquear la navegación.
4. Analista revisa señales, reglas coincidentes y explicación de una detección.
5. Owner conecta Google Ads, selecciona cuentas/campañas y valida permisos.
6. Política genera bloqueo temporal; worker reconcilia exclusión y muestra resultado.
7. Analista marca falso positivo; se revierte y alimenta métricas/calibración.
8. Tenant configura alertas y recibe webhook firmado sin duplicados lógicos.
9. Usuario solicita exportación; obtiene archivo temporal limitado a su tenant.
10. Licencia vence/suspende: se detienen acciones y acceso según política, conservando datos conforme al contrato.
11. Usuario ejerce eliminación/exportación de datos mediante proceso auditable.
12. Operador investiga incidente con trazas y auditoría sin ver secretos.

## 20. Roadmap por sprints

Cada sprint incluye diseño actualizado, ADR, migraciones, endpoints, pruebas, seguridad, observabilidad y documentación. No comienza el siguiente sin criterios de salida.

### Sprint 0 — Fundaciones

- Requisitos/amenazas, ADRs, estructura, CI, configuración, observabilidad base.
- Composer/autoload PSR-4, estándares, test harness, entornos.
- Salida: pipeline verde y decisiones críticas aprobadas; sin negocio aún.

### Sprint 1 — Tenancy, IAM y licencias

- Tenants, usuarios, membresías, RBAC, login/refresh/logout, planes/licencias/cuotas.
- Tests de aislamiento y auditoría desde el inicio.
- Salida: dos tenants no pueden cruzar datos bajo pruebas negativas exhaustivas.

### Sprint 2 — Dominios y tracker mínimo

- Registro/verificación, configuración/consentimiento y tracker liviano.
- Ingesta versionada, rate limit, idempotencia y CORS/origin checks.
- Salida: evento aceptado durablemente bajo carga objetivo sin afectar página.

### Sprint 3 — Pipeline de señales

- Cola/outbox, workers, catálogo y normalizadores; IP/ASN/geo vía adapter.
- Retención, cifrado/HMAC y degradación de proveedor.
- Salida: evidencia trazable y recuperación demostrada ante fallos.

### Sprint 4 — Reglas y detecciones

- AST, versionado, shadow mode, scoring, explicaciones, revisión humana.
- Salida: reglas determinísticas reproducibles y métricas de precisión inicial.

### Sprint 5 — Google Ads

- OAuth, cuentas/campañas, reconciliación, límites, expiración y rollback.
- Salida: sandbox/cuenta controlada completa E2E, sin duplicar operaciones.

### Sprint 6 — Paneles y analítica

- Dashboard tenant/global, agregados, filtros, campañas, detecciones y salud.
- Salida: consultas dentro del budget con accesibilidad y aislamiento validados.

### Sprint 7 — Alertas y exportaciones

- Email/webhook, firma/reintentos, CSV asíncrono, programación básica.
- Salida: deduplicación, DLQ y expiración de archivos verificadas.

### Sprint 8 — Hardening y beta

- Pentest, carga/chaos, restore, runbooks, privacidad, onboarding y soporte.
- Salida: SLO medidos, riesgos críticos cerrados y checklist go-live aprobado.

### Posterior

- Billing automático, PDF/Excel, nuevos canales, OLAP, IA shadow/canary, regiones y planes dedicados.

## 21. Riesgos técnicos y mitigación

| Riesgo | Impacto | Mitigación |
|---|---|---|
| Falsos positivos bloquean clientes legítimos | crítico | shadow mode, umbrales, expiración, revisión, rollback, allowlists |
| Límites/cambios Google Ads API | alto | adapter versionado, reconciliación, cuotas, monitoreo y revisión oficial por sprint |
| Tracker bloqueado por browsers/ad blockers | alto | expectativas honestas, endpoint/CDN robusto, cobertura medible; no evasión |
| Fingerprinting incumple privacidad | crítico | DPIA, consentimiento, minimización y desactivado por defecto |
| Fuga cross-tenant | crítico | TenantContext, constraints, tests negativos, revisión y pentest |
| MySQL saturado por eventos/analítica | alto | índices medidos, retención, partición, réplicas y proyección a OLAP |
| Proveedor geo/VPN incorrecto o costoso | medio/alto | abstraction, cache, múltiples proveedores y score probabilístico |
| JWT robado/revocación débil | alto | cookies seguras, tokens cortos, refresh rotation/family revocation, MFA |
| Noisy neighbor/abuso de ingesta | alto | cuotas multinivel, bulkheads, payload limits y pricing por consumo |
| Estimación de ahorro engañosa | comercial/legal | fórmula transparente, rangos y disclaimers |
| Complejidad operativa prematura | alto | monolito modular y extracción guiada por métricas |

## 22. Decisiones y alternativas

| Decisión | Justificación | Alternativa / disparador de cambio |
|---|---|---|
| Monolito modular | menor costo y consistencia transaccional manteniendo límites | microservicios al existir cuello/equipos autónomos medibles |
| MySQL compartido | requisito, madurez operativa y costo inicial | PostgreSQL si RLS es requisito; DB dedicada por compliance |
| Redis para cache/cola inicial | baja latencia y operación simple | broker durable dedicado al crecer garantías/backlog |
| REST + OpenAPI | interoperabilidad y ecosistema | eventos/stream internos; GraphQL sólo ante necesidad UI demostrada |
| JS vanilla en tracker | peso y compatibilidad | ninguna dependencia salvo beneficio medido |
| Reglas determinísticas primero | explicabilidad y datos iniciales insuficientes para ML | ML sólo con dataset, evaluación y fallback |
| JWT corto + refresh rotatorio | escalabilidad con revocación controlada | sesión opaca server-side si simplifica riesgo operativo |
| Datos raw en MySQL inicialmente | velocidad de producto | object storage/OLAP al superar budgets |

## 23. Estrategia comercial y de crecimiento técnico

- Planes basados en dominios, campañas, usuarios, eventos y retención; cuotas observables y alertas antes del límite.
- Feature flags/entitlements centralizados, no condicionales dispersos.
- Onboarding con validación de instalación, conexión Ads y modo observación.
- Tier enterprise: SSO/SAML, SCIM, retención configurable, claves/DB dedicadas, SLA y región.
- Cost attribution por tenant (eventos, enriquecimientos, almacenamiento, API Ads) para asegurar margen.
- APIs y webhooks estables permiten ecosistema sin acoplar integraciones al núcleo.

## 24. ADRs requeridos antes del Sprint 0

1. ADR-001 monolito modular y límites de módulos.
2. ADR-002 estrategia multi-tenant MySQL versus PostgreSQL/RLS.
3. ADR-003 mecanismo de sesión/JWT, cookies y CSRF.
4. ADR-004 cola: Redis Streams versus broker gestionado y garantías.
5. ADR-005 cifrado/HMAC/rotación para IP, GCLID y OAuth.
6. ADR-006 política de privacidad, consentimiento y fingerprinting.
7. ADR-007 proveedor(es) de geo/ASN/VPN y estrategia de cache.
8. ADR-008 hosting, región, backups, RPO/RTO y object storage.
9. ADR-009 límites/políticas vigentes de Google Ads y modelo de reconciliación.
10. ADR-010 métricas de ahorro y metodología comercial.

## 25. Preguntas que bloquean la implementación

1. Mercado/jurisdicciones iniciales y rol legal de las partes.
2. Volumen esperado: eventos por mes, pico por segundo, tenants y retención por plan.
3. Cloud/proveedor, región primaria, presupuesto y requisitos de residencia.
4. ¿Se mantiene MySQL aun si se prioriza RLS fuerte, o se permite evaluar PostgreSQL?
5. Proveedor y credenciales de geolocalización/VPN/ASN.
6. Estado de aprobación, developer token y cuentas de prueba de Google Ads.
7. Política exacta ante vencimiento: ingesta, acceso, retención y periodo de gracia.
8. Umbrales iniciales, aprobación humana y duración máxima de un bloqueo.
9. Identidad visual, idiomas, moneda y fórmula de ahorro.
10. Requisitos contractuales: SLA, DPA, soporte, exportación y eliminación.

## 26. Criterio de aprobación

Este documento se considera aprobado sólo cuando el Product Owner confirme explícitamente:

- alcance de MVP y exclusiones;
- estrategia multi-tenant y tecnología de datos;
- postura de privacidad/fingerprinting;
- flujo y límites de Google Ads;
- SLO, volumen, retención y presupuesto;
- roadmap y criterios de salida.

Hasta entonces no se crearán archivos de aplicación, migraciones ni endpoints. Después de la aprobación, el único trabajo autorizado será Sprint 0; cualquier cambio arquitectónico posterior requerirá un ADR con contexto, decisión, alternativas y consecuencias.
