# Local audit — 19 Aug 2026 Full audit of the local database, files, and the running app before the team enters the first production month. **Verdict: system healthy and ready; three data-cleanup items for the team below.** ## What was checked | Check | Result | |---|---| | Database integrity (`PRAGMA integrity_check`) | ✅ ok — `ar_aging.db`, 295 MB, 20 tables | | Foreign keys / orphaned rows | ✅ zero violations, zero orphans | | Transactions | ✅ 883,930 rows across 4 processed closings, none missing currency or marketplace | | Uploaded files vs database | ✅ all 4 files present on disk, sizes match, SHA-256 recorded | | Duplicate upload rows (historical double-count bug) | ✅ none found — no closing ever double-counted a file | | Orphan files on disk | ✅ none | | Users | ✅ 4 active accounts (login verified for each) | | Full test suite | ✅ 152 passed, 0 failed (12 skipped — large sample files) | | Live API (running app, port 8010) | ✅ health deep-check ok; no token → 401; wrong password → 401; login ok; month-ordered listing; pending-months explanations; controls 5/6 on Jan | | Frontend (port 5174) | ✅ serving, proxying to the API | | Exchange-rate provider (live call) | ✅ Frankfurter reachable; EUR→USD 2026-06-30 = **1.139406**, 2026-01-30 = 1.191895 | One environment fix made during the audit: this Windows machine's OS certificate store is corrupted (Python `ssl [ASN1: NOT_ENOUGH_DATA]`), which blocked HTTPS calls. The FX service now uses the `certifi` CA bundle instead (added to requirements) — affects nothing else. ## Findings for the team (data, not code) ### 1. ⚠️ June closings are valued at January's exchange rate — ≈ $50k overstated Closings **#3, #4, #5** (all 2026-06) carry EUR→USD = **1.185665**, the January-2026 workbook snapshot, and it was *confirmed* at that value. The actual ECB rate on 2026-06-30 was **1.139406** — the June receivable of $1,290,921 is overstated by roughly **$50,000**. Fix on whichever June closing is kept: Controls tab → **Fetch month-end rates** → review → Confirm → re-run controls. This is precisely the failure mode the new FX fetch exists to prevent. ### 2. ⚠️ Three identical June closings + three empty drafts Closings #3 ("July finance report"), #4 ("june"), #5 ("Test Case - Germany Jun-2026") are the **same June file processed three times** — identical 214,166 transactions and identical receivable. Keep one, delete the other two. Drafts #2, #6 (2026-06) and #7 (2026-01) are empty and can be deleted. The dashboard now flags all of these with a duplicate-month ⚠. Going forward the app blocks accidental month duplicates at creation. ### 3. ℹ️ No month is published yet No journal has been approved, so the Accounts Summary is empty — the summary page now lists each processed month with the reason ("journal not approved yet") and a link. When January is final: Journal Entry tab → Mark reviewed → Approve (records the signed-in user's name). ## State after cleanup (recommended target) - One closing per month: `2026-01` (#1) and one `2026-06`, both with fetched + confirmed June/January rates, journals approved, then **Complete** to lock them read-only. - First production month gets entered by the team on the deployed server per `deploy/DEPLOY.md`; this local database migrates there as-is.