# Regional Bike-Sharing Network

A platform for operating and integrating a regional bike-sharing network across multiple municipalities. It provides real-time station availability, trip management, pricing rules, maintenance workflows, and a unified API for rider applications and operations teams.

## Overview

The project supports docked and dockless bicycles, including electric bikes, under a shared regional service. Operators can manage stations, vehicles, service zones, memberships, and maintenance events while riders can find bikes, plan trips, unlock vehicles, and review trip history.

The reference implementation includes:

- A REST API for rider and operator applications
- A background worker for trip, billing, and telemetry events
- PostgreSQL for operational data
- Redis for caching and asynchronous jobs
- A local development environment powered by Docker Compose

## Features

- Real-time bike and dock availability
- Docked, dockless, and electric-bike support
- Station and service-area management
- Trip reservation, start, pause, and completion flows
- Membership plans and municipality-specific pricing
- Payment-provider integration
- Maintenance reporting and vehicle status tracking
- Rebalancing alerts for low-capacity stations
- Role-based access for riders, technicians, dispatchers, and administrators
- GBFS-compatible public feeds
- Audit logs and operational metrics
- Webhook delivery for trip and vehicle events

## Requirements

- Node.js 20 or later
- npm 10 or later
- PostgreSQL 15 or later
- Redis 7 or later
- Docker and Docker Compose, recommended for local development

## Installation

Clone the repository and install dependencies:

```bash
git clone https://github.com/example/regional-bike-share.git
cd regional-bike-share
npm install
```

Create a local environment file:

```bash
cp .env.example .env
```

Start PostgreSQL and Redis:

```bash
docker compose up -d postgres redis
```

Apply database migrations and load sample data:

```bash
npm run db:migrate
npm run db:seed
```

Start the API and background worker:

```bash
npm run dev
```

The API is available at `http://localhost:3000`. Health status can be checked at `http://localhost:3000/health`.

## Usage

### Find nearby stations

```bash
curl "http://localhost:3000/api/v1/stations?lat=43.6532&lon=-79.3832&radius=1500"
```

### View station availability

```bash
curl "http://localhost:3000/api/v1/stations/stn_1042"
```

### Reserve a bike

```bash
curl -X POST "http://localhost:3000/api/v1/reservations" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bikeId": "bike_8271",
    "durationMinutes": 10
  }'
```

### Start a trip

```bash
curl -X POST "http://localhost:3000/api/v1/trips" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "bikeId": "bike_8271",
    "originStationId": "stn_1042"
  }'
```

### Run the test suite

```bash
npm test
```

Run integration tests against the local services:

```bash
npm run test:integration
```

### Generate GBFS feeds

```bash
npm run gbfs:generate
```

Generated feeds are served from `/gbfs/v2`.

## Configuration

Configuration is loaded from environment variables. Values in `.env` are used during local development.

| Variable | Default | Description |
|---|---:|---|
| `NODE_ENV` | `development` | Runtime environment |
| `PORT` | `3000` | API server port |
| `DATABASE_URL` | — | PostgreSQL connection string |
| `REDIS_URL` | `redis://localhost:6379` | Redis connection string |
| `JWT_SECRET` | — | Secret used to sign access tokens |
| `JWT_EXPIRES_IN` | `15m` | Access-token lifetime |
| `RESERVATION_TTL_SECONDS` | `600` | Time before an unused reservation expires |
| `DEFAULT_SEARCH_RADIUS_METERS` | `1000` | Default nearby-station search radius |
| `MAX_SEARCH_RADIUS_METERS` | `10000` | Maximum allowed station search radius |
| `DEFAULT_TIMEZONE` | `America/Toronto` | Time zone used for schedules and reports |
| `PAYMENT_PROVIDER` | `sandbox` | Payment integration to use |
| `PAYMENT_API_KEY` | — | Payment-provider API key |
| `TELEMETRY_WEBHOOK_SECRET` | — | Secret for validating bike telemetry events |
| `GBFS_BASE_URL` | `http://localhost:3000/gbfs/v2` | Public base URL for GBFS feeds |
| `LOG_LEVEL` | `info` | Application logging level |
| `CORS_ORIGINS` | `http://localhost:5173` | Comma-separated allowed browser origins |

Example development configuration:

```dotenv
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://bike_share:bike_share@localhost:5432/bike_share
REDIS_URL=redis://localhost:6379
JWT_SECRET=replace-this-in-production
DEFAULT_TIMEZONE=America/Toronto
PAYMENT_PROVIDER=sandbox
LOG_LEVEL=debug
CORS_ORIGINS=http://localhost:5173
```

Municipality-specific service zones, pricing rules, station capacities, and operating hours are stored in the database and can be managed through the operator API. Seeded examples are located in `config/regions`.

Never commit production credentials or signing secrets. Use a managed secret store in staging and production environments.

## Project Structure

```text
src/
  api/            HTTP routes and request validation
  auth/           Authentication and authorization
  billing/        Fares, memberships, and payments
  gbfs/           Public GBFS feed generation
  operations/     Maintenance and rebalancing workflows
  trips/          Reservations and trip lifecycle
  vehicles/       Bike state and telemetry
  workers/        Background job processors
config/           Regional defaults and seed configuration
migrations/       Database migrations
tests/            Unit and integration tests
```

## License

Licensed under the MIT License. See `LICENSE` for details.