Aufgabe zur Task hinzugefügt :-)

This commit is contained in:
Marco Kittel 2025-07-21 06:48:18 +02:00
parent 586159a56d
commit 72df26d58e

403
readme.md
View File

@ -1,5 +1,6 @@
# Bewerbungsaufgabe von Marco Kittel 2025
# Vorraussetzungen
Docker und Docker Compose, Posix Compatibles System und Golang >= 1.24
# CsvService
@ -30,3 +31,405 @@ Starten mit./starteWebservice
# Abschlussbesprechung der Aufgabe
[Abschlussbesprechnung](https://www.youtube.com/watch?v=psz58bMyeMM)
# Aufgabe
Organisational requirements
Objective
Application Requirements
Task 1
Task 2 - Stock Import
Task 3 - Cross Country / State Delivery Times
Task 4 - Stock and Delivery Time API
Task 5 - Reservation API
Automatic Release
Order Handling
Target
Organisational requirements
Share all your work with us by using a git-based version control platform like
github.com or gitlab.com in private mode, so we can see your development
progress and test your final results. Please always use the e-mail address for
sharing code.
Objective
Our customer is a global operator of online shops, with a presence spanning
across numerous countries worldwide. They have established country-specific
online shops tailored to serve the unique needs of customers in Germany,
Austria, and Switzerland. Additionally, they operate expansive, nation-wide
shops dedicated to serving customers across all other European Union countries,
the United States, and the rest of the world.
This global reach is supported by an extensive network of warehouses,
strategically located in several countries. These warehouses not only ensure
efficient and effective distribution of products, but also contribute to a
streamlined shopping experience for customers, regardless of their location.
For every product our customer sells, there exists a specific quantity
available in each of their warehouses. However, the availability of these
products can vary significantly; while some warehouses may hold a substantial
stock of a particular product, others may have a limited quantity, or may not
have the product in stock at all. One warehouse may provide products to several
online shops.
The warehouses generate csv files that contain the information about the
available stock per product. Right now each e-commerce application must process
all of the given stock information individually. The stock information files
generated by each warehouse are sent to all shops and are processed there. Each
shop is holding its own copy of the stock information. This is causing the
problem that false stocks and delivery times are advertise. E.g. both the
Germany and Switzerland shop knows that we have x items present in the EU
warehouse, if two customers are buying the same products in two individual
shops we oversell the item.
To avoid this we want to introduce one central instance that processes the
stock information and is asked by the shop instances via api about the
currently available stock. This application should be written in golang.
Application Requirements
The application must be written in golang
In case additional services (databases, message brokers, …) are used a
docker-compose.yml must be provided.
A readme with instructions about how to run this project must be given
A documentation about how to use the api must be given (can be in readme, api
spec, postman collection, …)
The import files used to test the application must be provided in the request
The approx duration for the implementation should be one day
Task 1
Before you start, please create a free account at https://gitlab.com/ and
create a new repository there. You will share later the repository containing
the source code with us.
Task 2 - Stock Import
We maintain detailed knowledge of the specific products and their current stock
levels in each of our warehouses. Each warehouse is operating their own
database that holds that information. There is no centralized database that
contains the stock per product and warehouse. The software used by each
warehouse cannot be modified and only allows file exports.
Each warehouse is generating every hour a csv file with the current stocks.
This csv file is synced with a centralized storage. Only full updates are
supported, which means that each file generated every hour contains all
products. The estimated size will be 700.000 products / lines per file.
Our application must read these csv files and import them into a local database.
Our application that we need to develop will read csv files from the local
filesystem. There will be one directory where all files are saved in. We do not
need to care about the centralized storage.
The filename created by each warehouse has the following structure
Time[RFC-3339, ISO_8601]-WarehouseId-stock.csv
Examples:
$ ls -a | sort
2023-11-09T15:02:17+00:00-CH-stock.csv
2023-11-09T16:01:14+00:00-CH-stock.csv
2023-11-09T16:03:02+00:00-DE-stock.csv
2023-11-09T16:03:17+00:00-AT-stock.csv
2023-11-09T16:04:44+00:00-EU-stock.csv
Text
Copy
In case there are multiple files from one warehouse present the latest file
must be processed.
Files are always full exports.
The file contains the product id which is a string and the currently available
quantity of this product in the warehouse that generated the export file.
product_id;quantity
A1000;50
B3009;80
A8771;158
The file must be processed by our application. The contents must be saved in a
database that we later use to query the currently available stocks. It is
sufficient to save the WarehouseId, ProductId and the Quantity in our database.
The data model you choose here is up to you.
Files that have been processed must be moved to another directory. For
simplification we do not care about cleanup or failed imports.
├── new
│ ├── 2023-11-09T16:03:17+00:00-AT-stock.csv
│ └── 2023-11-09T16:04:44+00:00-EU-stock.csv
└── processed
├── 2023-11-09T15:02:17+00:00-CH-stock.csv
├── 2023-11-09T16:01:14+00:00-CH-stock.csv
└── 2023-11-09T16:03:02+00:00-DE-stock.csv
Text
Copy
Target
The target of task 1 is that our go application searches for new csv files in a
predefined directory. Files are processed and the contents saved in our
database.
Task 3 - Cross Country / State Delivery Times
We have precise data on the average delivery time from each warehouse to every
eligible country and state it serves. This information is provided via csv
export that is generated by each warehouse. The exports are saved on the same
centralized storage as in task 2. Files will be saved in the same directory.
As an example: We have a warehouse in Germany - in case one product is not
available we can fallback to the european warehouse to serve the customer from
there, but we cannot fallback to our US warehouse.
Our application that we need to develop will read csv files from the local
filesystem. There will be one directory where all files are saved in.
├── new
│ ├── 2023-11-09T16:00:10+00:00-CH-delivery.csv
│ ├── 2023-11-09T16:00:20+00:00-DE-delivery.csv
│ ├── 2023-11-09T16:00:37+00:00-EU-delivery.csv
│ ├── 2023-11-09T16:01:56+00:00-AT-delivery.csv
│ ├── 2023-11-09T16:03:17+00:00-AT-stock.csv
│ └── 2023-11-09T16:04:44+00:00-EU-stock.csv
└── processed
├── 2023-11-09T15:02:17+00:00-CH-stock.csv
├── 2023-11-09T16:01:14+00:00-CH-stock.csv
└── 2023-11-09T16:03:02+00:00-DE-stock.csv
Text
Copy
The delivery time files will be saved in the same directory as the stock files
processed in task 2.
The filename created by each warehouse has the following structure
Time[RFC-3339, ISO_8601]-WarehouseId-delivery.csv
$ ls -a | sort
2023-11-09T16:00:10+00:00-CH-delivery.csv
2023-11-09T16:00:20+00:00-DE-delivery.csv
2023-11-09T16:00:37+00:00-EU-delivery.csv
2023-11-09T16:01:56+00:00-AT-delivery.csv
Text
Copy
In case there are multiple files from one warehouse present the latest file
must be processed.
Files are always full exports.
The file contains the country iso, the state and the average delivery time in
days regardless of the product.
// 2023-11-09T16:00:10+00:00-CH-delivery.csv
country;state;delivery_time
CH;;3
DE;BW;4
The here show file is generated by the swiss warehouse. The average delivery
time in switzerland (CH) are 3 days. Nevertheless products can also be delivery
to germany, but only to Baden Württemberg which will take 4 days. If a state
is specified it means that we only delivery to this specific stage. All
countries that are not present or all states that are not present are not
served by this warehouse. If the state is not given, it means that we serve the
whole country. Depending in the location of the warehouse it can be possible
that for some states the delivery time is lower than for the remaining country.
Due to that we can have an entry for the whole country and entries for the
country and a state in the same file.
The file must be processed by our application. The contents must be saved in a
database that we later need to query the currently delivery times.
Files that have been processed must be moved to another directory. For
simplification we do not care about cleanup or failed imports.
Target
The provided files are processed, the contents are stored in our database.
Task 4 - Stock and Delivery Time API
The online shops the customer operates for each country and region are
isolated. This means that their databased and the knowledge about the current
stock and delivery times are not saved in a centralized database. Each shop
must process the aforementioned file imports individually which is causing a
high load on every system every hour. Furthermore as each shop is using its own
source of truth more products than available can be sold or even wrong delivery
times can be advertised.
We now want to remove the processing of the stock and delivery time imports in
all online shop applications and replace that with an api call to our golang
application. The result of your api call is displayed in the shipping cart.
There we display per product the calculated delivery times and the available
stocks.
For that we must provide a new api endpoint which is consumed by the online
shops applications. For simplicity we do not care about authentication.
The api endpoint must accept the following parameters:
Product-IDs + Quantity: We submit the products for that we would like to know
the current instock and delivery times.
Customer Country: As the delivery times depend on the country we submit this as
part of our context
Customer State: As the delivery times may depend on the state we submit this as
part of our context
{
"products": {
"A1000": 20,
"B3009": 1200
},
"context": {
"country": "DE",
"state": "BY"
}
}
Jav
CopyThe result of this api call should contain the product numbers that we
submitted in the request and per product the information about the available
stock in each warehouse that is required. The warehouses should be picked
depending on the available stock and the lowest delivery time. If we for
example can server the products from DE and EU warehouse, we pick the one with
the lowest delivery time first and fill up the remaining quantities.
{
"products": {
"A1000": [
{"warehouse": "DE", "quantity": "5", "delivery_time": 1},
{"warehouse": "EU", "quantity": "15", "delivery_time": 8}
],
"B3009": [
{"warehouse": "DE", "quantity": "110", "delivery_time": 1}
]
}
}
As a result we receive per product the information about the possible
quantities and the delivery times.
Target
We have an api endpoint that accepts the aforementioned payload
Calculate the delivery times based in the previously imported data
Respond with the above shown result
No auth is required
Task 5 - Reservation API
After implementing the stock api the customer is facing less problems with
wrong stocks or delivery times, but the problem still exists for a small number
of customers.
To prevent this we want to introduce a reserve, confirm and release api
endpoint.
Reserve
The reservation api is called by the online shops during the checkout process.
If the customer is navigating to the last checkout step before payment the
online shop calls the reserve api endpoint. The payload will be exactly the
same as for the stock and delivery time api.
{
"products": {
"A1000": 20,
"B3009": 1200
},
"context": {
"country": "DE",
"state": "BY"
}
}
The reservation will perform a stock and delivery time lookup and will reserve
the stock in each required warehouse.
Our api must respond like before with the available stocks and the possible
delivery times. Now we receive in addition a reservation id. This id can be
used to confirm and release the reservation.
{
"id": "59e57f14-be24-43c4-8a8e-4c22f5f2154e",
"products": {
"A1000": [
{"warehouse": "DE", "quantity": "5", "delivery_time": 1},
{"warehouse": "EU", "quantity": "15", "delivery_time": 8}
],
"B3009": [
{"warehouse": "DE", "quantity": "110", "delivery_time": 1}
]
}
}
Abort
In case the customer does not finish the checkout process in one of the online
shops, the online shop calls the abort api endpoint. This removes the
previously created reservation.
The following payload is submitted to this endpoint:
{
"id": "59e57f14-be24-43c4-8a8e-4c22f5f2154e"
}
As there is no result in this api call our response will be 204 no content.
Confirm
In case the customer finishes the checkout and payment process the online shop
will now call the confirm api endpoint including the previously given
reservation id. After this request the information about the reserved stock
stays permanently in our database.
{
"id": "59e57f14-be24-43c4-8a8e-4c22f5f2154e"
}
As there is no result in this api call our response will be 204 no content.
Automatic Release
In case the reservation is not released or confirmed within one day our
application must automatically remove the reserved stock from the database.
Order Handling
The online shops submit the orders to a centralized order management system.
The online shops include the information provided by our reserve api endpoint.
The order management system will now deliver the products based on the
information our api provides. This prevents that more products than available
are sold or wrong delivery times are shown.
If the order management system is processing the orders, stocks in the
warehouses are changed. We receive the new stock information with the next file
export. To release the reserved stock the order management system will call an
api endpoint of our application (release api). The payload includes the
reservation id that we created during the reservation.
{
"id": "59e57f14-be24-43c4-8a8e-4c22f5f2154e"
}
As there is no result in this api call our response will be 204 no content.
Target
Create 4 api endpoints (reserve, abort, confirm, release)
The reservation should block a specific amount in specific warehouses
All further api calls to our stock and delivery time api or the reserve api
must use this information