Files
The-transit-Project/monitoring_ui/docs/transit_api
Sven laptop e169e37b5e
Build and Push Docker Images / detect-changes (push) Successful in 20s
Build and Push Docker Images / build-auth-api (push) Successful in 2m2s
Build and Push Docker Images / build-employee-api (push) Successful in 2m2s
Build and Push Docker Images / build-transit-api (push) Successful in 2m8s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m58s
Build and Push Docker Images / build-monitoring-ui (push) Has been cancelled
Build and Push Docker Images / build-admin-ui (push) Has been cancelled
Build and Push Docker Images / deploy-test-node (push) Has been cancelled
Refactored all api endpoints to /bus/xxxxx
2026-09-24 20:20:43 +02:00
..

Transit API

Transit API for managing bus routes, navigation, and GPS tracking for bus drivers.

Project Structure

transit_api/
├── index.js           # Main API endpoints
├── middleware.js      # JWT authentication middleware
├── db.js              # PostgreSQL connection
├── schema.sql         # Database schema setup
├── package.json       # Dependencies
└── .env               # Environment variables

Setup

1. Install Dependencies

npm install

2. Set Up Database Schema

Execute the following in PostgreSQL:

# Via psql command line
psql -U your_user -d your_database -f schema.sql

Or copy-paste the SQL queries directly into pgAdmin.

3. Environment Variables (.env)

PG_HOST=localhost
PG_PORT=5432
PG_USER=your_user
PG_PASS=your_password
PG_DB=your_database
JWT_SECRET=your_jwt_secret
PORT=5001

Note: ADMIN_USER_CODES has been moved to the auth_api service. Configure admin user codes in auth_api/.env as a comma-separated list.

4. Start API

npm start

The API runs at https://transit.xtransit.testinstance.nl

The service group also includes the Employee API at https://employees.xtransit.testinstance.nl and the central monitoring dashboard. See ../MONITORING_UI.md for health checks, error inspection, and the controlled request tester.

API Endpoints

All endpoints require an Authorization: Bearer {token} header.

GET /health

  • Checks whether the deployed transit API is running and the database is reachable.
  • Returns 200 with {"status":"ok","database":"ok"} on success.
  • Returns 503 if the API is running but the database is unreachable.

Schedule

Schedules are weekly templates. Each row in "transit.bus".schedules represents one departure time for one bus line and one day_of_week:

  • 1 to 5: weekdays
  • 6: Saturday
  • 0: Sunday

Driver assignments are stored separately in "transit.bus".shifts with (schedule_id, driver_id), where driver_id references workers.users(id). The current shifts shape represents the active assignment. To retain different assignments for different calendar weeks, add a week_start (or assignment date range) column and include it in the unique key.

GET /bus/driver/schedules/daily?date=2026-09-18

  • Returns only weekly schedule templates assigned to the authenticated driver through "transit.bus".shifts.

PATCH /bus/driver/weekly-schedules/:scheduleId/status

  • Updates the status of an assigned weekly schedule.

GET /bus/admin/weekly-schedules

  • Lists weekly templates and their current driver assignments.

GET /bus/admin/shift-drivers

  • Lists drivers from workers.users for shift assignment.

POST /bus/admin/weekly-schedules

  • Creates one template. Body: { "busLineId": 1, "dayOfWeek": 1, "startTime": "08:00", "endTime": "09:00", "driverId": 12 }.

POST /bus/admin/weekly-schedules/bulk

  • Creates multiple departures in one transaction. The API derives each end time from the selected bus line duration. Body: { "busLineId": 1, "dayOfWeeks": [1,2,3,4,5], "startTimes": ["06:00", "06:30", "07:00"], "driverId": 12 }.

PUT /bus/admin/weekly-schedules/:scheduleId/shift

  • Replaces the driver assignment. Pass { "driverId": 12 } or { "driverId": null }.

The legacy /admin/schedules and /schedule/daily aliases remain for older clients, but new clients must use the /bus/-prefixed canonical endpoints (/bus/admin/schedules, /bus/schedule/daily) and the weekly schedule endpoints above.

GET /bus/schedule/daily?date=2024-05-05

  • Retrieve daily schedule for driver
  • Response:
{
  "date": "2024-05-05",
  "routes": [
    {
      "id": 1,
      "startTime": "2024-05-05T08:00:00Z",
      "status": "scheduled",
      "busLine": {
        "lineNumber": 1,
        "startStop": "Central Station",
        "endStop": "Airport"
      },
      "busType": {
        "name": "Standard Bus",
        "seatCapacity": 50,
        "licensePlate": "BUS-001"
      }
    }
  ]
}

GET /bus/routes/:routeId

  • Details of a specific route
  • Response: { "route": {...} }

Public Schedule Overview

