# Veloregion Bike Share

Veloregion is a regional bike-sharing platform for cities, transit agencies, and campus partners that operate a shared network of docks, e-bikes, and classic bikes across multiple service zones.

The project includes APIs and worker services for station availability, trip lifecycle management, rider accounts, fleet operations, pricing rules, and partner reporting.

## Features

- Real-time station and bike availability
- Support for docked bikes, e-bikes, and virtual stations
- Trip start, pause, resume, and end workflows
- Regional zones, service boundaries, and geofencing
- Membership plans, day passes, and usage-based pricing
- Maintenance flags, battery status, and fleet rebalancing tasks
- Operator dashboard APIs for stations, bikes, trips, and alerts
- GBFS-style public data endpoints for trip planners
- Configurable payment, notification, and mapping providers

## Install

### Requirements

- Node.js 20+
- PostgreSQL 15+
- Redis 7+
- pnpm 9+

### Setup

```bash
git clone https://github.com/example/veloregion-bike-share.git
cd veloregion-bike-share
pnpm install
cp .env.example .env
```

Create the database:

```bash
createdb veloregion
pnpm db:migrate
pnpm db:seed
```

Start the local services:

```bash
pnpm dev
```

The API will be available at:

```text
http://localhost:8080
```

## Usage

Run the API server:

```bash
pnpm start
```

Run background workers:

```bash
pnpm worker
```

Run tests:

```bash
pnpm test
```

Fetch nearby stations:

```bash
curl "http://localhost:8080/v1/stations?lat=43.6532&lng=-79.3832&radius=1500"
```

Start a trip:

```bash
curl -X POST "http://localhost:8080/v1/trips" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "bikeId": "bike_12842",
    "stationId": "station_union_01"
  }'
```

End a trip:

```bash
curl -X POST "http://localhost:8080/v1/trips/trip_90214/end" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "stationId": "station_riverfront_03"
  }'
```

## Configuration

Configuration is loaded from environment variables.

| Variable | Description | Default |
| --- | --- | --- |
| `PORT` | API server port | `8080` |
| `DATABASE_URL` | PostgreSQL connection string | Required |
| `REDIS_URL` | Redis connection string | Required |
| `JWT_SECRET` | Secret used to sign rider and operator tokens | Required |
| `REGION_ID` | Public region identifier used in feeds and reports | `veloregion` |
| `DEFAULT_TIMEZONE` | Regional operating timezone | `America/Toronto` |
| `GBFS_BASE_URL` | Public base URL for GBFS feeds | `http://localhost:8080/gbfs` |
| `MAP_PROVIDER` | Map provider name, such as `mapbox` or `osm` | `osm` |
| `PAYMENT_PROVIDER` | Payment integration, such as `stripe` or `mock` | `mock` |
| `NOTIFICATION_PROVIDER` | SMS/email provider, such as `twilio`, `sendgrid`, or `mock` | `mock` |
| `TRIP_MAX_DURATION_MINUTES` | Maximum allowed trip duration | `1440` |
| `LOW_BATTERY_THRESHOLD` | Battery percentage that marks an e-bike for service | `20` |

Example `.env`:

```env
PORT=8080
DATABASE_URL=postgres://localhost:5432/veloregion
REDIS_URL=redis://localhost:6379
JWT_SECRET=replace-with-a-local-secret
REGION_ID=greater-valley-bike-share
DEFAULT_TIMEZONE=America/Toronto
GBFS_BASE_URL=http://localhost:8080/gbfs
PAYMENT_PROVIDER=mock
NOTIFICATION_PROVIDER=mock
TRIP_MAX_DURATION_MINUTES=1440
LOW_BATTERY_THRESHOLD=20
```

## Project Structure

```text
src/
  api/          HTTP routes and controllers
  auth/         rider and operator authentication
  billing/      plans, passes, invoices, and payment adapters
  fleet/        bikes, stations, batteries, and maintenance state
  gbfs/         public bike-share feed generation
  trips/        trip lifecycle and pricing calculation
  workers/      scheduled jobs and background processing
  config/       environment and regional configuration
```

## License

MIT