You are required to model the following fare card system which is a limited version of London’s Oyster card system. At the end of the test, you should be able to demonstrate a user loading a card with £30, and taking the following trips, and then viewing the balance.
- Tube Holborn to Earl’s Court
- 328 bus from Earl’s Court to Chelsea
- Tube Earl’s court to Hammersmith
- All bus journey doesn't belong to any zone.
- If User start his journey at zone 1 and end his journey at zone 2 it means two zones.
- If User start his journey at zone 1 and end his journey at zone 3 it means three zones.
- Other than bus journey we need to deduct 3.20 max fare in advanced if user will not do swipe-out at the end of journey he will be charges with max fare.
- In Bus journey max fare would be 1.80 in both cases user swipe-out or not swipe-out.
Stations and zones:
Stations | Zones |
---|---|
Holborn | 1 |
Earl’s Court | 1,2 |
Wimbledon | 3 |
Hammersmith | 2 |
Fares:
Journey | Fare |
---|---|
Anywhere in Zone 1 | £2.50 |
Any one zone outside zone 1 | £2.00 |
Any two zones including zone 1 | £3.00 |
Any two zones excluding zone 1 | £2.25 |
Any three zones | £3.20 |
Any bus journey | £1.80 |
- Java8
- Spring Boot
- Spring Data JPA
- H2 DB
- Spring Doc open API
- Gradle project
- JUnit 5
- JaCoCo
- Docker
- Run below command:
./gradlew bootBuildImage --imageName=az-farecard-service
docker run -p 8080:8080 az-farecard-service
./gradlew clean build bootRun
- Make sure SonarQube server up and running or execute below command
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:6.7.5
- Please validate SonarQube server up
- Default username/password admin/admin
- Please run below command to check SonarQube report
./gradlew clean build sonarqube
- Limiting the scope of requirements I have inserted some cards with initial balance in DB by
data.sql
. - In resources folder I have added
schema.sql
anddata.sql
for DB and predefined cards. - There are four cards available for testing with
cardId
would be one of [1,2,3,4]. - Limiting the scope of requirements I'm assuming there will be only three zones so
zoneId
would be one of [0,1,2,3] - You can easily test whole application with
swagger-ui
.
- User swipeIn his card from zone 1 and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 1,
"swipeType": "IN"
}
- In the response you will get remaining balance:
26.8
- User swipeOut his card with in zone 1 then: Request
{
"cardId":1,
"zoneId": 1,
"swipeType": "OUT"
}
Response
27.50
- User swipeIn his card from zone 2 and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 2,
"swipeType": "IN"
}
- In the response you will get remaining balance:
26.8
- User swipeOut his card with in zone 2 then: Request
{
"cardId":1,
"zoneId": 2,
"swipeType": "OUT"
}
Response
28
- User swipeIn his card from zone 1 and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 1,
"swipeType": "IN"
}
- In the response you will get remaining balance:
26.8
- User swipeOut his card with in zone 2 then: Request
{
"cardId":1,
"zoneId": 2,
"swipeType": "OUT"
}
Response
27
- User swipeIn his card from zone 2 and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 2,
"swipeType": "IN"
}
- In the response you will get remaining balance:
26.8
- User swipeOut his card with in zone 3 then: Request
{
"cardId":1,
"zoneId": 3,
"swipeType": "OUT"
}
Response
27.75
- User swipeIn his card from zone 1 and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 1,
"swipeType": "IN"
}
- In the response you will get remaining balance:
26.8
- User swipeOut his card with in zone 3 then: Request
{
"cardId":1,
"zoneId": 3,
"swipeType": "OUT"
}
Response
26.8
- User swipeIn his card from zone 0 (because all bus journey doesn't belong to any zone) and backend API will be triggered with below request:
{
"cardId":1,
"zoneId": 0,
"swipeType": "IN"
}
- In the response you will get remaining balance:
28.2
- User swipeOut his card with in zone 1 then: Request
{
"cardId":1,
"zoneId": 0,
"swipeType": "OUT"
}
Response
28.2
- TDD reporting with the help of
JaCoCo
. SonarQube
plugin also configured for Code quality, coverage , vulnerabilities and many more.Docker
Image, so we can easily build, ship and deploy.Swagger-UI
, Spring doc open API configured so that we can use swagger-UI for testing purpose.@EnableJpaAuditing
, Spring Data JPA Auditing is active.
- Zone and stations should come from DB dynamically, right now I have hardcoded.
- We should have authentication and authorization for accessing endpoints.
- We should have
UserController
OR user endpoint for login and registration purpose. - We should link cards with Customers on top customers registration.
- Then after we should have spring-security with JTW token base authentication & authorization.
- We should use
Drools
for fare rules. So we don't need to hard code rules by if-else wise. - Right Spring data jpa auditing implemented half some more fields still needs to cover.