diff --git a/CLAUDE.md b/CLAUDE.md index 2b46201..04f917b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -171,6 +171,7 @@ All views carry a `COMMENT ON VIEW` referencing their spec — `\d+ tracksolid.v | FIX-M15 | `ingest_movement_rev.py` | `get_device_locations()` — on-demand precision refresh | | FIX-M16 | `ingest_movement_rev.py` | `distance` from API is metres → divide by 1000 before storing | | FIX-M17 | `ingest_movement_rev.py` | `sync_devices()` ON CONFLICT now updates all 26 fields (was 5) | +| FIX-M18 | `ingest_movement_rev.py` | `sync_devices()` pulls `vehicleName`/`vehicleNumber`/`driverName`/`driverPhone`/`sim` from `jimi.track.device.detail` — list endpoint returns null for these even when set | | FIX-E06 | `ingest_events_rev.py` | Alarm field mapping: `alertTypeId`/`alarmTypeName`/`alertTime` | | BUG-02 | Migration 04 | Historical `distance_m` rows ÷1,000,000 → renamed to `distance_km` | diff --git a/ingest_movement_rev.py b/ingest_movement_rev.py index 67ad1b2..9ccc332 100644 --- a/ingest_movement_rev.py +++ b/ingest_movement_rev.py @@ -30,6 +30,10 @@ REVISIONS (QA-Verified): jimi.device.location.get for up to 50 specific IMEIs on demand. Used for precision refreshes (alarm enrichment, stale device recovery) without waiting for the next full fleet sweep. + [FIX-M18] sync_devices: Pull vehicleName / vehicleNumber / driverName / + driverPhone / sim from jimi.track.device.detail first (list + endpoint returns null for these even when populated via + jimi.open.device.update). ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ """ @@ -134,10 +138,17 @@ def sync_devices(): last_synced_at = NOW(), updated_at = NOW() """, ( + # [FIX-M18] vehicleName/vehicleNumber/driverName/driverPhone/sim + # only surface via jimi.track.device.detail — list returns null. imei, clean(d.get("deviceName")), clean(d.get("mcType")), clean(d.get("mcTypeUseScope")), - clean(d.get("vehicleName")), clean(d.get("vehicleNumber")), clean(d.get("vehicleModels")), clean(d.get("vehicleIcon")), + clean(dtl.get("vehicleName") or d.get("vehicleName")), + clean(dtl.get("vehicleNumber") or d.get("vehicleNumber")), + clean(d.get("vehicleModels")), clean(d.get("vehicleIcon")), clean(dtl.get("vin")), clean(dtl.get("engineNumber")), clean(dtl.get("vehicleBrand")), clean_num(dtl.get("fuel_100km")), - clean(d.get("driverName")), clean(d.get("driverPhone")), clean(d.get("sim")), clean(dtl.get("iccid")), clean(dtl.get("imsi")), + clean(dtl.get("driverName") or d.get("driverName")), + clean(dtl.get("driverPhone") or d.get("driverPhone")), + clean(dtl.get("sim") or d.get("sim")), + clean(dtl.get("iccid")), clean(dtl.get("imsi")), clean(dtl.get("account")), clean(dtl.get("customerName")), clean(d.get("deviceGroupId")), clean(d.get("deviceGroup")), clean_ts(d.get("activationTime")), clean_ts(d.get("expiration")), clean_int(d.get("enabledFlag", 1)), clean(dtl.get("status", "active")), clean_num(dtl.get("currentMileage"))