# ONEtoONE · Inteligencia de Red — MVP

> Dado un dominio de empresa, identifica qué advisors de la red ya tienen relación con ella, qué tan sólida es y con quién han hablado.

---

## ⚙️ Qué hace

- Cruza interacciones históricas con empresas por dominio de email y nombre
- Puntúa cada relación advisor–empresa con reglas ponderadas y auditables
- Identifica el contacto concreto dentro de la empresa (nombre + cargo)
- Expone el resultado como HTML interactivo y como API JSON

---

## 🛠 Stack

- PHP 8.3 (sin frameworks) + PDO-ready para MySQL/MariaDB
- JavaScript ES5+ vanilla (sin dependencias de frontend)
- PHPUnit 11
- Docker (opcional)
- gettext i18n (ES / EN / FR / DE / TR)

---

## 🚀 Ejecutar

```bash
composer install
```

### PHP built-in

```bash
php -S localhost:8080 -t public/
```

### Docker

```bash
make install   # construye imagen y levanta
make start     # arranca sin reconstruir
make stop      # pausa
make test      # 26 tests unitarios
make pomo      # compila .mo a partir de .po
make down      # tira abajo los contenedores docker
```

Acceso: `http://localhost:8080`

---

## 🏗 Arquitectura

```
Controller → orquesta, sin lógica de negocio
Service    → lógica pura (scoring, matching, extracción de contacto)
Repository → acceso a datos; sustituir arrays por PDO no toca nada más
View       → partials PHP reutilizables; sin template engine
```

Cambiar la fuente de datos (MySQL, CRM, API) = modificar solo los repositorios.

Separación completa de responsabilidades que permite escalar o sustituir capas sin afectar al resto del sistema.

---

## 🧪 Testing

```bash
make test   # PHPUnit 11 · 26 pruebas unitarias
```

`ScoreCalculatorTest` cubre todos los tipos de interacción, cada bonificación por separado y los tres rangos de etiqueta. Sin dependencia de servidor ni base de datos.

---

## 🔌 API

```bash
GET /api.php?domain=acme.com          # contactos de red con score y desglose
GET /api.php?id=1                     # mismo, por ID interno
GET /api.php?stats=top_users&limit=5  # ranking de advisors por actividad
```

Diseñada para ser consumida por otros sistemas internos o frontends desacoplados.

Documentación completa: `/api-docs.php`

### Postman

Colección lista para importar en `data/postman_example/onetoone.postman_collection.json`. Cubre los tres endpoints con ejemplos de respuesta.

---

## 🟨 JavaScript

Vanilla ES5+ sin dependencias. Todo en `public/js/app.js`, encapsulado en IIFE con `'use strict'`.

| Funcionalidad | Detalle |
|---|---|
| Toggle de formato de fecha | Alterna entre DD-MM-YYYY (europeo) e ISO. Preferencia persistida en `localStorage` |
| Selector de idioma | Escribe cookie `lang` y recarga para que PHP aplique el locale via gettext |
| Ordenación del score breakdown | Ordena interacciones por fecha (asc/desc) o por puntos (asc/desc) sin recargar |
| Smooth scroll con offset | Compensa la altura del header sticky al navegar a anclas internas |

No usa jQuery ni ningún framework. El DOM se manipula directamente con `querySelectorAll`, `addEventListener` y `dataset`.

---

## 📊 Scoring

Aditivo, ponderado y transparente. Cada punto tiene una justificación visible en `score_breakdown`.

| Factor | Puntos |
|---|---|
| Reunión | +15 |
| Llamada | +10 |
| Email | +7 |
| Evento | +5 |
| Relación activa (últimos 12 meses) | +20 |
| Relación continuada (varios años) | +15 |
| Contacto repetido 2+ veces | +10 |
| Contacto identificado (por nombre) | +5 |

Etiquetas: `low` (0–24) · `medium` (25–49) · `high` (50+). Todas las constantes en `src/Services/ScoreCalculator.php`.

---

## 📁 Estructura

```
bootstrap.php                   Autoloader PSR-4 + init gettext
public/                         Webroot (único directorio expuesto)
  index.php / view.php / users.php / api.php
  api-docs.php / scoring.php / docs/instalacion.php
src/
  Controllers/                  CompanyInsightController · UserInsightController
  Services/                     ScoreCalculator · CompanyMatcherService · ContactExtractor
  Repositories/                 Company · User · Interaction · WebContent
  Views/partials/               head · header · footer · breakdown
data/                           Arrays PHP (simulan BD): empresas, usuarios, 45 interacciones
locale/                         .po/.mo por idioma (make pomo para compilar)
tests/Services/                 ScoreCalculatorTest.php
```

---

## 📚 Documentación adicional

| Fichero | Contenido |
|---|---|
| `ANALYSIS.md` | Decisiones de diseño, camino a producción, trade-offs |
| `SPECS.md` | Especificaciones de construcción fase a fase |

---

## 💡 Decisiones técnicas

PHP sin framework para demostrar la comprensión de la arquitectura.
En producción utilizaría: Laravel.
El scoring usa reglas explícitas porque en M&A la explicabilidad es un requisito operativo, no una limitación.

---

## 🤖 Evolución con IA y Google Workspace

El MVP usa reglas deterministas y datos simulados para demostrar la lógica de negocio. El enunciado no especifica cómo se registran las interacciones; dado que ONEtoONE opera con Google Workspace, la hipótesis más razonable es que la fuente real son Gmail y Google Calendar.

**Pipeline de ingesta presupuesto:**

```
Gmail API + Calendar API  →  Claude / Gemini  →  BD interactions
(correos y reuniones          (clasificación,       ↓
 con contactos externos)       normalización,   InteractionRepository
                               extracción        (sin cambios)
                               de contacto)
```

El dato crudo de Workspace no llega estructurado. Claude o Gemini clasifican el tipo de interacción, normalizan el nombre de empresa y extraen el contacto a partir de la firma del email o la descripción del evento. El resultado se persiste en la BD y el resto de la aplicación lo consume igual que hoy.

Adicionalmente, el stack de IA encaja en otras dos capas:

- **Extracción de contactos desde web** — LLM sobre el contenido indexado en la BD no relacional existente para identificar nombres y cargos con mayor precisión que el matching por texto
- **Resumen ejecutivo** — briefing en lenguaje natural del historial relación advisor–empresa

La arquitectura de repositorios permite conectar estas capas sin tocar la lógica de negocio ni el scoring. Ver detalle en `ANALYSIS.md`.
