Smart demand signals for B2B dental clinics. Daily commercial alerts powered by two ML engines, explained with SHAP, and turned into actionable outreach by Gemini 2.5 Flash.
English · Español · Website tour →
NextBuy turns a flat sales-history table into a prioritised, explainable inbox for sales reps. Every morning it produces:
- Commodity alerts — promiscuous clients (buy elsewhere → opportunity to capture) and loyal-but-deteriorating accounts.
- Technical alerts — churn / abandonment risk relative to each client's own historical pattern.
Each alert ships with: motive, priority (impact × urgency), top-3 explainable reasons (TreeSHAP), Gemini-written whyActNow + recommendation, and a suggested channel (call / WhatsApp / email).
| Head | Best model | TEST AUC | TEST AP | P@5% |
|---|---|---|---|---|
| Commodity (buy 90d) | LightGBM | 0.870 | 0.788 | 0.949 |
| Technical (churn 90d) | XGBoost | 0.807 | 0.818 | 0.908 |
Holdout split is temporal, not random — see TECHNICAL_REPORT.md for the leakage-prevention story and the full preprocessing pipeline.
| Layer | Tech |
|---|---|
| Frontend | Vue 3 · Vite · Tailwind · Pinia · chart.js |
| Backend | FastAPI · Motor (async MongoDB) · Pydantic |
| LLM | Gemini 2.5 Flash (cached in Mongo) |
| ML | LightGBM · XGBoost · HistGB · LogReg · TreeSHAP |
| Voice | ElevenLabs (delegado voice clones) |
NextBuy/
├── README.md
├── TECHNICAL_REPORT.md # End-to-end ML + system writeup
├── LICENSE
├── docs/
│ └── NAVIGATION.md # Website tour (every view explained)
├── back/ # FastAPI + Mongo + Gemini + ML pipeline
│ ├── main.py # API endpoints
│ ├── db.py # Async Mongo with in-memory fallback
│ ├── llm.py # Gemini wrapper + Mongo cache
│ ├── services.py # ETL + aggregations + KPIs
│ ├── models_pyd.py # Pydantic schemas
│ ├── tests/ # 5 smoke tests
│ └── models/ # ML pipeline: clean → features → train → alerts
└── front/ # Vue 3 SPA
└── src/views/ # 10 views — see docs/NAVIGATION.md
Backend — runs offline if Mongo or Gemini are missing (in-memory fallback + Spanish templates):
cd back
cp .env.example .env # fill in MONGODB_URI and GEMINI_API_KEY
pip install -r requirements.txt
uvicorn main:app --reload --port 8000
# http://localhost:8000/docsFrontend:
cd front
npm install
npm run dev # http://localhost:5173Regenerate alerts after new data lands:
cd back/models
python -m src.audit && python -m src.clean && python -m src.features
for HEAD in commodity tecnico; do
for MODEL in lightgbm xgboost histgb logreg; do
python -m src.train_one --head $HEAD --model $MODEL
done
done
python -m src.alerts # → back/models/data/processed/alerts_*.csv
curl -X POST http://localhost:8000/api/alerts/refresh # ETL CSV → Mongo| Endpoint | What it returns |
|---|---|
GET /api/health |
Mongo + Gemini connectivity |
GET /api/alerts?priority=&motivo=&owner=&q=&top_n= |
Filterable alert list |
GET /api/alerts/{id} |
Alert detail + Gemini whyActNow / recommendation |
POST /api/alerts/{id}/feedback |
{result, notes} — feedback loop |
POST /api/alerts/refresh |
Re-import CSV → Mongo |
GET /api/kpis |
5 dashboard KPIs |
GET /api/distribution/{family|urgency} |
Donut data |
GET /api/geo |
Provinces + criticality (map) |
GET /api/top-risk?n=4 |
Top at-risk clients |
GET /api/contacts-evolution?days=7 |
Contacts timeline + conversion |
GET /api/recommendations |
Suggested actions for the sales manager |
GET /api/clients/{id}/history?months=24 |
Client purchase history |
GET /api/clients/{id}/summary |
Gemini behaviour summary |
- Want to navigate the UI? →
docs/NAVIGATION.md— every view explained. - Want the ML / preprocessing details? →
TECHNICAL_REPORT.md. - Want backend internals? →
back/README.md. - Want frontend internals? →
front/README.md.
NextBuy convierte una tabla plana de historial de ventas en un inbox priorizado y explicable para delegados comerciales. Cada mañana produce:
- Alertas de commodity — clientes promiscuos (compran fuera → oportunidad de captura) y leales que se están deteriorando.
- Alertas técnicas — riesgo de fuga / abandono vs el patrón histórico individual del cliente.
Cada alerta lleva: motivo, prioridad (impacto × urgencia), top-3 razones explicables (TreeSHAP), whyActNow + recommendation redactados por Gemini, y canal recomendado (llamada / WhatsApp / email).
| Cabeza | Mejor modelo | TEST AUC | TEST AP | P@5% |
|---|---|---|---|---|
| Commodity (buy 90d) | LightGBM | 0.870 | 0.788 | 0.949 |
| Técnico (churn 90d) | XGBoost | 0.807 | 0.818 | 0.908 |
El holdout es temporal, no aleatorio — la prevención de leakage y el pipeline completo de preprocesado están en TECHNICAL_REPORT.md.
| Capa | Tecnología |
|---|---|
| Frontend | Vue 3 · Vite · Tailwind · Pinia · chart.js |
| Backend | FastAPI · Motor (Mongo async) · Pydantic |
| LLM | Gemini 2.5 Flash (cacheado en Mongo) |
| ML | LightGBM · XGBoost · HistGB · LogReg · TreeSHAP |
| Voz | ElevenLabs (clon de voz por delegado) |
NextBuy/
├── README.md
├── TECHNICAL_REPORT.md # Documentación ML + sistema
├── LICENSE
├── docs/
│ └── NAVIGATION.md # Tour de la web (cada vista explicada)
├── back/ # FastAPI + Mongo + Gemini + pipeline ML
│ ├── main.py # Endpoints API
│ ├── db.py # Mongo async con fallback in-memory
│ ├── llm.py # Wrapper Gemini + cache Mongo
│ ├── services.py # ETL + agregaciones + KPIs
│ ├── models_pyd.py # Schemas Pydantic
│ ├── tests/ # 5 smoke tests
│ └── models/ # Pipeline ML: clean → features → train → alerts
└── front/ # SPA Vue 3
└── src/views/ # 10 vistas — ver docs/NAVIGATION.md
Backend — corre offline si faltan Mongo o Gemini (fallback in-memory + plantillas en español):
cd back
cp .env.example .env # completa MONGODB_URI y GEMINI_API_KEY
pip install -r requirements.txt
uvicorn main:app --reload --port 8000
# http://localhost:8000/docsFrontend:
cd front
npm install
npm run dev # http://localhost:5173Regenerar alertas tras nuevos datos:
cd back/models
python -m src.audit && python -m src.clean && python -m src.features
for HEAD in commodity tecnico; do
for MODEL in lightgbm xgboost histgb logreg; do
python -m src.train_one --head $HEAD --model $MODEL
done
done
python -m src.alerts # → back/models/data/processed/alerts_*.csv
curl -X POST http://localhost:8000/api/alerts/refresh # ETL CSV → Mongo| Endpoint | Descripción |
|---|---|
GET /api/health |
Conectividad Mongo + Gemini |
GET /api/alerts?priority=&motivo=&owner=&q=&top_n= |
Lista filtrable de alertas |
GET /api/alerts/{id} |
Detalle + Gemini whyActNow / recommendation |
POST /api/alerts/{id}/feedback |
{result, notes} — feedback loop |
POST /api/alerts/refresh |
Re-importa CSV → Mongo |
GET /api/kpis |
5 KPIs del dashboard |
GET /api/distribution/{family|urgency} |
Datos donut |
GET /api/geo |
Provincias + criticidad (mapa) |
GET /api/top-risk?n=4 |
Top clientes en riesgo |
GET /api/contacts-evolution?days=7 |
Línea temporal contactos + conversión |
GET /api/recommendations |
Acciones sugeridas para el sales manager |
GET /api/clients/{id}/history?months=24 |
Histórico de compras del cliente |
GET /api/clients/{id}/summary |
Resumen Gemini del comportamiento |
- ¿Quieres navegar la UI? →
docs/NAVIGATION.md— cada vista explicada. - ¿Detalles ML / preprocesado? →
TECHNICAL_REPORT.md. - ¿Internals del backend? →
back/README.md. - ¿Internals del frontend? →
front/README.md.