From 980261632eab8b57a82d2ed13110b422010f82ad Mon Sep 17 00:00:00 2001 From: M1 Date: Wed, 18 Mar 2026 17:17:29 +0400 Subject: [PATCH] fix: deserialize scheduled_at_ms as string or number (postgres bigint serializes as string) --- apps/monitor/src/types.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/apps/monitor/src/types.rs b/apps/monitor/src/types.rs index 74e7dd8..36067e3 100644 --- a/apps/monitor/src/types.rs +++ b/apps/monitor/src/types.rs @@ -1,7 +1,19 @@ -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::HashMap; +// Postgres BIGINT sometimes comes back as a JSON string — handle both +fn deserialize_ms<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { + use serde::de::Error; + let v: Option = Option::deserialize(d)?; + match v { + None => Ok(None), + Some(serde_json::Value::Number(n)) => Ok(n.as_i64()), + Some(serde_json::Value::String(s)) => s.parse::().map(Some).map_err(D::Error::custom), + Some(other) => Err(D::Error::custom(format!("unexpected type for scheduled_at_ms: {other}"))), + } +} + #[derive(Debug, Deserialize)] pub struct Monitor { pub id: String, @@ -13,6 +25,7 @@ pub struct Monitor { pub interval_s: i64, pub query: Option, pub scheduled_at: Option, // ISO string for backward compat in PingResult + #[serde(deserialize_with = "deserialize_ms")] pub scheduled_at_ms: Option, // unix ms from API for precise scheduling pub regions: Option>, }