Skip to content

lrbtn/mototrail

Repository files navigation

MotoTrail

Web-first freemium route planning platform for motorcyclists. Plan, save, share, and export motorcycle routes with moto-specific map layers (road surface, twistiness, elevation, fuel stops).

Prerequisites

Tool Version Install
Node.js >= 22.0.0 nvm install 22
pnpm >= 10.0.0 npm install -g pnpm
Docker >= 26.0.0 https://docs.docker.com/install
Docker Compose >= 2.27.0 Bundled with Docker Desktop

Quick Start

# 1. Clone and install
git clone https://github.com/your-org/mototrail.git
cd mototrail
pnpm install

# 2. Set up environment files
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env.local

# 3. Generate JWT keys for local auth
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in private.pem -pubout -out public.pem
# Base64-encode and paste into apps/api/.env as JWT_PRIVATE_KEY and JWT_PUBLIC_KEY
# macOS:
#   base64 -i private.pem | tr -d '\n'
#   base64 -i public.pem | tr -d '\n'
# Linux:
#   base64 -w 0 private.pem
#   base64 -w 0 public.pem
rm private.pem public.pem  # clean up after copying

# 4. Set your MapTiler key in apps/web/.env.local
#    Get a free key at https://www.maptiler.com/

# 5. Start PostgreSQL + Redis
docker-compose -f infra/docker-compose.yml up -d

# 6. Run database migrations
pnpm --filter api run db:migrate

# 7. Seed sample data (optional)
pnpm --filter api run seed:dev

# 8. Start dev servers
pnpm dev

The API runs at http://localhost:3001 and the web app at http://localhost:3000.

Project Structure

mototrail/
├── apps/
│   ├── api/          # NestJS backend (port 3001)
│   └── web/          # Next.js frontend (port 3000)
├── packages/
│   └── shared/       # Shared Zod schemas, DTOs, types
├── infra/
│   ├── docker-compose.yml   # Local dev (Postgres + Redis)
│   └── valhalla/            # Valhalla routing engine config
├── docs/             # PRD, tech spec, API docs, roadmap
└── turbo.json        # Turborepo pipeline config

Infrastructure (Docker)

Local development runs PostgreSQL 16 + PostGIS and Redis 7 via Docker Compose:

# Start
docker compose -f infra/docker-compose.yml up -d

# Stop
docker compose -f infra/docker-compose.yml down

# Stop and wipe data
docker compose -f infra/docker-compose.yml down -v

Default database credentials (from docker-compose.yml):

Setting Value
Host localhost:5434
Database mototrail
User mototrail
Password mototrail_dev
URL postgresql://mototrail:mototrail_dev@localhost:5434/mototrail

Common Commands

# Development
pnpm dev                            # Start all dev servers
pnpm --filter api start:dev         # API only (watch mode)
pnpm --filter api start:debug       # API with debugger

# Build
pnpm build                          # Build all packages
pnpm --filter api build             # Build API only
pnpm --filter web build             # Build web only

# Testing
pnpm test                           # All unit tests
pnpm --filter api test              # API tests
pnpm --filter web test              # Web tests
pnpm --filter api test:watch        # Watch mode
pnpm --filter api test:cov          # Coverage report
pnpm --filter api test:e2e          # API end-to-end tests
pnpm --filter web test:e2e          # Playwright end-to-end tests

# Code quality
pnpm lint                           # ESLint
pnpm format                         # Prettier (write)
pnpm format:check                   # Prettier (check only)
pnpm typecheck                      # TypeScript (no emit)

# Database (Drizzle)
pnpm --filter api run db:generate   # Generate migration from schema diff
pnpm --filter api run db:migrate    # Run pending migrations
pnpm --filter api run db:studio     # Open Drizzle Studio (DB browser)

Environment Variables

API (apps/api/.env)

