UX + Full-Stack Case Study

Receipt scanning,
reimagined

CartLog is an AI-powered PWA that photographs grocery receipts, auto-categorizes every item, and turns raw spending into a living budget dashboard — built in 28.5 hours.

BuiltMar 5–6, 2026
Duration28.5 hours
RoleSolo — UX + Dev
StatusLive ✓
↗ Open App Read Case Study ↓
scroll

The blind spot in every budget app

Mint, Rocket Money, YNAB — they all see groceries as a single transaction. You spent $88 at HEB, but on what? Chicken? Soda? Paper towels? That granularity disappears, making it impossible to actually change behavior.

CartLog reads the receipt itself. Every line item is extracted by AI, categorized, and stored — so your budget knows the difference between a necessity and an impulse buy.

⚠ The Gap
Existing apps track totals, not items
Every competitor aggregates by merchant. You see "$312 at HEB this month" with no insight into what drove that number or where to cut.
✓ The Fix
A photo is all it takes
Claude Vision reads the receipt, infers categories with high accuracy, and populates a real budget breakdown — no manual entry, no bank connection required.
28.5h
Concept to live deployed app
~95%
AI category accuracy on real receipts
11
Items extracted from first test receipt
0
Manual line items required from the user

From photo to insight in ~15 seconds

Getting a real image through Claude's Vision API, parsed cleanly, and stored reliably across a serverless edge function took three architectural pivots. The final pipeline is deceptively simple.

Pivot 1 — 413 Payload Errors
Base64 images exceeded Vercel's body limit
Original approach sent images as base64 in the API request body. Large receipt photos hit Vercel's 4MB limit. Fix: upload to Supabase Storage first, pass the public URL to the scan function instead of the raw bytes.
Pivot 2 — Runtime Failures
Python serverless wouldn't deploy cleanly
The scan endpoint started as Python to reuse existing logic. Vercel's Python runtime had cold start and dependency conflicts. Rewrote scan.js in Node.js — faster, zero runtime friction, simpler dependency tree.
Pivot 3 — File Corruption
Terminal commands pasting into source files
Multiline heredoc writes to scan.js were being interrupted, injecting shell commands into the file content. Switched to programmatic writes via node -e + fs.writeFileSync — no shell interpolation, no corruption.

Every screen is a deliberate decision

CartLog's design language is precise and data-forward — the same aesthetic as the product itself, applied consistently. Finance tools should feel like they're on your side, not anxious to impress you.

const theme = { background: "#0a0f1e", // deep navy — calm, focused accent: "#22d3ee", // cyan — data, not decoration fonts: "DM Serif Display + DM Sans", motion: "spring curves, not bounce", density: "mobile-first, thumb-reachable", }
Choice
Pie chart as the hero, not a card
The total used to sit in a separate card above the chart — redundant. Moving the number inside the donut eliminated the card, made the chart the main subject, and lets it swap to category detail on hover.
Choice
Progress bar over spinner during scan
A spinner during a 15-second wait feels like it's hanging. A 0–100% bar with phase labels ("Uploading → Reading receipt → Saving") communicates progress and reduces perceived wait time.
Choice
Inline category editing, not a modal
Correcting an AI-assigned category should be as frictionless as possible. An inline picker that opens in context — no modal, no navigation change — keeps the user in flow.
Choice
Scrollable bar chart on mobile
Compressing 12 monthly bars into 375px made them unreadable. Fixed-width bars with horizontal scroll preserves data density without sacrificing legibility on any screen size.

What CartLog actually does

🧾
AI Receipt Scanning
Photograph or upload a receipt. Claude Vision extracts every line item with quantity, price, sale flag, and tax status — returning structured JSON in under 15 seconds. No OCR preprocessing, no templates.
Claude Sonnet Vision API
🍩
Interactive Budget Dashboard
Animated donut chart with total spent in the center. Hover any slice to swap the center to that category's amount and percentage. A glow shifts color to match the active slice. Tap any bar to drill into items.
SVG · Spring animations · React state
📈
Category Trend View
The view Rocket Money doesn't give you. Tap any spending category to see a month-by-month bar chart, click a bar to drill into that month's items, and see your monthly average at a glance.
Monthly analytics · Item drill-down
✏️
Inline Category Correction + Receipt Editing
AI categorization is accurate but not perfect. Every item has a tap-to-edit category label. Receipt titles are also inline-editable — tap the store name to rename it, enter to save. All changes persist to Supabase immediately.
Live Supabase sync · Zero modals

Built to ship fast

Every tool chosen to minimize ops overhead and maximize iteration speed. The goal was a working app — not an architecture demo.

⚛️
React + Vite
UI · PWA
🟢
Supabase
Postgres · Storage · RLS
🤖
Claude Vision API
Receipt parsing · Categorization
Vercel
Deployment · Serverless API
🔶
Node.js Serverless
scan.js edge function
🎨
DM Serif + DM Sans
Typography system

28.5 hours, three pivots, one shipped product

CartLog started as a portfolio project to demonstrate technical range for a Digital Designer application at Funlab. It ended up being the most complete product I've shipped solo — from database schema to deployed PWA — in under 29 hours.

"The gap between a good idea and a shipped product is almost entirely infrastructure and iteration speed. CartLog forced me to get comfortable with both."
— Andre Espinoza
🏗️
Architecture decisions compound
Every shortcut created two problems downstream. Taking the extra hour to store images in Supabase before calling the API solved three issues at once. Good structure is worth the upfront cost.
🎨
Design and engineering reinforce each other
The best UX decisions came from thinking like both a user and the engineer who has to build it. Designing things you implement makes you honest about complexity trade-offs.
🤖
AI is a multiplier, not a replacement
Claude Vision gets categories right ~95% of the time. The 5% that's wrong is a UX problem — make correction frictionless. That insight is more valuable than chasing 100% accuracy.

The roadmap

Near-term
PIN-based access control
Simple passcode gate so CartLog can be shared without exposing all receipt data publicly.
Near-term
Monthly budget targets
Set a spending goal per category and get a visual indicator when approaching the limit.
Future
Auto shopping list
Items bought 3+ times in 30 days surface automatically as a suggested restock list.
Future
Multi-user household
Supabase RLS is already structured per-user. Adding auth is the only remaining step.
Available Now

Try CartLog live

Scan a grocery receipt and see your spending broken down by item and category in under 15 seconds.

↗ Open CartLog Get in Touch