# Garden Manager — Lovable build prompt

Paste **Prompt 1** into a fresh Lovable project. Then run the follow-up prompts one at a time, checking the app after each. Lovable produces far better results from four focused prompts than from one giant one.

---

## Prompt 1 — Foundation, auth, and data model

> Build a web app called **Garden Manager**. It helps home gardeners map their real garden from satellite imagery and get a weather-aware daily watering plan for each plant.
>
> **This first step: authentication, database, and app shell only. Do not build the garden editor or plant features yet.**
>
> **Stack**
> - React + Tailwind, Supabase for auth, database, and storage.
> - Email/password signup plus Google OAuth. Email confirmation required.
> - Every table has Row Level Security so a user can only ever read or write their own rows.
>
> **Database schema**
>
> `profiles` — id (references auth.users), display_name, address_text, latitude, longitude, timezone, units (default 'metric'), email_digest_enabled (default true), digest_send_hour (default 6), created_at
>
> `gardens` — id, user_id, name, satellite_image_url, center_lat, center_lng, zoom_level, meters_per_pixel (numeric), image_width_px, image_height_px, created_at
>
> `beds` — id, garden_id, name, polygon jsonb (array of {x, y} points normalized 0–1 against the image), area_sqm numeric, soil_type enum ('sandy','loamy','clay','potting_mix','unknown'), sun_exposure enum ('full_sun','partial_shade','full_shade'), created_at
>
> `plants` — id, bed_id, user_id, nickname, common_name, scientific_name, photo_url, quantity (default 1), planted_on date, position jsonb ({x, y} normalized against the image), care jsonb, identification_confidence numeric, identified_at, created_at
>
> The `care` jsonb holds: water_need_coefficient (numeric ~0.3–1.2), watering_frequency_days, preferred_watering_time ('morning' | 'evening' | 'either'), sun_requirement, soil_preference, pruning_months (array of ints 1–12), pruning_notes, fertilizing_notes, hardiness_notes, common_problems (array of strings).
>
> `weather_cache` — id, latitude, longitude, forecast_date, payload jsonb, fetched_at. Unique on (latitude, longitude, forecast_date).
>
> `watering_tasks` — id, user_id, plant_id, task_date, slot enum ('morning','evening'), recommended_litres numeric, reason text, completed_at, skipped boolean, created_at. Unique on (plant_id, task_date, slot).
>
> `api_usage` — id, user_id, kind ('plant_id' | 'satellite'), created_at. Used to rate-limit expensive calls.
>
> **App shell**
> - Logged out: a clean landing page explaining the product with a single "Start your garden — free" call to action.
> - Logged in: sidebar navigation with Dashboard, My Garden, Plants, Settings.
> - After first login, an onboarding step asks for the user's home address and saves it to `profiles`, geocoding it to lat/lng.
>
> **Design direction**
> Calm, natural, and legible — not a generic SaaS template. Deep green and warm sand palette, generous whitespace, rounded cards, one clear primary action per screen. Mobile-first: the whole app must be usable one-handed on a phone, since people check it standing in the garden. Metric units and °C throughout.

---

## Prompt 2 — Satellite view and the garden editor

> Now build the garden mapping feature.
>
> **Satellite image**
> - When a user creates a garden, geocode their saved address and fetch a Google Maps Static API satellite image (`maptype=satellite`) at zoom 20, 640×640, scale=2.
> - **Fetch it exactly once per garden.** Store the image in Supabase Storage and save the public URL in `gardens.satellite_image_url`. Never re-fetch on page load — always render from storage. Cost control matters here.
> - Call the Google API only from a Supabase Edge Function so the API key is never exposed in the browser.
> - Compute and store `meters_per_pixel` using the Web Mercator formula: `156543.03392 * cos(latitude * π / 180) / 2^zoom`, divided by the scale factor. This lets the app convert drawn shapes into real square metres.
> - Let the user nudge the map centre and re-fetch once if the framing is off, then lock it.
>
> **Bed editor**
> - An SVG overlay on top of the satellite image where the user draws garden beds as polygons by clicking corner points, then double-clicking to close the shape.
> - Store polygon points normalized 0–1 so shapes stay correct at any display size.
> - Calculate each bed's area in m² from the polygon using the shoelace formula times `meters_per_pixel²`, and show it on the bed.
> - The user names each bed and sets soil type and sun exposure.
> - Beds can be renamed, reshaped, and deleted. Show them as semi-transparent coloured overlays with the name and area labelled.
> - Pinch-zoom and pan on mobile. Drawing must work with touch, not just mouse.
>
> **Plant placement**
> - Inside a bed, the user drops plant markers at specific points. Markers show a small plant icon and the nickname.
> - Tapping a marker opens that plant's detail panel.

---

## Prompt 3 — Plant identification with Claude

