Skip to content

bobbrose/plant-picker

Repository files navigation

Plant Picker

A quiz-based plant recommendation tool. Answer 7 questions about your yard and get 5 tailored plant recommendations powered by Claude AI. Your location is detected automatically from your IP, or you can enter a city/state or ZIP code — recommendations are specific to your local climate and region.

Features

  • AI recommendations — Claude generates 5 plants matched to your yard conditions and local climate
  • Shareable results — every result set gets a /?id=<uuid> URL that loads instantly from the database (no re-calling Claude)
  • Persistent cache — identical quiz inputs are cached in Neon PostgreSQL (30-day TTL) so repeat queries skip the Claude API entirely
  • Session tracking — every quiz completion is recorded with inputs, results, location, and device info
  • Feedback — thumbs up/down prompt on results; thumbs down reveals an optional comment field
  • Saved location — ZIP/city saved in localStorage so returning users skip the location step
  • Nursery links — each plant includes local nursery suggestions with URL validation

Stack

  • Frontend: React 18 + Vite (no CSS framework — custom CSS)
  • Backend: Node.js + Express
  • AI: Anthropic Claude (claude-sonnet-4-6) via @anthropic-ai/sdk
  • Database: Neon PostgreSQL (@neondatabase/serverless)
  • Deployment: Vercel

Local Development

# 1. Install dependencies
npm install

# 2. Copy .env.example and add your keys
cp .env.example .env

# 3. Start both the Express server (port 3000) and Vite dev server (port 5173)
npm run dev

Open http://localhost:5173. Vite proxies /api requests to the Express server on port 3000.

Required environment variables:

  • ANTHROPIC_API_KEY — Anthropic API key
  • DATABASE_URL — Neon PostgreSQL connection string

Mock API Mode

To develop without consuming Anthropic API credits, set MOCK_API=true in your .env:

MOCK_API=true

The server will return sample plant data from mockPlants.js instead of calling Claude. The health check will also pass immediately without validating the API key.

Database Setup

The app uses Neon PostgreSQL. Create a project at neon.tech, copy the connection string into DATABASE_URL, then run:

CREATE TABLE sessions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  zip_code VARCHAR(10),
  usda_zone VARCHAR(5),
  city_state VARCHAR(100),
  quiz_inputs JSONB NOT NULL,
  plant_results JSONB NOT NULL,
  affiliate_clicks JSONB DEFAULT '[]'::jsonb,
  feedback_rating VARCHAR(20) DEFAULT NULL,
  feedback_comment TEXT DEFAULT NULL,
  traffic_source VARCHAR(50) DEFAULT NULL,
  device_type VARCHAR(20) DEFAULT NULL
);

CREATE INDEX idx_sessions_zone ON sessions(usda_zone);
CREATE INDEX idx_sessions_created ON sessions(created_at);
CREATE INDEX idx_sessions_feedback ON sessions(feedback_rating);

CREATE TABLE plant_cache (
  cache_key   VARCHAR(64) PRIMARY KEY,
  plants      JSONB NOT NULL,
  location    TEXT,
  created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  hit_count   INTEGER NOT NULL DEFAULT 0,
  last_hit_at TIMESTAMPTZ
);

CREATE INDEX idx_plant_cache_created ON plant_cache(created_at);

CREATE TABLE nursery_blocklist (
  url TEXT PRIMARY KEY,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Production Build

npm run build   # builds React into dist/
npm start       # serves everything on port 3000

Deploying to Vercel

  1. Push to GitHub.
  2. Import the repo in vercel.com → Add New Project.
  3. Add environment variables in Vercel project settings:
    • ANTHROPIC_API_KEY
    • DATABASE_URL
  4. Deploy — Vercel runs npm run build, then serves dist/ from CDN and routes /api/* to api/index.js.

vercel.json routes all /api/* requests to api/index.js (a standalone Express serverless function). Static assets are served directly from dist/ by Vercel's CDN.

Quiz Flow

All questions are optional — skipped questions default to "no preference".

  1. Plant type — trees, shrubs, flowering plants, perennials, grasses, ground cover (multi-select, optional)
  2. Sun exposure
  3. Soil type
  4. Terrain
  5. Planting goals (multi-select)
  6. Irrigation preference
  7. Special concerns — deer, fire zone, pet-safe, wind, allergens, etc. (multi-select, optional)

Each result includes: why it fits your specific yard, companion plants, fire safety rating (Low / Medium / High), bloom time, water needs, height, and links to local nurseries.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors