Phase 4: Transaction Matching #46
Labels
No Label
architecture
backend
bug
feature
frontend
priority:critical
priority:high
priority:low
priority:medium
priority:nice-to-have
ux
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: null/BillTracker#46
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Let users match imported or manually entered transactions to bills. This connects transaction data to bill status, but only after user confirmation. No auto-marking.
Depends on: Phase 1 (#43 ✅), Phase 2 (#44 ✅)
Blocks: Phase 5 (#47)
Parent: #42
✅ All Acceptance Criteria Verified
POST /api/transactions/:id/matchwith{ billId }viatransactionMatchService.matchTransactionToBill()POST /api/transactions/:id/unmatchviatransactionMatchService.unmatchTransaction(), restores balance deltaPOST /api/transactions/:id/ignoreviatransactionMatchService.ignoreTransaction(), setsmatch_status = "ignored"POST /api/transactions/:id/unignoreviatransactionMatchService.unignoreTransaction(), resets tomatch_status = "unmatched"GET /api/matches/suggestionsviamatchSuggestionService.listMatchSuggestions()is read-only (no writes), scores by amount/date/name proximity, minimum score threshold of 20computeBalanceDelta()called on match,current_balanceupdated on bills tablerestorePaymentBalance()reverses the balance delta, recalculatespayment_source = "manual") untouchedImplementation Details
Backend
services/transactionMatchService.js— match, unmatch, ignore, unignore withdb.transaction()wrappers, proper balance trackingservices/matchSuggestionService.js— scoring engine (amount + date + name + prior match), rejections tableroutes/matches.js—GET /suggestions,POST /:id/rejectroutes/transactions.js—POST /:id/match,POST /:id/unmatch,POST /:id/ignore,POST /:id/unignoredb/database.js— v0.61 (payment transaction active index), v0.62 (match_suggestion_rejections table)Frontend
client/pages/DataPage.jsx—MatchBillDialogmodal,SuggestedMatchesPanel, filter tabs (Unmatched/Matched/Ignored), action buttonsclient/api.js—matchTransaction,unmatchTransaction,ignoreTransaction,unignoreTransaction,matchSuggestions,rejectMatchSuggestionMatching Rules
matched_bill_id,match_status = "matched", creates payment withpayment_source = "transaction_match", updatescurrent_balancematched_bill_id, setsmatch_status = "unmatched", soft-deletes or unlinks payment, restores balanceignored = 1,match_status = "ignored", clears match, unlinks paymentPrevious → Phase 3 (#45 ✅)
Next → Phase 5 (#47)