A crowdsourced web app that maps real-time food prices. Search by location or dish, tap a pin to see menus and prices, and add or update data by photographing a menu. No login required.
- Map discovery — Map with pins; search by place (geocoding) or by dish (filter pins).
- Add food spots — Name, address, category, optional photo; then add or update menu via photo.
- AI menu scan — Mistral OCR turns a menu photo into structured items; edit and finalize before saving.
- Admin — Token-protected dashboard for verification, flags, and history.
| Layer | Technology |
|---|---|
| Frontend | React (Vite), TypeScript, Tailwind CSS, TanStack Query |
| Map | Mapbox GL, react-map-gl |
| Geocoding | Photon API |
| Backend | FastAPI (Python) |
| OCR | Mistral |
| Database | Supabase (PostGIS) |
| Storage | Supabase Storage (menu_photos, storefronts) |
| Auth | Supabase Anonymous |
| Hosting | Vercel (frontend), Render (backend) |
- Node.js 18+
- Python 3.10+
- Supabase project (PostGIS enabled)
- Mistral API key
git clone https://github.com/your-org/pricepin.git
cd pricepinFrontend:
cd apps/web
cp .env.example .env
# Edit .env with your Supabase and API URL
npm install
npm run devBackend:
cd apps/api
cp .env.example .env
# Edit .env: SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, MISTRAL_API_KEY
pip install -r requirements.txt
uvicorn main:app --reloadCreate a Supabase project and enable PostGIS. Apply migrations in supabase/migrations/ (via Supabase CLI or SQL Editor). See migration files for schema (e.g. food_spots, menu_items, spatial indexes).
apps/web/.env
VITE_SUPABASE_URL— Supabase project URLVITE_SUPABASE_ANON_KEY— Supabase anon keyVITE_API_URL— Backend API URL (e.g.http://localhost:8000for local)VITE_MAPBOX_ACCESS_TOKEN— Mapbox access token (map tiles)
apps/api/.env
SUPABASE_URL— Supabase project URLSUPABASE_SERVICE_ROLE_KEY— Service role keyMISTRAL_API_KEY— Mistral API key for OCRCORS_ORIGINS— Allowed origins (e.g.http://localhost:5173)- Optional:
TURNSTILE_SECRET— Enables Turnstile for/process-menu(requires frontend widget and token)
- Frontend (Vercel): Set root to
apps/web. Add env varsVITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY,VITE_API_URL(production API URL),VITE_MAPBOX_ACCESS_TOKEN. Redeploy after env changes. - Backend (Render): Deploy from
apps/api; start commanduvicorn main:app. SetCORS_ORIGINSto your frontend URL. Optional: use an uptime monitor (e.g. UptimeRobot) pinging/healthevery 5 minutes to avoid cold starts on free tier.
Production builds use the VITE_API_URL from build time; ensure it points to your deployed API, not localhost.
pricepin/
├── apps/
│ ├── web/ # React (Vite, TS, Tailwind), Leaflet, Supabase client
│ └── api/ # FastAPI, Mistral OCR, Supabase server client
└── supabase/
└── migrations/ # PostGIS schema, RLS, indexes
TBD.