From ed4f7ca97b63164eaee44f49df486738693efb46 Mon Sep 17 00:00:00 2001 From: Munkherdene Date: Sun, 23 Aug 2026 00:26:56 +0800 Subject: [PATCH] fix(web): categorize queue excludes salary/income/transfers (only uncategorized spending) --- src/features/accounting/CategorizeReview.tsx | 5 +++++ src/features/accounting/TransactionList.tsx | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/features/accounting/CategorizeReview.tsx b/src/features/accounting/CategorizeReview.tsx index 80522ea..12a09d8 100644 --- a/src/features/accounting/CategorizeReview.tsx +++ b/src/features/accounting/CategorizeReview.tsx @@ -34,6 +34,11 @@ function buildQueue(txns: Txn[]): ReviewItem[] { const groups = new Map(); for (const t of txns) { if (t.category) continue; // defensive — the fetch already scopes to Uncategorized + // Only uncategorized SPENDING needs sorting. Salary (auto-detected income), + // any income, and transfers between accounts are not expenses to categorize. + if (t.salary === true) continue; + if (t.direction === "income") continue; + if (t.transfer === true) continue; const key = t.matchKey || t.title; if (!key) continue; const amount = parseFloat(t.amount) || 0; diff --git a/src/features/accounting/TransactionList.tsx b/src/features/accounting/TransactionList.tsx index 7439a46..9729d81 100644 --- a/src/features/accounting/TransactionList.tsx +++ b/src/features/accounting/TransactionList.tsx @@ -163,7 +163,15 @@ export function TransactionList() { const categoryOptions = useMemo(() => categoriesIn(all), [all]); const hasUncategorized = useMemo( - () => all.some((txn) => !txn.category && (txn.matchKey || txn.title)), + () => + all.some( + (txn) => + !txn.category && + txn.salary !== true && + txn.transfer !== true && + txn.direction !== "income" && + (txn.matchKey || txn.title), + ), [all], );