From e446c4097ac177681974ef1a1dd805cb87463f2f Mon Sep 17 00:00:00 2001 From: Dane Sabo Date: Mon, 25 May 2026 21:05:38 -0400 Subject: [PATCH] Migration: rebuild battle-test learnings + opening-balance orphan fix - build_rebuild_dataset.py: subtract orphan paired-transfer amounts from destination card's derived opening; html.unescape descriptions. - merchant_map.json: +110 auto-tail rules from rebuild long-tail, +20 recurring rules + 135 auto-cluster acceptances; stripped all cached account_ids; Rock Auto -> Z(Mizumi) review:true; Duquesne Light -> Utilities; categories stripped from _auto_tail rules per user policy. - migration/README.md: 'Lessons from the first rebuild' section. - migration/rebuild_clusters.{json,md}: clustering proposal artifact. --- merchant_map.json | 1771 +++++++++++++++++++++++++++- migration/README.md | 29 + migration/build_rebuild_dataset.py | 22 +- migration/rebuild_review.html | 25 +- sam-bachelor-party-invoice.pdf | 86 ++ 5 files changed, 1876 insertions(+), 57 deletions(-) create mode 100644 sam-bachelor-party-invoice.pdf diff --git a/merchant_map.json b/merchant_map.json index 59a78a6..19668ab 100644 --- a/merchant_map.json +++ b/merchant_map.json @@ -5,10 +5,1711 @@ "daily_cash_adjustment": "'DAILY CASH ADJUSTMENT' => Apple Card Daily Cash; the ADJUSTMENT is NEGATIVE cashback income (clawback on a return). Sign follows amount; revenue acct 'Apple Card Cashback'." }, "rules": [ + { + "match": "SETTEBELLO LLC - S260 S", + "account_name": "Settebello Llc", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "AIRBNB * HMJPZQ3FCN 888 BRANNAN", + "account_name": "Airbnb Hmjpzq Fcn Brannan", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "DOLLY'S BOOKSTORE", + "account_name": "Dolly's Bookstore", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MAMACITASMEXICANBI300 ADAMS", + "account_name": "Mamacitasmexicanbi Adams", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "EINSTEIN BROS. BENEQPS3700 OHARA", + "account_name": "Einstein Bros. Beneqps Ohara", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MARIO'S EAST SIDE5442 WALNU", + "account_name": "Mario's East Side Walnu", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "RENTAPPLICATION", + "account_name": "Rentapplication", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "POTOMAC BQPS1530 POTOM", + "account_name": "Potomac Bqps Potom", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "EAT_N_PARK #0044 100 PARK MANOR", + "account_name": "Eat Park Park Manor", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "GIANT-EAGLE", + "account_name": "Giant Eagle", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "J. CREW FACTORY", + "account_name": "J. Crew Factory", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BELVEDERES ULTRA-D4016 BUTLE", + "account_name": "Belvederes Ultra Butle", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "WAL-MART", + "account_name": "Wal Mart", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "NASCAR CUP SERIES", + "account_name": "Nascar Cup Series", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "1Z9F1752039500088455 GLENLAK", + "account_name": "Glenlak", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MARGAUX - EAST LIB5947 PENN", + "account_name": "Margaux East Lib Penn", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "DEY'S DONUTS & HOT1190 N", + "account_name": "Dey's Donuts Hot", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HOOVER DAM PARK/TOUR 81 HOOVER A", + "account_name": "Hoover Dam Park Tour", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LSP*NOMAD TAQUERIA BEE18485 W CO", + "account_name": "Lsp Nomad Taqueria Bee", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LOVE'S", + "account_name": "Love's", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CTLP*3D VENDING OH 10456 RIVERSI", + "account_name": "Ctlp Vending Oh Riversi", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ROLLIER'S HARDWARE", + "account_name": "Rollier's Hardware", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CTLP*VEND 1800-766-8722590 ELM R", + "account_name": "Ctlp Vend Elm", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CHESTNUT HILLS - SQUIR5889 FORBE", + "account_name": "Chestnut Hills Squir Forbe", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CVS/PHARMACY #05094 328 COCHRAN", + "account_name": "Cvs Pharmacy Cochran", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PITT-CAMPUS REC OFFICE3719 TERRA", + "account_name": "Pitt Campus Rec Office", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CONDADO TACOS - D971 LIBERT", + "account_name": "Condado Tacos Libert", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SHORTY'S NORTH SH353 N SHOR", + "account_name": "Shorty's North Sh Shor", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CAPPY'SCAFE", + "account_name": "Cappy'scafe", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SHREEMADHQPS101 ST JOH", + "account_name": "Shreemadhqps St Joh", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CVS/PHARMACY #02348 3422 FORBES", + "account_name": "Cvs Pharmacy Forbes", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "TINA'S COCKTAIL B4114 MAIN", + "account_name": "Tina's Cocktail Main", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "WITHDRAWAL XXXXX8118 WITHDRAWAL XXXXX8118", + "account_name": "Withdrawal Xxxxx8118 Withdrawal Xxxxx8118", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "OWLFEATHERS WATERC5860 DARLI", + "account_name": "Owlfeathers Waterc5860 Darli", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SHAKE SHACK CONC A SLC474", + "account_name": "Shake Shack Conc A Slc474", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SETTEBELLO LLC S260 S", + "account_name": "Settebello Llc S260 S", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "DIAMOND PARKING", + "account_name": "Diamond Parking", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "UTAH MAIN CAMPUS STORE270 S", + "account_name": "Utah Main Campus Store270 S", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "UU VISITOR PARKING Q40311 FORT", + "account_name": "Uu Visitor Parking Q40311 Fort", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "AIRBNB HMJPZQ3FCN", + "account_name": "Airbnb Hmjpzq3fcn", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CRYSTAL INN SLC", + "account_name": "Crystal Inn Slc", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PARK CITY DESSERTS401 MAIN S", + "account_name": "Park City Desserts401 Main S", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "7-ELEVEN FOOD STORES 525 MAIN ST", + "account_name": "7-eleven Food Stores 525 Main St", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PARK CITY PARKING SERV445 MARSAC", + "account_name": "Park City Parking Serv445 Marsac", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "DOLLYS BOOKSTORE", + "account_name": "Dollys Bookstore", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BLACK SHEEP CAFE", + "account_name": "Black Sheep Cafe", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CULVERS SOUTH JORDAN", + "account_name": "Culvers South Jordan", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HUDSON ST2380", + "account_name": "Hudson St2380", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SPO MAMACITASMEXICANBI300 ADAMS", + "account_name": "Spo Mamacitasmexicanbi300 Adams", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CRANBERRY FITNESS CENT1000 WESTI", + "account_name": "Cranberry Fitness Cent1000 Westi", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "RED ROBIN NO", + "account_name": "Red Robin No", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ORDERENGINE", + "account_name": "Orderengine", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ROCK AUTO", + "account_name": "Rock Auto", + "type": "withdrawal", + "category": "Z (Mizumi)", + "review": true + }, + { + "match": "SP ICT BILLET", + "account_name": "Sp Ict Billet", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SALOON OF", + "account_name": "Saloon Of", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "GOING GOING GONE", + "account_name": "Going Going Gone", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "J CREW FACTORY", + "account_name": "J Crew Factory", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "EINSTEIN BROS BENEQPS3700 OHARA", + "account_name": "Einstein Bros Beneqps3700 Ohara", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PA COURTS FINES AND CO601 COMMON", + "account_name": "Pa Courts Fines And Co601 Common", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "RAISING CANES", + "account_name": "Raising Canes", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MARIOS EAST SIDE5442 WALNU", + "account_name": "Marios East Side5442 Walnu", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "JAPANPARTSC TOKYOTO MINATOKU KIT", + "account_name": "Japanpartsc Tokyoto Minatoku Kit", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ZG RENTAPPLICATION", + "account_name": "Zg Rentapplication", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MT LEBANON - PARKMOBIL710 WASHIN", + "account_name": "Mt Lebanon - Parkmobil710 Washin", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MT. LEBANON - FLOWBIRD710 WASHIN", + "account_name": "Mt. Lebanon - Flowbird710 Washin", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SP DARN TOUGH", + "account_name": "Sp Darn Tough", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BP 1797700POTOMAC BQPS1530 POTOM", + "account_name": "Bp 1797700potomac Bqps1530 Potom", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FIORI S PIZZARIA", + "account_name": "Fiori S Pizzaria", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BIG BUCK SPORT SHOP", + "account_name": "Big Buck Sport Shop", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "OMAR S HALAL GRILL", + "account_name": "Omar S Halal Grill", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "JIMMY JOHNS", + "account_name": "Jimmy Johns", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "THE TIRE RACK", + "account_name": "The Tire Rack", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FORBES STREET QPS3955 FORBES", + "account_name": "Forbes Street Qps3955 Forbes", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "EAT N PARK", + "account_name": "Eat N Park", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PAGE DAIRY MART", + "account_name": "Page Dairy Mart", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FREETAXUSACOM PO BOX", + "account_name": "Freetaxusacom Po Box", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "KELLYS WAY VALERO", + "account_name": "Kellys Way Valero", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BARNES & NOBLE", + "account_name": "Barnes & Noble", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BELVEDERES ULTRA D4016 BUTLE", + "account_name": "Belvederes Ultra D4016 Butle", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "TRACE BREWING", + "account_name": "Trace Brewing", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PITT UNIV PARKING", + "account_name": "Pitt Univ Parking", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LONGHORN STK EC", + "account_name": "Longhorn Stk Ec", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "WAL MART", + "account_name": "Wal Mart", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FOXS PIZZA DEN BROOKLI902 BROOKL", + "account_name": "Foxs Pizza Den Brookli902 Brookl", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "TM NASCAR CUP SERIES", + "account_name": "Tm Nascar Cup Series", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "7-ELEVEN 36193 999 GREENTREE RD", + "account_name": "7-eleven 36193 999 Greentree Rd", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ROW HOUSE CINEMA", + "account_name": "Row House Cinema", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "UPS 1Z9F1752039500088455 GLENLAK", + "account_name": "Ups 1z9f1752039500088455 Glenlak", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PAINTING WITH A TWIST", + "account_name": "Painting With A Twist", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MARGAUX EAST LIB5947 PENN", + "account_name": "Margaux East Lib5947 Penn", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "THRIFTY SKI RENTAL", + "account_name": "Thrifty Ski Rental", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "IRON BORN PIZZA", + "account_name": "Iron Born Pizza", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PAPA JS TWIN PLAZA2016 SMALL", + "account_name": "Papa Js Twin Plaza2016 Small", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LOWES", + "account_name": "Lowes", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LGB BUSINESS JRN SHOP LONG", + "account_name": "Lgb Business Jrn Shop Long", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "DEYS DONUTS & HOT1190 N", + "account_name": "Deys Donuts & Hot1190 N", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SENOR BIRRIA LOS ALAMI11151 LOS", + "account_name": "Senor Birria Los Alami11151 Los", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HOOVER DAM SOUVENIR AN81 HOOVER", + "account_name": "Hoover Dam Souvenir An81 Hoover", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CULVERS KINGMAN AIRWAY1737 AIRWA", + "account_name": "Culvers Kingman Airway1737 Airwa", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SP NEVER SUMMER IND", + "account_name": "Sp Never Summer Ind", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HOOVER DAM PARK TOUR", + "account_name": "Hoover Dam Park Tour", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ROCK GARDEN EATERY670 EAST H", + "account_name": "Rock Garden Eatery670 East H", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "IN-N-OUT LV - RUSSELL 3397 W. RU", + "account_name": "In-n-out Lv - Russell 3397 W. Ru", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "EXXON RR THOMPSON 7ELE460 SOUTH", + "account_name": "Exxon Rr Thompson 7ele460 South", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ORDERVILLE ENTP SINCLA15 E STATE", + "account_name": "Orderville Entp Sincla15 E State", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "LSP NOMAD TAQUERIA BEE18485 W", + "account_name": "Lsp Nomad Taqueria Bee18485 W", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "KINGSIDE DINER EX6170 DELMA", + "account_name": "Kingside Diner Ex6170 Delma", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "AC HOTEL CLAYTON", + "account_name": "Ac Hotel Clayton", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CTLP 3D VENDING", + "account_name": "Ctlp 3d Vending", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "AIR FORCE MUSEUM F1100 SPAAT", + "account_name": "Air Force Museum F1100 Spaat", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PTC EZ PASS AUTO RE", + "account_name": "Ptc Ez Pass Auto Re", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "TRADER JOE S", + "account_name": "Trader Joe S", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "STEAM PURCHASE", + "account_name": "Steam Purchase", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "ROLLIERS HARDWARE", + "account_name": "Rolliers Hardware", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FIORI S PIZZA", + "account_name": "Fiori S Pizza", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PARKING", + "account_name": "Parking", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "GREY PARROT CONSIG322 CASTLE", + "account_name": "Grey Parrot Consig322 Castle", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "AMK ACRISURE CONCESSIO500 ART RO", + "account_name": "Amk Acrisure Concessio500 Art Ro", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PANDA SUPERMARKET", + "account_name": "Panda Supermarket", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "GATEWAYCENTER", + "account_name": "Gatewaycenter", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BURGHERS BREWING MILLV400 GRANT", + "account_name": "Burghers Brewing Millv400 Grant", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CHESTNUT HILLS SQUIR5889 FORBE", + "account_name": "Chestnut Hills Squir5889 Forbe", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "STBC PITTSBURGH", + "account_name": "Stbc Pittsburgh", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HALF CROWN HILL OR600 N", + "account_name": "Half Crown Hill Or600 N", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PITT CAMPUS REC OFFICE3719 TERRA", + "account_name": "Pitt Campus Rec Office3719 Terra", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CONVENTION CTR GARAGE", + "account_name": "Convention Ctr Garage", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "CONDADO TACOS D971 LIBERT", + "account_name": "Condado Tacos D971 Libert", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SHORTYS NORTH SH353 N SHOR", + "account_name": "Shortys North Sh353 N Shor", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PONDEROSA GOLF COURSE", + "account_name": "Ponderosa Golf Course", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "THE DOG PENN", + "account_name": "The Dog Penn", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SPO CAPPYSCAFE", + "account_name": "Spo Cappyscafe", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "MARATHON PETRO188011", + "account_name": "Marathon Petro188011", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BP 2695000SHREEMADHQPS101", + "account_name": "Bp 2695000shreemadhqps101", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "HOP FARM BREWING", + "account_name": "Hop Farm Brewing", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "FOOD FOR THOUGHT", + "account_name": "Food For Thought", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "GOODWILL OF SW", + "account_name": "Goodwill Of Sw", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "7-ELEVEN 40172 3505 LIBRARY RD C", + "account_name": "7-eleven 40172 3505 Library Rd C", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "SP MR JONES WATCHES", + "account_name": "Sp Mr Jones Watches", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "TINAS COCKTAIL B4114 MAIN", + "account_name": "Tinas Cocktail B4114 Main", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "PITT BOOK CENTER", + "account_name": "Pitt Book Center", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "BUFFALO WILD WNGS", + "account_name": "Buffalo Wild Wngs", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "COSTCO ANNUAL MEMBERSHIP RE", + "account_name": "Costco Annual Membership Re", + "type": "withdrawal", + "_auto_tail": true + }, + { + "match": "RNK PITTSBURGH", + "account_name": "Roots Natural Kitchen", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "WWW COSTCO COM", + "account_name": "Costco", + "category": "Groceries", + "type": "withdrawal" + }, + { + "match": "HOFBRAUHAUS", + "account_name": "Hofbrauhaus Pittsburgh", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "HEMINGWAY", + "account_name": "Hemingway's Cafe", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "PAM PITTSBURGH PARKING", + "account_name": "Pittsburgh Parking Authority", + "category": "Auto: Parking", + "type": "withdrawal" + }, + { + "match": "BOROUGH OF DORMONT", + "account_name": "Borough of Dormont", + "category": "Auto: Parking", + "type": "withdrawal" + }, + { + "match": "BRUSTER", + "account_name": "Bruster's", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "COSTCO ONLINE RX", + "account_name": "Costco Pharmacy", + "category": "Medical", + "type": "withdrawal" + }, + { + "match": "DICKS SPORTING|DICK'S SPORTING", + "account_name": "Dick's Sporting Goods", + "category": "Clothes", + "type": "withdrawal", + "regex": true + }, + { + "match": "FUKU TEA", + "account_name": "Fuku Tea", + "category": "Coffee", + "type": "withdrawal" + }, + { + "match": "SPORTS CAR CLUB", + "account_name": "SCCA", + "category": "Recreation: Racing", + "type": "withdrawal" + }, + { + "match": "WHOLE FOODS", + "account_name": "Whole Foods", + "category": "Groceries", + "type": "withdrawal" + }, + { + "match": "VILLA FRESH ITALI", + "account_name": "Villa Fresh Italian", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "MT LEBANON GOLF", + "account_name": "Mt Lebanon Golf Course", + "category": "Recreation: Golf", + "type": "withdrawal" + }, + { + "match": "BOOZY BARR", + "account_name": "Boozy Barre", + "category": "Groceries", + "type": "withdrawal" + }, + { + "match": "SMITHS-FUEL", + "account_name": "Smith's Fuel", + "category": "Auto: Fuel", + "type": "withdrawal" + }, + { + "match": "SUMMIT RACING", + "account_name": "Summit Racing", + "category": "Z (Mizumi)", + "type": "withdrawal" + }, + { + "match": "MILKSHAKE FACT", + "account_name": "The Milkshake Factory", + "category": "Restaurants", + "type": "withdrawal" + }, + { + "match": "WM SUPERCENTER", + "account_name": "Walmart", + "category": "Groceries", + "type": "withdrawal" + }, + { + "match": "ZOHO", + "account_name": "Zoho", + "category": "Subscriptions", + "type": "withdrawal" + }, + { + "match": "GOMOBILEPGH", + "account_name": "GomobilePGH", + "type": "withdrawal", + "category": "Auto: Parking" + }, + { + "match": "AUTOZONE", + "account_name": "Autozone", + "type": "withdrawal", + "category": "Auto: Fees" + }, + { + "match": "SUNOCO", + "account_name": "Sunoco", + "type": "withdrawal", + "category": "Auto: Fuel" + }, + { + "match": "COSTCO WHSE", + "account_name": "Costco Whse", + "type": "withdrawal" + }, + { + "match": "HARBOR FREIGHT TOOLS", + "account_name": "Harbor Freight Tools", + "type": "withdrawal", + "category": "Tools" + }, + { + "match": "PETCO", + "account_name": "Petco", + "type": "withdrawal", + "category": "Pets" + }, + { + "match": "CHICK-FIL-A", + "account_name": "Chick-fil-A", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "COSTCO GAS", + "account_name": "Costco Gas", + "type": "withdrawal", + "category": "Auto: Fuel" + }, + { + "match": "D J*WSJ", + "account_name": "D J*wsj", + "type": "withdrawal", + "category": "Subscriptions" + }, + { + "match": "ROCKAUTO", + "account_name": "Rockauto", + "type": "withdrawal", + "category": "Z (Mizumi)", + "review": true + }, + { + "match": "UNIVERSITY CLUB", + "account_name": "University Club", + "type": "withdrawal", + "category": "Education" + }, + { + "match": "CHIKN OAKLAND", + "account_name": "Chikn Oakland", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "RAISING CANE'S", + "account_name": "Raising Cane's", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "BARNES & NOBLE", + "account_name": "Barnes & Noble", + "type": "withdrawal" + }, + { + "match": "LOWE'S", + "account_name": "Lowe's", + "type": "withdrawal" + }, + { + "match": "PMUSA", + "account_name": "PMUSA", + "type": "withdrawal", + "category": "Other" + }, + { + "match": "HOME DEPOT", + "account_name": "Home Depot", + "type": "withdrawal" + }, + { + "match": "REI", + "account_name": "REI", + "type": "withdrawal" + }, + { + "match": "TARGET", + "account_name": "Target", + "type": "withdrawal" + }, + { + "match": "THE SALOON OF", + "account_name": "The Saloon Of", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "BEST BUY", + "account_name": "Best Buy", + "type": "withdrawal" + }, + { + "match": "CHECK", + "account_name": "Check", + "type": "withdrawal" + }, + { + "match": "EXPEDIA", + "account_name": "Expedia", + "type": "withdrawal", + "category": "Travel" + }, + { + "match": "MICHAELS STORES", + "account_name": "Michaels Stores", + "type": "withdrawal", + "category": "Other" + }, + { + "match": "RITA'S", + "account_name": "Rita's", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "ALS CORNER", + "account_name": "Als Corner", + "type": "withdrawal" + }, + { + "match": "CVS PHARMACY", + "account_name": "CVS Pharmacy", + "type": "withdrawal", + "category": "Medical" + }, + { + "match": "DUNKIN", + "account_name": "Dunkin", + "type": "withdrawal", + "category": "Coffee" + }, + { + "match": "FIVE GUYS", + "account_name": "Five Guys", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "REDHAWK COFFEE", + "account_name": "Redhawk Coffee", + "type": "withdrawal", + "category": "Coffee" + }, + { + "match": "SPORTSMANS WAREHOUSE", + "account_name": "Sportsmans Warehouse", + "type": "withdrawal" + }, + { + "match": "TACO BELL", + "account_name": "Taco Bell", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "TNT PIZZA", + "account_name": "TNT Pizza", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "ACT CNTYALLEGHENYPRK", + "account_name": "Act Cntyalleghenyprk", + "type": "withdrawal" + }, + { + "match": "BUTTERJOINT", + "account_name": "Butterjoint", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "CTLP*CSC SERVICEWORKS", + "account_name": "Ctlp*csc Serviceworks", + "type": "withdrawal" + }, + { + "match": "FIORI'S PIZZARIA", + "account_name": "Fiori's Pizzaria", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "GET GO", + "account_name": "Get Go", + "type": "withdrawal" + }, + { + "match": "HEMINGWAY'S CAFE", + "account_name": "Hemingway's Cafe", + "type": "withdrawal", + "category": "Coffee" + }, + { + "match": "HINGE", + "account_name": "Hinge", + "type": "withdrawal" + }, + { + "match": "J.CREW FACTORY", + "account_name": "J.Crew Factory", + "type": "withdrawal" + }, + { + "match": "MOONLIT BURGERS", + "account_name": "Moonlit Burgers", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "PARKWHIZ", + "account_name": "ParkWhiz", + "type": "withdrawal" + }, + { + "match": "REI COM", + "account_name": "Rei Com", + "type": "withdrawal" + }, + { + "match": "T-GATEWAY CENTER", + "account_name": "T-Gateway Center", + "type": "withdrawal" + }, + { + "match": "TRADER JOE'S", + "account_name": "Trader Joe's", + "type": "withdrawal", + "category": "Groceries" + }, + { + "match": "UBER *TRIP", + "account_name": "Uber *trip", + "type": "withdrawal" + }, + { + "match": "WHOLEFOODS PIT", + "account_name": "Wholefoods Pit", + "type": "withdrawal", + "category": "Groceries" + }, + { + "match": "AMMOJOY LLC", + "account_name": "Ammojoy Llc", + "type": "withdrawal" + }, + { + "match": "AMZ*VEDDER HOLSTERS", + "account_name": "Amz*vedder Holsters", + "type": "withdrawal" + }, + { + "match": "ARCO", + "account_name": "Arco", + "type": "withdrawal" + }, + { + "match": "BABY GEE", + "account_name": "Baby Gee", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "BLUE ALPHA", + "account_name": "Blue Alpha", + "type": "withdrawal" + }, + { + "match": "BR FACTORY", + "account_name": "Br Factory", + "type": "withdrawal" + }, + { + "match": "BRILLOBOX", + "account_name": "Brillobox", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "CRFS ONLY", + "account_name": "Crfs Only", + "type": "withdrawal" + }, + { + "match": "CTLP VEND", + "account_name": "Ctlp Vend", + "type": "withdrawal" + }, + { + "match": "CYCLE GEAR", + "account_name": "Cycle Gear", + "type": "withdrawal" + }, + { + "match": "DAKOTA WATCH", + "account_name": "Dakota Watch", + "type": "withdrawal" + }, + { + "match": "DELTA", + "account_name": "DELTA", + "type": "withdrawal" + }, + { + "match": "FITBOD", + "account_name": "Fitbod", + "type": "withdrawal" + }, + { + "match": "FLYING J", + "account_name": "Flying J", + "type": "withdrawal" + }, + { + "match": "FORBES BAKERY", + "account_name": "Forbes Bakery", + "type": "withdrawal" + }, + { + "match": "FUJI SUSHI", + "account_name": "Fuji Sushi", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "GAMMA SPORTS", + "account_name": "Gamma Sports", + "type": "withdrawal" + }, + { + "match": "GAP OUTLET", + "account_name": "Gap Outlet", + "type": "withdrawal" + }, + { + "match": "GOLF GALAXY", + "account_name": "Golf Galaxy", + "type": "withdrawal" + }, + { + "match": "GRNDCYNASSNVCP", + "account_name": "Grndcynassnvcp", + "type": "withdrawal" + }, + { + "match": "HITCHHIKER BREWING", + "account_name": "Hitchhiker Brewing", + "type": "withdrawal" + }, + { + "match": "INBOX HEALTH", + "account_name": "Inbox Health", + "type": "withdrawal", + "category": "Medical" + }, + { + "match": "JIMMY JOHN'S", + "account_name": "Jimmy John's", + "type": "withdrawal" + }, + { + "match": "KUHN'S MCKNIGHT", + "account_name": "Kuhn's Mcknight", + "type": "withdrawal" + }, + { + "match": "LORELEI", + "account_name": "Lorelei", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "LOVES", + "account_name": "Loves", + "type": "withdrawal" + }, + { + "match": "MOMOYAO STUDIO", + "account_name": "Momoyao Studio", + "type": "withdrawal" + }, + { + "match": "NORTHSHORE GARAGE", + "account_name": "Northshore Garage", + "type": "withdrawal", + "category": "Auto: Parking" + }, + { + "match": "ORBIS CAFFE", + "account_name": "Orbis Caffe", + "type": "withdrawal" + }, + { + "match": "OUTLOOK INN", + "account_name": "Outlook Inn", + "type": "withdrawal" + }, + { + "match": "PANERA BREAD", + "account_name": "Panera Bread", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "PEPBOYS STORE", + "account_name": "Pepboys Store", + "type": "withdrawal" + }, + { + "match": "PITT RACE", + "account_name": "Pitt Race", + "type": "withdrawal" + }, + { + "match": "RANGE", + "account_name": "Range", + "type": "withdrawal" + }, + { + "match": "RENT APPLICATION", + "account_name": "Rent Application", + "type": "withdrawal", + "category": "Rent" + }, + { + "match": "REVZILLA MOTORSPORTS", + "account_name": "Revzilla Motorsports", + "type": "withdrawal" + }, + { + "match": "RNK PITTSBURGH", + "account_name": "RNK Pittsburgh", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "ROLLIER HARDWARE", + "account_name": "Rollier Hardware", + "type": "withdrawal" + }, + { + "match": "ROSS STORES", + "account_name": "Ross Stores", + "type": "withdrawal" + }, + { + "match": "RUGGERS PUB", + "account_name": "Ruggers Pub", + "type": "withdrawal" + }, + { + "match": "SIMONES", + "account_name": "Simones", + "type": "withdrawal" + }, + { + "match": "SNOW.COM/VAIL RESORTS", + "account_name": "Snow.Com/vail Resorts", + "type": "withdrawal" + }, + { + "match": "SP PARTIFY", + "account_name": "Sp Partify", + "type": "withdrawal" + }, + { + "match": "TELNYX LLC", + "account_name": "Telnyx Llc", + "type": "withdrawal" + }, + { + "match": "THE EXCHANGE", + "account_name": "The Exchange", + "type": "withdrawal" + }, + { + "match": "THE PORCH", + "account_name": "The Porch", + "type": "withdrawal" + }, + { + "match": "TROPHYSMACK", + "account_name": "Trophysmack", + "type": "withdrawal" + }, + { + "match": "TWILIO INC", + "account_name": "Twilio Inc", + "type": "withdrawal" + }, + { + "match": "UNDERGROUNDSHIRTS.COM", + "account_name": "undergroundshirts.com", + "type": "withdrawal" + }, + { + "match": "UPTOWN COFFEE", + "account_name": "Uptown Coffee", + "type": "withdrawal", + "category": "Coffee" + }, + { + "match": "UU STOREFRONT-CAMPUS", + "account_name": "Uu Storefront-campus", + "type": "withdrawal" + }, + { + "match": "WALMART", + "account_name": "Walmart", + "type": "withdrawal", + "category": "Auto: Parking" + }, + { + "match": "WP*PITTRACE.COM", + "account_name": "wp*pittrace.com", + "type": "withdrawal" + }, + { + "match": "APPLE SERVICES", + "account_name": "Apple Services", + "type": "withdrawal" + }, + { + "match": "APPLE STORE", + "account_name": "Apple Store", + "type": "withdrawal" + }, + { + "match": "CAPPY'S CAFE", + "account_name": "Cappy's Cafe", + "type": "withdrawal", + "category": "Coffee" + }, + { + "match": "COSTCO CASHBACK", + "account_name": "Costco Cashback", + "type": "withdrawal" + }, + { + "match": "CTLP*LAUREL FOODSYSTEM", + "account_name": "Ctlp*laurel Foodsystem", + "type": "withdrawal" + }, + { + "match": "DAVID PABST", + "account_name": "David Pabst", + "type": "withdrawal" + }, + { + "match": "FACEBOOK MARKETPLACE", + "account_name": "Facebook Marketplace", + "type": "withdrawal", + "category": "Groceries" + }, + { + "match": "GOOGLE", + "account_name": "Google", + "type": "withdrawal" + }, + { + "match": "HOFBRAUHAUS PITTSBURGH", + "account_name": "Hofbrauhaus Pittsburgh", + "type": "withdrawal" + }, + { + "match": "IKEA", + "account_name": "IKEA", + "type": "withdrawal" + }, + { + "match": "INTEREST INCOME", + "account_name": "Interest Income", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "INVESTMENT APPRECIATION", + "account_name": "Investment Appreciation", + "type": "withdrawal" + }, + { + "match": "IRS REFUND", + "account_name": "IRS Refund", + "type": "withdrawal" + }, + { + "match": "KUHN'S MARKET", + "account_name": "Kuhn's Market", + "type": "withdrawal", + "category": "Groceries" + }, + { + "match": "LONGHORN STEAKHOUSE", + "account_name": "LongHorn Steakhouse", + "type": "withdrawal" + }, + { + "match": "MARRIOTT", + "account_name": "Marriott", + "type": "withdrawal" + }, + { + "match": "NIKE", + "account_name": "Nike", + "type": "withdrawal" + }, + { + "match": "NLR DIVIDEND", + "account_name": "NLR Dividend", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "PITT SALARY", + "account_name": "Pitt Salary", + "type": "withdrawal" + }, + { + "match": "PNC BANK", + "account_name": "PNC Bank", + "type": "withdrawal" + }, + { + "match": "PNC INTEREST", + "account_name": "PNC Interest", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "PRIMANTI BROTHERS", + "account_name": "Primanti Brothers", + "type": "withdrawal" + }, + { + "match": "SCHWAB DIVIDENDS", + "account_name": "Schwab Dividends", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "SLC FREDDYSSTEAKBURGER", + "account_name": "Slc Freddyssteakburger", + "type": "withdrawal", + "category": "Restaurants" + }, + { + "match": "SPY DIVIDEND", + "account_name": "SPY Dividend", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "STEAM GAMES", + "account_name": "Steam Games", + "type": "withdrawal" + }, + { + "match": "SWVXX INTEREST", + "account_name": "SWVXX Interest", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "TOW-TEGRITY INCORP", + "account_name": "Tow-tegrity Incorp", + "type": "withdrawal" + }, + { + "match": "VEU DIVIDEND", + "account_name": "VEU Dividend", + "type": "withdrawal", + "category": "Investment: Appreciation" + }, + { + "match": "WHO KNOWS", + "account_name": "Who Knows", + "type": "withdrawal" + }, + { + "match": "YARDI SYSTEMS", + "account_name": "Yardi Systems", + "type": "withdrawal" + }, + { + "match": "ZAGG", + "account_name": "Zagg", + "type": "withdrawal" + }, + { + "match": "ZELLE INCOME", + "account_name": "Zelle Income", + "type": "withdrawal" + }, + { + "match": "ZOHO", + "account_name": "Zoho", + "type": "withdrawal" + }, { "match": "DUQUESNE LIGHT", "account_name": "Duquesne Light", - "category": "Utilities: Electric", + "category": "Utilities", "budget": "Needs", "type": "withdrawal" }, @@ -73,15 +1774,13 @@ "regex": true, "account_name": "Amazon", "review": true, - "type": "withdrawal", - "account_id": 720 + "type": "withdrawal" }, { "match": "EBAY", "account_name": "eBay", "review": true, - "type": "withdrawal", - "account_id": 622 + "type": "withdrawal" }, { "match": "SVDP", @@ -100,29 +1799,25 @@ "regex": true, "account_name": "Comcast / Xfinity", "review": true, - "type": "withdrawal", - "account_id": 585 + "type": "withdrawal" }, { "match": "LIBERTY MUTUAL", "account_name": "Liberty Mutual", "review": true, - "type": "withdrawal", - "account_id": 871 + "type": "withdrawal" }, { "match": "JEGS", "account_name": "JEGS", "review": true, - "type": "withdrawal", - "account_id": 887 + "type": "withdrawal" }, { "match": "APEX RACE PARTS", "account_name": "Apex Race Parts", "review": true, - "type": "withdrawal", - "account_id": 594 + "type": "withdrawal" }, { "match": "ADVANCE AUTO", @@ -134,16 +1829,14 @@ "match": "SUBARU OF SOUTH HILLS", "account_name": "Subaru of South Hills", "review": true, - "type": "withdrawal", - "account_id": 555 + "type": "withdrawal" }, { "match": "ALLEGHENY ARMS", "account_name": "Allegheny Arms", "category": "Recreation: Firearms", "review": true, - "type": "withdrawal", - "account_id": 657 + "type": "withdrawal" }, { "match": "WILLI S SKI|WILLIS SKI", @@ -158,8 +1851,7 @@ "account_name": "Shop 'n Save", "category": "Groceries", "budget": "Needs", - "type": "withdrawal", - "account_id": 572 + "type": "withdrawal" }, { "match": "MARKET DISTRICT|GIANT EAGLE", @@ -167,16 +1859,14 @@ "account_name": "Giant Eagle", "category": "Groceries", "budget": "Needs", - "type": "withdrawal", - "account_id": 592 + "type": "withdrawal" }, { "match": "KUHNS", "account_name": "Kuhn's Market", "category": "Groceries", "budget": "Needs", - "type": "withdrawal", - "account_id": 563 + "type": "withdrawal" }, { "match": "COMPEER", @@ -190,8 +1880,7 @@ "account_name": "UPMC Student Insurance", "category": "Medical", "budget": "Needs", - "type": "withdrawal", - "account_id": 612 + "type": "withdrawal" }, { "match": "SPIEGEL FREEDMAN", @@ -219,8 +1908,7 @@ "account_name": "OpenAI", "category": "Subscriptions", "budget": "Wants", - "type": "withdrawal", - "account_id": 576 + "type": "withdrawal" }, { "match": "YOUTUBE TV", @@ -234,16 +1922,14 @@ "account_name": "Peacock", "category": "Subscriptions", "budget": "Wants", - "type": "withdrawal", - "account_id": 607 + "type": "withdrawal" }, { "match": "MCDONALD", "account_name": "McDonald's", "category": "Restaurants", "budget": "Wants", - "type": "withdrawal", - "account_id": 580 + "type": "withdrawal" }, { "match": "PAMELA.?.?S? ?DINER|PAMELA'SDINER", @@ -258,8 +1944,7 @@ "account_name": "Primanti Bros", "category": "Restaurants", "budget": "Wants", - "type": "withdrawal", - "account_id": 747 + "type": "withdrawal" }, { "match": "MINEO'S|MINEOS", @@ -275,16 +1960,14 @@ "account_name": "Dave & Andy's", "category": "Restaurants", "budget": "Wants", - "type": "withdrawal", - "account_id": 769 + "type": "withdrawal" }, { "match": "STARBUCKS", "account_name": "Starbucks", "category": "Coffee", "budget": "Wants", - "type": "withdrawal", - "account_id": 611 + "type": "withdrawal" }, { "match": "TAZZA D|ENRICO'S TAZZA", @@ -299,8 +1982,7 @@ "account_name": "La Gourmandine", "category": "Coffee", "budget": "Wants", - "type": "withdrawal", - "account_id": 595 + "type": "withdrawal" }, { "match": "NEEDLE & BEAN|NEEDLE & BEAN|NEEDLE AND BEAN", @@ -308,15 +1990,13 @@ "account_name": "Needle & Bean", "category": "Coffee", "budget": "Wants", - "type": "withdrawal", - "account_id": 660 + "type": "withdrawal" }, { "match": "SHEETZ", "account_name": "Sheetz", "category": "Auto: Fuel", - "type": "withdrawal", - "account_id": 566 + "type": "withdrawal" }, { "match": "BP#9604786|UKANI BRO", @@ -335,8 +2015,7 @@ "match": "PITT PARKING", "account_name": "Pitt Parking", "category": "Auto: Parking", - "type": "withdrawal", - "account_id": 870 + "type": "withdrawal" }, { "match": "T2\\* MT LEBANON", @@ -354,4 +2033,4 @@ "type": "withdrawal" } ] -} \ No newline at end of file +} diff --git a/migration/README.md b/migration/README.md index 9088477..5b156a5 100644 --- a/migration/README.md +++ b/migration/README.md @@ -76,3 +76,32 @@ transfers. - `*review_preview*.html` -- review-UI previews on real data Nothing here writes to Firefly except the final `--post` in step 6. + +## Lessons from the first rebuild (2026-05-20) + +Captured here so a second rebuild doesn't re-discover them. + +- **Orphan paired transfers**: the PNC->Apple payment from 2025-08-01 has no + Apple-side line (Apple's QFX starts 08-02). Its effect was already in + Apple's derived opening; posting the transfer ALSO crediting Apple + double-counted by $3,218. Fix: `build_rebuild_dataset.py` now subtracts + orphan transfer amounts from the destination card's opening. See + `references/transfers.md` in the skill. +- **Asset accounts require `account_role`** on POST /accounts. `defaultAsset` + works universally. +- **Budgets do not auto-create.** If wiping to scratch, recreate Needs / + Wants / Savings via UI or POST before the import. +- **Wipe via UI leaves stale revenue accounts / categories** (only + transaction-referenced asset accounts go). Prune manually if you want a + truly clean slate. +- **Strip cached `account_id` from `merchant_map.json` before any rebuild.** + Pre-wipe ids are invalid post-wipe. The skill no longer caches to the map + (in-memory only) but old maps may still carry stale ids. +- **Background Python with `nohup ... &` can lose stdout to buffering.** Use + `python -u` for the import step. The first rebuild's log was empty because + Python buffered everything and we mistook it for "ran but did nothing." +- **`error_if_duplicate_hash` is now off** — Firefly's content-hash dedup + was too eager (rejected legit-distinct rows with same date+amt+desc, like + two parking sessions same garage). `external_id` precheck is the only dedup. +- **Wipe by deleting transactions, not by deleting accounts.** Otherwise you + end up with stale ids referenced by merchant_map cache. diff --git a/migration/build_rebuild_dataset.py b/migration/build_rebuild_dataset.py index dbb73fa..96a6145 100644 --- a/migration/build_rebuild_dataset.py +++ b/migration/build_rebuild_dataset.py @@ -13,7 +13,7 @@ Costco, with: Nothing is posted. Output feeds `firefly_import.py --emit-plan/--review-html`. """ -import re, json, hashlib, sys +import re, json, hashlib, sys, html from collections import Counter D = "/Users/danesabo/Documents/Finances/EXPORTS/-MAY172026" @@ -35,7 +35,7 @@ def parse(path): for b in blocks: out.append({"date": g(b, "DTPOSTED")[:8], "amt": float(g(b, "TRNAMT")), "ttype": g(b, "TRNTYPE").upper(), - "desc": (g(b, "NAME") + " " + g(b, "MEMO")).strip(), + "desc": html.unescape((g(b, "NAME") + " " + g(b, "MEMO")).strip()), "fitid": g(b, "FITID")}) return ledger, out @@ -100,6 +100,24 @@ for acct, (path, tag) in SRC.items(): rec["type"] = "withdrawal" if amt < 0 else "deposit" records.append(rec) +# --- Orphan adjustment: a PNC->Apple/Costco payment whose date predates the +# card QFX window has its card-side effect already baked into the card's +# DERIVED opening (because opening = ledger - sum_kept_card_lines, and the +# orphan never appeared on the card side). If we ALSO post the PNC->card +# transfer in the rebuild, the card account gets credited twice. So subtract +# orphan transfer amounts from the card opening. +APPLE_WINDOW_START = "2025-08-02" +COSTCO_WINDOW_START = "2025-08-02" +for r in records: + if r.get("type") == "transfer" and r["asset_account"] == "PNC Checking": + dest = r.get("destination_account") + if dest == "Apple Credit Card" and r["date"] < APPLE_WINDOW_START: + recon["Apple Credit Card"]["opening"] -= float(r["amount"]) + recon["Apple Credit Card"]["opening"] = round(recon["Apple Credit Card"]["opening"], 2) + elif dest == "Costco Visa Card" and r["date"] < COSTCO_WINDOW_START: + recon["Costco Visa Card"]["opening"] -= float(r["amount"]) + recon["Costco Visa Card"]["opening"] = round(recon["Costco Visa Card"]["opening"], 2) + print("=== RECONCILIATION (must all tie) ===") ok = True for a, r in recon.items(): diff --git a/migration/rebuild_review.html b/migration/rebuild_review.html index 25e35fc..a472454 100644 --- a/migration/rebuild_review.html +++ b/migration/rebuild_review.html @@ -55,6 +55,9 @@ .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; @@ -87,7 +90,7 @@

Needs Clarity UNMATCHED + REVIEW — set the canonical account, category, budget, then approve

- +
DateAmountDescriptionAccount#DateAmountDescriptionAccount CategoryBudgetCommentDecision
@@ -97,7 +100,7 @@

Auto-Proposed matched a rule — approved by default, deny or edit if wrong

- +
DateAmountDescriptionAccount#DateAmountDescriptionAccount CategoryBudgetCommentDecision
@@ -107,7 +110,7 @@

All Transactions complete picture, read-only (includes skipped duplicates)

- +
DateAmountTypeDescription#DateAmountTypeDescription BucketTarget
@@ -120,7 +123,7 @@