From f84a7f2d820f6f432be2b1d78d6bf833b5b19380 Mon Sep 17 00:00:00 2001 From: soryu Date: Fri, 16 Jan 2026 17:07:44 +0000 Subject: Fixup: fix history call and try to start pending tasks when a daemon is available --- makima/src/db/models.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'makima/src/db/models.rs') diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 6accb48..0e1303c 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -6,6 +6,42 @@ use sqlx::FromRow; use utoipa::ToSchema; use uuid::Uuid; +/// Flexible datetime deserialization module. +/// Accepts both date-only ("2026-01-15") and full ISO 8601 datetime ("2026-01-15T00:00:00Z") formats. +pub mod flexible_datetime { + use chrono::{DateTime, NaiveDate, NaiveTime, TimeZone, Utc}; + use serde::{self, Deserialize, Deserializer}; + + /// Deserializes a datetime from either date-only or full datetime format. + pub fn deserialize<'de, D>(deserializer: D) -> Result>, D::Error> + where + D: Deserializer<'de>, + { + let s: Option = Option::deserialize(deserializer)?; + match s { + None => Ok(None), + Some(s) if s.is_empty() => Ok(None), + Some(s) => { + // Try full datetime first (RFC 3339 / ISO 8601) + if let Ok(dt) = DateTime::parse_from_rfc3339(&s) { + return Ok(Some(dt.with_timezone(&Utc))); + } + + // Try date-only format (YYYY-MM-DD) and convert to start of day UTC + if let Ok(date) = NaiveDate::parse_from_str(&s, "%Y-%m-%d") { + let datetime = date.and_time(NaiveTime::MIN); + return Ok(Some(Utc.from_utc_datetime(&datetime))); + } + + Err(serde::de::Error::custom(format!( + "Invalid datetime format '{}'. Expected ISO 8601 datetime (e.g., '2026-01-15T00:00:00Z') or date (e.g., '2026-01-15')", + s + ))) + } + } + } +} + /// TranscriptEntry stored in JSONB - matches frontend TranscriptEntry #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] @@ -1646,7 +1682,9 @@ pub struct ToolCallInfo { pub struct HistoryQueryFilters { pub phase: Option, pub event_types: Option>, + #[serde(default, deserialize_with = "flexible_datetime::deserialize")] pub from: Option>, + #[serde(default, deserialize_with = "flexible_datetime::deserialize")] pub to: Option>, pub limit: Option, pub cursor: Option, -- cgit v1.2.3