🏢 Caso Práctico Real: Ingeniero de Datos y Aseguramiento de Ingresos (Telco)
1. 📌 Planteamiento del Problema de Negocio (Escenario Real)
Contexto de la Empresa
Una compañía de Telecomunicaciones móvil y fija con operaciones regionales (Chile, Perú, Colombia) ofrece planes móviles pospago y bolsas de datos adicionales.
La Fuga de Ingresos Detectada (The Leakage Issue)
Durante el cierre financiero mensual, el área de Contabilidad reporta una discrepancia no explicada de $45.000.000 CLP entre el volumen de datos de alta velocidad consumido en las antenas/nodos de red y lo efectivamente cobrado en el sistema de facturación (Billing).
flowchart TD
A["📡 Red Móvil (HSS/PCRF/CDRs)<br>Tráfico Real de Datos"] -->|Falta de Sincronización| D{"❌ Fuga de Ingresos<br>($45M CLP / mes)"}
B["💼 CRM de Clientes<br>Planes y Estados (Activo/Baja)"] -->|Error en API / Cola de Mensajes| D
C["💳 Sistema de Facturación<br>Cargos Emitidos"] -->|Subfacturación| D
D --> E["🔧 Ingeniero de Datos y RA<br>Pipeline Automatizado de Conciliación"]
Causas Raíz Identificadas:
- Tráfico Fantasma (Ghost Traffic): 1.420 líneas dadas de baja o suspendidas por morosidad en el CRM siguen navegando en la red porque el aprovisionador de red (HLR/PCRF) no procesó la orden de corte debido a timeouts en la API.
- Subtarificación de Bolsas Adicionales: Clientes que superaron su cuota de gigas contratada consumieron bolsas de emergencia automáticas que el sistema de facturación no liquidó en el ciclo de corte.
- Ineficiencia Operativa: El equipo de Control de Gestión realiza este cruce manualmente los lunes descargando 3 Excels de 500.000 filas, demorando 14 horas/hombre semanales con alto margen de error humano.
2. ⚙️ Procedimientos Técnicos y Operativos Implementados
Como Ingeniero de Datos y Aseguramiento de Ingresos, se implementa una solución integral estructurada en 5 etapas:
[1. Ingesta ETL] ──> [2. Motor de Cruce] ──> [3. Alertas & Tickets] ──> [4. Power BI Dashboard] ──> [5. Documentación SOP]
Etapa 1: Ingesta Automatizada y Normalización (ETL)
- Frecuencia: Diaria a las 02:00 AM (Job programado desatendido).
- Fuentes de Datos:
- Base de datos transaccional del CRM (PostgreSQL / Oracle).
- Data Lake / Servidor SFTP de registros de tráfico de red (CDRs en formato parquet/csv).
- Base de datos del ERP de Facturación (SAP / NetSuite / Billing Engine).
Etapa 2: Motor de Reconciliación Automatizada (Python + SQL)
A continuación, el script productivo desarrollado para cruzar las 3 fuentes y detectar fugas:
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from datetime import datetime, timedelta
import pandas as pd
import sqlalchemy as sa
# 1. Conexiones a bases de datos
ENGINE_DW = sa.create_engine("postgresql://user:pass@dw-telco.internal:5432/revenue_db")
def ejecutar_conciliacion_diaria():
fecha_proceso = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
print(f"[{datetime.now()}] Iniciando conciliación para la fecha: {fecha_proceso}")
# 2. Query de Reconciliación de 3 vías (Red vs CRM vs Facturación)
query = f"""
WITH ConsumoRed AS (
SELECT
numero_linea,
SUM(gigas_consumidos) AS total_gb_red,
MAX(ultima_conexion) AS ultima_actividad_red
FROM raw_cdrs_trafico
WHERE fecha_evento = '{fecha_proceso}'
GROUP BY numero_linea
),
EstadoCRM AS (
SELECT
numero_linea,
cliente_id,
pais,
plan_nombre,
estado_linea, -- 'ACTIVO', 'SUSPENDIDO', 'BAJA'
limite_gb_plan,
tarifa_base_clp,
precio_gb_adicional_clp
FROM dim_clientes_lineas
),
FacturacionDia AS (
SELECT
numero_linea,
SUM(monto_cargo_adicional) AS cobro_adicional_facturado
FROM fact_cargos_diarios
WHERE fecha_cargo = '{fecha_proceso}'
GROUP BY numero_linea
)
SELECT
c.pais,
c.cliente_id,
c.numero_linea,
c.plan_nombre,
c.estado_linea,
COALESCE(r.total_gb_red, 0) AS gb_consumidos_red,
c.limite_gb_plan,
COALESCE(f.cobro_adicional_facturado, 0) AS cobrado_en_factura,
-- Regla 1: Tráfico en línea cancelada/suspendida
CASE
WHEN c.estado_linea IN ('SUSPENDIDO', 'BAJA') AND COALESCE(r.total_gb_red, 0) > 0.05
THEN 'FUGA_LINEA_NO_HABILITADA'
-- Regla 2: Sobreconsumo no facturado
WHEN COALESCE(r.total_gb_red, 0) > c.limite_gb_plan
AND COALESCE(f.cobro_adicional_facturado, 0) < ((COALESCE(r.total_gb_red, 0) - c.limite_gb_plan) * c.precio_gb_adicional_clp)
THEN 'FUGA_SUBFACTURACION_DATOS'
ELSE 'CORRECTO'
END AS clasificacion_fuga,
-- Cálculo económico del impacto
CASE
WHEN c.estado_linea IN ('SUSPENDIDO', 'BAJA') AND COALESCE(r.total_gb_red, 0) > 0
THEN (COALESCE(r.total_gb_red, 0) * c.precio_gb_adicional_clp)
WHEN COALESCE(r.total_gb_red, 0) > c.limite_gb_plan
THEN ((COALESCE(r.total_gb_red, 0) - c.limite_gb_plan) * c.precio_gb_adicional_clp) - COALESCE(f.cobro_adicional_facturado, 0)
ELSE 0
END AS monto_fuga_estimado_clp
FROM EstadoCRM c
LEFT JOIN ConsumoRed r ON c.numero_linea = r.numero_linea
LEFT JOIN FacturacionDia f ON c.numero_linea = f.numero_linea;
"""
df_resultado = pd.read_sql(query, ENGINE_DW)
# 3. Filtrar únicamente las inconsistencias
df_fugas = df_resultado[df_resultado['clasificacion_fuga'] != 'CORRECTO'].copy()
# Guardar en base de datos para consumo de Power BI
df_resultado.to_sql("fact_conciliacion_aseguramiento", ENGINE_DW, if_exists="append", index=False)
print(f"Procesadas {len(df_resultado):,} líneas. Fugas detectadas: {len(df_fugas):,}")
return df_fugas
if __name__ == "__main__":
ejecutar_conciliacion_diaria()
3. 📊 Salidas y Entregables Concretos (Outputs)
Output 1: Reporte Operativo de Discrepancias (CSV / Base de Datos)
El pipeline genera una tabla limpia con los registros accionables para auditoría y corrección inmediata:
| Pais | Cliente_ID | Numero_Linea | Plan | Estado_CRM | GB_Red | Limite_GB | Facturado | Clasificacion_Fuga | Monto_Fuga_CLP |
|---|---|---|---|---|---|---|---|---|---|
| CL | CLT-88912 | +56984123456 | Pro 5G 50GB | SUSPENDIDO |
14.2 GB | 50.0 GB | $0 | FUGA_LINEA_NO_HABILITADA |
$28.400 |
| CL | CLT-10294 | +56976543210 | Flexible 30GB | ACTIVO |
48.5 GB | 30.0 GB | $0 | FUGA_SUBFACTURACION_DATOS |
$37.000 |
| PE | CLT-55120 | +51912345678 | Ilimitado Red | BAJA |
8.1 GB | 20.0 GB | $0 | FUGA_LINEA_NO_HABILITADA |
$16.200 |
Output 2: Alerta Automática de Incidencia a Equipos Clave (Payload JSON / Webhook)
Cuando el script detecta un volumen de fuga superior al umbral crítico (> $5.000.000 CLP diarios), envía un payload a la API de ServiceNow / Jira Service Desk para aislar el problema de red:
{
"incident_type": "REVENUE_LEAKAGE_CRITICAL",
"source_system": "Revenue_Assurance_Bot",
"timestamp": "2026-08-15T03:15:00Z",
"affected_lines_count": 1420,
"estimated_daily_loss_clp": 8750000,
"assigned_group": "Telecom_Core_Network_Provisioning",
"priority": "P1_HIGH",
"summary": "Desincronización PCRF vs CRM: 1.420 líneas suspendidas continúan consumiendo datos de red.",
"recommended_action": "Ejecutar script de purga de sesiones activas en HSS/PCRF Nodo Huechuraba."
}
Output 3: Dashboard Operacional en Power BI
A. Arquitectura del Modelo de Datos (Star Schema):
- Tabla de Hechos:
Fact_Conciliacion_Aseguramiento(Millones de registros de consumo y cruce). - Tablas de Dimensiones:
Dim_Calendario,Dim_Paises,Dim_Planes,Dim_Tipos_Fuga.
B. Métricas DAX Clave Implementadas:
// 1. Fuga Total Acumulada ($)
Monto Fuga Total CLP =
SUM(Fact_Conciliacion_Aseguramiento[Monto_Fuga_Estimado_CLP])
// 2. Tasa de Fuga Operacional (%)
% Fuga sobre Facturacion =
DIVIDE(
[Monto Fuga Total CLP],
SUM(Fact_Conciliacion_Aseguramiento[Cobrado_En_Factura]) + [Monto Fuga Total CLP],
0
)
// 3. Eficacia de Recuperación / SLA de Corrección
% Discrepancias Resueltas < 24h =
DIVIDE(
CALCULATE(COUNTROWS(Fact_Conciliacion_Aseguramiento), Fact_Conciliacion_Aseguramiento[Horas_Resolucion] <= 24),
COUNTROWS(Fact_Conciliacion_Aseguramiento),
0
)
C. Distribución Visual del Dashboard:
- Header: Tarjetas KPI con semáforos (Fuga del mes vs. Meta tolerable < 0.5%, Líneas afectadas, Ahorro recuperado).
- Gráfico Central: Tendencia diaria de fugas desglosadas por tipo (Subfacturación, Línea No Habilitada, Error de Tarifa).
- Selector Regional: Filtro interactivo por país (Chile / Perú / Colombia).
- Tabla de Acción Rápida (Drill-Down): Exportable con un clic para el equipo de Facturación con los IDs y números de línea afectados.
Output 4: Documentación de Gobernanza (Ficha Técnica de KPI y SOP)
Ficha Técnica de Respaldo del KPI
- Identificador:
KPI-RA-TELCO-01 - Nombre: Tasa de Fuga de Ingresos por Tráfico No Liquidado.
- Propietario: Subgerencia de Aseguramiento de Ingresos y Control de Gestión.
- Periodicidad: Diaria (Corte acumulado mensual al día 28 de cada mes).
- Fórmula Auditable:
(Total_Ingresos_Esperados - Total_Ingresos_Facturados) / Total_Ingresos_Esperados.
Procedimiento Operativo Estándar (SOP - Troubleshooting)
- Si falla el pipeline de las 02:00 AM:
- Verificar en el log
/var/log/ra_pipeline.logsi hubo caída de la VPN hacia el SFTP de CDRs. - Ejecutar contingencia manual:
python conciliacion.py --fecha YYYY-MM-DD --forzar-recarga. - Si las discrepancias aumentan en más de 20% vs. día anterior:
- Validar con el equipo Comercial si hubo lanzamiento de un nuevo plan o cambio en la tabla de tarifas no notificado.
4. 📈 Impacto y Retorno de Inversión (ROI) del Proyecto
| Indicador | Antes del Proyecto (Manual) | Después del Proyecto (Automatizado) | Beneficio Concreto |
|---|---|---|---|
| Tiempo de Ejecución | 14 horas semanales (Lunes completos en Excel) | 8 minutos (Job desatendido nocturno) | 98% de reducción de tiempo (Liberación de horas analista) |
| Detección de Fugas | Al día 30 (Al cierre contable, cuando ya no se puede cobrar) | Diaria (En menos de 24 horas) | Detección temprana antes de emitir la boleta |
| Impacto Financiero | Pérdida de ~$45M CLP / mes | Recuperación y corrección de ~$38.5M CLP / mes | ROI inmediato de más de 10x el costo del cargo |
| Calidad y Auditoría | Archivos Excel dispersos y propensos a manipulación | Base de datos centralizada, auditable y en Power BI | Cumplimiento normativo y gobernanza de datos |