From e46ffe6c0652833b684243cf9a50e5d30af4a476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=ADcolas=20Varela=20Auler?= Date: Wed, 18 Dec 2024 00:51:18 -0300 Subject: [PATCH] fix: removing balance from classifier and passing external category (#179) * schema: saving external category to expenses table * feat: using optional external category on classifier * feat: increasing page_size of list transactions from 20 to 100 * sqlx: cargo sqlx prepared for offline queries --- ...d4e2249b3e1b6415ba97febf671770cdf47b4.json | 58 ------------------- ...7a2c61c00a047bdfcfef4302f53878d3be5be.json | 38 ++++++++++++ ...308b742def182c0521111f2b91ed0af1fa0a4.json | 25 ++++++++ ...fe35bdcff8d7eb1335d86fb2d4fe8657f6d83.json | 45 -------------- .../20241218025611_external-category.down.sql | 2 + .../20241218025611_external-category.up.sql | 2 + src/client/classifier.rs | 3 +- src/client/pluggy/transactions.rs | 6 +- src/features/expenses.rs | 2 +- src/queries/expenses.rs | 12 ++-- src/tasks.rs | 4 +- 11 files changed, 81 insertions(+), 116 deletions(-) delete mode 100644 .sqlx/query-14459c299f5108ac575fdb60f3ad4e2249b3e1b6415ba97febf671770cdf47b4.json create mode 100644 .sqlx/query-2dcfe22ca5e08175957d96ca3477a2c61c00a047bdfcfef4302f53878d3be5be.json create mode 100644 .sqlx/query-bece2ad91b1d91a7301d0159f89308b742def182c0521111f2b91ed0af1fa0a4.json delete mode 100644 .sqlx/query-f5eb9b7164e178212ac6e591634fe35bdcff8d7eb1335d86fb2d4fe8657f6d83.json create mode 100644 migrations/20241218025611_external-category.down.sql create mode 100644 migrations/20241218025611_external-category.up.sql diff --git a/.sqlx/query-14459c299f5108ac575fdb60f3ad4e2249b3e1b6415ba97febf671770cdf47b4.json b/.sqlx/query-14459c299f5108ac575fdb60f3ad4e2249b3e1b6415ba97febf671770cdf47b4.json deleted file mode 100644 index 20fb277..0000000 --- a/.sqlx/query-14459c299f5108ac575fdb60f3ad4e2249b3e1b6415ba97febf671770cdf47b4.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT id, description, price, category as \"category: ExpenseCategory\"\n FROM expenses\n WHERE category IS NULL\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "description", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "price", - "type_info": "Float4" - }, - { - "ordinal": 3, - "name": "category: ExpenseCategory", - "type_info": { - "Custom": { - "name": "expense_category", - "kind": { - "Enum": [ - "restaurants", - "shopping", - "services", - "entertainment", - "groceries", - "salary", - "interest Income", - "utilities", - "pharmacy", - "transfer", - "transport", - "others" - ] - } - } - } - } - ], - "parameters": { - "Left": [] - }, - "nullable": [ - false, - false, - false, - true - ] - }, - "hash": "14459c299f5108ac575fdb60f3ad4e2249b3e1b6415ba97febf671770cdf47b4" -} diff --git a/.sqlx/query-2dcfe22ca5e08175957d96ca3477a2c61c00a047bdfcfef4302f53878d3be5be.json b/.sqlx/query-2dcfe22ca5e08175957d96ca3477a2c61c00a047bdfcfef4302f53878d3be5be.json new file mode 100644 index 0000000..942a385 --- /dev/null +++ b/.sqlx/query-2dcfe22ca5e08175957d96ca3477a2c61c00a047bdfcfef4302f53878d3be5be.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "\n SELECT id, description, price, external_category\n FROM expenses\n WHERE category IS NULL\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "description", + "type_info": "Varchar" + }, + { + "ordinal": 2, + "name": "price", + "type_info": "Float4" + }, + { + "ordinal": 3, + "name": "external_category", + "type_info": "Text" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + false, + true + ] + }, + "hash": "2dcfe22ca5e08175957d96ca3477a2c61c00a047bdfcfef4302f53878d3be5be" +} diff --git a/.sqlx/query-bece2ad91b1d91a7301d0159f89308b742def182c0521111f2b91ed0af1fa0a4.json b/.sqlx/query-bece2ad91b1d91a7301d0159f89308b742def182c0521111f2b91ed0af1fa0a4.json new file mode 100644 index 0000000..0328325 --- /dev/null +++ b/.sqlx/query-bece2ad91b1d91a7301d0159f89308b742def182c0521111f2b91ed0af1fa0a4.json @@ -0,0 +1,25 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO expenses\n (description, price, bank_source, external_account_id, external_id, date, uuid, is_essential, user_id, created_at, external_created_at, external_category)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Varchar", + "Float4", + "Text", + "Uuid", + "Uuid", + "Date", + "Uuid", + "Bool", + "Int4", + "Timestamptz", + "Timestamptz", + "Text" + ] + }, + "nullable": [] + }, + "hash": "bece2ad91b1d91a7301d0159f89308b742def182c0521111f2b91ed0af1fa0a4" +} diff --git a/.sqlx/query-f5eb9b7164e178212ac6e591634fe35bdcff8d7eb1335d86fb2d4fe8657f6d83.json b/.sqlx/query-f5eb9b7164e178212ac6e591634fe35bdcff8d7eb1335d86fb2d4fe8657f6d83.json deleted file mode 100644 index 81bc077..0000000 --- a/.sqlx/query-f5eb9b7164e178212ac6e591634fe35bdcff8d7eb1335d86fb2d4fe8657f6d83.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n INSERT INTO expenses\n (description, price, category, bank_source, external_account_id, external_id, date, uuid, is_essential, user_id, created_at, external_created_at)\n VALUES ($1, $2, $3 :: expense_category, $4, $5, $6, $7, $8, $9, $10, $11, $12)\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Float4", - { - "Custom": { - "name": "expense_category", - "kind": { - "Enum": [ - "restaurants", - "shopping", - "services", - "entertainment", - "groceries", - "salary", - "interest Income", - "utilities", - "pharmacy", - "transfer", - "transport", - "others" - ] - } - } - }, - "Text", - "Uuid", - "Uuid", - "Date", - "Uuid", - "Bool", - "Int4", - "Timestamptz", - "Timestamptz" - ] - }, - "nullable": [] - }, - "hash": "f5eb9b7164e178212ac6e591634fe35bdcff8d7eb1335d86fb2d4fe8657f6d83" -} diff --git a/migrations/20241218025611_external-category.down.sql b/migrations/20241218025611_external-category.down.sql new file mode 100644 index 0000000..ecf32fc --- /dev/null +++ b/migrations/20241218025611_external-category.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE expenses + DROP COLUMN external_category; diff --git a/migrations/20241218025611_external-category.up.sql b/migrations/20241218025611_external-category.up.sql new file mode 100644 index 0000000..2105fcb --- /dev/null +++ b/migrations/20241218025611_external-category.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE expenses + ADD COLUMN external_category text; diff --git a/src/client/classifier.rs b/src/client/classifier.rs index f84d82e..0401add 100644 --- a/src/client/classifier.rs +++ b/src/client/classifier.rs @@ -10,8 +10,7 @@ pub struct TransactionToCategorize { pub id: String, pub description: String, pub amount: f32, - pub balance: f32, - pub category: String, + pub category: Option, } #[derive(Deserialize)] diff --git a/src/client/pluggy/transactions.rs b/src/client/pluggy/transactions.rs index 51af2d3..0ac17be 100644 --- a/src/client/pluggy/transactions.rs +++ b/src/client/pluggy/transactions.rs @@ -169,9 +169,13 @@ pub async fn list_transactions( vec![ ("accountId", account_id.to_string()), ("from", last_day.to_string()), + ("pageSize", "100".to_owned()), ] } else { - vec![("accountId", account_id.to_string())] + vec![ + ("accountId", account_id.to_string()), + ("pageSize", "100".to_owned()), + ] }; let client = reqwest::Client::new(); diff --git a/src/features/expenses.rs b/src/features/expenses.rs index 01f2aca..435d86e 100644 --- a/src/features/expenses.rs +++ b/src/features/expenses.rs @@ -92,13 +92,13 @@ pub async fn process_pluggy_expenses( let params = crate::queries::expenses::CreateParamsFromPluggy { description: transaction.description, price: transaction.amount, - category: None, bank: Some(item.connector_name.clone()), external_account_id: transaction.account_id, external_id: transaction.id, external_created_at: transaction.created_at, is_essential: false, date: transaction.date.date(), + external_category: transaction.category, now: OffsetDateTime::now_utc(), }; let res = diff --git a/src/queries/expenses.rs b/src/queries/expenses.rs index 6298178..36b82a8 100644 --- a/src/queries/expenses.rs +++ b/src/queries/expenses.rs @@ -40,7 +40,6 @@ pub async fn create( pub struct CreateParamsFromPluggy { pub description: String, pub price: f32, - pub category: Option, pub bank: Option, pub date: Date, pub now: OffsetDateTime, @@ -48,6 +47,7 @@ pub struct CreateParamsFromPluggy { pub external_id: Uuid, pub external_created_at: Option, pub is_essential: bool, + pub external_category: Option, } pub async fn insert_from_pluggy( @@ -58,12 +58,11 @@ pub async fn insert_from_pluggy( sqlx::query!( r#" INSERT INTO expenses - (description, price, category, bank_source, external_account_id, external_id, date, uuid, is_essential, user_id, created_at, external_created_at) - VALUES ($1, $2, $3 :: expense_category, $4, $5, $6, $7, $8, $9, $10, $11, $12) + (description, price, bank_source, external_account_id, external_id, date, uuid, is_essential, user_id, created_at, external_created_at, external_category) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) "#, p.description, p.price, - p.category as Option, p.bank, p.external_account_id, p.external_id, @@ -73,6 +72,7 @@ pub async fn insert_from_pluggy( user_id, p.now, p.external_created_at, + p.external_category, ) .execute(conn) .await @@ -269,7 +269,7 @@ pub struct UncategorizedTransactions { pub id: i32, pub description: String, pub price: f32, - pub category: Option, + pub external_category: Option, } pub async fn list_uncategorized( @@ -278,7 +278,7 @@ pub async fn list_uncategorized( sqlx::query_as!( UncategorizedTransactions, r#" - SELECT id, description, price, category as "category: ExpenseCategory" + SELECT id, description, price, external_category FROM expenses WHERE category IS NULL "# diff --git a/src/tasks.rs b/src/tasks.rs index 9a554c8..8211c43 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -65,9 +65,7 @@ pub fn categorize_transactions_task( id: row.id.to_string(), description: row.description.clone(), amount: row.price, - balance: 0.0, - // FIX: use external category - category: row.category.clone().unwrap_or_default().to_string(), + category: row.external_category.clone(), }) .collect();