This project implements a RESTful API for managing a subway system, including train lines, stations, and optimal route calculations.
- Node.js
- TypeScript
- Express.js
- Neo4j (Graph Database)
- PostgreSQL
- Docker & Docker Compose
- Docker and Docker Compose installed on your machine
- Node.js (for local development)
This is project is setup on Docker Environment - user dockercompse for spawning entire setup including databases - PostGres & Neo4j Docker Compose is used as development enviroment, for production use cases, build image using docker file as it creates prod version and deploy it in your production env (k8 Env) lot of configurations are preset - check docker-compose.yml file
- clone / download this project
- Start the application using Docker Compose:
docker compose up
This will start the Node.js application, PostgreSQL database, and Neo4j database.
- The API will be available at
http://localhost:3000
if databasse is not initialized
p.s. following steps needs to be performed when application is up so that you can access spawned postgres DB
prisma schema file location - prisma/schema.prisma
-
create prima migration file
docker-compose exec app npx prisma migrate dev --name init
-
Review Migration file (optional). Push/apply migration to database
docker-compose exec app npx prisma db push
-
Generate Primsa client
docker-compose exec app npx prisma generate
yes
calling following postmant api's
- create trainline 1
- create trainline 2
to test call Get Rounte post man API
- Create trainline previously already mandates of fare param in body.
- create Card API
- once card created - call Station Enter API
- Station Exit.
yes, code is well thoughtout, following standard practices. It is shouuld it terms of both features scaling and data scaling.
when it comes to rides, Fare and cards - transactions are used efficinetly used when its requried.
The code has been designed with extensibility in mind:
- Modular Architecture: The project is structured into services, controllers, and models, making it easy to add new features or modify existing ones.
- Database Abstraction: We use repositories to abstract database operations, allowing for easy switching or addition of new data sources.
- Middleware Pattern: Express middleware is used for cross-cutting concerns like error handling and logging, making it easy to add new global behaviors.
- Configuration Management: Environment variables and a config module are used for easy configuration in different environments.
- Scalable Graph Algorithms: The use of Neo4j's Graph Data Science library allows for easy implementation of more complex routing algorithms in the future.
To extend the system, you can:
- Add new models to src/models/
- Implement new services in src/services/
- Create new controllers in src/controllers/
- Add new routes in src/routes/
Performed Manual integration test using postman
postman API's JSON file - ./GetParkerCoding.postman_collection.json
This project implements a subway system based on the provided problem statement, with the following key features:
- Adding train lines with stations and fares
- Finding optimal routes between stations
- Managing prepaid cards for passengers
- Handling entry and exit of passengers at stations
TrainLineService
: Manages train lines, stations, and route calculations.CardService
: Handles prepaid card operations.RideService
: Manages passenger rides, including entry and exit operations.
The current implementation is based on a simplified problem statement that doesn't fully address the complexities of real-world subway systems. This has led to certain limitations in the system design:
The problem statement specifies:
"The amount users should pay when taking trains from this line"
This implies a single fare per line, which doesn't account for:
- Stations served by multiple lines
A significant limitation arises from the requirement to deduct the fare when a passenger enters a station:
"POST /station/[station]/enter card_number - unique identification of the card being used to pay for the ride returns the amount left in the card after paying for the ride"
This requirement introduces several challenges:
- Unknown Destination: At the point of entry, the system doesn't know the passenger's destination, making it impossible to calculate an accurate fare for distance-based or zone-based pricing systems.
Arbitrary Line Selection: For multi-line stations, the system arbitrarily selects the fare from one of the lines.
As the result system is forced to Arbitrary Line Selection