Se unen por
(gateway_msg_id, part_no). La vista cdr_pnl hace un left join entre submit y final,
por lo que los registros aún sin resultado aparecen como PENDING. La exposición en vuelo se
mantiene visible en lugar de excluirse silenciosamente de sus números.
Por qué los acuses de progreso viven en su propia tabla
Un vendor puede enviar varios acuses por un mensaje:ACCEPTD cuando lo toma, BUFFRED mientras
reintenta, y luego DELIVRD o un fallo. Solo el último es un resultado.
Todo lector toma la fila cdr_final más temprana de un mensaje: la lista de mensajes, el
dashboard del portal, las consultas de ingresos y la vista cdr_pnl lo hacen. Por tanto, escribir
acuses de progreso en cdr_final haría que un ACCEPTD prevaleciera sobre el DELIVRD que le
siguió, en toda lista, todo gráfico y el P&L.
El barrido de expiraciones depende de lo mismo: encuentra mensajes sin resolver haciendo anti-join
sobre cdr_final, así que un acuse de progreso allí haría parecer cerrado a un mensaje abierto y
nunca se volvería a revisar.
Las dos tablas también tienen vidas distintas. cdr_final es historia de facturación y vive tanto
como el CDR. cdr_interim es historia de calidad (con qué rapidez informa un vendor, y si informa
en absoluto), que es una pregunta sobre tráfico reciente, por lo que se poda con su propia ventana
más corta (smsg.cdr.interim.retention.days, por defecto 30). Perderla cuesta un informe, no una
factura.
Ambos lados del trato
La tasa, las unidades y el total se registran por separado por lado, porque ambos pueden facturar legítimamente distintos conteos de unidades por un mensaje: un vendor factura por segmento donde usted puede facturar por mensaje.
Para un mensaje concatenado el dinero vive por completo en la parte 1, cuyo coste ya cubre cada
segmento. Los segmentos posteriores son filas de entrega sin dinero. Escribir importes en cada
segmento multiplicaría ambos lados por el número de segmentos.
Un mensaje rechazado no lleva dinero
Cualquier cosa que llegó a un vendor tiene una fila encdr_submit, aceptada o no. Un mensaje que el
vendor rechazó se registra por completo: identidad, tiempos, vendor, direcciones, más una fila
cdr_final y una fila cdr_rejected con el código de estado del vendor.
Pero price, cost y margin son null, porque el crédito del cliente se devolvió en el momento
del rechazo.
Las tres columnas de TLV
Tres puntos en una tubería. Toda pregunta útil es una comparación entre dos de ellos.NULL significa que nada registró la columna; {} significa registrado y no había ninguno.
tlvs_sent es NULL para todo vendor no SMPP.
Leer una tormenta de reintentos
Cada intento contra un vendor deja ahora su propia filacdr_submit — no solo el que finalmente
tuvo éxito o falló de forma terminal. vendor_attempt los numera, submit_status lleva lo que el
vendor realmente dijo en cada uno, y NULL allí significa “no registrado”, no “aceptado”. Vea
Tablas de registros de llamada para la forma exacta.
El cuerpo del mensaje
Se registra solo si lo activa.
Un valor no reconocido se trata como
off: el fallo que importa es almacenar contenido que nadie
pidió almacenar, por lo que un tipo no debe activar la grabación.
Resultados
dlr_state conserva el valor SMPP crudo junto al resultado grueso, porque EXPIRED, REJECTD y
UNDELIV facturan todos como fallos pero vale la pena distinguirlos.
El barrido de expiraciones cierra como EXPIRED cualquier cosa pasada su fecha límite, dejando
que la facturación decida cuánto vale un resultado desconocido. La fecha límite está topada por
debajo de tres días: pasada la ventana de correlación un acuse ya no puede emparejarse aunque
llegue, por lo que esperar más no puede cambiar la respuesta.
Si un mensaje no aparece en ninguna lista
El escritor suele estar apuntando a una base de datos distinta de la del panel. Compruebesmsg.cdr.sink y el FIREFLO_DB_URL de la pasarela frente al METRICS_DATABASE_URL del panel antes
de mirar en cualquier otro sitio.
Relacionado
Uso y retención
Qué sobrevive cuando se purgan los registros de llamada.
Cómo funciona la tarificación
Dónde se liquida cada lado del trato.