# RideRegion

RideRegion is an open-source platform for operating a regional bike-sharing network across multiple cities, transit hubs, and partner communities. It provides a unified API and command-line tools for managing stations, bicycles, memberships, trips, pricing, and real-time availability.

## Features

- Multi-city station and service-area management
- Real-time bicycle and dock availability
- Support for standard, electric, and adaptive bicycles
- Memberships, day passes, and pay-as-you-go pricing
- Trip creation, completion, billing, and history
- Maintenance status and bicycle rebalancing workflows
- GBFS-compatible public data feeds
- Role-based access for riders, operators, and administrators
- PostgreSQL persistence with Redis-backed caching
- Local development with Docker Compose

## Requirements

- Node.js 20 or later
- PostgreSQL 15 or later
- Redis 7 or later
- npm 10 or later
- Docker and Docker Compose (optional)

## Installation

Clone the repository and install dependencies:

```bash
git clone https://github.com/example/rideregion.git
cd rideregion
npm install
```

Create a local environment file:

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

Start PostgreSQL and Redis with Docker Compose:

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

Prepare the database and load sample stations:

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

Start the development server:

```bash
npm run dev
```

The API is available at `http://localhost:3000`. A health check is exposed at `GET /health`.

To run the complete application stack in containers:

```bash
docker compose up --build
```

## Usage

### Check station availability

```bash
curl "http://localhost:3000/api/v1/stations?region=lake-county"
```

Example response:

```json
{
  "stations": [
    {
      "id": "LC-CENTRAL-01",
      "name": "Central Station",
      "bikesAvailable": 14,
      "docksAvailable": 8,
      "electricBikesAvailable": 5
    }
  ]
}
```

### 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": "EB-1042",
    "originStationId": "LC-CENTRAL-01"
  }'
```

### End a trip

```bash
curl -X POST "http://localhost:3000/api/v1/trips/trip_01J8N4K9/end" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "destinationStationId": "LC-RIVER-03"
  }'
```

### Operator commands

Import stations from a CSV file:

```bash
npm run cli -- stations import ./data/stations.csv
```

Generate a rebalancing report:

```bash
npm run cli -- rebalance plan --region lake-county
```

Publish updated GBFS feeds:

```bash
npm run cli -- gbfs publish
```

## 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` | HTTP server port |
| `PUBLIC_BASE_URL` | `http://localhost:3000` | Public URL used in links and GBFS feeds |
| `DATABASE_URL` | — | PostgreSQL connection string |
| `REDIS_URL` | `redis://localhost:6379` | Redis connection string |
| `JWT_SECRET` | — | Secret used to sign access tokens |
| `DEFAULT_TIMEZONE` | `America/Toronto` | Time zone for schedules and reports |
| `DEFAULT_CURRENCY` | `CAD` | ISO 4217 billing currency |
| `TRIP_UNLOCK_FEE` | `1.00` | Default trip unlock fee |
| `TRIP_RATE_PER_MINUTE` | `0.20` | Default per-minute charge |
| `RESERVATION_TTL_SECONDS` | `600` | Bicycle reservation lifetime |
| `GBFS_ENABLED` | `true` | Enables public GBFS endpoints |
| `GBFS_CACHE_SECONDS` | `30` | Cache duration for GBFS responses |
| `LOG_LEVEL` | `info` | Application log verbosity |

Required production values should be provided by the deployment environment rather than committed to source control.

Example `.env`:

```dotenv
NODE_ENV=development
PORT=3000
PUBLIC_BASE_URL=http://localhost:3000
DATABASE_URL=postgresql://rideregion:rideregion@localhost:5432/rideregion
REDIS_URL=redis://localhost:6379
JWT_SECRET=replace-this-with-a-long-random-value
DEFAULT_TIMEZONE=America/Toronto
DEFAULT_CURRENCY=CAD
GBFS_ENABLED=true
LOG_LEVEL=debug
```

Region-specific pricing, operating hours, vehicle types, and station capacity rules are stored in `config/regions.yml`. Environment variables take precedence over shared defaults, while database-level operator settings take precedence for individual regions.

## Testing

Run the test suite:

```bash
npm test
```

Run integration tests against local PostgreSQL and Redis services:

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

Run linting and type checks:

```bash
npm run lint
npm run typecheck
```

## License

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