From 3ed610054eab879ef2d03e2eadb57ebe20265614 Mon Sep 17 00:00:00 2001 From: piekstra Date: Wed, 29 Jul 2026 13:51:19 -0400 Subject: [PATCH] Read orders from the list that isn't stale after a partial fill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raw-verified against the live API (2026-07-29), same orderId after 1 of 3 tokens filled: GET /orders?propertyId=X -> quantity 3 (the ORIGINAL size, stale) GET /orders?all=true -> quantity 2 (what remains) GET /orders/{id} -> quantity 2 (authoritative, agrees) The property-scoped list keeps reporting the original quantity, so the quote primitives — its only readers — sized and covered against a position that no longer existed: a recenter would re-post the original 3 rather than the remaining 2, quietly re-growing a position a fill had just reduced. Two of three endpoints agree on the remainder, so this is upstream rather than our parsing — confirmed through the raw passthrough before concluding anything, per the LOF-8/9 lesson. fetch_state now uses `all=true` filtered client-side, matching what `account coverage` and `rewards eligibility` already do — which is why those two disagreed with `quote recenter` about the same live order. Claude-Session: https://claude.ai/code/session_01J7bz8aijn2Uwv1yF5rUenW --- src/commands/quote.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/commands/quote.rs b/src/commands/quote.rs index e419eb1..96fb152 100644 --- a/src/commands/quote.rs +++ b/src/commands/quote.rs @@ -254,17 +254,23 @@ fn fetch_state(client: &crate::client::LoftyClient, property_id: &str) -> Result .cloned() }) .ok_or_else(|| CliError::NotFound(format!("no active LP program for {property_id}")))?; + // Deliberately the `all=true` list filtered client-side, NOT the cheaper + // `?propertyId=` query: after a PARTIAL fill the property-scoped list keeps + // reporting the order's ORIGINAL quantity, while `all=true` and the + // single-order GET both report what actually remains (raw-verified 2026-07-29, + // same orderId: 3 vs 2 vs 2). Sizing or covering a quote off the stale number + // works from a position that no longer exists. let mine: Vec = client - .get( - "/public/v1/orders", - &[("propertyId", property_id.to_string())], - )? + .get("/public/v1/orders", &[("all", "true".to_string())])? .get("orders") .and_then(Value::as_array) .cloned() .unwrap_or_default() .into_iter() - .filter(|o| o.get("status").and_then(Value::as_str) == Some("active")) + .filter(|o| { + o.get("status").and_then(Value::as_str) == Some("active") + && o.get("propertyId").and_then(Value::as_str) == Some(property_id) + }) .collect(); let book = client.get( &format!("/public/v1/properties/{property_id}/orderbook"),