From dc193e12bfa562096e91b927f6b2bcf377206549 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 26 May 2026 22:02:18 +0800 Subject: [PATCH] 1 --- app/dispatcher.py | 6 +++--- tests/test_dispatcher.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/dispatcher.py b/app/dispatcher.py index 5d27de7..348297b 100644 --- a/app/dispatcher.py +++ b/app/dispatcher.py @@ -25,7 +25,7 @@ class ValidationError(ValueError): def normalize_alert(payload: dict[str, Any]) -> dict[str, Any]: normalized = dict(payload) - normalized["timeframe"] = str(payload.get("timeframe", "")).strip() + normalized["timeframe"] = str(payload.get("timeframe", "")).strip().lower() normalized["symbol"] = str(payload.get("symbol", "")).strip().upper() normalized["strategy"] = str(payload.get("strategy", "")).strip() if "price" in normalized and normalized["price"] not in (None, ""): @@ -139,7 +139,7 @@ class Dispatcher: """ SELECT * FROM routing_rules WHERE enabled = 1 - AND (timeframe = '' OR timeframe = ?) + AND (timeframe = '' OR lower(timeframe) = ?) AND (symbol = '' OR upper(symbol) = ?) AND (strategy = '' OR strategy = ?) AND (timeframe <> '' OR symbol <> '' OR strategy <> '') @@ -175,7 +175,7 @@ class Dispatcher: mismatches = [] if not row["enabled"]: mismatches.append("rule disabled") - if row["timeframe"] and row["timeframe"] != normalized["timeframe"]: + if row["timeframe"] and row["timeframe"].lower() != normalized["timeframe"]: mismatches.append(f"timeframe {normalized['timeframe'] or '-'} != {row['timeframe']}") if row["symbol"] and row["symbol"].upper() != normalized["symbol"]: mismatches.append(f"symbol {normalized['symbol'] or '-'} != {row['symbol']}") diff --git a/tests/test_dispatcher.py b/tests/test_dispatcher.py index 7464685..7cb34b6 100644 --- a/tests/test_dispatcher.py +++ b/tests/test_dispatcher.py @@ -114,6 +114,20 @@ class DispatcherTest(unittest.TestCase): self.assertEqual(result["status"], "queued") self.assertEqual(result["matched_rule_id"], rule_id) + def test_timeframe_match_is_case_insensitive(self) -> None: + target_id = self.add_target() + rule_id = self.add_rule(target_id, timeframe="5m") + + result = self.dispatcher.receive_alert( + {"timeframe": "5M", "symbol": "BTCUSDT", "strategy": "breakout", "action": "buy"} + ) + + with self.db.connect() as conn: + alert = conn.execute("SELECT * FROM alerts WHERE id = ?", (result["alert_id"],)).fetchone() + self.assertEqual(result["status"], "queued") + self.assertEqual(result["matched_rule_id"], rule_id) + self.assertEqual(alert["timeframe"], "5m") + def test_more_specific_rule_wins_when_priority_ties(self) -> None: broad_target = self.add_target("broad") specific_target = self.add_target("specific")