From 593f529d5d99c7df82bcbce1e48ff990dced36e0 Mon Sep 17 00:00:00 2001 From: SureBot Date: Sun, 5 Apr 2026 15:50:57 +0000 Subject: [PATCH] Add bank statement reconciliation to PDF processor prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add reconciliation check section to PdfProcessor instructions - Extended JSON response to include reconciliation data - Added reconciliation field to PdfProcessingResult Data.define The LLM now uses available tools (GetAccounts, GetTransactions) to: - Match statement to correct account - Compare closing balance with account balance - Compare transaction counts - Match individual transactions (date ±1 day, amount ±sh.10) - Report new and missing transactions Fixes #1379 --- app/models/provider/llm_concept.rb | 2 +- app/models/provider/openai/pdf_processor.rb | 23 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/models/provider/llm_concept.rb b/app/models/provider/llm_concept.rb index c4ee70ef7..febc4a2c4 100644 --- a/app/models/provider/llm_concept.rb +++ b/app/models/provider/llm_concept.rb @@ -19,7 +19,7 @@ module Provider::LlmConcept raise NotImplementedError, "Subclasses must implement #enhance_provider_merchants" end - PdfProcessingResult = Data.define(:summary, :document_type, :extracted_data) + PdfProcessingResult = Data.define(:summary, :document_type, :extracted_data, :reconciliation) def supports_pdf_processing? false diff --git a/app/models/provider/openai/pdf_processor.rb b/app/models/provider/openai/pdf_processor.rb index 1cb63e773..2bace54c6 100644 --- a/app/models/provider/openai/pdf_processor.rb +++ b/app/models/provider/openai/pdf_processor.rb @@ -63,6 +63,14 @@ class Provider::Openai::PdfProcessor - Opening and closing balances (if visible) - Currency used + 4. **Reconciliation Check** (ONLY for bank_statement or credit_card_statement): + - First, use available tools to get accounts and their transactions for the relevant time period + - Match the statement to the correct account by comparing institution name, account holder, or account number + - Compare the statement closing balance with the account current balance + - Count transactions in the statement and compare with synced transaction count for that period + - Match individual transactions (by date within ±1 day, amount within ±$0.10, similar description) + - Report which transactions are new (in statement but not synced) and which are missing (synced but not in statement) + IMPORTANT GUIDELINES: - Be factual and precise - only report what you can clearly see in the document - If information is unclear or redacted, note it as "not clearly visible" or "redacted" @@ -84,6 +92,18 @@ class Provider::Openai::PdfProcessor "closing_balance": number or null, "currency": "USD/EUR/etc or null", "account_holder": "Name or null" + }, + "reconciliation": { + "performed": true|false, + "account_id": "account_id or null", + "balance_match": true|false|null, + "statement_transaction_count": number|null, + "synced_transaction_count": number|null, + "matched_count": number|null, + "new_count": number|null, + "missing_count": number|null, + "new_transactions": [{"date":"YYYY-MM-DD","amount":0.00,"description":"..."}], + "missing_transactions": [{"date":"YYYY-MM-DD","amount":0.00,"description":"..."}] } } INSTRUCTIONS @@ -226,7 +246,8 @@ class Provider::Openai::PdfProcessor PdfProcessingResult.new( summary: parsed["summary"], document_type: normalize_document_type(parsed["document_type"]), - extracted_data: parsed["extracted_data"] || {} + extracted_data: parsed["extracted_data"] || {}, + reconciliation: parsed["reconciliation"] ) end