The interesting part here is deciding when the system should ask a question, not just which question to ask. A bank line with no match could be a missing invoice, a bank fee, or a single payment covering several bills.
I’d probably give each unmatched line a reconciliation state rather than treating every mismatch as a missing-document request. For example, a €2,400 supplier payment could match three invoices of €800, while a €12.50 bank charge might need categorisation rather than a client reminder. Only genuinely unresolved cases would trigger a request, with the confidence level and previous attempts kept in the audit trail.
How are you thinking about duplicate requests and late-arriving documents? If an invoice lands after the reminder has already gone out, the system should ideally close that request automatically instead of asking the client for something they’ve already sent.
Giving each line a state is roughly where I landed too - a €12.50 bank fee should never become a question to the client. The question only goes out for a line that's still unmatched after the obvious stuff is ruled out (fees, transfers between the client's own accounts, one payment covering several invoices).
On late documents, the request belongs to the bank line, so the reminder should read the line's state at the moment it's about to go out, instead of being scheduled once and fired regardless. If the invoice arrived and got matched in the meantime, the line is already closed and nothing gets sent. The part I don't have an answer for yet is that the invoice lands in the practice's own intake, not in my tool, so I need to see that match happen somewhere I can read it. Until then, the fallback is a reminder that says exactly which line it's about, so a client who already sent it can just say so.
None of this is built yet, so treat it as the plan.
One edge case worth considering is a race condition between reconciliation and the reminder queue. Imagine a €7,860 supplier transfer that initially matches three invoices, but a fourth invoice arrives in the accounting system just before the reminder is sent. If the matching result and notification job operate on different snapshots, you could end up requesting a document that has already been accounted for.
I'd consider making the reminder conditional on the bank line's current version, with an idempotency key to prevent duplicate sends and a final reconciliation check immediately before dispatch. If the accounting practice can't expose match events, even a periodic sync with a clear last-checked timestamp would make the fallback more reliable. That also gives you a useful distinction between genuinely unresolved lines and lines whose status is simply stale.
The tricky part isn't just deciding whether to ask, but making sure the decision is still valid when the question actually reaches the client.
The interesting part here is deciding when the system should ask a question, not just which question to ask. A bank line with no match could be a missing invoice, a bank fee, or a single payment covering several bills.
I’d probably give each unmatched line a reconciliation state rather than treating every mismatch as a missing-document request. For example, a €2,400 supplier payment could match three invoices of €800, while a €12.50 bank charge might need categorisation rather than a client reminder. Only genuinely unresolved cases would trigger a request, with the confidence level and previous attempts kept in the audit trail.
How are you thinking about duplicate requests and late-arriving documents? If an invoice lands after the reminder has already gone out, the system should ideally close that request automatically instead of asking the client for something they’ve already sent.