A travel itinerary organizer with a Flutter client and Convex backend.
- Upload PDFs and let AI automatically parse and extract flights, accommodations, or activities
- Manage trips with multiple destinations
- Track accommodations per destination
- Store flight details with full booking info
- Organize daily activities and itinerary
- Interactive map view with flutter_map (OpenStreetMap tiles)
- Bun installed
- Flutter installed (for mobile client)
- Rust installed (required by
convex_flutterpackage)
-
Install dependencies:
bun install
-
Start Convex development server:
bun run dev:convex
This will prompt you to:
- Log in with GitHub
- Create a new Convex project
- Sync your functions to the cloud
-
Your backend is ready! Convex provides real-time subscriptions out of the box.
-
Set up shared environment files (symlinks client env to root):
bun run setup:client
-
Configure Google Places API Key (required for address autocomplete and geocoding):
Add your API key to
.env.localin the project root:GOOGLE_PLACES_API_KEY=your-actual-api-key-hereTo get an API key:
- Go to Google Cloud Console
- Create a new API key
- Enable these APIs: Geocoding API, Places API
-
Configure Weather API Key (required for weather forecasts):
Add your OpenWeatherMap API key to your Convex environment variables:
- Go to your Convex Dashboard
- Select your project → Settings → Environment Variables
- Add:
OPENWEATHERMAP_API_KEY= your API key
To get an API key:
- Sign up at OpenWeatherMap
- Subscribe to the One Call API 3.0 (free tier: 1000 calls/day)
Note: Weather data is cached server-side to reduce API calls. All users share the same cache, so popular destinations won't exhaust your quota.
-
Configure FlightAware AeroAPI Key (optional, for live flight status):
Add your AeroAPI key to your Convex environment variables:
- Go to your Convex Dashboard
- Select your project → Settings → Environment Variables
- Add:
AERO_API_KEY= your API key
To get an API key:
- Sign up at FlightAware
- The Personal tier includes a limited number of free queries per month
Note: Flight status is fetched on-demand when viewing flight details. If no API key is configured, flight status features will be unavailable.
-
Install Flutter dependencies:
cd client flutter pub get -
Run the app:
flutter run
Note: The client uses
convex_flutterwhich requires Rust. Make sure your Rust toolchain is up to date:rustup update stable
This app uses flutter_map with free OpenStreetMap/CARTO tiles — no Google Maps API key required for map display!
- Light mode: CARTO Voyager tiles
- Dark mode: CARTO Dark Matter tiles
- Geocoding: Uses Google Geocoding API (requires
GOOGLE_PLACES_API_KEY)
| Module | Functions |
|---|---|
trips |
list, get, create, update, remove |
destinations |
listByTrip, get, create, update, remove |
accommodations |
listByDestination, get, create, update, remove |
flights |
listByTrip, get, create, update, remove |
flightStatus |
refreshStatus (live status from AeroAPI) |
activities |
listByTrip, get, create, update, remove |
weather |
getWeather (cached via Action Cache) |
Weather data is cached server-side using Convex Action Cache:
| Date Range | TTL | Notes |
|---|---|---|
| Past dates | 24 hours | Historical data never changes |
| Today/tomorrow | 1 hour | Fresher data for near-term |
| 3+ days ahead | 2 hours | Forecasts are stable |
This shared cache reduces OpenWeatherMap API calls across all users, keeping you well under the 1000 calls/day free tier limit.
| Script | Description |
|---|---|
bun run setup:client |
Set up client env symlinks (run once) |
bun run dev:convex |
Start Convex dev server |
bun run dev:client |
Run Flutter client |
travel-organizer-app/
├── client/ # Flutter mobile app
├── server/
│ └── convex/ # Convex backend functions
│ ├── schema.ts # Database schema
│ ├── trips.ts # Trip functions
│ ├── destinations.ts
│ ├── accommodations.ts
│ ├── flights.ts
│ ├── activities.ts
│ └── weather.ts # Weather API with caching
├── convex.json # Convex configuration
└── package.json
Ensure you're logged in:
bunx convex loginThis means the Google Places API key is missing or invalid:
- Check that
.env.localhasGOOGLE_PLACES_API_KEYset - Ensure the API key has these APIs enabled in Google Cloud Console:
- Geocoding API
- Places API
- Restart the app (not hot reload) after changing env files
Check the Google Cloud Console to ensure:
- The API key is not restricted incorrectly
- Billing is enabled on the Google Cloud project
- The required APIs are enabled





