2ebc9efeb2
- scratchpad/gen_docs.py - scratchpad/gen_intel.py - scratchpad/gen_verify.py - scratchpad/intel_build.json - scratchpad/intel_lineage.json - scratchpad/lineage_graph.json - scratchpad/trace_intel.py - scratchpad/trace_lineage.py Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
165 lines
8.0 KiB
Python
165 lines
8.0 KiB
Python
"""Genera 05_construccion_clientes_intel/ (SQL CTAS de cada tabla de clientes_intel)
|
|
y 00b_FUENTES_DE_CLIENTE.txt (mapa fuente-de-cliente -> consulta que la lee).
|
|
|
|
Fuente de datos: scratchpad/intel_build.json (SQL de construccion capturado de
|
|
INFORMATION_SCHEMA.JOBS) y scratchpad/intel_lineage.json (tablas implicadas).
|
|
"""
|
|
import json
|
|
import os
|
|
import textwrap
|
|
|
|
DEST = "/mnt/c/Users/egutierrez/Desktop/linaje_customer_marts"
|
|
PROJECT = "autingo-159109"
|
|
builds = json.load(open("scratchpad/intel_build.json"))
|
|
lin = json.load(open("scratchpad/intel_lineage.json"))
|
|
|
|
# Tablas para las que escribimos el SQL de construccion: las del linaje de customer_marts
|
|
# + las que leen fuentes de cliente/Salesforce.
|
|
EXTRA = ["seg_vega_persona", "fact_campana_respuesta__sfnew"]
|
|
want = sorted(set(lin["intel_involved"]) | set(EXTRA))
|
|
want = [t for t in want if t in builds] # solo las que tienen SQL capturado
|
|
|
|
DESC = {
|
|
"_persona_records":
|
|
"IDENTIDAD DEL CLIENTE (nucleo). UNION de 7 fuentes -> normaliza DNI/NIE/CIF, email y "
|
|
"telefono -> resuelve persona_id (FARM_FINGERPRINT de persona_key) con nivel de confianza. "
|
|
"AQUI es donde se juntan TPV customers, customers web, OTR, Navision, citaprevia, users y "
|
|
"Salesforce contacts_latest.",
|
|
"dim_persona":
|
|
"Dimension PERSONA final: una fila por persona_id, elegida desde _persona_records "
|
|
"(prioriza el mejor registro por fuente/confianza) + banderas de contacto.",
|
|
"dim_vehiculo":
|
|
"Dimension VEHICULO: una fila por vehiculo (matricula/bastidor) desde TPV vehicles, OTR, "
|
|
"citaprevia matriculas y calibrado de ano de matricula.",
|
|
"map_persona_fuente":
|
|
"Mapeo persona -> fuente(s) de origen (tpv/web/otr/navision/citaprevia/users/salesforce). "
|
|
"Registra de que sistemas proviene cada persona.",
|
|
"map_persona_vehiculo":
|
|
"Mapeo N:N persona <-> vehiculo (quien conduce/posee que coche) desde OTR, TPV vehicleowner "
|
|
"y citaprevia matriculas.",
|
|
"map_persona_canal8":
|
|
"Mapeo persona -> canal8 (canal de entrada del cliente).",
|
|
"fact_transaccion":
|
|
"Tabla de HECHOS de transaccion (linea/venta por persona). Base de los marts monetarios.",
|
|
"fact_visita":
|
|
"Tabla de HECHOS de visita (visitas del cliente al taller/tienda).",
|
|
"fact_campana_respuesta":
|
|
"HECHOS de respuesta a campanas: cruza envios/aperturas/clics/sms de Salesforce con personas.",
|
|
"fact_campana_respuesta__sfnew":
|
|
"Variante de fact_campana_respuesta con el esquema nuevo de Salesforce (email_sent/opened/clicked/sms).",
|
|
"feat_cliente_persona":
|
|
"Features agregadas por PERSONA (RFM, mix de canal, ticket medio, margen, recencia...).",
|
|
"feat_cliente_vehiculo":
|
|
"Features agregadas por VEHICULO.",
|
|
"seg_cliente_360":
|
|
"Segmentacion 360 del cliente (segmentos/clusters de negocio).",
|
|
"seg_vega_persona":
|
|
"Segmentacion VEGA por persona (contactabilidad/valor); lee fuentes de cliente para calcular "
|
|
"disponibilidad de contacto.",
|
|
"seg_cluster_persona":
|
|
"Clustering de personas (asignacion de cluster) que alimenta la segmentacion.",
|
|
"reco_acciones":
|
|
"Recomendaciones / proxima mejor accion (NBA) por cliente.",
|
|
"data_points_contacto":
|
|
"Puntos de dato de contacto (email/telefono) consolidados y calidad por persona.",
|
|
"_margen_rate_producto":
|
|
"Tasa de margen por producto (auxiliar para features monetarias).",
|
|
"_plate_year_calib":
|
|
"Calibrado del ano a partir de la matricula (auxiliar para dim_vehiculo).",
|
|
"dim_cp_provincia":
|
|
"Diccionario codigo postal -> provincia/CCAA.",
|
|
"tipologia_cliente":
|
|
"Tipologia de cliente (clasificacion de negocio).",
|
|
}
|
|
|
|
# Descripcion corta de cada fuente de cliente.
|
|
SRC_DESC = {
|
|
"psql_dcpublic.tpv_customers": "Clientes del TPV (mostrador). Replica Postgres ANJANA (DCPublic).",
|
|
"psql_dcpublic.customers": "Clientes web (e-commerce). Replica Postgres ANJANA (DCPublic).",
|
|
"psql_dcpublic.otr_customers": "Clientes de OTR (ordenes de reparacion/taller). Replica Postgres ANJANA.",
|
|
"psql_dcpublic.users": "Usuarios (cuentas). Replica Postgres ANJANA (DCPublic).",
|
|
"mssql2022_dbo.anjana_customer": "Cliente de NAVISION (SQL Server 2022, esquema dbo). Campos no_/e_mail/movil/name/post_code.",
|
|
"salesforce_ew1.contacts_latest": "Contactos de SALESFORCE (ultima version). Dataset en europe-west1.",
|
|
"salesforce_ew1.email_sent": "Envios de email de Salesforce (Marketing Cloud).",
|
|
"salesforce_ew1.email_opened": "Aperturas de email de Salesforce.",
|
|
"salesforce_ew1.email_clicked": "Clics de email de Salesforce.",
|
|
"salesforce_ew1.sms": "SMS de Salesforce.",
|
|
"citaprevia_aurphcp.clientes": "Clientes de CITA PREVIA (aurphcp).",
|
|
"citaprevia_aurphcp.clientes_matriculas": "Matriculas por cliente en cita previa.",
|
|
"psql_dcpublic.tpv_vehicles_vehicle": "Vehiculos del TPV. Replica Postgres ANJANA.",
|
|
"psql_dcpublic.tpv_vehicles_vehicleowner": "Propietarios de vehiculo del TPV (N:N). Replica Postgres ANJANA.",
|
|
}
|
|
|
|
CUST_SOURCES = list(SRC_DESC.keys())
|
|
|
|
SEP = "=" * 78 + "\n"
|
|
|
|
def w(path, text):
|
|
full = os.path.join(DEST, path)
|
|
os.makedirs(os.path.dirname(full), exist_ok=True)
|
|
with open(full, "w", newline="\r\n", encoding="utf-8") as f:
|
|
f.write(text)
|
|
|
|
def build_file(tbl):
|
|
b = builds[tbl]
|
|
out = [SEP, f"OBJETO : {PROJECT}.clientes_intel.{tbl}\n",
|
|
f"TIPO : TABLA BASE construida por {b['stmt']} (se reconstruye periodicamente)\n",
|
|
f"ULTIMA EJECUCION CAPTURADA: {b['last_run']}\n", SEP,
|
|
"\nQUE ES\n------\n",
|
|
textwrap.fill(DESC.get(tbl, "(sin descripcion)"), width=78) + "\n"]
|
|
if b["refs"]:
|
|
out.append("\nLEE DE (tablas fuente / intermedias)\n------------------------------------\n")
|
|
for r in b["refs"]:
|
|
note = " << FUENTE DE CLIENTE" if r in SRC_DESC else ""
|
|
out.append(f" - {PROJECT}.{r}{note}\n")
|
|
out.append("\nSQL DE CONSTRUCCION (copiable)\n------------------------------\n\n")
|
|
out.append(b["query"].strip() + "\n")
|
|
return "".join(out)
|
|
|
|
for t in want:
|
|
w(f"05_construccion_clientes_intel/{t}.txt", build_file(t))
|
|
|
|
# 00b_FUENTES_DE_CLIENTE.txt
|
|
f = [SEP, "FUENTES DE CLIENTE -> QUE CONSULTA DE clientes_intel LAS USA\n", SEP,
|
|
"\nResponde a: de donde salen los clientes (TPV, web, OTR, Navision, Salesforce, cita\n"
|
|
"previa) y en que consulta se juntan. El punto de union de identidades es\n"
|
|
"_persona_records (ver 05_construccion_clientes_intel/_persona_records.txt).\n\n"]
|
|
|
|
f.append(SEP + "RESUMEN: LO QUE PEDISTE\n" + SEP + "\n")
|
|
mapping = [
|
|
("TPV customers", "psql_dcpublic.tpv_customers"),
|
|
("customers (web)", "psql_dcpublic.customers"),
|
|
("customers (OTR / taller)", "psql_dcpublic.otr_customers"),
|
|
("users", "psql_dcpublic.users"),
|
|
("customer de NAVISION", "mssql2022_dbo.anjana_customer"),
|
|
("SALESFORCE (contactos)", "salesforce_ew1.contacts_latest"),
|
|
]
|
|
for label, src in mapping:
|
|
f.append(f" {label:26s} -> {PROJECT}.{src}\n")
|
|
f.append("\n SI: tenemos Salesforce. El dataset es `salesforce_ew1` (europe-west1):\n"
|
|
" contactos en contacts_latest; marketing en email_sent/opened/clicked y sms.\n\n")
|
|
|
|
for src in CUST_SOURCES:
|
|
consumers = sorted(t for t, b in builds.items() if src in b["refs"])
|
|
f.append(SEP)
|
|
f.append(f"{PROJECT}.{src}\n")
|
|
f.append(SEP)
|
|
f.append(f" {SRC_DESC[src]}\n")
|
|
f.append(" La leen estas tablas de clientes_intel (con su SQL en 05_construccion_...):\n")
|
|
if consumers:
|
|
for t in consumers:
|
|
star = " [SQL disponible]" if t in want else ""
|
|
f.append(f" - {t} ({builds[t]['stmt']}){star}\n")
|
|
else:
|
|
f.append(" (ninguna la referencia directamente)\n")
|
|
f.append("\n")
|
|
|
|
w("00b_FUENTES_DE_CLIENTE.txt", "".join(f))
|
|
|
|
print("Generado:")
|
|
print(f" 05_construccion_clientes_intel/ -> {len(want)} archivos con SQL de construccion")
|
|
print(f" 00b_FUENTES_DE_CLIENTE.txt")
|
|
print("\nTablas con SQL de construccion escrito:")
|
|
for t in want:
|
|
print(f" - {t}")
|