finances/migration/test_overlap_review.html
Dane Sabo a37d8f4d2c merchant_map: +24 rules from overlap-test learning loop; test review artifact
- 22 UNMATCHED + 2 REVIEW resolutions from the 2026-05-01..05-25 overlap
  import got folded back via apply_decisions/upsert_rule: the Charlotte
  bachelor-trip vendors (Tot Hill Farm, Lexington BBQ, Wooden Robot Brewing,
  Grace O'Malley, Buddy's Place, Stop and Go, Yamazaru, Publix, Krispy Kreme,
  Charlotte Motor Speedway), Pittsburgh first-timers (Utrecht/Blick's,
  Westinghouse Food Court, Halal Guys, Five Guys, Firestone, Leatherman, PRT
  via Masabi), plus Patrick Murphy (rent) and Emerson (wages).
- migration/test_overlap_review.html: the rendered review doc from the test
  (PNC+Apple+Costco 2026-05-01..05-25; 57 dedup-skip, 44 actionable).
2026-05-25 21:35:32 -04:00

386 lines
70 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Firefly import review</title>
<style>
:root { --bg:#0f1115; --panel:#181b22; --line:#2a2f3a; --fg:#e7e9ee;
--muted:#9aa3b2; --accent:#4f9cf9; --ok:#3fb950; --no:#f85149;
--warn:#d29922; }
* { box-sizing:border-box; }
body { margin:0; font:14px/1.45 -apple-system,Segoe UI,Roboto,sans-serif;
background:var(--bg); color:var(--fg); }
header { position:sticky; top:0; z-index:5; background:var(--panel);
border-bottom:1px solid var(--line); padding:12px 18px;
display:flex; gap:18px; align-items:center; flex-wrap:wrap; }
header h1 { font-size:15px; margin:0; font-weight:600; }
.counts { display:flex; gap:14px; color:var(--muted); font-size:13px; }
.counts b { color:var(--fg); }
.spacer { flex:1; }
button { font:inherit; cursor:pointer; border:1px solid var(--line);
background:#222732; color:var(--fg); border-radius:6px;
padding:7px 12px; }
button:hover { border-color:var(--accent); }
button.primary { background:var(--accent); border-color:var(--accent);
color:#06203f; font-weight:600; }
section { margin:22px auto; max-width:1200px; padding:0 18px; }
h2 { font-size:15px; border-bottom:1px solid var(--line);
padding-bottom:6px; }
h2 .sub { color:var(--muted); font-weight:400; font-size:12px;
margin-left:8px; }
table { width:100%; border-collapse:collapse; }
th,td { text-align:left; padding:7px 8px; border-bottom:1px solid var(--line);
vertical-align:top; font-size:13px; }
th { color:var(--muted); font-weight:600; }
td.amt { text-align:right; font-variant-numeric:tabular-nums;
white-space:nowrap; }
.desc { color:var(--fg); }
.desc small { color:var(--muted); display:block; }
input[type=text], select { font:inherit; background:#11141a; color:var(--fg);
border:1px solid var(--line); border-radius:5px; padding:5px 6px;
width:100%; }
.toggle { display:inline-flex; border:1px solid var(--line);
border-radius:6px; overflow:hidden; }
.toggle button { border:0; border-radius:0; padding:5px 10px;
background:#11141a; }
.toggle button.on-ok { background:var(--ok); color:#04210b;
font-weight:600; }
.toggle button.on-no { background:var(--no); color:#2a0606;
font-weight:600; }
.pill { font-size:11px; padding:1px 7px; border-radius:999px;
border:1px solid var(--line); color:var(--muted); }
.pill.review { color:var(--warn); border-color:var(--warn); }
.pill.unmatched { color:var(--no); border-color:var(--no); }
.pill.create { color:var(--ok); border-color:var(--ok); }
.pill.transfer { color:#fff; background:#8e5cf7; border-color:#8e5cf7; }
.pill.dup { color:var(--muted); }
.pill.autotail { color:#d29922; border-color:#d29922; margin-left:5px; }
td.pid { color:var(--muted); font-size:11px; font-variant-numeric:tabular-nums;
white-space:nowrap; }
tr.is-transfer td:first-child { box-shadow: inset 3px 0 0 #8e5cf7; }
.amt .dir { font-weight:700; margin-right:2px; }
.amt .io { font-size:9px; letter-spacing:.05em; opacity:.65;
margin-left:4px; vertical-align:1px; }
.amt.in { color:#3fb950; }
.amt.out { color:#f0883e; }
.amt.xfer{ color:#a983f7; }
tr.grp td { background:#1b2030; font-weight:700; color:#9fb3c8;
padding:7px 9px; border-top:2px solid #2a3140;
letter-spacing:.02em; }
tr.grp .sub { color:var(--muted); font-weight:400; }
.sugg { color:var(--muted); font-size:12px; margin-top:3px; }
.sugg a { color:var(--accent); cursor:pointer; text-decoration:underline; }
.readonly td { color:var(--muted); }
.empty { color:var(--muted); padding:10px 0; }
footer { max-width:1200px; margin:30px auto 60px; padding:0 18px;
color:var(--muted); font-size:12px; }
</style>
</head>
<body>
<header>
<h1>Firefly import review</h1>
<div class="counts" id="counts"></div>
<div class="spacer"></div>
<button id="approveAuto">Approve all auto</button>
<button id="export" class="primary">Export decisions</button>
</header>
<section>
<h2>Needs Clarity <span class="sub">UNMATCHED + REVIEW &mdash; set the
canonical account, category, budget, then approve</span></h2>
<table><thead><tr>
<th>#</th><th>Date</th><th>Amount</th><th>Description</th><th>Account</th>
<th>Category</th><th>Budget</th><th>Comment</th><th>Decision</th>
</tr></thead><tbody id="tb-clarity"></tbody></table>
<div class="empty" id="empty-clarity" hidden>Nothing needs clarification.</div>
</section>
<section>
<h2>Auto-Proposed <span class="sub">matched a rule &mdash; approved by
default, deny or edit if wrong</span></h2>
<table><thead><tr>
<th>#</th><th>Date</th><th>Amount</th><th>Description</th><th>Account</th>
<th>Category</th><th>Budget</th><th>Comment</th><th>Decision</th>
</tr></thead><tbody id="tb-auto"></tbody></table>
<div class="empty" id="empty-auto" hidden>No auto-proposed rows.</div>
</section>
<section>
<h2>All Transactions <span class="sub">complete picture, read-only
(includes skipped duplicates)</span></h2>
<table><thead><tr>
<th>#</th><th>Date</th><th>Amount</th><th>Type</th><th>Description</th>
<th>Bucket</th><th>Target</th>
</tr></thead><tbody id="tb-all"></tbody></table>
</section>
<footer>
Decisions are exported as <code>decisions.json</code> (keyed by
external_id). Re-run
<code>firefly_import.py &lt;normalized&gt; --decisions decisions.json --post</code>
to post only approved rows.
</footer>
<script>
const PLAN = {"meta": {"generated": "2026-05-25T21:11:55", "config": ".firefly.json", "record_count": 101, "categories": ["Auto: Fees", "Auto: Fuel", "Auto: Insurance", "Auto: Parking", "Books", "Clothes", "Coffee", "Education", "Groceries", "Investment: Interest", "Medical", "Other", "Personal Care", "Pets", "Poker", "Recreation: Firearms", "Recreation: Golf", "Recreation: Racing", "Recreation: Snowboarding", "Rent", "Restaurants", "Shopping", "Subscriptions", "Taxes", "Tools", "Travel", "Utilities", "Utilities: Electric", "WRX (Aimee)", "Wages", "Z (Mizumi)"], "accounts": ["24/7 Travel Store", "7-eleven 36193 999 Greentree Rd", "7-eleven 40172 3505 Library Rd C", "7-eleven Food Stores 525 Main St", "Ac Hotel Clayton", "Act Cntyalleghenyprk", "Advance Auto Parts", "Air Force Museum F1100 Spaat", "Airbnb", "Allegheny Arms", "Als Corner", "Amazon", "Amk Acrisure Concessio500 Art Ro", "Ammojoy Llc", "Amz*vedder Holsters", "Apex Race Parts", "Apple", "Apple Card Cashback", "Apple Credit Card", "Arco", "Autozone", "BP", "Baby Gee", "Barnes & Noble", "Belvederes Ultra Butle", "Best Buy", "Big Buck Sport Shop", "Black Sheep Cafe", "Blue Alpha", "Boozy Barre", "Borough of Dormont", "Br Factory", "Brillobox", "Bruster's", "Buffalo Wild Wngs", "Burghers Brewing Millv400 Grant", "Butterjoint", "Capital One", "Cappy'scafe", "Cash", "Check", "Chestnut Hills Squir Forbe", "Chick-fil-A", "Chikn Oakland", "Claude.ai", "Comcast / Xfinity", "Compeer Investments", "Condado Tacos Libert", "Convention Ctr Garage", "Costco", "Costco Annual Membership Re", "Costco Gas", "Costco Pharmacy", "Costco Visa Card", "Costco Whse", "Coverdell", "Cranberry Fitness Cent1000 Westi", "Crfs Only", "Crystal Inn Slc", "Ctlp Vend Elm", "Ctlp Vending Oh Riversi", "Ctlp*csc Serviceworks", "Ctlp*laurel Foodsystem", "Culvers Kingman Airway1737 Airwa", "Culvers South Jordan", "Cvs Pharmacy Cochran", "Cvs Pharmacy Forbes", "Cycle Gear", "D J*wsj", "DELTA", "Dakota Watch", "Darn Tough", "Dave & Andy's", "Dey's Donuts Hot", "Diamond Parking", "Dianne Hulings", "Dick's Sporting Goods", "Dolly's Bookstore", "Don't Know", "Dunkin", "Duquesne Light", "Eat Park Park Manor", "Einstein Bros. Beneqps Ohara", "Expedia", "Exxon Rr Thompson 7ele460 South", "Fine Wine & Good Spirits", "Fiori S Pizza", "Fiori S Pizzaria", "Fitbod", "Five Guys", "Flying J", "Food For Thought", "Forbes Bakery", "Forbes Street Qps3955 Forbes", "Foxs Pizza Den Brookli902 Brookl", "Freetaxusacom Po Box", "Fuji Sushi", "Fuku Tea", "Gamma Sports", "Gap Outlet", "Gatewaycenter", "Get Go", "Giant Eagle", "Glenlak", "Going Going Gone", "Golf Galaxy", "GomobilePGH", "Goodwill Of Sw", "Google", "Grey Parrot Consig322 Castle", "Grndcynassnvcp", "Half Crown Hill Or600 N", "Harbor Freight Tools", "Hemingway's Cafe", "Hinge", "Hitchhiker Brewing", "Hofbrauhaus Pittsburgh", "Home Depot", "Hoover Dam Park Tour", "Hoover Dam Souvenir An81 Hoover", "Hop Farm Brewing", "Hudson St2380", "ICT Billet", "IKEA", "IRS Refund", "Illiquid Assets", "In-n-out Lv - Russell 3397 W. Ru", "Inbox Health", "Interest Income", "Iron Born Pizza", "J Crew Factory", "J. Crew Factory", "JEGS", "Japanpartsc Tokyoto Minatoku Kit", "Jimmy Johns", "Joanne Bogert", "Kellys Way Valero", "Kingside Diner Ex6170 Delma", "Kuhn's Market", "Kuhn's Mcknight", "La Gourmandine", "Lgb Business Jrn Shop Long", "Liberty Mutual", "Longhorn Stk Ec", "Lorelei", "Love's", "Lowes", "Lsp Nomad Taqueria Bee", "Luis Benitez", "Mamacitas", "Marathon Petro188011", "Marc Karakouzian", "Margaux East Lib Penn", "Mario's East Side Walnu", "Matt Barry", "McDonald's", "Michaels Stores", "Mineo's Pizza", "Momoyao Studio", "Moonlit Burgers", "Mt Lebanon - Parkmobil710 Washin", "Mt Lebanon Golf Course", "Mt Lebanon Parking", "Mt. Lebanon - Flowbird710 Washin", "Nascar Cup Series", "Needle & Bean", "Nike", "Northshore Garage", "Omar S Halal Grill", "OpenAI", "Orbis Caffe", "Orderengine", "Orderville Entp Sincla15 E State", "Outlook Inn", "Owlfeathers Waterc5860 Darli", "PMUSA", "PNC Checking", "Pa Courts Fines And Co601 Common", "Page Dairy Mart", "Painting With A Twist", "Pamela's Diner", "Panda Supermarket", "Panera Bread", "Papa Js Twin Plaza2016 Small", "Park City Desserts", "Park City Parking Serv445 Marsac", "ParkWhiz", "Parking", "Peacock", "Pepboys Store", "Petco", "Pitt Book Center", "Pitt Campus Rec Office", "Pitt Race", "Pitt Salary", "Pitt Univ Parking", "Ponderosa Golf Course", "Potomac Bqps Potom", "Primanti Bros", "Ptc Ez Pass Auto Re", "REI", "Raising Canes", "Range", "Red Robin", "Redhawk Coffee", "Revzilla Motorsports", "Rita's", "Rock Auto", "Rock Garden Eatery670 East H", "Rollier's Hardware", "Roots Natural Kitchen", "Ross Stores", "Row House Cinema", "Ruggers Pub", "SCCA", "Saloon Of", "Schwab Savings", "Schwab Stocks", "Senor Birria Los Alami11151 Los", "Settebello Llc", "Shake Shack Conc A Slc474", "Sheetz", "Shop 'n Save", "Shorty's North Sh Shor", "Shreemadhqps St Joh", "Simones", "Slc Freddyssteakburger", "Smith's Fuel", "Snow.Com/vail Resorts", "Sp Mr Jones Watches", "Sp Never Summer Ind", "Sp Partify", "Spiegel Freedman Psychological Associates", "Sportsmans Warehouse", "St. Vincent de Paul", "Starbucks", "Stbc Pittsburgh", "Steam Purchase", "Subaru of South Hills", "Summit Racing", "Sunoco", "TNT Pizza", "Taco Bell", "Target", "Tazza D'Oro", "Telnyx Llc", "The Dog Penn", "The Exchange", "The Milkshake Factory", "The Porch", "The Tire Rack", "Thrifty Ski Rental", "Tina's Cocktail Main", "Tow-tegrity Incorp", "Trace Brewing", "Trader Joe S", "Trophysmack", "Twilio Inc", "UPMC Student Insurance", "Uber *trip", "University Club", "University of Pittsburgh", "Uptown Coffee", "Utah Main Campus Store270 S", "Uu Storefront-campus", "Uu Visitor Parking Q40311 Fort", "Venmo", "Villa Fresh Italian", "Wal Mart", "Walmart", "Whole Foods", "Wholefoods Pit", "Willi's Ski Shop", "Withdrawal Xxxxx8118 Withdrawal Xxxxx8118", "Xceptional Style", "Zagg", "Zillow", "Zoho", "eBay", "undergroundshirts.com", "wp*pittrace.com"], "note": "Overlap test 2026-05-01..05-25; 57 deduped via external_id; 44 new (incl. NC bachelor trip + a few PGH first-timers)", "rendered": "2026-05-25T21:12:42"}, "rows": [{"external_id": "pnc:952673929534609207#1#001#2026-05-22#", "bucket": "TRANSFER", "date": "2026-05-22", "amount": "5285.71", "type": "transfer", "description": "APPLECARD GSBANK PAYMENT ACH WEB APPLECARD GSBANK PAYMENT ACH WEB xxxxx9213", "asset_account": "PNC Checking", "destination_account": "Apple Credit Card", "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 1, "group_account": "PNC Checking"}, {"external_id": "apple:814008e6-b2b8-48c6-aafd-4449a8227e", "bucket": "CREATE", "date": "2026-05-23", "amount": "90.05", "type": "withdrawal", "description": "WM SUPERCENTER #2134 7735 N TRYO", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Walmart", "proposed_account_id": null, "proposed_category": "Groceries", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 2, "budget_suggestions": ["Needs"]}, {"external_id": "apple:30175deb-d20b-48fc-8fd3-729f6630d3", "bucket": "CREATE", "date": "2026-05-23", "amount": "15.45", "type": "withdrawal", "description": "CHICK-FIL-A #04158 100 HYLTON LN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Chick-fil-A", "proposed_account_id": null, "proposed_category": "Restaurants", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 3, "budget_suggestions": ["Wants"]}, {"external_id": "apple:32507db0-3ae3-496c-b06c-b9fc6e9dd4", "bucket": "CREATE", "date": "2026-05-22", "amount": "20.16", "type": "withdrawal", "description": "SHEETZ 0206 39 BERLIN RD WESTON", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 4, "budget_suggestions": ["Needs"]}, {"external_id": "apple:dea359be-4307-44db-9999-057c5f22c6", "bucket": "CREATE", "date": "2026-05-22", "amount": "61.78", "type": "withdrawal", "description": "SHEETZ 2206 39 BERLIN RD WESTON", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 5, "budget_suggestions": ["Needs"]}, {"external_id": "apple:40974ebc-8489-4dfa-badf-abff8aa407", "bucket": "CREATE", "date": "2026-05-22", "amount": "6.35", "type": "withdrawal", "description": "APPLE.COM/BILL ONE APPLE PARK WA", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Apple", "proposed_account_id": null, "proposed_category": "Subscriptions", "proposed_budget": "Wants", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 6}, {"external_id": "apple:a465afef-d5ea-4798-8e3f-12483ebcc8", "bucket": "CREATE", "date": "2026-05-22", "amount": "38.24", "type": "withdrawal", "description": "SPO*MINEO'SPIZZAHOUSE-713 WASHIN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Mineo's Pizza", "proposed_account_id": null, "proposed_category": "Restaurants", "proposed_budget": "Wants", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 7}, {"external_id": "apple:c827c639-195b-48f1-b0d6-34c166c959", "bucket": "CREATE", "date": "2026-05-21", "amount": "9.66", "type": "withdrawal", "description": "SUNOCO 0859331103 QPS301 CRAFT A", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sunoco", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 8, "budget_suggestions": ["Needs"]}, {"external_id": "apple:08e8a466-5296-40f7-8882-2a88b62d20", "bucket": "CREATE", "date": "2026-05-20", "amount": "8.55", "type": "withdrawal", "description": "SQ *LA GOURMANDINE OAK116 MEYRAN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "La Gourmandine", "proposed_account_id": null, "proposed_category": "Coffee", "proposed_budget": "Wants", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 9}, {"external_id": "apple:163cd4c3-ede3-4304-a7a9-a9ac10be8d", "bucket": "CREATE", "date": "2026-05-19", "amount": "0.99", "type": "withdrawal", "description": "APPLE.COM/BILL ONE APPLE PARK CU", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Apple", "proposed_account_id": null, "proposed_category": "Subscriptions", "proposed_budget": "Wants", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 10}, {"external_id": "apple:79cdeb83-0da7-4dad-9539-2ef2c78a9b", "bucket": "CREATE", "date": "2026-05-19", "amount": "4.39", "type": "withdrawal", "description": "GIANT-EAGLE #0052 132 BEN AVON H", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Giant Eagle", "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": true, "plan_id": 11, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:180e1ee6-8474-4393-b4d4-74f9d5b341", "bucket": "CREATE", "date": "2026-05-19", "amount": "32.93", "type": "withdrawal", "description": "GIANT-EAGLE #0052 132 BEN AVON H", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Giant Eagle", "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": true, "plan_id": 12, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:61d06f05-aa09-454c-a1f5-0cc982e40d", "bucket": "CREATE", "date": "2026-05-18", "amount": "2.03", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 13, "budget_suggestions": ["Needs"]}, {"external_id": "apple:a4a849ae-8685-413f-b2be-ddc8ea366a", "bucket": "CREATE", "date": "2026-05-18", "amount": "45.69", "type": "withdrawal", "description": "SHEETZ 2353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 14, "budget_suggestions": ["Needs"]}, {"external_id": "apple:b657cd56-17ab-4181-9d9a-c5fc61ca57", "bucket": "CREATE", "date": "2026-05-18", "amount": "27.24", "type": "withdrawal", "description": "HARBOR FREIGHT TOOLS 25185 CAMPB", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Harbor Freight Tools", "proposed_account_id": null, "proposed_category": "Tools", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 15, "budget_suggestions": []}, {"external_id": "apple:0193b4a5-76df-42c5-908f-47d427c3cc", "bucket": "CREATE", "date": "2026-05-18", "amount": "88.74", "type": "withdrawal", "description": "MARKET DISTRICT #0047 100 SETTLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Giant Eagle", "proposed_account_id": null, "proposed_category": "Groceries", "proposed_budget": "Needs", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 16}, {"external_id": "apple:94f76827-57db-4a63-ab35-4e5e2e7068", "bucket": "CREATE", "date": "2026-05-18", "amount": "9.57", "type": "withdrawal", "description": "KUHNS BANKSVILLE 3125 BANKSVILLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Kuhn's Market", "proposed_account_id": null, "proposed_category": "Groceries", "proposed_budget": "Needs", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 17}, {"external_id": "apple:939591e5-9405-4b19-a9df-a041a3fe60", "bucket": "CREATE", "date": "2026-05-17", "amount": "62.32", "type": "withdrawal", "description": "SHEETZ 2353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 18, "budget_suggestions": ["Needs"]}, {"external_id": "apple:6ab13a36-9439-4ac5-8ba5-5cc087756f", "bucket": "CREATE", "date": "2026-05-17", "amount": "2.66", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Sheetz", "proposed_account_id": null, "proposed_category": "Auto: Fuel", "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 19, "budget_suggestions": ["Needs"]}, {"external_id": "apple:0cf004cc-94c2-40d0-b745-796d7551a1", "bucket": "CREATE", "date": "2026-05-17", "amount": "9.96", "type": "withdrawal", "description": "SQ *NEEDLE & BEAN 320 CASTLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": "Needle & Bean", "proposed_account_id": null, "proposed_category": "Coffee", "proposed_budget": "Wants", "suggestions": [], "review": false, "auto_tail": false, "plan_id": 20}, {"external_id": "pnc:952673929534609207#1#001#2026-05-19#", "bucket": "REVIEW", "date": "2026-05-19", "amount": "1428.33", "type": "deposit", "description": "ZEL FROM PATRICK MURPHY ZEL FROM PATRICK MURPHY", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": "Don't Know", "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": true, "auto_tail": false, "plan_id": 21, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "pnc:952673929534609207#1#001#2026-05-18#", "bucket": "REVIEW", "date": "2026-05-18", "amount": "5.00", "type": "deposit", "description": "ZEL FROM PATRICK MURPHY ZEL FROM PATRICK MURPHY", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": "Don't Know", "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": true, "auto_tail": false, "plan_id": 22, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "pnc:952673929534609207#2#001#2026-05-18#", "bucket": "UNMATCHED", "date": "2026-05-18", "amount": "1091.55", "type": "deposit", "description": "MOBILE DEPOSIT xxxxx1536 MOBILE DEPOSIT xxxxx1536", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Withdrawal Xxxxx8118 Withdrawal Xxxxx8118", "ICT Billet", "GomobilePGH", "Pepboys Store", "Barnes & Noble"], "review": false, "auto_tail": false, "plan_id": 23, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:ce2fce22-cdec-433a-bf66-5a00facd6a", "bucket": "UNMATCHED", "date": "2026-05-25", "amount": "5.46", "type": "withdrawal", "description": "TST* WOODEN ROBOT BREW1440 S TRY", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Foxs Pizza Den Brookli902 Brookl", "Roots Natural Kitchen", "Grey Parrot Consig322 Castle", "Red Robin"], "review": false, "auto_tail": false, "plan_id": 24, "category_suggestions": ["Restaurants"], "budget_suggestions": ["Wants"]}, {"external_id": "apple:b20a1d6e-e9d3-4084-aa83-cf4b877bd4", "bucket": "UNMATCHED", "date": "2026-05-25", "amount": "23.14", "type": "withdrawal", "description": "LEXINGTON BARBECUE INC100 SMOKEH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Twilio Inc", "Longhorn Stk Ec", "Subaru of South Hills"], "review": false, "auto_tail": false, "plan_id": 25, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:ac8a27e2-770e-4ca7-bd51-02a87a2c0a", "bucket": "UNMATCHED", "date": "2026-05-25", "amount": "40.66", "type": "withdrawal", "description": "SQ *SMIP - CHARLOTTE M5239 Z MAX", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Cvs Pharmacy Forbes", "Margaux East Lib Penn", "Ctlp*laurel Foodsystem", "Gamma Sports", "Nascar Cup Series"], "review": false, "auto_tail": false, "plan_id": 26, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:205cb374-4041-4e56-9850-905d328309", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "37.69", "type": "withdrawal", "description": "TST* GRACE O'MALLEY'S 157 N TRAD", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Apex Race Parts", "Apex Race Parts", "Pitt Race", "Gamma Sports", "Advance Auto Parts"], "review": false, "auto_tail": false, "plan_id": 27, "category_suggestions": ["Restaurants"], "budget_suggestions": ["Wants"]}, {"external_id": "apple:ee228415-7628-4de4-9c3c-d250e47856", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "124.02", "type": "withdrawal", "description": "SP LEATHERMAN CA B2C 12106 NORTH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Eat Park Park Manor", "Shorty's North Sh Shor", "The Dog Penn", "The Exchange", "The Milkshake Factory"], "review": false, "auto_tail": false, "plan_id": 28, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:8f05331b-28da-4874-aea6-f4780c3880", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "22.93", "type": "withdrawal", "description": "STOP AND GO CONVENIENT1632 SOUTH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Culvers South Jordan", "Exxon Rr Thompson 7ele460 South", "In-n-out Lv - Russell 3397 W. Ru", "Pa Courts Fines And Co601 Common", "Subaru of South Hills"], "review": false, "auto_tail": false, "plan_id": 29, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:bc752699-f142-468d-99ab-1b4ab986c1", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "22.49", "type": "withdrawal", "description": "TST*YAMAZARU 2173 HAWKINS ST A C", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Pitt Salary", "Kuhn's Market", "Mario's East Side Walnu", "Michaels Stores", "Tina's Cocktail Main"], "review": false, "auto_tail": false, "plan_id": 30, "category_suggestions": ["Restaurants"], "budget_suggestions": ["Wants"]}, {"external_id": "apple:c6434bc9-aab5-43c6-8f94-fffb3c28e7", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "114.45", "type": "withdrawal", "description": "PUBLIX #1453 2222 SOUTH BLVD CHA", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Culvers South Jordan", "Exxon Rr Thompson 7ele460 South", "In-n-out Lv - Russell 3397 W. Ru", "Ruggers Pub", "Subaru of South Hills"], "review": false, "auto_tail": false, "plan_id": 31, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:26572716-45c6-4d6e-bdb4-47f60353b8", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "68.61", "type": "withdrawal", "description": "EXXON 7-ELEVEN 35547 9608 UNIVER", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["7-eleven 36193 999 Greentree Rd", "7-eleven 40172 3505 Library Rd C", "7-eleven Food Stores 525 Main St", "Exxon Rr Thompson 7ele460 South", "Pitt Univ Parking"], "review": false, "auto_tail": false, "plan_id": 32, "category_suggestions": ["Auto: Fuel"], "budget_suggestions": ["Needs"]}, {"external_id": "apple:e906bc4f-82ea-4a5a-9925-bfb0745be9", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "19.47", "type": "withdrawal", "description": "KRISPY KREME #0108 2116 HAWKINS", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Utah Main Campus Store270 S", "Redhawk Coffee", "Als Corner", "Apex Race Parts", "Apex Race Parts"], "review": false, "auto_tail": false, "plan_id": 33, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:30645d0c-9d68-4900-ba05-dfeec84634", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "8.00", "type": "withdrawal", "description": "KRISPY KREME #0108 2116 HAWKINS", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Utah Main Campus Store270 S", "Redhawk Coffee", "Als Corner", "Apex Race Parts", "Apex Race Parts"], "review": false, "auto_tail": false, "plan_id": 34, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:34fd921f-ba77-4525-86f9-a5685343a9", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "14.00", "type": "withdrawal", "description": "4UP*TOT HILL FARM GOL 3185 TOT H", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Half Crown Hill Or600 N", "Hop Farm Brewing", "Ac Hotel Clayton", "Subaru of South Hills", "Goodwill Of Sw"], "review": false, "auto_tail": false, "plan_id": 35, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:a899e88e-8f32-4ca1-ada5-8bc38df316", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "20.00", "type": "withdrawal", "description": "4UP*TOT HILL FARM GOL 3185 TOT H", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Half Crown Hill Or600 N", "Hop Farm Brewing", "Ac Hotel Clayton", "Subaru of South Hills", "Goodwill Of Sw"], "review": false, "auto_tail": false, "plan_id": 36, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:ee44e499-a82d-4e42-8e12-536db3aa54", "bucket": "UNMATCHED", "date": "2026-05-24", "amount": "1080.00", "type": "withdrawal", "description": "4UP*TOT HILL FARM GOL 3185 TOT H", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Half Crown Hill Or600 N", "Hop Farm Brewing", "Ac Hotel Clayton", "Subaru of South Hills", "Goodwill Of Sw"], "review": false, "auto_tail": false, "plan_id": 37, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:0d240138-f8dc-4c0d-80d2-3b2115d58f", "bucket": "UNMATCHED", "date": "2026-05-23", "amount": "16.16", "type": "withdrawal", "description": "TST*BUDDYS PLACE 1470 S MAIN ST", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["7-eleven Food Stores 525 Main St", "Tina's Cocktail Main", "Utah Main Campus Store270 S", "Crystal Inn Slc", "Dey's Donuts Hot"], "review": false, "auto_tail": false, "plan_id": 38, "category_suggestions": ["Restaurants"], "budget_suggestions": ["Wants"]}, {"external_id": "apple:38d5ad7c-00fb-41b4-b0b6-5903ad4011", "bucket": "UNMATCHED", "date": "2026-05-21", "amount": "2.75", "type": "withdrawal", "description": "MASABI PRTREADY2RIDE HEINZ 57 CE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Nascar Cup Series", "Pitt Campus Rec Office", "Thrifty Ski Rental", "Mario's East Side Walnu", "Ptc Ez Pass Auto Re"], "review": false, "auto_tail": false, "plan_id": 39, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:d24d3883-15d1-493a-b092-3ed1110fdf", "bucket": "UNMATCHED", "date": "2026-05-20", "amount": "9.54", "type": "withdrawal", "description": "SQ *PITTS HALAL GUYS I136 COUNTY", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Five Guys", "Omar S Halal Grill", "Pitt Book Center", "Pitt Campus Rec Office", "Pitt Race"], "review": false, "auto_tail": false, "plan_id": 40, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:05fd8e57-ed4e-4168-b8b9-d0a28910f2", "bucket": "UNMATCHED", "date": "2026-05-20", "amount": "314.96", "type": "withdrawal", "description": "FIRESTONE347119 20030 ROUTE 19 C", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["In-n-out Lv - Russell 3397 W. Ru", "IRS Refund", "Interest Income", "Best Buy", "Belvederes Ultra Butle"], "review": false, "auto_tail": false, "plan_id": 41, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:edd27a02-ab04-4222-a288-b4fe5e4fb7", "bucket": "UNMATCHED", "date": "2026-05-20", "amount": "19.60", "type": "withdrawal", "description": "5GUYS 1061 QSR 20002 US 19 CRANB", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Five Guys", "Pepboys Store", "Range", "Crystal Inn Slc", "Michaels Stores"], "review": false, "auto_tail": false, "plan_id": 42, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:bddd6317-6ad1-4c8e-9b28-9fb2233e15", "bucket": "UNMATCHED", "date": "2026-05-19", "amount": "8.29", "type": "withdrawal", "description": "PARKHURST@WESTINGHOU 71000 WESTI", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Cranberry Fitness Cent1000 Westi", "Eat Park Park Manor", "Hoover Dam Park Tour", "Park City Desserts", "Park City Parking Serv445 Marsac"], "review": false, "auto_tail": false, "plan_id": 43, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "apple:9e4c976f-f80a-4b08-89b4-669cb25cc5", "bucket": "UNMATCHED", "date": "2026-05-17", "amount": "51.79", "type": "withdrawal", "description": "UTRECHT ART 80044718921930 EAST", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": ["Amk Acrisure Concessio500 Art Ro", "Margaux East Lib Penn", "Mario's East Side Walnu", "Pitt Campus Rec Office", "Rock Garden Eatery670 East H"], "review": false, "auto_tail": false, "plan_id": 44, "category_suggestions": [], "budget_suggestions": []}, {"external_id": "pnc:952673929534609207#1#001#2026-05-15#", "bucket": "SKIP-dup", "date": "2026-05-15", "amount": "78.41", "type": "transfer", "description": "CITI AUTOPAY PAYMENT ACH WEB-REC CITI AUTOPAY PAYMENT ACH WEB-RECUR xxxxxxxxxxx0023", "asset_account": "PNC Checking", "destination_account": "Costco Visa Card", "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 45, "group_account": "PNC Checking"}, {"external_id": "pnc:952673929534609207#2#001#2026-05-08#", "bucket": "SKIP-dup", "date": "2026-05-08", "amount": "0.05", "type": "deposit", "description": "INTEREST PAYMENT INTEREST PAYMENT", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 46}, {"external_id": "pnc:952673929534609207#1#001#2026-05-08#", "bucket": "SKIP-dup", "date": "2026-05-08", "amount": "2150.00", "type": "withdrawal", "description": "CHECK 143 xxxxx2209 CHECK 143 xxxxx2209", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 47}, {"external_id": "pnc:952673929534609207#1#001#2026-05-05#", "bucket": "SKIP-dup", "date": "2026-05-05", "amount": "2150.00", "type": "withdrawal", "description": "CHECK 142 xxxxx1771 CHECK 142 xxxxx1771", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 48}, {"external_id": "pnc:952673929534609207#2#001#2026-05-04#", "bucket": "SKIP-dup", "date": "2026-05-04", "amount": "48.09", "type": "withdrawal", "description": "DUQUESNE LIGHT PAYMENT ACH DEBIT DUQUESNE LIGHT PAYMENT ACH DEBIT xxxxxx5333", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 49}, {"external_id": "pnc:952673929534609207#1#001#2026-05-04#", "bucket": "SKIP-dup", "date": "2026-05-04", "amount": "1025.00", "type": "withdrawal", "description": "COMPEER-COMP-CP WEB PMTS ACH WEB COMPEER-COMP-CP WEB PMTS ACH WEB C5R6SL", "asset_account": "PNC Checking", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 50}, {"external_id": "pnc:952673929534609207#1#001#2026-05-01#", "bucket": "SKIP-dup", "date": "2026-05-01", "amount": "1650.72", "type": "transfer", "description": "APPLECARD GSBANK PAYMENT ACH WEB APPLECARD GSBANK PAYMENT ACH WEB-RECUR xxxxx9213", "asset_account": "PNC Checking", "destination_account": "Apple Credit Card", "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 51, "group_account": "PNC Checking"}, {"external_id": "apple:33d7c223-2866-4f99-9ec1-6e80425615", "bucket": "SKIP-dup", "date": "2026-05-17", "amount": "2.64", "type": "withdrawal", "description": "SHEETZ 0152 3611 FOURTH AVE BEAV", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 52}, {"external_id": "apple:6cb579da-1a1f-4b0d-b20f-46c715b188", "bucket": "SKIP-dup", "date": "2026-05-17", "amount": "20.00", "type": "withdrawal", "description": "SQ *OWLFEATHERS WATERC5860 DARLI", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 53}, {"external_id": "apple:cbff1203-92aa-468c-8293-13de94a0e1", "bucket": "SKIP-dup", "date": "2026-05-16", "amount": "2.66", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 54}, {"external_id": "apple:2ecc31e0-f251-43cd-9652-78a4e8b8c5", "bucket": "SKIP-dup", "date": "2026-05-16", "amount": "50.00", "type": "withdrawal", "description": "COMCAST / XFINITY 15 SUMMIT PARK", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 55}, {"external_id": "apple:77ef1e13-c5f8-4aea-9e54-e29f07b40b", "bucket": "SKIP-dup", "date": "2026-05-16", "amount": "10.00", "type": "withdrawal", "description": "SPIEGEL FREEDMAN PSYCH470 JAMES", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 56}, {"external_id": "apple:24812f5c-7be0-47ce-9344-81ce5c76d9", "bucket": "SKIP-dup", "date": "2026-05-15", "amount": "7.65", "type": "withdrawal", "description": "SHAKE SHACK CONC A SLC474 N 3700", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 57}, {"external_id": "apple:b81be5cb-f6c7-46a1-8af8-a51f5356b8", "bucket": "SKIP-dup", "date": "2026-05-15", "amount": "27.25", "type": "withdrawal", "description": "CASTLE SHANNON SHOP' 799 CASTLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 58}, {"external_id": "apple:ec527d28-c3a8-4dfb-a1d7-99e7bcf837", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "38.78", "type": "withdrawal", "description": "TST*SETTEBELLO LLC - S260 S 200", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 59}, {"external_id": "apple:a08c131a-98c3-471a-adf0-888f2ca6bb", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "14.55", "type": "withdrawal", "description": "DIAMOND PARKING 605 1ST AVENUE S", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 60}, {"external_id": "apple:91e19a1f-e34d-46a4-af33-7e5c76cbe8", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "32.52", "type": "withdrawal", "description": "UTAH MAIN CAMPUS STORE270 S 1500", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 61}, {"external_id": "apple:aeb5d29d-2542-438f-b8c4-487820f699", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "28.39", "type": "withdrawal", "description": "UU VISITOR PARKING Q40311 FORT D", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 62}, {"external_id": "apple:c9987443-d840-4ac5-ae4a-d08f2e0c11", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "1.53", "type": "withdrawal", "description": "SMITHS-FUEL #9001 873 E SOUTH TE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 63}, {"external_id": "apple:7587ed14-98ea-4e28-98e6-a9873ca658", "bucket": "SKIP-dup", "date": "2026-05-14", "amount": "39.40", "type": "withdrawal", "description": "SMITHS-FUEL #9001 873 E SOUTH TE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 64}, {"external_id": "apple:b33d0638-b27e-4a7d-a7f6-60bd7f4ee0", "bucket": "SKIP-dup", "date": "2026-05-13", "amount": "1330.99", "type": "withdrawal", "description": "AIRBNB * HMJPZQ3FCN 888 BRANNAN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 65}, {"external_id": "apple:046beb12-6794-4a52-bda3-f76e906a8b", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "1.00", "type": "withdrawal", "description": "CRYSTAL INN SLC 230 W 500 S SALT", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 66}, {"external_id": "apple:d0c775b7-ddf9-4766-b8fd-a08be4a45d", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "17.49", "type": "withdrawal", "description": "TST*PARK CITY DESSERTS401 MAIN S", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 67}, {"external_id": "apple:cb755719-e2c5-4331-85a4-196c4887da", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "3.89", "type": "withdrawal", "description": "7-ELEVEN FOOD STORES 525 MAIN ST", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 68}, {"external_id": "apple:dfdf2261-c29c-45a1-8871-0c8c2ad8b2", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "1.00", "type": "withdrawal", "description": "PARK CITY PARKING SERV445 MARSAC", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 69}, {"external_id": "apple:d8223596-f052-4112-ad1e-dafc837659", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "18.72", "type": "withdrawal", "description": "WM SUPERCENTER #3848 2228 W 1700", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 70}, {"external_id": "apple:7a474967-9423-472f-b24f-71b31e78c0", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "22.90", "type": "withdrawal", "description": "SQ *DOLLY'S BOOKSTORE 510 MAIN S", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 71}, {"external_id": "apple:074e847c-4e8c-419f-97be-19ed4099b9", "bucket": "SKIP-dup", "date": "2026-05-12", "amount": "31.24", "type": "withdrawal", "description": "SQ *BLACK SHEEP CAFE 19 N UNIVER", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 72}, {"external_id": "apple:9f8ba228-b021-485c-bf75-a78b4e1bd5", "bucket": "SKIP-dup", "date": "2026-05-11", "amount": "39.57", "type": "withdrawal", "description": "AMAZON MKTPL*BF7BE7JO1440 TERRY", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 73}, {"external_id": "apple:2597e89d-2e92-4450-9f12-4b51a8423f", "bucket": "SKIP-dup", "date": "2026-05-11", "amount": "11.15", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 74}, {"external_id": "apple:b437e8ee-5976-42f7-bea1-3e0b88243a", "bucket": "SKIP-dup", "date": "2026-05-11", "amount": "5.52", "type": "withdrawal", "description": "CULVERS SOUTH JORDAN 3372 W SOUT", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 75}, {"external_id": "apple:3aa8acb0-b2d7-4d3f-ab2f-8d25ae83ab", "bucket": "SKIP-dup", "date": "2026-05-11", "amount": "3.49", "type": "withdrawal", "description": "HUDSON ST2380 1000 AIRPORT BLVD", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 76}, {"external_id": "apple:2ea83dee-5557-4bab-b624-b734c6a0dc", "bucket": "SKIP-dup", "date": "2026-05-10", "amount": "107.00", "type": "withdrawal", "description": "CLAUDE.AI SUBSCRIPTION548 MARKET", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 77}, {"external_id": "apple:c13fe320-f1af-4b3f-a201-f725e9c4da", "bucket": "SKIP-dup", "date": "2026-05-10", "amount": "10.56", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 78}, {"external_id": "apple:8e94b947-10eb-4f48-948b-a2cc323b93", "bucket": "SKIP-dup", "date": "2026-05-10", "amount": "4.27", "type": "withdrawal", "description": "SHEETZ 0353 5410 CAMPBELLS RUN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 79}, {"external_id": "apple:e4907916-4a9c-4b16-8f57-4ad509a5d4", "bucket": "SKIP-dup", "date": "2026-05-10", "amount": "21.00", "type": "withdrawal", "description": "SQ *NEEDLE & BEAN 320 CASTLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 80}, {"external_id": "apple:6f919944-db4a-4f24-b638-1d82264555", "bucket": "SKIP-dup", "date": "2026-05-09", "amount": "15.95", "type": "withdrawal", "description": "TST* RNK PITTSBURGH - 3610 FORBE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 81}, {"external_id": "apple:f364ad48-0b85-405f-9528-df1c5aa1c6", "bucket": "SKIP-dup", "date": "2026-05-09", "amount": "3.31", "type": "withdrawal", "description": "KUHNS BANKSVILLE 3125 BANKSVILLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 82}, {"external_id": "apple:94f8e1ca-e80b-4f54-a2e6-d6899c7569", "bucket": "SKIP-dup", "date": "2026-05-08", "amount": "5.55", "type": "withdrawal", "description": "SQ *REDHAWK COFFEE 120 MEYRAN AV", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 83}, {"external_id": "apple:a643712a-102f-4dcb-b9d3-8797f46c72", "bucket": "SKIP-dup", "date": "2026-05-08", "amount": "81.86", "type": "withdrawal", "description": "SUNOCO 8001687502 QPS339 COCHRAN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 84}, {"external_id": "apple:49ada98c-dc51-44dc-a85b-02f205961b", "bucket": "SKIP-dup", "date": "2026-05-08", "amount": "11.65", "type": "withdrawal", "description": "PEACOCK X6258 PREMIUM 30 ROCKEFE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 85}, {"external_id": "apple:27942d6c-da48-442b-81e9-9b9bfa02c1", "bucket": "SKIP-dup", "date": "2026-05-07", "amount": "25.20", "type": "withdrawal", "description": "SPO*MAMACITASMEXICANBI300 ADAMS", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 86}, {"external_id": "apple:d975f252-a7b4-4c3d-ae55-22ee9258f5", "bucket": "SKIP-dup", "date": "2026-05-07", "amount": "3.90", "type": "withdrawal", "description": "GOMOBILEPGH 2 232 BOULEVARD OF T", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 87}, {"external_id": "apple:ba13b7a4-c388-4910-90e4-678a270f3a", "bucket": "SKIP-dup", "date": "2026-05-06", "amount": "16.50", "type": "withdrawal", "description": "CRANBERRY FITNESS CENT1000 WESTI", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 88}, {"external_id": "apple:c7a2ec81-cab5-4a9b-a12c-bb39ef5919", "bucket": "SKIP-dup", "date": "2026-05-05", "amount": "28.16", "type": "withdrawal", "description": "RED ROBIN NO 460 1678 ROUTE 228", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 89}, {"external_id": "apple:32ae791e-e3ce-4cd9-9f7b-23de03425d", "bucket": "SKIP-dup", "date": "2026-05-04", "amount": "51.39", "type": "withdrawal", "description": "SUNOCO 8001687502 QPS339 COCHRAN", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 90}, {"external_id": "apple:494b495c-e31e-4aa2-8c4a-39ea47b07c", "bucket": "SKIP-dup", "date": "2026-05-04", "amount": "20.00", "type": "withdrawal", "description": "PAYPAL *ORDERENGINE 7700 EASTPOR", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 91}, {"external_id": "apple:60792aa3-b3cd-41df-a7a1-2bc4723a43", "bucket": "SKIP-dup", "date": "2026-05-04", "amount": "25.11", "type": "withdrawal", "description": "UPMC STUDENT INSURANCE600 GRANT", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 92}, {"external_id": "apple:fff3d3f6-d7f9-4c6e-9b04-b5bbc179b2", "bucket": "SKIP-dup", "date": "2026-05-03", "amount": "11.25", "type": "withdrawal", "description": "CHICK-FIL-A #01583 1700 ROUTE 22", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 93}, {"external_id": "apple:6770dc74-8a00-42ee-b7f8-f619cffbe3", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "3.95", "type": "withdrawal", "description": "SQ *LA GOURMANDINE 300 COCHRAN R", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 94}, {"external_id": "apple:4fd6a3eb-80de-48ad-abda-768be15f6e", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "21.65", "type": "withdrawal", "description": "MARKET DISTRICT #0014 7000 OXFOR", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 95}, {"external_id": "apple:a6dd04ad-f3cf-4636-9684-bcae39ea3f", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "107.73", "type": "withdrawal", "description": "PETCO 1819 59 FORT COUCH RD BETH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 96}, {"external_id": "apple:3dac8cfc-338e-4b4c-a3b9-62b61fc7b8", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "13.48", "type": "withdrawal", "description": "KUHNS BANKSVILLE 3125 BANKSVILLE", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 97}, {"external_id": "apple:f32e23e8-7ad6-4fde-b646-3da92778a6", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "5.00", "type": "withdrawal", "description": "PITT PARKING PAY STATI127 NORTH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 98}, {"external_id": "apple:51916533-619e-481b-8601-c8cfdeec9f", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "11.59", "type": "withdrawal", "description": "STARBUCKS STORE 27117 4022 FIFTH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 99}, {"external_id": "apple:71c45920-65b2-40ef-8e7d-27cc9aa312", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "14.00", "type": "withdrawal", "description": "PITT PARKING PAY STATI127 NORTH", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 100}, {"external_id": "apple:a5a2f67c-b765-495c-9e62-979446e27a", "bucket": "SKIP-dup", "date": "2026-05-02", "amount": "68.24", "type": "withdrawal", "description": "ROCK AUTO 6418 NORMANDY LANE MAD", "asset_account": "Apple Credit Card", "destination_account": null, "proposed_account": null, "proposed_account_id": null, "proposed_category": null, "proposed_budget": null, "suggestions": [], "review": false, "auto_tail": false, "plan_id": 101}]};
const BUDGETS = ["", "Needs", "Wants", "Savings"];
const rows = PLAN.rows || [];
// Per-row decision state, keyed by external_id (the stable id).
const state = {};
for (const r of rows) {
const isAuto = r.bucket === "CREATE" || r.bucket === "TRANSFER";
state[r.external_id] = {
approved: isAuto, // auto rows default-approved; clarity not
account: r.proposed_account || "",
account_id: (r.proposed_account_id != null) ? r.proposed_account_id : null,
category: r.proposed_category || "",
budget: r.proposed_budget || "",
comment: ""
};
}
function esc(s) {
return String(s == null ? "" : s)
.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
// Amount cell with explicit direction: deposit = green +in, withdrawal =
// red -out, transfer = purple between-accounts.
function amtCell(r) {
const t = r.type;
const sign = t === "deposit" ? "+" : t === "transfer" ? "⇄" : "";
const word = t === "deposit" ? "in" : t === "transfer" ? "xfer" : "out";
return `<td class="amt ${word}"><span class="dir">${sign}</span>` +
`$${esc(r.amount)} <span class="io">${word.toUpperCase()}</span></td>`;
}
function budgetOptions(sel) {
return BUDGETS.map(b =>
`<option value="${esc(b)}"${b===sel?" selected":""}>${esc(b||"—")}</option>`
).join("");
}
function decisionCell(id) {
const s = state[id];
return `<div class="toggle" data-id="${esc(id)}">
<button class="d-ok${s.approved?" on-ok":""}">Approve</button>
<button class="d-no${!s.approved?" on-no":""}">Deny</button></div>`;
}
function editableRow(r) {
const id = r.external_id, s = state[id];
const pill = r.bucket === "UNMATCHED"
? '<span class="pill unmatched">UNMATCHED</span>'
: r.bucket === "TRANSFER"
? '<span class="pill transfer">TRANSFER</span>'
: (r.review ? '<span class="pill review">REVIEW</span>'
: '<span class="pill create">CREATE</span>');
const canon = r.bucket === "TRANSFER"
? `Transfer &rarr; <b>${esc(r.destination_account || "?")}</b>`
: (r.proposed_account
? `Canonical account &rarr; <b>${esc(r.proposed_account)}</b>` +
(r.proposed_account_id != null
? ` <span style="color:#888">#${esc(r.proposed_account_id)}</span>`
: ` <span style="color:#888">(new)</span>`)
: `Canonical account &rarr; <b style="color:#c0392b">unset</b> ` +
`<span style="color:#888">&mdash; set it below</span>`);
let sugg = "";
if (r.suggestions && r.suggestions.length) {
sugg = `<div class="sugg">did you mean: ` +
r.suggestions.map(x =>
`<a data-id="${esc(id)}" data-acct="${esc(x)}">${esc(x)}</a>`
).join(", ") + `</div>`;
}
let catsugg = "";
if (r.category_suggestions && r.category_suggestions.length) {
catsugg = `<div class="sugg catsugg">try: ` +
r.category_suggestions.map(x =>
`<a data-id="${esc(id)}" data-cat="${esc(x)}">${esc(x)}</a>`
).join(", ") + `</div>`;
}
let budsugg = "";
if (r.budget_suggestions && r.budget_suggestions.length) {
budsugg = `<div class="sugg budsugg">` +
r.budget_suggestions.map(x =>
`<a data-id="${esc(id)}" data-bud="${esc(x)}">${esc(x)}</a>`
).join(", ") + `</div>`;
}
const tail = r.auto_tail
? ` <span class="pill autotail">auto-tail</span>` : "";
return `<tr data-id="${esc(id)}" class="${r.bucket==="TRANSFER"?"is-transfer":""}">
<td class="pid">#${esc(r.plan_id || "")}</td>
<td>${esc(r.date)}</td>
${amtCell(r)}
<td class="desc">${esc(r.description)}
<small>${esc(r.asset_account)} ${pill}${tail}</small>
<div class="canon" style="margin-top:3px;font-size:12px">${canon}</div>${sugg}</td>
<td><input type="text" class="f-account" list="acctlist"
value="${esc(s.account)}" placeholder="pick / type account"></td>
<td><input type="text" class="f-category" list="catlist"
value="${esc(s.category)}" placeholder="pick existing category">${catsugg}</td>
<td><select class="f-budget">${budgetOptions(s.budget)}</select>${budsugg}</td>
<td><input type="text" class="f-comment" value="${esc(s.comment)}"
placeholder="note"></td>
<td>${decisionCell(id)}</td></tr>`;
}
function readonlyRow(r) {
let tgt = "";
if (r.bucket === "TRANSFER") tgt = "→ " + esc(r.destination_account || "?");
else if (r.proposed_account) tgt = "→ " + esc(r.proposed_account) +
(r.proposed_account_id != null ? " #" + esc(r.proposed_account_id)
: " (new)");
else if (r.bucket === "SKIP-dup") tgt = "dup";
const cls = {"SKIP-dup":"dup","UNMATCHED":"unmatched","TRANSFER":"transfer",
"REVIEW":"review","CREATE":"create"}[r.bucket] || "";
return `<tr class="readonly${r.bucket==="TRANSFER"?" is-transfer":""}">
<td class="pid">#${esc(r.plan_id || "")}</td>
<td>${esc(r.date)}</td>${amtCell(r)}
<td>${esc(r.type)}</td><td>${esc(r.description)}${r.auto_tail?' <span class="pill autotail">auto-tail</span>':''}</td>
<td><span class="pill ${cls}">${esc(r.bucket)}</span></td>
<td>${tgt}</td></tr>`;
}
// Group a section's rows by the statement they came from (PNC / Apple /
// Costco ...) with a subheader per account, so a multi-statement rebuild is
// reviewable account-by-account instead of one undifferentiated list.
function groupByAccount(list, rowFn, cols) {
const order = [], groups = {};
for (const r of list) {
const a = r.group_account || r.asset_account || "(unknown)";
if (!(a in groups)) { groups[a] = []; order.push(a); }
groups[a].push(r);
}
return order.map(a =>
`<tr class="grp"><td colspan="${cols}">${esc(a)} ` +
`<span class="sub">${groups[a].length}</span></td></tr>` +
groups[a].map(rowFn).join("")).join("");
}
function render() {
const clarity = rows.filter(r =>
r.bucket === "UNMATCHED" || r.bucket === "REVIEW");
const auto = rows.filter(r =>
r.bucket === "CREATE" || r.bucket === "TRANSFER");
const tbC = document.getElementById("tb-clarity");
const tbA = document.getElementById("tb-auto");
const tbAll = document.getElementById("tb-all");
tbC.innerHTML = groupByAccount(clarity, editableRow, 9);
tbA.innerHTML = groupByAccount(auto, editableRow, 9);
tbAll.innerHTML = groupByAccount(rows, readonlyRow, 7);
document.getElementById("empty-clarity").hidden = clarity.length > 0;
document.getElementById("empty-auto").hidden = auto.length > 0;
const nApproved = Object.values(state).filter(s => s.approved).length;
document.getElementById("counts").innerHTML =
`<span><b>${rows.length}</b> rows</span>` +
`<span><b>${clarity.length}</b> need clarity</span>` +
`<span><b>${auto.length}</b> auto</span>` +
`<span><b>${rows.filter(r=>r.bucket==="SKIP-dup").length}</b> dup</span>` +
`<span><b>${nApproved}</b> approved</span>`;
}
// --- event wiring (delegated, so re-render keeps working) ------------------
document.body.addEventListener("input", e => {
const tr = e.target.closest("tr[data-id]");
if (!tr) return;
const id = tr.dataset.id, s = state[id];
if (e.target.classList.contains("f-account")) {
s.account = e.target.value; s.account_id = null; // typed name => re-resolve
} else if (e.target.classList.contains("f-category")) {
s.category = e.target.value;
} else if (e.target.classList.contains("f-budget")) {
s.budget = e.target.value;
} else if (e.target.classList.contains("f-comment")) {
s.comment = e.target.value;
}
});
document.body.addEventListener("click", e => {
// suggestion chip -> fill account
if (e.target.matches(".sugg a") && e.target.dataset.acct != null) {
const id = e.target.dataset.id;
state[id].account = e.target.dataset.acct;
state[id].account_id = null;
render();
return;
}
if (e.target.matches(".catsugg a") && e.target.dataset.cat != null) {
const id = e.target.dataset.id;
state[id].category = e.target.dataset.cat;
render();
return;
}
if (e.target.matches(".budsugg a") && e.target.dataset.bud != null) {
const id = e.target.dataset.id;
state[id].budget = e.target.dataset.bud;
render();
return;
}
const tog = e.target.closest(".toggle");
if (tog) {
const id = tog.dataset.id;
if (e.target.classList.contains("d-ok")) state[id].approved = true;
else if (e.target.classList.contains("d-no")) state[id].approved = false;
render();
}
});
document.getElementById("approveAuto").addEventListener("click", () => {
for (const r of rows) {
if (r.bucket === "CREATE" || r.bucket === "TRANSFER")
state[r.external_id].approved = true;
}
render();
});
document.getElementById("export").addEventListener("click", () => {
// Only emit rows the user can act on (clarity + auto). SKIP-dup rows are
// read-only context and are never posted, so they stay out of decisions.
const out = {};
for (const r of rows) {
if (r.bucket === "SKIP-dup") continue;
const s = state[r.external_id];
out[r.external_id] = {
approved: !!s.approved,
account: s.account || null,
account_id: (s.account_id != null) ? s.account_id : null,
category: s.category || null,
budget: s.budget || null,
comment: s.comment || ""
};
}
const blob = new Blob([JSON.stringify(out, null, 2)],
{ type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url; a.download = "decisions.json";
document.body.appendChild(a); a.click(); a.remove();
setTimeout(() => URL.revokeObjectURL(url), 1000);
});
// Constrain category/account inputs to what already exists in Firefly, so
// the user clicks/filters real values instead of free-typing near-duplicates
// ("Restaurants" vs "Restaurant" vs "Dining"). New values are still possible
// but it's a deliberate type-through, not the path of least resistance.
function buildList(id, items) {
const dl = document.createElement("datalist");
dl.id = id;
for (const v of (items || [])) {
const o = document.createElement("option");
o.value = v;
dl.appendChild(o);
}
document.body.appendChild(dl);
}
buildList("catlist", (PLAN.meta && PLAN.meta.categories) || []);
buildList("acctlist", (PLAN.meta && PLAN.meta.accounts) || []);
render();
</script>
</body>
</html>