From 2191fe906659f4fd22c25b6cb9fbb95c03472f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elisi=C3=A1rio=20Couto?= Date: Tue, 9 Sep 2025 16:51:26 +0100 Subject: [PATCH] feat: improve notification filters configuration format - Change filters config from nested dict to simple arrays - Update NotificationFilters model to use List[str] instead of Dict[str, str] - Modify notification service to handle list-based filters - Update API routes and tests for new format - Update README with new configuration example Before: [filters.case-insensitive] salary = 'salary' After: [filters] case-insensitive = ['salary', 'utility'] --- README.md | 6 +++--- leggend/api/models/notifications.py | 6 +++--- leggend/api/routes/notifications.py | 2 +- leggend/services/notification_service.py | 23 +++++++++++++++++++---- tests/unit/test_config.py | 7 +++++-- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e1baf6b..a032a74 100644 --- a/README.md +++ b/README.md @@ -114,9 +114,9 @@ chat_id = 12345 enabled = true # Optional: Transaction filters for notifications -[filters.case-insensitive] -salary = "salary" -bills = "utility" +[filters] +case-insensitive = ["salary", "utility"] +case-sensitive = ["SpecificStore"] ``` ## 📖 Usage diff --git a/leggend/api/models/notifications.py b/leggend/api/models/notifications.py index 20541ca..0ffbe38 100644 --- a/leggend/api/models/notifications.py +++ b/leggend/api/models/notifications.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, List +from typing import Optional, List from pydantic import BaseModel @@ -21,8 +21,8 @@ class TelegramConfig(BaseModel): class NotificationFilters(BaseModel): """Notification filters configuration""" - case_insensitive: Dict[str, str] = {} - case_sensitive: Optional[Dict[str, str]] = None + case_insensitive: List[str] = [] + case_sensitive: Optional[List[str]] = None amount_threshold: Optional[float] = None keywords: List[str] = [] diff --git a/leggend/api/routes/notifications.py b/leggend/api/routes/notifications.py index 099a152..fb204e2 100644 --- a/leggend/api/routes/notifications.py +++ b/leggend/api/routes/notifications.py @@ -46,7 +46,7 @@ async def get_notification_settings() -> APIResponse: if (telegram_config.get("token") or telegram_config.get("api-key")) else None, filters=NotificationFilters( - case_insensitive=filters_config.get("case-insensitive", {}), + case_insensitive=filters_config.get("case-insensitive", []), case_sensitive=filters_config.get("case-sensitive"), amount_threshold=filters_config.get("amount_threshold"), keywords=filters_config.get("keywords", []), diff --git a/leggend/services/notification_service.py b/leggend/services/notification_service.py index 2cd0fdb..3d97cd8 100644 --- a/leggend/services/notification_service.py +++ b/leggend/services/notification_service.py @@ -63,14 +63,29 @@ class NotificationService: ) -> List[Dict[str, Any]]: """Filter transactions based on notification criteria""" matching = [] - filters_case_insensitive = self.filters_config.get("case-insensitive", {}) + filters_case_insensitive = self.filters_config.get("case-insensitive", []) + filters_case_sensitive = self.filters_config.get("case-sensitive", []) for transaction in transactions: - description = transaction.get("description", "").lower() + description = transaction.get("description", "") + description_lower = description.lower() # Check case-insensitive filters - for _filter_name, filter_value in filters_case_insensitive.items(): - if filter_value.lower() in description: + for filter_value in filters_case_insensitive: + if filter_value.lower() in description_lower: + matching.append( + { + "name": transaction["description"], + "value": transaction["transactionValue"], + "currency": transaction["transactionCurrency"], + "date": transaction["transactionDate"], + } + ) + break + + # Check case-sensitive filters + for filter_value in filters_case_sensitive: + if filter_value in description: matching.append( { "name": transaction["description"], diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index c26f151..fe696eb 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -188,7 +188,8 @@ class TestConfig: """Test filters configuration access.""" custom_config = { "filters": { - "case-insensitive": {"salary": "SALARY", "bills": "BILL"}, + "case-insensitive": ["salary", "utility"], + "case-sensitive": ["SpecificStore"], "amount_threshold": 100.0, } } @@ -197,5 +198,7 @@ class TestConfig: config._config = custom_config filters = config.filters_config - assert filters["case-insensitive"]["salary"] == "SALARY" + assert "salary" in filters["case-insensitive"] + assert "utility" in filters["case-insensitive"] + assert "SpecificStore" in filters["case-sensitive"] assert filters["amount_threshold"] == 100.0