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).
| 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 |
# 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 devThe API runs at http://localhost:3001 and the web app at http://localhost:3000.
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
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 -vDefault 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 |
# 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)| 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 |
| 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 |
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.
- Go to Google Cloud Console → Credentials
- Create a project (or select an existing one)
- Go to APIs & Services → OAuth consent screen, configure it (External, add your app name/email)
- Go to Credentials → Create Credentials → OAuth 2.0 Client ID
- Application type: Web application
- Add Authorized redirect URI:
http://localhost:3001/v1/auth/google/callback - 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
- Go to Apple Developer → Certificates, Identifiers & Profiles
- Register an App ID: Identifiers → App IDs → Register, enable "Sign In with Apple"
- 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
- Enable "Sign In with Apple", configure the return URL:
- Create a private key: Keys → Create, enable "Sign In with Apple", download the
.p8file - Base64-encode the
.p8key 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 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/statusBranches: 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
Unlicensed — proprietary.