# YNAB *Web-hosted admin dashboard that imports Amazon receipts from Gmail, matches and categorizes them (with AI), and updates YNAB — served at lucaslongo.com/ynab. The product focus is the hosted Gmail → YNAB flow plus unattended MCP automation.* ## Current focus - Web-hosted YNAB Amazon categorizer at /ynab with simplified review table, rich memos, and MCP-driven automation. ## Next up - [ ] Audit every endpoint that mutates `transaction_review_state` (zombie rows in review) - [ ] Add fixtures when live Gmail emails fail to parse ## Last touched - 2026-06-27 — Stopped the activity popover from being wiped right after a Gmail scan: the post-scan loadUnifiedRows() called note() (which clears the log), erasing the scan summary; loadUnifiedRows now has a quiet mode and the scan uses it, so the summary stays until the user dismisses it (refs #375). - 2026-06-27 — Fixed the Gmail scan silently failing on production: the client's NDJSON parser was swallowing server-sent error events (the throw landed in the same try/catch that ignores unparseable lines), so failures like an expired Gmail refresh token showed no feedback; errors now surface in the activity log (refs #375). - 2026-06-21 — YNAB: added dedicated resizable "New memo" column to review table (product summary + clickable Gmail deep-link + suggested category) when gmail scan data present; Memo column always renders plain YNAB text (no regression) fulfilling #309 spec (refs #309). - 2026-06-21 — Replaced the pinned bottom scan/status strip with a closable (×) activity popover and made its log human-readable: Gmail query syntax is rewritten into plain language (what's searched, date range, merchant/product keywords) and timing/internal noise is dropped, including the per-row Search Gmail modal's query lines (refs #331). - 2026-06-21 — Expanded Scan Gmail / per-txn Gmail lookup to non-Amazon merchants: top merchants helper, payee-seeded searches, generic receipt amount extraction, relaxed guards, lightweight match records, UI copy updates, frequent merchants surfaced in scan logs (refs #323). - 2026-06-21 — Reconfigured the dashboard command buttons: merged "Scan Gmail (full ~2yr)" + "Check New Emails" into one "Scan Gmail" button with a Recent/Full lookback selector, removed the redundant "Backfill sources" and "Reupload memos" buttons (the full scan already does both; endpoints retained), and demoted legacy "Import Files" into the secondary group next to Upload (refs #317). - 2026-06-21 — Targeted "Check new emails" scan now auto-pushes the canonical Amazon memo (product + direct-open Gmail link + current category) to YNAB via reuploadMatchedAmazonMemos, matching the full scan — no separate Reupload step needed (refs #315). - 2026-06-21 — Folded the "New memo" column's structured render (products, clickable Gmail link, suggested category) into the regular Memo column and removed the separate "New memo" column; plain memo text retained as fallback for non-scanned rows (refs #313). - 2026-06-20 — Added a "New memo" column to the review table showing the Gmail-scan results (products found, a working clickable "Open email in Gmail" link, and the suggested category) so the source email is reachable from the dashboard regardless of YNAB's plain-text memo rendering (refs #309). - 2026-06-20 — Made Amazon memo Gmail links open the email directly (#all/ deep link instead of #inbox/) and had the full ~2yr scan re-push corrected memos to YNAB for every matched Amazon transaction (refs #305). ## Blockers - Official Amazon export is async (1–3 days) ## Open questions ## Ideas - "Freeze" command to snapshot the DB before bulk operations - Surface all-time stats on fixes pushed back to YNAB ## Notes - **Web-hosted product** — canonical experience at `https://lucaslongo.com/ynab/` (blog admin login, GCS-persisted `ynab/ynab.db` via `src/gcs-persist.ts`). The monorepo dev mount at `http://localhost:3000/ynab/` is for developing/testing the web app (same code). Local SQLite files are only for dev sessions. - **Primary flow** — Gmail receipt import (Scan Gmail), amount/date matching, AI categorization against your own budget categories, rich memos, review, and push back to YNAB. - **Unattended sync** — scheduled Gmail MCP + YNAB MCP (`AMAZON-GMAIL-YNAB-SYNC.md`, `npm run mcp:ynab`). Stateless/direct to YNAB API (no SQLite). Legacy `ynab-sync` skill is deprecated — prefer MCP. - Legacy Mac tools (Playwright Amazon scrape, sweep scripts) are deprioritized; Gmail path is preferred. - Gmail OAuth (one-time): `npm run oauth:gmail` (listener on 127.0.0.1:8080). - Env: YNAB + Gmail + AI keys in monorepo root `.env`; production binds `YNAB_API_KEY` + `GMAIL_*` from Secret Manager. Every staged change is reversible (`pending_ynab_updates`). See `README.md`.