Gemelo Comercial — Runbook Operativo

1. Propósito

Este documento concentra los comandos seguros para operar, auditar, limpiar y validar el Gemelo Comercial.

Regla principal:

No editar archivos .jsonl manualmente. Toda modificación debe hacerse mediante script con backup.


2. Archivos operativos principales

data/commercial/prospect_store.jsonl
data/commercial/prospect_batches.jsonl
data/commercial/contacts_input.jsonl
data/commercial/discovery_profiles.jsonl
data/commercial/discovery_rejections.jsonl
data/commercial/prospect_store_crm_ready.jsonl

3. Validar sintaxis Python
python -m compileall prodisys/comercial

Validar archivos específicos:

python -m compileall prodisys/comercial/ui/tabs/lotes_tab.py
python -m compileall prodisys/comercial/ui/tabs/contactos_tab.py
python -m compileall prodisys/comercial/ui/tabs/prospectos_crm_tab.py
python -m compileall prodisys/comercial/ui/components/editable_grid.py
python -m compileall prodisys/comercial/company_parser.py

4. Ejecutar UI comercial

Desde JupyterLab:

from prodisys.comercial.ui.app_ui import build_comercial_ui
build_comercial_ui()

Si la UI no refleja cambios:

Kernel → Restart Kernel
5. Discovery desde UI

Ruta:

Actividades → Perfil activo → Ejecutar discovery

El perfil activo controla:

países
sectores
include keywords
exclude keywords
max pages
max companies
min score
require country
require company name
6. Discovery desde terminal
python -m prodisys.comercial.prospect_discovery
7. Pipeline comercial por terminal

Ver comandos disponibles:

python -m prodisys.comercial.pipeline_runner --help

Comandos principales:

python -m prodisys.comercial.pipeline_runner discover
python -m prodisys.comercial.pipeline_runner continue
python -m prodisys.comercial.pipeline_runner integrate
python -m prodisys.comercial.pipeline_runner push-crm
python -m prodisys.comercial.pipeline_runner crm-dry-run
python -m prodisys.comercial.pipeline_runner crm-execute --confirm
python -m prodisys.comercial.pipeline_runner summary
8. Crear lote desde UI

Ruta:

Lotes → Crear lote

Columnas relevantes:

user_selected
reject_candidate
user_note

Al guardar:

user_selected=True → prospect_store.jsonl
reject_candidate=True → discovery_rejections.jsonl
snapshot completo → prospect_batches.jsonl / all_candidates
9. Reabrir lote

Ruta:

Lotes → Reabrir lote

Estados visibles:

YA_CREADO_COMO_PROSPECTO
YA_RECHAZADO_MANUALMENTE
PENDIENTE

Regla:

Los pendientes seleccionados crean un lote complementario.
El lote original no se modifica.
10. Retirar prospectos antes de CRM

Ruta:

Prospectos CRM → retirar_antes_crm=True → Guardar cambios

Reglas:

Solo elimina si crm_state == NEW
Crea backup automático
Elimina de prospect_store.jsonl
No modifica prospect_batches.jsonl

Salida esperada:

🗑 Prospectos retirados antes de CRM: N
🚫 Prospectos no retirados por estado no NEW: N
🧾 Backup: data/commercial/prospect_store.jsonl.bak_YYYYMMDD_HHMMSS
11. Auditar lotes vacíos o huérfanos

Script:

python scripts/audit_empty_batches.py

Salida esperada:

Total lotes: N
Lotes vacios reales: 0
Lotes huerfanos sin prospectos activos: 0

Si hay huérfanos, inspeccionar antes de borrar:

python scripts/inspect_orphan_batches.py
12. Eliminar lotes huérfanos

Solo después de inspección:

python scripts/remove_orphan_batches.py

Este script debe:

crear backup
eliminar lotes sin prospectos activos
conservar lotes válidos
actualizar selected_count

Validar después:

python scripts/audit_empty_batches.py
13. Validar país inferido

Prueba rápida:

python - <<'PY'
from prodisys.comercial.company_parser import infer_country_from_url_or_query

profile = {
    "scope": {
        "countries": [
            "United States",
            "Canada",
            "Australia",
            "UAE",
            "Saudi Arabia",
            "Colombia",
            "Chile",
            "Peru",
        ]
    }
}

tests = [
    ("https://australia.chevron.com", "Chevron operations Australia"),
    ("https://shellenergy.com.au", "Shell operations Australia"),
    ("https://totalenergies.com.au", "TotalEnergies operations Australia"),
    ("https://canada.chevron.com", "Chevron operations Canada"),
    ("https://corporate.exxonmobil.com", "ExxonMobil operations United States"),
    ("https://www.oxy.com", "Oxy operations Colombia"),
]

for url, query in tests:
    print(url, "|", query, "=>", infer_country_from_url_or_query(url, query, profile))
PY

Resultado esperado:

Australia
Australia
Australia
Canada
United States
Colombia
14. Revisar últimos registros JSONL
tail -n 5 data/commercial/prospect_store.jsonl
tail -n 5 data/commercial/prospect_batches.jsonl
tail -n 5 data/commercial/contacts_input.jsonl
tail -n 5 data/commercial/discovery_rejections.jsonl
15. Contar registros
wc -l data/commercial/prospect_store.jsonl
wc -l data/commercial/prospect_batches.jsonl
wc -l data/commercial/contacts_input.jsonl
wc -l data/commercial/discovery_rejections.jsonl
16. Buscar duplicados empresa-país
python - <<'PY'
import json
from collections import Counter
from pathlib import Path

path = Path("data/commercial/prospect_store.jsonl")
pairs = []

for line in path.open(encoding="utf-8"):
    if not line.strip():
        continue
    row = json.loads(line)
    company = row.get("company", {}) or {}
    name = str(company.get("name") or "").strip().lower()
    country = str(company.get("country") or "").strip().lower()
    if name and country:
        pairs.append((name, country))

for pair, count in Counter(pairs).items():
    if count > 1:
        print(count, pair)
PY
17. Backup manual rápido
mkdir -p backups/manual_$(date +%Y%m%d_%H%M%S)
cp -r data/commercial backups/manual_$(date +%Y%m%d_%H%M%S)/
cp -r docs backups/manual_$(date +%Y%m%d_%H%M%S)/
cp -r prodisys/comercial/ui backups/manual_$(date +%Y%m%d_%H%M%S)/

Preferible hacer commit en Git después de cambios estables.

18. Regla de operación segura

Antes de cualquier limpieza:

1. Auditar
2. Inspeccionar
3. Crear backup
4. Ejecutar limpieza
5. Auditar de nuevo
6. Probar UI
19. Estado actual recomendado antes de CRM

Antes de ejecutar CRM real:

python -m compileall prodisys/comercial
python scripts/audit_empty_batches.py
python -m prodisys.comercial.pipeline_runner summary
python -m prodisys.comercial.pipeline_runner push-crm
python -m prodisys.comercial.pipeline_runner crm-dry-run

Solo después:

python -m prodisys.comercial.pipeline_runner crm-execute --confirm