First-run setup: upload Bills_Tracker.xlsx and loader_rules.json from the web page when the data folder is empty
build-container / build (push) Successful in 34s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 5.5 committed 2026-10-21 13:01:46 -04:00
1 parent 3dba054dca
commit 6f4ecd42f7
3 files changed
+16 -3

No files matched your search

+3 -1
View File
@@ -35,7 +35,7 @@ th{font-size:12px;color:var(--mute);font-weight:600}td.num{text-align:right;font
<div class="card">
<h2>1 · Add statements</h2>
<div id="drop">Drop PDF or CSV statements here, or click to choose files<input id="file" type="file" multiple accept=".pdf,.csv" hidden></div>
<div id="drop">Drop PDF or CSV statements here, or click to choose files<input id="file" type="file" multiple accept=".pdf,.csv,.xlsx,.json" hidden></div>
<div class="mute" style="margin-top:8px" id="uploadmsg">Supported: Chase Visa PDF · Ally Bank PDF · CVFCU PDF · Capital One CSV download.
<a href="#" id="helplink">Adding a different account?</a></div>
<div id="help" class="mute">Open <code>statement_loader.py</code>, add one line to <code>ACCOUNTS</code> (a name, a word printed on page 1 of its statement, and the day it closes), then ask Claude to write the parser for that bank’s layout. Any file the app can’t read is listed under “Needs attention”.</div>
@@ -67,6 +67,8 @@ async function refresh(msg){
$("#coverage").innerHTML="Reading statements…";
const r=await fetch("/api/state");const s=await r.json();
if(s.error){alertBox("bad",esc(s.error));return}
if(s.setup){$("#coverage").innerHTML="";$("#preview").innerHTML="";$("#import").disabled=true;
$("#summary").innerHTML="";alertBox("warn",`<b>First-time setup:</b> <code>Bills_Tracker.xlsx</code> isn’t in the data folder (<code>${esc(s.data_dir)}</code>). Drop it into the box above (or copy it into that folder), then reload.`+(s.rules?"":" Also add <code>loader_rules.json</code> if you have one (your name, so transfers between your accounts are recognized)."));return}
s.bad.forEach(b=>alertBox("bad",`<b>${esc(b.file)}</b>: the transactions I read add up to ${fmt(b.parsed)} but the statement says ${fmt(b.stated)}. It will <b>not</b> be imported until that matches.`));
s.skipped.forEach(b=>alertBox("warn",`<b>${esc(b.file)}</b>: ${esc(b.why)}`));
s.duplicates.forEach(b=>alertBox("warn",`<b>${esc(b.file)}</b> is a duplicate of ${esc(b.same_as)}; counted once.`));