← Portfolio

Plantry

In Progress

An AI pantry and meal-planning product built around real kitchen workflow

www.myplantry.app
↗ open

The Problem

Most people do not have a reliable system for tracking what is actually in their kitchen. That leads to wasted groceries, duplicate purchases, and the daily friction of figuring out what to make with what is already at home.

The Solution

Plantry turns pantry management into a usable product system: track ingredients, sync groceries into inventory, monitor freshness, and generate recipe ideas from what is already on hand.

Tools

Next.jsReactSupabase Postgrespgvectorpg_trgmGoogle GeminiNextAuthVercel

Case Study Snapshot

Ingestion

4 Capture Paths

Manual entry, receipt photo, fridge/pantry photo, and handwritten list, all parsed by Gemini vision, plus recipe import from URL or pasted text.

Freshness Engine

3-Tier Lookup

pg_trgm fuzzy match against a seeded 433-row USDA FoodKeeper table first. Unmatched items get a Gemini estimate that's cached back for next time.

Recipe Generation

Single Gemini Call

One guardrailed prompt bundles pantry, preferences, and recent recipe titles, then forces strict JSON output. No agent loop.

Data & API Layer

  • Supabase Postgres with pg_trgm and pgvector enabled.
  • Real API layer: Next.js App Router route handlers under src/app/api/*, not client-side logic.
  • Row-level security enabled on tables; server-side session checks via getServerSession.
  • Service-role key used inside API routes for privileged writes that need to bypass RLS.

Ingestion Pipeline

  • Receipt photo scan: Gemini parses line items and decodes abbreviations like "CHKN BRST".
  • Fridge/pantry photo scan: Gemini identifies items visible in the shot.
  • Handwritten list photo: transcribed directly into inventory.
  • Recipe import from a pasted URL or raw text, plus plain manual entry.
  • No barcode scanning or grocery-delivery API integration.

Freshness System

  1. pg_trgm fuzzy match against a seeded 433-row USDA FoodKeeper table.
  2. If no match, a Gemini call estimates shelf life for that item.
  3. The Gemini result is cached back into the FoodKeeper table, so it's a plain rule-based lookup for every user after that. Self-reinforcing, not a live AI call on every check.

Recipe Generation Prompt

  • Full current pantry: name, category, expiration date.
  • Dietary restrictions and cuisine preferences from user_preferences.
  • Titles of the user's last 10 saved recipes, for variety, not repeats.
  • Optional free-text request, plus hardcoded guardrails against invented combos (e.g. vinegar pasta) that force a recognizable dish and prioritize soonest-expiring ingredients.
  • Single Gemini call (gemini-3.1-pro-preview via @google/genai), not agentic. Output is forced strict JSON.

Auth & Hosting

NextAuth handles both Google OAuth and email/password credentials through the same session, checked server-side in every API route. The app runs on the Next.js App Router, deployed on Vercel.

Architecture / Flow

More PRODUCT Projects