Skip to content

nationalteam/trip-planner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

378 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trip-planner

繁體中文

AI-powered collaborative trip planning with activity voting, auto itinerary scheduling, and map visualization.

Features

  • Email/password authentication with secure cookie sessions
  • Per-trip access control (owner/viewer) with sharing by email
  • AI activity generation for places and food based on traveler preferences
  • Approve/reject flow for collaborative decision making
  • Automatic day-by-day itinerary construction from approved activities
  • Google Maps map view with place search + POI click-to-add (beta), plus legacy Leaflet fallback
  • Per-traveler preferences (likes, dislikes, budget)

Tech Stack

Layer Technology
Framework Next.js 15 (App Router, TypeScript)
Styling Tailwind CSS
Database SQLite via Prisma ORM + better-sqlite3 adapter
LLM OpenAI gpt-5-mini (default), Azure OpenAI / Bifrost optional
Map Google Maps JavaScript API (+ Places), Leaflet/OpenStreetMap fallback
Testing Jest + Testing Library

Getting Started

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env
# Set OPENAI_API_KEY=...

Optional: override model for non-Azure OpenAI.

OPENAI_MODEL=gpt-5-mini

Optional: enable Google Maps picker (frontend) and Google Maps Geocoding (backend).

GOOGLE_MAPS_API_KEY=your-google-maps-key

Optional: use Azure OpenAI instead of standard OpenAI.

AZURE_OPENAI_API_KEY=your-azure-key
AZURE_OPENAI_ENDPOINT=https://<resource-name>.openai.azure.com/
AZURE_OPENAI_DEPLOYMENT=your-deployment-name
AZURE_OPENAI_API_VERSION=2025-01-01-preview

Optional: use Bifrost OpenAI-compatible API provider.

LLM_PROVIDER=bifrost
BIFROST_BASE_URL=http://127.0.0.1:8080
# BIFROST_API_KEY=optional-api-key

Behavior:

  • If LLM_PROVIDER is set (openai, azure, bifrost), that provider is used.
  • Without LLM_PROVIDER, provider auto-detection is used in this order: OpenAI (OPENAI_API_KEY) → Azure (AZURE_OPENAI_API_KEY) → Bifrost (BIFROST_BASE_URL or BIFROST_API_KEY).
  • Bifrost uses OpenAI-compatible API calls via BIFROST_BASE_URL.
  • BIFROST_BASE_URL accepts host-only values (for example http://192.168.1.200:8080) and is normalized to /openai/v1.
  • If BIFROST_BASE_URL is not set, default is http://127.0.0.1:8080/openai/v1.
  • BIFROST_API_KEY is optional and defaults to an empty string when unset.
  • Bifrost model selection uses OPENAI_MODEL (default gpt-5-mini).
  • Activity lat/lng and Google Maps map picker use GOOGLE_MAPS_API_KEY when set.

Provider-specific error handling:

  • Bifrost auth errors (401/403) return a clear BIFROST_API_KEY message.
  • Bifrost endpoint errors (404, connection failures) return a clear BIFROST_BASE_URL/network message.
  • Bifrost rate-limit and server errors (429, 5xx) return retry-oriented messages.

3. Set up database

npx prisma migrate dev
npx prisma generate

4. Run development server

npm run dev

Open http://localhost:9527.

Authentication (v1)

  • Register/login at /auth
  • All pages and APIs require authentication except /auth and /api/auth/*
  • Trip sharing supports owner -> viewer by email:
    • owner: full read/write + delete/share
    • viewer: read-only
  • Legacy endpoints are deprecated:
    • /api/users
    • /api/users/[id]/preferences
    • Use /api/me and /api/me/preferences instead

API Naming

Primary endpoints use activities naming:

  • GET/POST /api/trips/[id]/activities
  • POST /api/trips/[id]/activities/fill
  • PATCH/DELETE /api/activities/[id]
  • POST /api/activities/[id]/approve
  • POST /api/activities/[id]/reject

Legacy activity-route aliases are removed.

Scripts

npm run dev      # Start development server
npm run build    # Production build
npm run start    # Start production server
npm run lint     # ESLint
npm run test     # Jest
npm run test:ci  # Jest (CI mode + coverage)
npm run test:e2e # Playwright end-to-end tests

Before running Playwright E2E for the first time:

npx playwright install chromium

CI

GitHub Actions workflow (.github/workflows/ci.yml) runs:

  1. npm ci
  2. npx prisma generate
  3. npm run lint
  4. npm run test:ci
  5. npm run build (with placeholder OPENAI_API_KEY)

Run equivalent checks locally:

just ci

Project Structure

src/
  app/
    page.tsx                      # Home – list & create trips
    trips/[id]/page.tsx           # Trip detail (Activities / Itinerary / Map tabs)
    trips/[id]/preferences/       # Per-traveler preference management
    api/                          # REST API routes
      trips/                      # CRUD for trips
      activities/[id]/approve|reject
      users/                      # CRUD for users & preferences
  components/
    GoogleMapView.tsx             # Google Maps place picker + map markers
    ActivityCard.tsx              # Activity card with approve/reject buttons
    ItineraryView.tsx             # Day-by-day itinerary grouped by time block
    MapView.tsx                   # Leaflet map (client-only)
    TripCard.tsx                  # Trip summary card
  lib/
    prisma.ts                     # Prisma client singleton
    llm.ts                        # OpenAI/Azure OpenAI activity generation
prisma/
  schema.prisma                   # Data model

Data Model

Entity Key fields
Trip name, cities (JSON array)
User name
Preference userId, likes, dislikes, budget
Activity tripId, type, title, description, reason, lat/lng, city, suggestedTime, durationMinutes, status
ItineraryItem tripId, activityId, day, timeBlock (morning/afternoon/dinner)

Demo Site (GitHub Pages)

A demo preview page is deployed to GitHub Pages on every push to main via .github/workflows/deploy-pages.yml.

Run with Docker

cp .env.example .env
# Set OPENAI_API_KEY or AZURE_OPENAI_* variables

docker compose up --build

Open http://localhost:9527.

Packages

 
 
 

Contributors

Languages