Operaciones
Combustible (ingesta)

Ingesta de combustible

Registra las cargas de combustible de la flota. El endpoint es genérico: no asume ningún proveedor de tarjetas. Cualquier cliente, con cualquier sistema de control de combustible, escribe acá — el proveedor entra como el valor del campo source_system.

Sobre estos datos corren las reglas de alerta de consumo (rendimiento fuera de rango, carga mayor que el tanque, odómetro incoherente y carga fuera de horario).

POST/transportes/sync/fuel-transactions

Ingesta idempotente de transacciones de combustible, en lotes de hasta 500.

Caso de uso

Un sistema externo lee periódicamente las transacciones de su proveedor de combustible, las normaliza a esta forma y las envía. Reenviar el mismo rango no duplica: la llave de idempotencia es (tenant, source_system, source_id).

Campos del payload

Raíz

CampoTipoRequeridoDescripción
source_systemstring (≤30)Sistema de origen. Se normaliza a minúsculas.
transactionsarrayEntre 1 y 500 ítems. Más de 500 → 400.

Cada transacción

Requeridos

CampoTipoDescripción
source_idstring (≤128)Identificador estable de la transacción en el sistema de origen. Es la llave de idempotencia.
platestring (≤20)Placa del vehículo. Se normaliza a mayúsculas y sin espacios ni guiones: pb-0001, PB 0001 y PB0001 ligan al mismo vehículo.
occurred_atstring ISO 8601Fecha y hora de la carga con offset UTC explícito (Z o ±HH:MM). Sin offset → 400.
volume_litersnumberLitros cargados. Debe ser mayor que 0.
raw_payloadobjectRegistro original del sistema de origen, para trazabilidad.

Opcionales

CampoTipoDescripción
unit_pricenumberPrecio por litro
amountnumberMonto total
product_namestring (≤60)Producto (DIESEL, SUPER, …)
odometer_reportednumberOdómetro reportado en el surtidor
station_namestring (≤120)Estación de servicio
station_addressstring (≤255)Dirección de la estación (texto)
driver_name_reportedstring (≤120)Nombre del conductor según el origen. No es una referencia al catálogo de conductores.
card_number_maskedstring (≤30)Número de tarjeta ya enmascarado

Dato personal: no envíes documentos de identidad. Si el campo CITIZEN_ID viene dentro de raw_payload, Smartfleet lo descarta — no se guarda en ninguna columna ni dentro del payload crudo.

Respuesta — los cuatro contadores

Los cuatro son disjuntos y suman received.

ContadorSignificado
receivedÍtems recibidos en el lote.
insertedTransacciones nuevas que se ligaron a un vehículo por placa.
duplicatesÍtems cuyo source_id ya existía para ese source_system. No es un error: se cuenta y se sigue.
quarantinedTransacciones nuevas cuya placa no coincide con ningún vehículo. No se pierden: se guardan con el vehículo vacío y se pueden religar después.

Request

{
  "source_system": "fleetmagic",
  "transactions": [
    {
      "source_id": "a3f1c8e2b7d9",
      "plate": "PB0001",
      "occurred_at": "2026-08-12T16:07:07-06:00",
      "volume_liters": 20.0,
      "unit_price": 2.0,
      "amount": 40.0,
      "product_name": "DIESEL",
      "odometer_reported": 15000,
      "station_name": "ESTACION 1",
      "station_address": "DIRECCION",
      "driver_name_reported": "CONDUCTOR 1",
      "raw_payload": { "REFERENCE": "000123456" }
    }
  ]
}

Response

{
  "ok": true,
  "code": "SYNC_OK",
  "message": "Sync processed successfully.",
  "data": {
    "received": 50,
    "inserted": 47,
    "duplicates": 2,
    "quarantined": 1
  },
  "meta": {
    "route": "/transportes/sync/fuel-transactions",
    "method": "PostFuelTransactionsSync",
    "operation": "ingest",
    "source_system": "fleetmagic"
  }
}

Reenvío del mismo lote (idempotencia)

{
  "received": 50,
  "inserted": 0,
  "duplicates": 50,
  "quarantined": 0
}

Errores

Todos los errores de validación abortan el lote entero — no hay ingesta parcial.

SituaciónRespuesta
volume_liters menor o igual que 0400 CAPTURED_ERROR: Validation error: …
source_id ausente o vacío400 CAPTURED_ERROR: Validation error: …
occurred_at sin offset UTC400 CAPTURED_ERROR: Validation error: … (tenant timezone is '…')
occurred_at con una fecha que no existe (2026-13-45T…, 2026-02-31T…)400 CAPTURED_ERROR: Validation error: occurred_at is not a real calendar date-time.
Un numérico que no cabe en la columna (odometer_reported de 15 dígitos)400 CAPTURED_ERROR: Validation error: …
raw_payload ausente400 CAPTURED_ERROR: Validation error: …
Más de 500 transacciones400 CAPTURED_ERROR: Validation error: …

Un lote con muchos ítems inválidos devuelve los primeros 20 problemas y un contador del resto (… (+380 more)): el mensaje está acotado a propósito para que la respuesta siga siendo un 400 legible.

El mensaje de occurred_at incluye la zona horaria configurada del cliente: es la zona con la que hay que estampar el offset cuando el sistema de origen reporta la fecha y la hora por separado y sin zona.

Cuarentena

Una transacción cuya placa no existe en el catálogo de vehículos no se rechaza y no se pierde: se guarda con el vehículo vacío y marcada como unmatched_vehicle, con la placa tal cual llegó. Al dar de alta el vehículo con esa placa, esas transacciones se pueden religar.

Perder consumo real es peor que guardar un registro huérfano.

Reglas de alerta que corren sobre estos datos

Se configuran como cualquier otra regla del motor de alertas (tipo de regla + parámetros + destinatarios). Ninguna nombra a un proveedor.

Tipo de reglaDispara cuandoParámetros
FUEL_EFFICIENCY_OUT_OF_RANGEEl km/l de una carga se desvía del baseline del vehículo (mediana de sus cargas previas) más que la toleranciamin_samples (5), tolerance_pct (30)
FUEL_VOLUME_EXCEEDS_TANKLos litros cargados superan la capacidad del tanque más el margen. Los vehículos sin capacidad cargada se omitenmargin_pct (5)
FUEL_ODOMETER_INCONSISTENTEl odómetro retrocede, salta más de lo posible, o no avanza entre dos cargasmax_km_jump (2000)
FUEL_TRANSACTION_OFF_HOURSLa carga ocurre fuera de la jornada, en la hora local del cliente. La ventana puede cruzar la medianoche (turno nocturno)start_hour (6), end_hour (18), weekend_is_off (true)

La regla de rendimiento evalúa todas las cargas de la ventana, no sólo la última: una carga anómala seguida de una normal igual genera su alerta.