{
  "version": "2.0",
  "description": "Payee normalization rules for Quicken database. Applied in order: aliases -> prefixes -> suffixes -> fee_suffix -> brands -> gusto -> locations -> cleanup -> check_extraction -> consolidation_merges",
  "aliases": {
    "Rancho Meat Market": "Mi Rancho",
    "Mi Rancho Mexican Restaurant": "Mi Rancho",
    "Mcdonalds? (says \"Store\")": "McDonald's",
    "Spencers": "Spencer Peters Charged",
    "Spencer": "Spencer Peters Charged",
    "bambi spencer- Fee Amount": "Bambi Spencer",
    "EB *2025 WASHINGTON RO": "Washington Rowing",
    "EB 2023 WASHINGTON RO": "Washington Rowing",
    "EB 2024 WASHINGTON RO": "Washington Rowing",
    "X8286 - BELLINGHAM INT AI": "Bellingham International Airport",
    "CARS Ferndale": "CARS Ferndale"
  },
  "prefix_rules": [
    {
      "pattern": "^-\\s+",
      "replace": "",
      "description": "Strip leading dash"
    },
    {
      "pattern": "^Ext Credit Card (?:Debit|Credit)\\s+",
      "replace": "",
      "description": "Strip Ext Credit Card Debit/Credit prefix"
    },
    {
      "pattern": "^TST\\*\\s*",
      "replace": "",
      "description": "Strip Toast POS prefix"
    },
    {
      "pattern": "^SQ\\s*\\*\\s*",
      "replace": "",
      "description": "Strip Square POS prefix"
    },
    {
      "pattern": "^SQU\\s*\\*\\s*",
      "replace": "",
      "description": "Strip Square POS variant prefix"
    },
    {
      "pattern": "^PY\\s*\\*?\\s*",
      "replace": "",
      "description": "Strip PayAnywhere POS prefix"
    },
    {
      "pattern": "^Purchase#?\\s*",
      "replace": "",
      "description": "Strip Purchase prefix"
    },
    {
      "pattern": "^BILL PAY\\([^)]+\\)\\s*",
      "replace": "",
      "description": "Strip BILL PAY(xxx) prefix"
    },
    {
      "pattern": "^-\\s*TST\\*\\s*",
      "replace": "",
      "description": "Strip - TST* prefix (dash + Toast POS)"
    },
    {
      "pattern": "^TST\\s+",
      "replace": "",
      "description": "Strip TST prefix (no asterisk)"
    },
    {
      "pattern": "^SQ\\s+(?!\\*)",
      "replace": "",
      "description": "Strip SQ prefix (no asterisk)"
    },
    {
      "pattern": "^AF\\*\\s*",
      "replace": "",
      "description": "Strip AF* prefix"
    },
    {
      "pattern": "^SP\\s+",
      "replace": "",
      "description": "Strip SP prefix (Shopify POS)"
    }
  ],
  "suffix_rules": [
    {
      "pattern": "\\s*Card\\s*#\\d+\\s*$",
      "replace": "",
      "description": "Strip Card #NNNN suffix"
    },
    {
      "pattern": "\\s+(?:US|USUS|CAUS|JPJP|GBGB|MXMX|ESES|DEDE|ITIT|AUAU)\\s*$",
      "replace": "",
      "description": "Strip country codes"
    }
  ],
  "brand_rules": [
    {
      "pattern": "^MCDONALD'?S\\b.*$",
      "canonical": "McDonald's"
    },
    {
      "pattern": "^BURGER KING\\b.*$",
      "canonical": "Burger King"
    },
    {
      "pattern": "^SAFEWAY FUEL\\b.*$",
      "canonical": "Safeway Fuel"
    },
    {
      "pattern": "^SAFEWAY\\b.*$",
      "canonical": "Safeway"
    },
    {
      "pattern": "^SUBWAY\\b.*$",
      "canonical": "Subway"
    },
    {
      "pattern": "^CHIPOTLE\\b.*$",
      "canonical": "Chipotle"
    },
    {
      "pattern": "^RITE AID\\b.*$",
      "canonical": "Rite Aid"
    },
    {
      "pattern": "^JACK IN THE BOX\\b.*$",
      "canonical": "Jack In The Box"
    },
    {
      "pattern": "^WAL-?MART\\b.*$",
      "canonical": "Wal-Mart"
    },
    {
      "pattern": "^ARCO\\b.*$",
      "canonical": "Arco"
    },
    {
      "pattern": "^SHELL OIL\\b.*$",
      "canonical": "Shell"
    },
    {
      "pattern": "^SOUTHWES\\b.*$",
      "canonical": "Southwest Airlines"
    },
    {
      "pattern": "^ALASKA AIR\\b.*$",
      "canonical": "Alaska Air"
    },
    {
      "pattern": "^DELTA AIR\\b.*$",
      "canonical": "Delta Air"
    },
    {
      "pattern": "^UNITED\\s+\\d{5,}.*$",
      "canonical": "United Airlines"
    },
    {
      "pattern": "^NWA AIR\\b.*$",
      "canonical": "Northwest Airlines"
    },
    {
      "pattern": "^GUSTO FEE\\b.*$",
      "canonical": "Gusto Fee"
    },
    {
      "pattern": "^GUSTO TAX\\b.*$",
      "canonical": "Gusto Tax"
    },
    {
      "pattern": "^GUSTO NET\\b.*$",
      "canonical": "Gusto Net"
    },
    {
      "pattern": "^DEPOSIT GUSTO\\b.*$",
      "canonical": "Deposit Gusto Payroll"
    },
    {
      "pattern": "^-\\s*BUILDERS ALLIANC\\b.*$",
      "canonical": "Builders Alliance"
    },
    {
      "pattern": "^TRANSFER TO BANK ACCOUNT\\b.*$",
      "canonical": "Transfer to Bank Account"
    },
    {
      "pattern": "^CHECK\\s+(?:NBR\\.?\\s*|#\\s*|PAID\\s+)?\\d+.*$",
      "canonical": "Check"
    },
    {
      "pattern": "^UNION 76\\b.*$",
      "canonical": "Union 76"
    },
    {
      "pattern": "^PORT OF SUBS\\b.*$",
      "canonical": "Port of Subs"
    },
    {
      "pattern": "^BLESSING'?S SALON\\b.*$",
      "canonical": "Blessing's Salon"
    },
    {
      "pattern": "^(?:FAIRHAVEN\\s+)?EDALEEN DAIRY\\b.*$",
      "canonical": "Edaleen Dairy"
    },
    {
      "pattern": "^SPENCER PETERS CHARGED\\b.*$",
      "canonical": "Spencer Peters Charged"
    },
    {
      "pattern": "^SPENCER PETERS PAID\\b.*$",
      "canonical": "Spencer Peters Paid"
    },
    {
      "pattern": "^AMZN MKTP\\b.*$",
      "canonical": "Amazon"
    },
    {
      "pattern": "^AMAZON\\.COM\\b.*$",
      "canonical": "Amazon"
    },
    {
      "pattern": "^AMAZON PRIME\\b.*$",
      "canonical": "Amazon Prime"
    },
    {
      "pattern": "^PRIME VIDEO\\b.*$",
      "canonical": "Prime Video"
    },
    {
      "pattern": "^COMMUNITY FOOD CO-?OP\\b.*$",
      "canonical": "Community Food Co-Op"
    },
    {
      "pattern": "^FRED M(?:EYER)? FUEL\\b.*$",
      "canonical": "Fred Meyer Fuel"
    },
    {
      "pattern": "^FRED M(?:EYER)?\\b.*$",
      "canonical": "Fred Meyer"
    },
    {
      "pattern": "^FRED MEYER\\b.*$",
      "canonical": "Fred Meyer"
    },
    {
      "pattern": "^STARBUCKS\\b.*$",
      "canonical": "Starbucks"
    },
    {
      "pattern": "^TACO BELL\\b.*$",
      "canonical": "Taco Bell"
    },
    {
      "pattern": "^TACO TIME\\b.*$",
      "canonical": "Taco Time"
    },
    {
      "pattern": "^WENDY'?S\\b.*$",
      "canonical": "Wendy's"
    },
    {
      "pattern": "^HOME DEPOT\\b.*$",
      "canonical": "Home Depot"
    },
    {
      "pattern": "^LOWE'?S\\b.*$",
      "canonical": "Lowe's"
    },
    {
      "pattern": "^COSTCO GAS\\b.*$",
      "canonical": "Costco Gas"
    },
    {
      "pattern": "^COSTCO WHSE\\b.*$",
      "canonical": "Costco"
    },
    {
      "pattern": "^COSTCO\\b.*$",
      "canonical": "Costco"
    },
    {
      "pattern": "^ATM WITHDRAWAL\\b.*$",
      "canonical": "ATM Withdrawal"
    },
    {
      "pattern": "^HERTZ RENT-?A-?CAR\\b.*$",
      "canonical": "Hertz"
    },
    {
      "pattern": "^(?:76 - |76-)?CHEVRON\\b.*$",
      "canonical": "Chevron"
    },
    {
      "pattern": "^FACEBOOK\\b.*$",
      "canonical": "Facebook Payouts"
    },
    {
      "pattern": "^LATE FEE\\b.*$",
      "canonical": "Late Fee"
    },
    {
      "pattern": "^BANK INT\\b.*$",
      "canonical": "Bank Interest"
    },
    {
      "pattern": "^-?\\s*WINDERMERE PROPE\\b.*$",
      "canonical": "Windermere Property Management"
    },
    {
      "pattern": "^- APPFOLIO\\b.*$",
      "canonical": "AppFolio"
    },
    {
      "pattern": "^IPHONE CITIZ\\*PAYMENT\\b.*$",
      "canonical": "iPhone Payment"
    },
    {
      "pattern": "^DEPOSIT\\s*:\\s*RENT\\b.*$",
      "canonical": "Deposit: Rent from Westphalen"
    },
    {
      "pattern": "^YOUTUBE TV\\b.*$",
      "canonical": "YouTube TV"
    },
    {
      "pattern": "^YOUTUBE\\b.*$",
      "canonical": "YouTube"
    },
    {
      "pattern": "^DEPOSIT - TRANSFER FROM DDA (\\d+)$",
      "canonical": "KEEP_ORIGINAL"
    },
    {
      "pattern": "^WITHDRAWAL - TRANSFER TO DDA (\\d+)$",
      "canonical": "KEEP_ORIGINAL"
    },
    {
      "pattern": "^76\\s*-?\\s.*$",
      "canonical": "76 Gas Station"
    },
    {
      "pattern": "^BAGELRY\\b.*$",
      "canonical": "Bagelry"
    },
    {
      "pattern": "^D.?ANNA.?S CAFE ITALIA\\b.*$",
      "canonical": "D'Anna's Cafe Italia"
    },
    {
      "pattern": "^HUDSON\\s*(?:ST|BLOCK|NEWS).*$",
      "canonical": "Hudson"
    },
    {
      "pattern": "^OASIS TEA ZONE.*$",
      "canonical": "Oasis Tea Zone"
    },
    {
      "pattern": "^PORT OF BELLINGHAM\\b.*$",
      "canonical": "Port of Bellingham"
    },
    {
      "pattern": "^REGAL BARKLEY\\b.*$",
      "canonical": "Regal Barkley"
    },
    {
      "pattern": "^(?:TST\\s+)?SALT\\s*(?:AND)?\\s*STRAW\\b.*$",
      "canonical": "Salt & Straw"
    },
    {
      "pattern": "^WESTSIDE PIZZA\\b.*$",
      "canonical": "Westside Pizza"
    },
    {
      "pattern": "^BELLINGHAM INT(?:ERNATIONAL)?\\s*(?:AI|AIRPORT)?\\b.*$",
      "canonical": "Bellingham International Airport"
    },
    {
      "pattern": "^ALLEGNT AIR.*$",
      "canonical": "Allegiant Air"
    },
    {
      "pattern": "^AIR CAN\\*.*$",
      "canonical": "Air Canada"
    },
    {
      "pattern": "^ALADDIN\\s*GYRO.*$",
      "canonical": "Aladdin Gyro Restaurant"
    },
    {
      "pattern": "^APPFOLIO.*$",
      "canonical": "AppFolio"
    },
    {
      "pattern": "^BUILDER'?S ALLIANC.*$",
      "canonical": "Builder's Alliance"
    },
    {
      "pattern": "^BUILDERS? FIRSTSOURCE.*$",
      "canonical": "Builders Firstsource"
    },
    {
      "pattern": "^CLEARWATER.*$",
      "canonical": "Clearwater Systems"
    },
    {
      "pattern": "^COCHRANE AGENC.*$",
      "canonical": "Cochrane Agencies"
    },
    {
      "pattern": "^CRUNCHYROLL.*$",
      "canonical": "Crunchyroll"
    },
    {
      "pattern": "^EDDIE BAUER.*$",
      "canonical": "Eddie Bauer"
    },
    {
      "pattern": "^(?:EASY\\s*PARK|EASYPARK).*$",
      "canonical": "EasyPark"
    },
    {
      "pattern": "^FLIX.*$",
      "canonical": "FlixBus"
    },
    {
      "pattern": "^HOTEL(?:S\\.?COM|COMX+).*$",
      "canonical": "Hotels.com"
    },
    {
      "pattern": "^IN-?N-?OUT.*$",
      "canonical": "In-N-Out Burger"
    },
    {
      "pattern": "^KUBOTA.*$",
      "canonical": "Kubota"
    },
    {
      "pattern": "^LEMONADE\\s*I.*$",
      "canonical": "Lemonade Insurance"
    },
    {
      "pattern": "^MT\\.?\\s*BAKER ROOFING.*$",
      "canonical": "Mt. Baker Roofing"
    },
    {
      "pattern": "^MUMM'?S.*$",
      "canonical": "Mumm's HVAC"
    },
    {
      "pattern": "^NOLAN'?S? ROOFING.*$",
      "canonical": "Nolan Roofing"
    },
    {
      "pattern": "^(?:NYTIMES|NYT).*$",
      "canonical": "NY Times"
    },
    {
      "pattern": "^RECYCLING.*DISPOSAL.*$",
      "canonical": "Recycling & Disposal Services"
    },
    {
      "pattern": "^(?:SP\\s+)?VISTA MATERIALS.*$",
      "canonical": "Vista Materials"
    },
    {
      "pattern": "^UNIQLO.*$",
      "canonical": "Uniqlo"
    },
    {
      "pattern": "^ZIPAIR.*$",
      "canonical": "Zipair"
    },
    {
      "pattern": "^DEBIT CARD (?:WITHDRAWAL|DEBIT).*$",
      "canonical": "Debit Card Withdrawal"
    },
    {
      "pattern": "^CPA\\s*-?\\s*VIRTUAL PAY.*$",
      "canonical": "CPA Virtual Pay"
    },
    {
      "pattern": "^AWL\\*?\\s*PEARSON.*$",
      "canonical": "Pearson Education"
    },
    {
      "pattern": "^KAISER\\s*(?:WA)?\\s*PHARMACY.*$",
      "canonical": "Kaiser Bellingham Pharmacy"
    },
    {
      "pattern": "^\\d+\\s*KP BELLINGHAM PHARMA.*$",
      "canonical": "Kaiser Bellingham Pharmacy"
    }
  ],
  "location_cities": [
    "BELLINGHAM",
    "FERNDALE",
    "LYNDEN",
    "SEATTLE",
    "TACOMA",
    "BLAINE",
    "BURLINGTON",
    "MT VERNON",
    "MOUNT VERNON",
    "EVERETT",
    "REDMOND",
    "KIRKLAND",
    "BELLEVUE",
    "SPOKANE",
    "OLYMPIA",
    "ANACORTES",
    "MARYSVILLE",
    "KENMORE",
    "BOTHELL",
    "LYNNWOOD",
    "SHORELINE",
    "RENTON",
    "KENT",
    "AUBURN",
    "FEDERAL WAY",
    "SUMAS",
    "NOOKSACK",
    "EVERSON",
    "DEMING",
    "MAPLE FALLS",
    "SEDRO WOOLLEY",
    "CUSTER",
    "BIRCH BAY",
    "BOW",
    "SEATAC",
    "TUKWILA",
    "ISSAQUAH",
    "WOODINVILLE",
    "LAKE FOREST PARK",
    "MUKILTEO",
    "EDMONDS",
    "SNOHOMISH"
  ],
  "location_states": [
    "WA",
    "CA",
    "OR",
    "TX",
    "NY",
    "FL",
    "AZ",
    "CO",
    "IL",
    "GA",
    "NV",
    "UT",
    "ID",
    "MT",
    "AK",
    "HI",
    "WY"
  ],
  "cleanup": {
    "normalize_apostrophes": true,
    "strip_trailing_punctuation": true,
    "normalize_whitespace": true,
    "title_case": true
  },
  "fee_suffix_rule": {
    "pattern": "\\s*-?\\s*Fee Amount.*$",
    "replace": "",
    "description": "Strip '- Fee Amount' suffix from payee names. Tag affected transactions with '| Fee' in ZFINOTE. Case-insensitive.",
    "finote_tag": "| Fee"
  },
  "gusto_rules": {
    "description": "Gusto payroll payees with long IDs are consolidated into 3 canonical payees based on type suffix",
    "rules": [
      {
        "pattern": ".*- NET\\b.*",
        "canonical": "Gusto Payroll NET"
      },
      {
        "pattern": ".*- TAX\\b.*",
        "canonical": "Gusto Payroll TAX"
      },
      {
        "pattern": ".*- FEE\\b.*|.*ACCTVERIFY.*",
        "canonical": "Gusto Fee"
      },
      {
        "pattern": "^GUSTO NET\\b.*",
        "canonical": "Gusto Payroll NET"
      },
      {
        "pattern": "^GUSTO TAX\\b.*",
        "canonical": "Gusto Payroll TAX"
      },
      {
        "pattern": "^GUSTO FEE\\b.*",
        "canonical": "Gusto Fee"
      },
      {
        "pattern": "^GUSTO PAYROLL.*",
        "canonical": "Gusto Payroll NET"
      }
    ]
  },
  "consolidation_policies": {
    "description": "Post-normalization consolidation rules for substring/fuzzy matching",
    "fee_amount_merge": {
      "description": "Strip '- Fee Amount' suffix, merge into base payee. Tag fee transactions in ZFINOTE with '| Fee'. Case-insensitive matching for base payee lookup.",
      "case_sensitive_warning": "Use case-INSENSITIVE lookup for base payee (learned the hard way with Kevin Cuddahy vs Kevin cuddahy)"
    },
    "deposit_policy": "NEVER consolidate payees starting with 'Deposit'. Each deposit variant (Deposit - Transfer from *3188, Deposit GoFundMe, etc.) is distinct and important.",
    "descriptive_deposit_policy": "Keep 'Descriptive Deposit', 'Descriptive Withdrawal', 'Direct Deposit', 'External Deposit' all separate.",
    "withdrawal_policy": "Consolidate 'Withdrawal XXXXXXXX*' (masked account numbers) into plain 'Withdrawal'. Keep named withdrawal variants (Transfer to DDA, etc.) separate.",
    "interest_policy": "Split into 'Interest Earned' and 'Interest Charge' \u2014 never merge these.",
    "keep_separate": [
      {
        "pair": [
          "Costco",
          "Costco Gas"
        ],
        "reason": "Different categories (groceries vs gas)"
      },
      {
        "pair": [
          "Fred Meyer",
          "Fred Meyer Fuel"
        ],
        "reason": "Different categories"
      },
      {
        "pair": [
          "Safeway",
          "Safeway Fuel"
        ],
        "reason": "Different categories"
      },
      {
        "pair": [
          "Amazon",
          "Amazon Kindle"
        ],
        "reason": "Different services"
      },
      {
        "pair": [
          "Hardware Sales",
          "Hardware Sales Rentals"
        ],
        "reason": "Sales vs equipment rental"
      },
      {
        "pair": [
          "YouTube",
          "YouTube TV"
        ],
        "reason": "Different services"
      },
      {
        "pair": [
          "Interest Earned",
          "Interest Charge"
        ],
        "reason": "Income vs expense"
      },
      {
        "pair": [
          "Hold placed by",
          "Hold Released By"
        ],
        "reason": "Different transaction types"
      }
    ]
  },
  "venmo_rules": {
    "description": "Venmo payee handling",
    "spencer_peters": "Merge ALL 'Spencer Peters Charged/Paid' variants into single 'Spencer Peters' payee. Venmo descriptions already preserved in ZFINOTE.",
    "ted_peters_paid": "Extract person name from 'Ted Peters Paid [Person] [desc]' \u2014 person becomes the payee. Use ZFINOTE first word to find boundary between person and description."
  }
}