尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
AI trip planner for Azerbaijan: pick a city, dates and places, get a day-by-day route on a map. Expo, Supabase Edge Functions, OpenRouter.
翻译准备中
正在加载完整 README。
查看完整 README ↗A mobile app that plans a trip day by day. The traveller picks a city and dates, swipes through places, and an AI model splits the places into days, orders them by proximity and draws the route on a map.
Built as a working prototype in 2025 with React Native, Expo and Supabase. Case study
Welcome -> City -> Dates -> Categories -> Swipe places -> Generate route -> Route on a map
generate-route Edge Function.No sign-up is needed and no personal data is sent to the model; the prompt contains only place data and dates.
| Folder | What it is |
|---|---|
mobile-frontend | Expo app: 7 screens, English and Azerbaijani, Zustand state, React Navigation, react-native-maps, optional Sentry |
backend/supabase | Database schema, RLS policies, SQL helpers and the generate-route Edge Function (Deno) |
The sample data has two cities, Baku and Gabala, and 19 places, all of them in Baku (Gabala is listed but has no places yet). It is enough to try the whole flow, and it is not the full dataset the original app used.
You need a current Node.js LTS release, a free Supabase project, an OpenRouter API key, and the Supabase CLI.
1. Database. In the Supabase SQL editor run these files from backend/supabase/database, in this order:
schema.sql, categories_schema.sql, rls_policies.sql, categories_rpc.sql, test_data.sql, categories_test_data.sql, route_quota.sql.
2. Edge Function.
cd backend
supabase secrets set OPENROUTER_API_KEY=your_key --project-ref YOUR_PROJECT_REF
supabase functions deploy generate-route --project-ref YOUR_PROJECT_REF
3. App.
cd mobile-frontend
cp .env.example .env # your Supabase URL and anon key
npm install
npx expo start
Android maps need a Google Maps SDK key in GOOGLE_MAPS_API_KEY. Restrict that key to your app in the Google Cloud console.
Each route request can cost up to four model calls, so generate-route refuses requests beyond a quota (table and function in route_quota.sql):
ROUTE_LIMIT_PER_HOUR)ROUTE_LIMIT_PER_DAY)Both are optional function secrets (supabase secrets set ROUTE_LIMIT_PER_HOUR=10); the numbers above are the defaults.
A client is identified by a salted hash of its IP address; the address itself is never stored. If the quota cannot be checked, the request fails instead of running unchecked, and a limit that is not a positive whole number falls back to the default.
The daily cap protects your bill, not your availability: someone who spreads requests over many IPs can use up the day's allowance for everyone. Also set a monthly credit limit on your OpenRouter key.
This is a prototype. Read this before you copy anything from it.
google/gemma-4-31b-it and google/gemma-4-26b-a4b-it) are set in the function; check that they still exist on OpenRouter and change them if not.user_trips table is unused. It is a placeholder for saving trips.MIT, see LICENSE.
Ramin Bakhshalıyev, Mobile & AI Product Builder in Baku. raminbakhshaliyev.com