Case Study — CartLog

Receipt scanning,
reimagined.

28.5-hour build. Snap a receipt, get auto-categorized groceries + budget tracking. Claude Vision API + Supabase + n8n.

BuiltMar 5-6, 2026
Duration28.5 hours
RoleSolo — UX + Dev
StatusLive
28h
Concept to deployed
~95%
AI category accuracy
0
Manual entries required

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.
CartLog user flow diagram
User Flow — Photo to Budget Insight

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.

Scan workflow diagram
Workflow — Receipt Scan Pipeline
Budget workflow diagram
Workflow — Budget Aggregation
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. 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 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 frictionless. 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.

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
CartLog scan interface
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.
SVG + Spring Animations + React State
CartLog budget dashboard
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
CartLog history and trends
Inline Category Correction + Receipt Editing
AI categorization is accurate but not perfect. Every item has a tap-to-edit category label. Receipt titles are inline-editable — tap the store name to rename it, enter to save. All changes persist to Supabase immediately.
Live Supabase Sync + Zero Modals
CartLog inline editing

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
n8n
Workflow automation

28 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

See how CartLog was built

Full source on GitHub — Vercel Function calling Claude Vision, Supabase schema, and the React frontend that ties it together.

View Source on GitHub Get in Touch