An example of an incorrect hexagonal architecture
Find a file
2025-10-27 21:41:53 +00:00
python Move vscode Python settings to the correct location 2025-10-27 22:36:03 +01:00
ts More stuff in the ts README 2025-10-27 22:36:22 +01:00
.gitignore Initial commit 2025-10-27 17:09:31 +01:00
README.md Update README.md 2025-10-27 21:41:53 +00:00
skyspell-ignore.toml Make room for other programming languages 2025-10-27 19:14:34 +01:00

Train Reservation with a pentagonal architecture

Context

You are implementing a back end API to book seats from trains.

Each train has an ID.

Each train contains coaches, identified with letters (A, B, C ...)

Each coach contain seats, which have a number containing the coach letter : "1A", "2A", and so on.

Each seat also has an optional booking reference (depending if they are free or already booked).

For now, two routes are implemented:

GET /trains

and

GET /trains/<name>/seats

But, the seats rule is not complete : your goal is to add the booking references to the data returned by the route.

Instructions

First, choose a programming language, and check you can :

  • run the tests
  • call the /trains and /trains/express_2000/seats routes (using curl for instance)

Part 1

Answer the following questions:

  • Are you confident that the code is working as expected ?
  • Do you think there are missing tests ?
  • Do you think the architecture is the right one ?

You may want to consider how the code and the tests would change when you implement the feature detailed in the "context" session.

Part 2

Come up with a better testing strategy, then refactor the code !

Hints:

  • use a in-memory DB and integration tests
  • you may not need an hexagonal architecture just yet :)

Part 3

Implement the POST /book route:

The body should look like:

{
  "train_id": "express_2000",
  "seats": ["1A", "2A"],
  "booking_reference": "abc123def"
}

Note that the server must prevent you from booking a seat that is already reserved with another booking reference, by returning a "409 conflict" status code.

It is however OK to try and book the same seat with twice with the same booking reference.

Implement this new route. Is the app still a CRUD app ?

Part 4

First off, your users won't know their seat numbers in advance !

So the POST /book should instead take a seat count:

{
  "train_id": "express_2000",
  "seat_count": 2,
  "booking_reference": "abc123def"
}

(you can assume the booking reference is fetched form an other source at this point)

Your code should then find some free seats and return them::

{
  "booked": ["1A", "2A"]
}

or return an error message if no free seats are available.

Part 5

You need to implement more business rules:

  • It should not be possible to book seats that are not in the same coach.

For instance, trying to book seat "1A" and "1B" should fail.

  • The app should try and maintain 70% occupancy for each coach

For instance, let's say each coach has 100 seats, and 80% of the seats in coach A are booked, but all the seats in coach B are free. Then, after trying to book 2 seats you should return 2 seats from coach B.

This time, it should be clear you app is no longer just a CRUD - time to do some serious refactoring :)