Most finance problems don't announce themselves. They sit quietly in a reconciliation that's been "close enough" for eight months, or in a vendor record nobody's touched since the person who set it up left. Then something breaks — a payment goes to the wrong account, a customer gets double-billed, an auditor asks a question you can't answer — and suddenly it's a fire drill.
A finance health check done properly, over one focused week, catches most of that before it becomes a crisis. Not a vague "let's review our processes" exercise, but a day-by-day diagnostic where you run specific queries, score what you find, rank it, and hand each item to a named person with a deadline.
This is the version I'd actually run. Sample SQL, a severity rubric, a prioritization matrix, and a 30-day remediation roadmap with owner assignments. You can compress it into three days if your data's clean, or stretch it across two weeks if you keep getting pulled into other things. The sequence matters more than the calendar.
Why one week, and why this order
The temptation is to boil the ocean — pull every report, audit every account, question every process. That's how these reviews die. People spend four days on the general ledger structure and never get to the bank reconciliation that's actually leaking money.
The one-week format forces triage. Each day targets a specific risk category, you capture findings in a running log, and you don't stop to fix anything until Friday. Diagnosis first, treatment second. Mixing them is the classic mistake — you find one duplicate payment, spend two hours chasing it, and lose the thread on everything else.
The order below runs from "most likely to be actively losing you cash" to "structural stuff that hurts later." If you only get three days in, you'll still have covered the expensive parts.
The daily diagnostic
Day 1 — Cash and bank reconciliation integrity
Stop letting accounting slow your business down.
Acctaly automates your financial operations so you can focus on growth and compliance.
- Automated bookkeeping
- Real-time financial reporting
- Integrated tax management
No credit card required
Start where money physically moves. The first question isn't "are we profitable" — it's "does our recorded cash match reality, and how long have the gaps been sitting there."
Pull unreconciled items and stale reconciling entries. Anything aging past 60 days on a bank rec is a red flag. It usually means either a real error nobody chased or a bookkeeping shortcut that's been rolled forward.
-- Stale unreconciled bank transactions SELECT accountid, txndate, description, amount, DATEDIFF(CURRENTDATE, txndate) AS daysoutstanding FROM banktransactions WHERE reconciled = 0 AND DATEDIFF(CURRENTDATE, txndate) > 30 ORDER BY days_outstanding DESC;
What shows up repeatedly: a handful of "in transit" items that have been in transit for 90+ days. Those aren't timing differences anymore — they're errors that got a polite label.
Day 2 — Duplicate and suspicious payments
Day 2 is about money going out the door twice, or going somewhere it shouldn't. This overlaps with fraud detection, but the framing is different — here you're catching operational sloppiness as much as bad actors.
-- Potential duplicate vendor payments SELECT vendorid, amount, invoicenumber, COUNT() AS paymentcount, MIN(paymentdate) AS firstpaid, MAX(paymentdate) AS lastpaid FROM appayments GROUP BY vendorid, amount, invoicenumber HAVING COUNT() > 1;
A softer version catches near-duplicates — same vendor, same amount, invoice numbers off by a character, paid a few days apart. Those slip through exact-match checks constantly. If you want the deeper set of anomaly queries for this — round-dollar clusters, weekend postings, sequential invoice gaps — the fraud-detection queries every bookkeeping team should run weekly go well beyond simple duplicate matching and pair nicely with this day.
Day 3 — Accounts receivable and revenue leakage
Now flip to money that should be coming in. Two things to check: aging that's drifted, and revenue that was earned but never billed.
-- AR aging buckets with concentration flag SELECT customerid, SUM(CASE WHEN DATEDIFF(CURRENTDATE, duedate) BETWEEN 1 AND 30 THEN balance ELSE 0 END) AS bucket30, SUM(CASE WHEN DATEDIFF(CURRENTDATE, duedate) BETWEEN 31 AND 60 THEN balance ELSE 0 END) AS bucket60, SUM(CASE WHEN DATEDIFF(CURRENTDATE, duedate) > 90 THEN balance ELSE 0 END) AS bucket90plus, SUM(balance) AS totalopen FROM arinvoices WHERE status = 'open' GROUP BY customerid HAVING bucket90plus > 0 ORDER BY bucket90plus DESC;
The pattern worth watching isn't just the 90+ bucket — it's a single customer sitting in it. Concentration in overdue AR is a much sharper warning than a spread of small late payments. One customer at 60% of your overdue balance is a cash-flow event waiting to happen.
Day 4 — Journal entries and manual adjustments
Manual journal entries are where the ledger gets quietly bent. You're looking for entries that are large, round, posted at odd times, or missing descriptions entirely.
-- High-risk manual journal entries SELECT jeid, postedby, posteddate, account, amount, memo FROM journalentries WHERE entrytype = 'manual' AND ( amount = ROUND(amount, -3) -- suspiciously round OR memo IS NULL OR EXTRACT(DOW FROM posteddate) IN (0, 6) -- weekend posting ) ORDER BY amount DESC;
A blank memo on a $12,000 manual entry isn't automatically fraud, but it's automatically a question. In practice, the worst discoveries here tend to be recurring "cleanup" entries someone made to force a subledger to tie — same account, same person, every month, no explanation.
Day 5 — Vendor and master-data hygiene
Bad master data causes downstream errors for months. Check for duplicate vendors, missing tax IDs, and bank details that match employee records.
-- Duplicate or incomplete vendor records SELECT vendorname, COUNT() AS recordcount, STRINGAGG(vendorid::text, ', ') AS ids, SUM(CASE WHEN taxid IS NULL THEN 1 ELSE 0 END) AS missingtaxids FROM vendors WHERE active = 1 GROUP BY vendorname HAVING COUNT() > 1 OR SUM(CASE WHEN tax_id IS NULL THEN 1 ELSE 0 END) > 0;
Two vendor records for the same supplier is how a duplicate payment happens in the first place — the two invoices route to two records and never collide on a match. This day feeds directly back into Day 2.
Day 6 — Chart of accounts and mapping drift
Look for expenses landing in wrong accounts, catch-all "Miscellaneous" buckets that keep growing, and accounts with activity that shouldn't have any.
-- Accounts absorbing too much unclassified activity SELECT accountname, COUNT(*) AS txncount, SUM(ABS(amount)) AS totalactivity FROM glentries e JOIN accounts a ON a.accountid = e.accountid WHERE a.accountname ILIKE ANY (ARRAY['%misc%', '%suspense%', '%other%', '%ask accountant%']) AND e.period = 'current' GROUP BY accountname ORDER BY total_activity DESC;
A suspense account that only ever grows is a sign nobody's clearing it. When "Miscellaneous Expense" is your third-largest expense line, your P&L isn't telling you anything useful.
Day 7 — Compile, score, and rank
No new queries today. Take everything in the findings log and score it. This is the day the diagnostic becomes a plan instead of a pile of observations.
Scoring what you found
Every finding gets two numbers: severity (how bad if it's real) and likelihood/spread (how confident you are it's real, and how widespread). Multiply them for a priority score.
Severity rubric
| Severity | Score | What it looks like |
|---|---|---|
| Critical | 5 | Active cash loss, likely fraud exposure, or a control gap an auditor would flag hard |
| High | 4 | Material misstatement risk, recurring error, or something touching regulatory/tax accuracy |
| Medium | 3 | Localized error, moderate dollar impact, fixable without process change |
| Low | 2 | Cosmetic or classification issue with no cash impact |
| Noise | 1 | Explainable timing difference or one-off |
Likelihood / spread rubric
| Rating | Score | Meaning |
|---|---|---|
| Confirmed & widespread | 5 | You verified it and it's happening across many records |
| Likely | 4 | Strong evidence, a few samples confirmed |
| Possible | 3 | Query flagged it, not yet verified |
| Isolated | 2 | One instance, verified |
| Probably fine | 1 | Flagged but likely a false positive |
Priority score = Severity × Likelihood. Anything scoring 16+ goes to the top of the roadmap. A stale $40k in-transit item that you've confirmed (5 × 5 = 25) beats a messy suspense account you haven't verified (3 × 3 = 9), and the math makes that obvious to everyone in the room — which matters when people are arguing about what to fix first.
The prioritization matrix
Plot findings on a simple two-axis grid. It turns a spreadsheet of scores into something people actually act on.
-
Top-right (high severity, high likelihood) Fix now. These are your Week-1 remediation items.
-
Top-left (high severity, low likelihood) Investigate immediately. If confirmed, they jump to top-right. Don't let a scary-but-unverified item sit — go prove or kill it fast.
-
Bottom-right (low severity, high likelihood) Batch these. Process fixes that prevent recurrence, scheduled but not urgent.
-
Bottom-left (low severity, low likelihood) Log and revisit next quarter.
The mistake people make with matrices like this is treating the top-left quadrant as "later." An unverified critical finding is the single most valuable thing to resolve, because the answer changes your whole priority stack.
The 30-day remediation roadmap
Diagnosis without assigned owners and dates is just a nicer-looking problem. Split the 30 days into three windows, and give every item a name and a due date — not a team, a person.
Days 1–7: Stop the bleeding
Everything scoring 16+. Duplicate payments to claw back, confirmed cash discrepancies, any active leak.
Days 8–20: Fix the recurring causes
The process failures behind the symptoms. Duplicate vendor records get merged and locked. Manual JE policy gets a required-memo rule. Suspense accounts get a weekly clearing owner.
Days 21–30: Structural and preventive
Chart-of-accounts cleanup, mapping rules, documentation so the next person doesn't rebuild the same mess. If your diagnostic surfaced deep data-quality problems — especially ahead of any system migration — the sequencing logic in this prioritization matrix for accounting data cleanup will save you from cleaning the same records twice.
Owner-assignment template
Finding ID: HC-2024-014 Description: Vendor "Acme" has 2 active records; caused split invoice routing Severity: High (4) Likelihood: Confirmed (5) Priority Score: 20 Quadrant: Top-right (Fix now) Owner: [Name] — AP Lead Reviewer: [Name] — Controller Due Date: Day 6 Status: Open / In progress / Verified / Closed Verification: How we'll confirm it's actually fixed
Assign the reviewer before the owner starts work so independent verification is baked into the timeline.
The two fields people skip are Reviewer and Verification. Without them, "closed" just means someone said they did it. A finding isn't closed until a second person can point to evidence the fix held — a re-run of the same query returning zero rows is the cleanest possible proof.
A quick real scenario
A distribution business, roughly 30 staff, ran this over a slightly stretched two weeks because they kept getting pulled into daily ops. Three things surfaced that were worth the effort:
-
Two duplicate vendor records that had caused roughly $9k in duplicate payments over the prior year — recovered most of it once they contacted the supplier.
-
A bank reconciliation with about $14k in "in-transit" items aged past 120 days, which turned out to be a bounced transfer nobody had reversed.
-
A suspense account that had quietly grown to the point where their monthly gross margin was off by a couple of points.
None of it was exotic. Every one of these had been sitting in the ledger for months, visible to anyone who ran the right query. The value wasn't clever analysis — it was the discipline of running the checks in order and assigning each finding to a person who had to close it.
When this is worth doing (and when it isn't)
Do this if: you've had surprises at month-end, you're heading into a fundraise or audit, you just changed accounting systems, or you simply haven't looked under the hood in over a year.
Skip the full version if: you already run continuous monitoring and reconcile daily. You're catching most of this in the normal flow, and a one-week sprint is redundant. Run a lighter quarterly spot-check instead.
Who should not run this solo: a single bookkeeper reviewing their own work. The whole point of the reviewer field is separation — the person who might have made the error shouldn't be the one signing off that it's clean. If you're a one-person finance function, borrow a second set of eyes for the scoring and verification days at minimum.
The one habit that makes it stick
Businesses that get lasting value from this don't treat it as a one-time cleanup. They keep the query set, re-run the top handful monthly, and watch whether findings recur. A duplicate-payment query that returned twelve rows in your first pass and zero rows three months later is the actual proof the process worked.
A finance health check compressed into one week isn't about finding everything — it's about finding the expensive, obvious things you've stopped seeing because they've been there so long. Run the queries in order, score honestly, assign real owners, and check that the fixes actually held. That's the whole discipline, and it catches more than most people expect.
A finance health check compressed into one week isn't about finding everything — it's about finding the expensive, obvious things you've stopped seeing because they've been there so long. Run the queries in order, score honestly, assign real owners, and check that the fixes actually held. That's the whole discipline, and it catches more than most people expect.
Ready to take control of your finances?
Join over 2,000 businesses using Acctaly to simplify accounting, accelerate cash flow, and ensure tax readiness.