Category β‘οΈ Software
Subcategory β‘οΈ Java Backend
Difficulty β‘οΈ Easy
As logistics and e-commerce continue to expand, efficient and intelligent supply chain management becomes critical. In this challenge, you will step into the role of a developer tasked with building the core functionality of a logistics management system, focusing on the seamless coordination between orders and logistics centers. From creating and managing logistics centers to implementing automatic assignment algorithms and real-time distance calculations, this project simulates the dynamic requirements of a modern supply chain. Reflecting the industryβs commitment to precision and optimization, this challenge emphasizes delivering robust, scalable, and user-friendly solutions to ensure operational excellence.
inditex-backend-java-logisticode/
βββ docker-compose.yml
βββ Dockerfile
βββ HELP.md
βββ mvnw
βββ mvnw.cmd
βββ pom.xml
βββ README.md
βββ src
βββ main
βββ java
β βββ com
β βββ hackathon
β βββ inditex
β βββ Controllers
β βββ DTO
β βββ Entities
β βββ InditexApplication.java
β βββ Repositories
β βββ Services
βββ resources
βββ application.properties
βββ static
βββ templates
This challenge involves building and enhancing endpoints for managing logistics centers and orders, including assignment logic, distance calculations, and ensuring data consistency in a dynamic codebase.
- Task 1: Dockerfile & Health Check
- Task 2: Center management (Create, Read, Update, Delete)
- Task 3: Order Management (Create, Read)
- Task 4: Center assignment
PLEASE READ THE ENTIRE README CAREFULLY BEFORE STARTING, AS WELL AS ALL THE RESOURCES PROVIDED.
The first thing to do is to configure the Dockerfile to be able to test the application in containers.
A health check endpoint is provided to which a first request will be sent to check that the container is working properly.
Before doing the first push, you should make sure that this file works correctly, as all other tasks will be tested by attacking the endpoint generated by this container on port 3000.
The contents of the /target folder must not be used for this task.
The second task will assess whether the application is able to correctly create, read, update, and delete logistics centre records correctly in the database. The centers can support 3 types of orders: B (Big), M (Medium), S (Small). Also a combination of two or all. For example, a centre can be MS for medium and small orders.
A guide to requests and responses will follow.
-
Create Logistics Center:
Request body:
{ "name": "Center A", "capacity": "MS", "status": "AVAILABLE", "maxCapacity": 5, "currentLoad": 4, "coordinates": { "latitude": 42.3601, "longitude": -71.0589 } }Response:
{ "message": "Logistics center created successfully." }There cannot be more than one centre at the same point. If this is the case, the response will be as follows:
{ "message": "There is already a logistics center in that position." }currentLoadcannot exceedmaxCapacity. In this case, the response must be as follows:{ "message": "Current load cannot exceed max capacity." } -
Read Logistics Centers: Returns the list of centers created so far.
Response:
[ { "id": 1, "name": "Center A", "capacity": "MS", "status": "AVAILABLE", "currentLoad": 5, "maxCapacity": 10, "coordinates": { "latitude": 48.8566, "longitude": 2.3522 } }, { "id": 2, "name": "Center B", "capacity": "B", "status": "AVAILABLE", "currentLoad": 4, "maxCapacity": 5, "coordinates": { "latitude": 47.8566, "longitude": 2.3522 } } ] -
Update Logistics Center: Any parameter can be changed. In the request you can include only the one you want to change.
Request body:
{ "status": "AVAILABLE" }Response:
{ "message": "Logistics center updated successfully." }currentLoadcannot exceedmaxCapacity. In this case, the response must be as follows:{ "message": "Current load cannot exceed max capacity." } -
Delete Logistics Center: Delete the center with the selected id.
Response:
{ "message": "Logistics center deleted successfully." }
The third task will assess whether the application can correctly handle order creation and retrieval. An order can be B, M or S. Never more than one.
By default, all orders must be marked as PENDING.
A guide to requests and responses follows.
-
Create order: Here you will test that the orders are created correctly.
Request body:
{ "customerId": 203, "size": "B", "coordinates": { "latitude": 51.5074, "longitude": -0.1278 } }Response body:
{ "orderId": 1, "customerId": 203, "size": "B", "assignedLogisticsCenter": null, "coordinates": { "latitude": 51.5074, "longitude": -0.1278 }, "status": "PENDING", "message": "Order created successfully in PENDING status." } -
Get all orders: It will check that the orders have been correctly created in the DB through an endpoint that returns a list of all the orders created so far.
Response body:
[ { "id": 1, "customerId": 203, "size": "B", "status": "PENDING", "assignedCenter": null, "coordinates": { "latitude": 51.5074, "longitude": -0.1278 } } ]
The fourth task assesses whether the application can effectively manage the assignment of logistics centers to orders based on proximity, order type and availability and correctly calculate the distance between an order and its assigned center. This task ensures that the system follows all allocation rules and provides accurate distance metrics. For the distance, the haversine formula must be used.
For the prioritisation of orders, the order in which they were placed must be taken into account. That is to say, the first one will have priority over the second one, so the Id of the order will have to be used as a reference.
An order can have two statuses: ASSIGNED or PENDING.
In this case, an endpoint will be created that will check the status of all orders, search for those with PENDING status and try to assign a logistics center to each of them. At this point, the maximum capacity of each center and the current load must be taken into account.
Suppose we have a logistics centre with the following properties:
[
{
"id": 1,
"name": "Center France",
"capacity": "B",
"status": "AVAILABLE",
"currentLoad": 4,
"maxCapacity": 5,
"coordinates": {
"latitude": 47.8566,
"longitude": 2.3522
}
}
]And two people make an order to be assigned to this center:
[
{
"id": 1,
"customerId": 204,
"size": "B",
"status": "PENDING",
"assignedCenter": null,
"coordinates": {
"latitude": 51.5074,
"longitude": -0.1278
}
},
{
"id": 2,
"customerId": 205,
"size": "B",
"status": "PENDING",
"assignedCenter": null,
"coordinates": {
"latitude": 52.5074,
"longitude": -1.1278
}
}
]When you run the order allocation endpoint, you will get the following response:
{
"processed-orders": [
{
"distance": 443.3660038293021,
"orderId": 1,
"assignedLogisticsCenter": "Center France",
"status": "ASSIGNED"
},
{
"distance": null,
"orderId": 2,
"assignedLogisticsCenter": null,
"message": "All centers are at maximum capacity.",
"status": "PENDING"
}
]
}If we include a new centre:
{
"name": "Center Spain",
"capacity": "M",
"status": "AVAILABLE",
"maxCapacity": 5,
"currentLoad": 0,
"coordinates": {
"latitude": 43.3709703,
"longitude": -8.3959425
}
}And we create a new order with no centers that support this type of order:
{
"customerId": 204,
"size": "S",
"coordinates": {
"latitude": 51.5074,
"longitude": -0.1278
}
}By re-running the endpoint, you should re-process all orders with PENDING status:
{
"processed-orders": [
{
"distance": null,
"orderId": 2,
"assignedLogisticsCenter": null,
"message": "All centers are at maximum capacity.",
"status": "PENDING"
},
{
"distance": null,
"orderId": 3,
"assignedLogisticsCenter": null,
"message": "No available centers support the order type.",
"status": "PENDING"
}
]
}But in this case the message that appears in the last order is different, because when trying to assign, there is no center that supports it.
| Endpoint | HTTP Method | Description | Request Body | Response | Status Codes |
|---|---|---|---|---|---|
/api/centers |
POST | Create a new logistics center | { "name": "Center Name", "capacity": "B", "status": "AVAILABLE", "maxCapacity": 0, "currentLoad": 0, "coordinates": { "latitude": 0.0, "longitude": 0.0 } } |
Success: { "message": "Logistics center created successfully." }Error: { "message": "There is already a logistics center in that position." } Error: { "message": "Current load cannot exceed max capacity." } |
201 CREATED, 500 |
/api/centers |
GET | Retrieve all logistics centers | None | [ { "id": 1, "name": "Center Name", "capacity": "B", "status": "AVAILABLE", "maxCapacity": 0, "currentLoad": 0, "coordinates": { "latitude": 0.0, "longitude": 0.0 } } ] |
200 OK |
/api/centers/{id} |
PATCH | Update details of an existing logistics center | { "name": "New Center Name", "capacity": "M", "status": "OCCUPIED", "coordinates": { "latitude": 0.0, "longitude": 0.0 } } |
Success: { "message": "Logistics center updated successfully." }Error: { "message": "Center not found." } |
200 OK, 404 Not Found |
/api/centers/{id} |
DELETE | Delete a logistics center | None | Success: { "message": "Logistics center deleted successfully." } |
200 OK |
/api/orders |
POST | Create a new order | { "customerId": 123, "size": "B", "coordinates": { "latitude": 40.7128, "longitude": -74.0060 } } |
Success: {"orderId":1,"customerId":123,"size":"B","assignedLogisticsCenter":null,"coordinates":"latitude": 40.7128, "longitude": -74.0060 },"status":"PENDING","message":"Order created successfully in PENDING status."} |
201 CREATED |
/api/orders |
GET | Retrieve all orders | None | [ { "id": 1, "customerId": 123, "size": "B", "assignedCenter": "Center Name", "status": "ASSIGNED", "coordinates": { "latitude": 0.0, "longitude": 0.0 } } ] |
200 OK |
/api/orders/order-assignations |
POST | Assigns a logistics center to orders with PENDING status. | None | {"processed-orders":[{"distance":443.3660038293021,"orderId":1,"assignedLogisticsCenter":"Center France","status":"ASSIGNED"},{"distance":null,"orderId":2,"assignedLogisticsCenter":null,"message":"All centers are at maximum capacity.","status":"PENDING"},{"distance":null,"orderId":3,"assignedLogisticsCenter":null,"message":"No available centers support the order type.","status":"PENDING"}]} |
200 OK |
The application.properties file contains the configuration necessary for the correct functioning of the application.
The tests will simulate the interaction of a user directly with the API running in a container and exposed on port 3000
- Solve the proposed tasks.
- Continuously push the changes you have made.
- Wait for the results.
- Click submit challenge when you have reached your maximum score.
The final score will be given according to whether or not the objectives have been met.
In this case, the challenge will be evaluated on 1600 (1200 for tasks and 400 for code quality) points which are distributed as follows:
- Task 1: 100 points
- Task 2: 400 points
- Task 3: 200 points
- Task 4: 500 points
- Code quality: 400 points
Only the files proposed in the objectives should be modified. You are not allowed to modify anything other than the proposed files.
Q1: What happens if I modify files that are not in scope?
A1: The correction will fail because those changes will not be taken into account.
Q2: Can I add resources that are not in pom.xml?
A2: No, everything needed to complete the challenge is included.
Q3: Can I modify docker-compose?
A3: No, modifying this file may cause the application to malfunction.