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.