GET /bus/schedules/overview?date=2026-05-06&lineId=1

  • Fetches a date-based overview of scheduled services
  • Weekly templates are selected by day_of_week and driver assignments by shifts
  • One-off / incidental services are only included on their exact date
  • Filters: driverId/chauffeurId, stopId/busStopId, lineId, status
  • Response: { "date": "2026-05-06", "summary": {...}, "schedules": [...] }

The legacy endpoint GET /schedules remains available as a deprecated alias for existing clients; the canonical path is GET /bus/schedules.

Example:

curl "https://transit.xtransit.testinstance.nl/bus/schedules/overview?date=2026-05-06&chauffeurId=12&busStopId=3"

Navigation

POST /bus/navigation/route

  • Save calculated route from OSRM
  • Body:
{
  "routeId": 1,
  "startLat": 52.5200,
  "startLon": 13.4050,
  "endLat": 52.5300,
  "endLon": 13.4150,
  "totalDistance": 15000,
  "totalDuration": 900,
  "geojson": {
    "type": "LineString",
    "coordinates": [[13.4050, 52.5200], ...]
  }
}

GET /bus/bus-lines/:busLineId/stops

  • All stops of a bus line (for navigation waypoints)
  • Response:
{
  "stops": [
    {
      "id": 1,
      "order": 1,
      "name": "Central Station",
      "latitude": 52.52,
      "longitude": 13.405
    }
  ]
}

GPS Tracking

POST /bus/gps/track

  • Save real-time position
  • Body:
{
  "routeId": 1,
  "latitude": 52.521,
  "longitude": 13.406,
  "speed": 45.5,
  "heading": 180,
  "accuracy": 5.0
}

GET /bus/gps/route/:routeId

  • All recorded position points of a route
  • Response:
{
  "positions": [
    {
      "id": 1,
      "latitude": 52.521,
      "longitude": 13.406,
      "speed": 45.5,
      "heading": 180,
      "recordedAt": "2024-05-05T08:15:00Z"
    }
  ]
}

Route Status

PATCH /bus/routes/:routeId/status

  • Update route status
  • Body: { "status": "in_progress" }
  • Valid statuses: scheduled, in_progress, completed, cancelled

Admin

All admin endpoints require, in addition to a valid JWT token, that your userCode is present in ADMIN_USER_CODES.

POST /bus/admin/stops

  • Create a reusable stop
  • Body:
{
  "name": "Central Station",
  "latitude": 52.52,
  "longitude": 13.405
}

POST /bus/admin/bus-lines/:busLineId/stops

  • Link an existing stop to a bus line
  • Body:
{
  "stopId": 1,
  "stopOrder": 1,
  "estimatedArrivalMinutes": 0
}

Database Schema

bus_types

  • id - Primary key
  • name - Bus type name (Standard Bus, etc.)
  • seat_capacity - Number of seats
  • license_plate - Unique license plate

bus_lines

  • id - Primary key
  • line_number - Unique line number (1, 5, 12, etc.)
  • start_stop - Start stop name
  • end_stop - End stop name
  • estimated_duration_minutes - Expected route duration

stops

  • id - Primary key
  • name - Stop name
  • latitude, longitude - Stop location

route_stops

  • id - Primary key
  • bus_line_id - Which bus line the stop belongs to
  • stop_id - Reusable stop reference
  • stop_order - Stop sequence on that bus line
  • estimated_arrival_minutes - Optional ETA per stop

routes

  • id - Primary key
  • user_id - Driver (references workers.users)
  • bus_line_id - Which line (references bus_lines)
  • bus_type_id - Which bus (references bus_types)
  • start_time - Scheduled start
  • status - scheduled/in_progress/completed/cancelled

navigation_routes

  • id - Primary key
  • route_id - Link to route (unique)
  • polyline_geojson - GeoJSON LineString of the route
  • total_distance_meters - Route distance
  • total_duration_seconds - Estimated duration

gps_tracking

  • id - Primary key
  • route_id - Which route
  • latitude, longitude - Current position
  • speed_kmh - Current speed
  • recorded_at - Timestamp

Integration with Flutter App

// In schedule_service.dart

// Save navigation route
await scheduleService.saveNavigationRoute(
  routeId: 1,
  navRoute: navigationRoute,
);

// Track GPS
await scheduleService.trackGPS(
  routeId: 1,
  currentPos: navigationPoint,
  speed: 45.5,
  heading: 180,
);

// Update route status
await scheduleService.updateRouteStatus(1, 'in_progress');

Error Handling

All endpoints return error responses:

{
  "error": "error_code",
  "details": "More information"
}

Common errors:

  • missing_token - No Authorization header
  • invalid_token - Token verification failed
  • missing_required_fields - Required data missing
  • invalid_status - Invalid status value
  • route_not_found - Route not found
  • unauthorized - User doesn't own this resource