Variable Required Description
DATABASE_URL Yes PostgreSQL connection string
REDIS_URL Yes Redis connection string
JWT_PRIVATE_KEY Yes Base64-encoded RS256 private key
JWT_PUBLIC_KEY Yes Base64-encoded RS256 public key
VALHALLA_URL No Valhalla routing engine URL
GOOGLE_CLIENT_ID No Google OAuth client ID
GOOGLE_CLIENT_SECRET No Google OAuth client secret
GOOGLE_CALLBACK_URL No Google OAuth callback URL
APPLE_CLIENT_ID No Apple Sign In services ID
APPLE_TEAM_ID No Apple Developer team ID
APPLE_KEY_ID No Apple Sign In private key ID
APPLE_PRIVATE_KEY No Base64-encoded Apple .p8 private key
APPLE_CALLBACK_URL No Apple Sign In callback URL

Web (apps/web/.env.local)

Variable Required Description
NEXT_PUBLIC_API_URL Yes API base URL with /v1
NEXT_PUBLIC_MAPTILER_KEY Yes MapTiler Cloud API key
NEXT_PUBLIC_APP_URL Yes Web app public URL

Authentication

MotoTrail supports three authentication methods:

  • Email/password — register with username, email, and password (always available)
  • Google OAuth — sign in with Google account (optional, requires credentials)
  • Apple Sign In — sign in with Apple ID (optional, requires credentials)

OAuth providers are optional — if their env vars are not set, the corresponding routes are not registered and the app works with email/password only.

Setting up Google OAuth

  1. Go to Google Cloud Console → Credentials
  2. Create a project (or select an existing one)
  3. Go to APIs & Services → OAuth consent screen, configure it (External, add your app name/email)
  4. Go to Credentials → Create Credentials → OAuth 2.0 Client ID
  5. Application type: Web application
  6. Add Authorized redirect URI: http://localhost:3001/v1/auth/google/callback
  7. Copy the Client ID and Client Secret into your .env:
    GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
    GOOGLE_CLIENT_SECRET=your-client-secret
    GOOGLE_CALLBACK_URL=http://localhost:3001/v1/auth/google/callback
    

Setting up Apple Sign In

  1. Go to Apple Developer → Certificates, Identifiers & Profiles
  2. Register an App ID: Identifiers → App IDs → Register, enable "Sign In with Apple"
  3. Register a Services ID (this is your APPLE_CLIENT_ID): Identifiers → Services IDs → Register
    • Enable "Sign In with Apple", configure the return URL: http://localhost:3001/v1/auth/apple/callback
  4. Create a private key: Keys → Create, enable "Sign In with Apple", download the .p8 file
  5. Base64-encode the .p8 key and add to your .env:
    APPLE_CLIENT_ID=com.your.services.id
    APPLE_TEAM_ID=YOUR_TEAM_ID
    APPLE_KEY_ID=YOUR_KEY_ID
    APPLE_PRIVATE_KEY=<base64-encoded contents of the .p8 file>
    APPLE_CALLBACK_URL=http://localhost:3001/v1/auth/apple/callback
    

Note: Apple requires HTTPS for production callbacks. For local development, you may need a tool like ngrok to tunnel HTTPS to your local server.

Valhalla (Routing Engine)

Valhalla is optional for local development (only needed for route calculation features).

# Download Poland OSM extract (~1.5 GB, builds in ~5-10 min)
cd infra/valhalla
wget https://download.geofabrik.de/europe/poland-latest.osm.pbf -O custom_files/data.osm.pbf

# Start Valhalla alongside other services
docker-compose -f ../docker-compose.yml up valhalla -d

# Verify it's running
curl http://localhost:8002/status

Git Conventions

Branches: feature/, fix/, chore/, docs/ + short description.

Commits: Conventional Commits format:

feat(routes): add GPX export endpoint
fix(routing): handle Valhalla circuit breaker open state
test(auth): add refresh token rotation unit tests
chore(deps): upgrade MapLibre GL to 4.2.0

Documentation

License

Unlicensed — proprietary.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages