From 8089a16f484e9150e5fa4125136e81d1b8a8c2d5 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Mon, 20 Apr 2026 09:21:10 -0500 Subject: [PATCH] fix(commercial): decode commercial_links.id as Uuid, not i64 The commercial schema uses uuid primary keys everywhere in this project (all schemas: `@primary_key {:id, :binary_id, autogenerate: true}`), but the Rust port bound SELECTs against commercial_links.id and commercial_samples.link_id as i64. The f00 analysis step failed on first contact with: error occurred while decoding column 0: mismatched types; Rust type `i64` (as SQL type `INT8`) is not compatible with SQL type `UUID` Switched LinkLookupEntry.link_id and fetch_per_link_degradation's parameter to uuid::Uuid, updated the sqlx::query_as tuple type, and patched the test helper to build distinct UUIDs from a byte tag so the no-range / aggregation / rounding tests still exercise the same identity semantics without needing a real DB column. --- rust/prop_grid_rs/src/commercial.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/rust/prop_grid_rs/src/commercial.rs b/rust/prop_grid_rs/src/commercial.rs index 4efbebee..33e07ec8 100644 --- a/rust/prop_grid_rs/src/commercial.rs +++ b/rust/prop_grid_rs/src/commercial.rs @@ -13,6 +13,7 @@ //! and let the scorer fold it in. use sqlx::PgPool; +use uuid::Uuid; const DEFAULT_RADIUS_KM: f64 = 75.0; const DEFAULT_BASELINE_DAYS: i64 = 7; @@ -21,7 +22,7 @@ const MIN_BASELINE_SAMPLES: i64 = 5; #[derive(Debug, Clone)] pub struct LinkLookupEntry { - pub link_id: i64, + pub link_id: Uuid, pub endpoint: (f64, f64), pub baseline_dbm: f64, pub current_dbm: f64, @@ -60,7 +61,7 @@ pub async fn build_link_lookup( // keys. Failures of that assumption are dropped rather than // surfaced — a malformed endpoint is a data-quality issue, not a // chain-blocker. - let link_rows = sqlx::query_as::<_, (i64, serde_json::Value)>( + let link_rows = sqlx::query_as::<_, (Uuid, serde_json::Value)>( r#" SELECT id, endpoint_a FROM commercial_links @@ -98,7 +99,7 @@ fn extract_endpoint(v: &serde_json::Value) -> Option<(f64, f64)> { async fn fetch_per_link_degradation( pool: &PgPool, - link_id: i64, + link_id: Uuid, baseline_cutoff: chrono::DateTime, current_cutoff: chrono::DateTime, valid_time: chrono::DateTime, @@ -204,9 +205,13 @@ fn round2(v: f64) -> f64 { mod tests { use super::*; - fn entry(link_id: i64, lat: f64, lon: f64, baseline: f64, current: f64) -> LinkLookupEntry { + fn entry(n: u8, lat: f64, lon: f64, baseline: f64, current: f64) -> LinkLookupEntry { + // Tests don't care about the actual UUID value, only that each entry + // has a distinct identity — a fixed-byte-0 pattern is plenty. + let mut bytes = [0u8; 16]; + bytes[0] = n; LinkLookupEntry { - link_id, + link_id: Uuid::from_bytes(bytes), endpoint: (lat, lon), baseline_dbm: baseline, current_dbm: current,