Integration with Every.Farm

Why Crop Picker was built as a spinoff, its current boundaries with Every.Farm, the scaffolded farm tables, and the phased plan for shared auth, per-farm scoring, buyer matching, and a data contract.

Crop Picker is a spinoff project that will fold into the wider Every.Farm ecosystem. This document describes the current state of the relationship and the planned integration points.

#Why a spinoff

Crop Picker was built as a focused, public-facing catalog. Shipping it independently:

  • Avoids coupling public marketing/SEO content to internal Every.Farm schemas during early iteration
  • Lets us move fast on the catalog UX without scheduling around core Every.Farm release cycles
  • Gives ag researchers, buyers, and prospective users a low-friction way to explore crop fit without signing up for anything

The long-term goal is to integrate Crop Picker data and UX into Every.Farm's authenticated app — so a logged-in farmer sees crop recommendations scored against their farm's soil/drainage/equipment rather than a generic regional profile.

#Current boundaries

Aspect Crop Picker (today) Every.Farm (today)
Domain crops.every.farm app.every.farm / every.farm
Supabase project Dedicated Separate project
Auth None (public read-only) Full auth: Magic link, OAuth
User data farm_* tables scaffolded but empty Canonical farm records, fields, equipment, etc.
Shared resources @every.farm domain, branding, analytics goals —

Today these are two independent systems that happen to share a brand.

#The farm_* scaffold

Crop Picker's database has four user-owned tables that are not exposed anywhere in the UI today:

  • farm_profiles — per-farm record
  • farm_fields — field geometries, soil, drainage
  • farm_equipment — owned equipment
  • farm_crop_scores — per-farm × per-crop suitability

All four have RLS enabled with zero policies — locked down entirely. When auth lands, we'll add USING (user_id = auth.uid()) policies and expose read-only endpoints. No schema migration needed at that point; just a policy migration and a frontend feature flag.

#Integration strategy (planned, not built)

#Phase 1: shared authentication

  • Swap Crop Picker's Supabase project to use Every.Farm's auth provider.
  • Add authenticated-role SELECT policies to the farm_* tables gated by auth.uid().
  • Log-in persists via standard Supabase session; the existing useSupabase() composable picks it up automatically via the Supabase client.

#Phase 2: per-farm scoring

  • When a logged-in user views a crop, the snowflake is computed against their farm profile (drainage, equipment, region) instead of the regional default.
  • Implementation: a crop_farm_scores computation that joins crops × farm_profiles × farm_fields on agronomy prefs and produces a personalized score.
  • The regional crop_snowflake_summary remains the default for unauthenticated users.

#Phase 3: buyer matching

  • The existing nearby_buyers RPC gets a companion nearby_buyers_for_farm that uses the farm's own geography instead of a picker-provided lat/lng.

#Phase 4: data contract

  • A public internal API at api.every.farm/crop-picker/* that proxies Crop Picker data with auth-aware scoring.
  • Shared TypeScript types between the two apps so schema changes propagate cleanly.

#Design principles that survive the merger

  • Public read-only by default. Even after auth lands, unauthenticated visitors continue to see the regional snowflake and generic catalog. Logged-in users get personalization layered on top; they're not gated behind a wall.
  • Audit log stays the provenance system of record. Every data point continues to cite a source, regardless of whose farm is consuming the data.
  • SEO-friendly crop pages. The public /crops/:slug pages remain server-rendered and indexable forever; auth is additive.

Updated

Something missing or out of date? Tell us — the docs are updated with every release.