> Now add plant identification.
>
> **Flow**
> The user taps "Add plant", picks a bed, and either uploads a photo / takes one with the camera, or searches by name manually. Photos go to Supabase Storage first.
>
> **Identification**
> Create a Supabase Edge Function that calls the Anthropic Messages API (`https://api.anthropic.com/v1/messages`) with the image as a base64 `image` content block. Use the current Sonnet model string from Anthropic's docs. Keep the API key server-side only.
>
> Prompt the model to act as a horticultural expert, identify the plant, and **return only a JSON object with no prose and no markdown fences**, matching this shape:
>
> ```json
> {
>   "common_name": "string",
>   "scientific_name": "string",
>   "confidence": 0.0,
>   "water_need_coefficient": 0.0,
>   "watering_frequency_days": 0,
>   "preferred_watering_time": "morning | evening | either",
>   "sun_requirement": "full_sun | partial_shade | full_shade",
>   "soil_preference": "string",
>   "pruning_months": [1, 2],
>   "pruning_notes": "string",
>   "fertilizing_notes": "string",
>   "hardiness_notes": "string",
>   "common_problems": ["string"]
> }
> ```
>
> Explain in the prompt that `water_need_coefficient` is a crop coefficient roughly between 0.3 (drought-tolerant, e.g. lavender, succulents) and 1.2 (thirsty, e.g. tomatoes, hydrangea), used to scale reference evapotranspiration.
>
> **Rules**
> - Parse the JSON defensively — strip any stray fences, and if parsing fails, show a friendly "couldn't identify this one" state with a manual entry fallback.
> - **Always show the result for user confirmation before saving.** Display the identified name, confidence, and care summary with "Yes, that's it" and "No, let me search manually" buttons.
> - If confidence is below 0.6, lead with the manual search instead.
> - Store the result in `plants.care` so it is never re-fetched. Identification runs once per plant, not on every page view.
> - Log each call to `api_usage` and cap identification at 20 per user per day. Show a clear message when the cap is hit.

---

## Prompt 4 — Weather, the watering engine, and email digests

> Now add the weather-driven watering plan.
>
> **Weather**
> Use the **Open-Meteo** API — it is free and needs no API key. Fetch daily forecast for the garden's lat/lng with these variables: `et0_fao_evapotranspiration`, `precipitation_sum`, `precipitation_probability_max`, `temperature_2m_max`, `temperature_2m_min`, `wind_speed_10m_max`. Also fetch hourly `precipitation` for the next 24 hours.
>
> Cache every response in `weather_cache` and refresh at most twice a day per location.
>
> **Watering calculation**
> For each plant, for each day, compute litres per plant:
>
> ```
> plant_area_sqm  = bed.area_sqm / (number of plants in that bed)
> gross_need_mm   = et0_fao_evapotranspiration × care.water_need_coefficient
> effective_rain  = precipitation_sum × 0.8
> net_need_mm     = max(0, gross_need_mm − effective_rain)
> litres          = net_need_mm × plant_area_sqm × quantity × soil_factor × sun_factor
> ```
>
> - `soil_factor`: sandy 1.2, loamy 1.0, clay 0.85, potting_mix 1.15, unknown 1.0
> - `sun_factor`: full_sun 1.1, partial_shade 1.0, full_shade 0.85
> - If `net_need_mm` is 0, or forecast rain over 24h exceeds 5mm, generate **no task** and show "Rain is doing the work today."
> - Respect `watering_frequency_days` — do not water a plant that was watered within its interval unless the deficit is large.
> - Split by `preferred_watering_time`: morning tasks default to 07:00, evening to 19:00. If either is fine, put it in the morning; if max temperature exceeds 28°C, favour the evening and say why in the `reason` field.
> - Every task carries a short plain-language `reason` — for example "Hot and dry, no rain expected" — so the number never appears unexplained.
>
> Run this once daily per user via a scheduled Edge Function (pg_cron) and write results to `watering_tasks`.
>
> **Dashboard**
> - Today's weather summary at the top: temperature range, rain chance, a one-line verdict.
> - Two grouped lists, Morning and Evening, each row showing plant name, bed, litres, and the reason. Big tap-to-complete checkboxes.
> - A 7-day outlook strip.
> - A **pruning alerts** card: any plant whose current month appears in `care.pruning_months` shows a "Time to prune" note with its `pruning_notes`.
> - A simple streak or "watered on time" count for motivation.
>
> **Email digest**
> Send a morning email via Resend from a scheduled Edge Function at each user's `digest_send_hour` in their timezone. Content: today's weather line, the morning and evening watering lists with litres, and any pruning alerts. Plain, readable HTML, no images. Every email has a one-click unsubscribe that sets `email_digest_enabled = false`. Only send when there is something to do.

---

## Before you paste

- **Keys you'll need:** Google Maps Static API (billed per request — set a quota cap in Google Cloud), Anthropic API, Resend. Open-Meteo needs none. Add all of them as Supabase Edge Function secrets, never as client-side env vars.
- **The free-app maths:** with per-garden satellite caching and one identification call per plant, a typical user costs you a handful of cents once, then near-zero. That only holds if Lovable actually implements the caching — verify it after Prompt 2 and Prompt 3 by checking that no API call fires on a page refresh.
- **Language:** these prompts produce an English UI. Add "All UI text in German" to Prompt 1 if you want it the other way.
- **Deliberately out of scope for v1:** soil moisture sensors, plant disease diagnosis from photos, harvest tracking, companion planting suggestions, sharing gardens between users. Each is a good Prompt 5.
