Go to file
Thom Werring 135f23da75 Added some extra information about auth (and included demo api credentials) 2024-03-27 08:30:35 +01:00
.husky Chore: Enabled autoformat code on commit 2024-03-23 13:27:25 +01:00
database/entrypoint Added Authentication 2024-03-26 21:32:33 +01:00
src Throw a NotFoundException when container is not found 2024-03-26 22:28:36 +01:00
tech-assignment-data@89136dcd85 Updated submodule 2024-03-26 21:33:06 +01:00
tests Throw a NotFoundException when container is not found 2024-03-26 22:28:36 +01:00
.dockerignore Added Authentication 2024-03-26 21:32:33 +01:00
.env Added .env 2024-03-26 21:50:57 +01:00
.eslintrc.js WIP: Implemented tests & processed tracking information 2024-03-26 18:23:40 +01:00
.gitignore Added Authentication 2024-03-26 21:32:33 +01:00
.gitmodules Added data samples as submodule to project 2024-03-23 15:03:06 +01:00
.prettierrc Initial commit 2024-03-23 13:23:59 +01:00
Dockerfile Added Authentication 2024-03-26 21:32:33 +01:00
README.md Added some extra information about auth (and included demo api credentials) 2024-03-27 08:30:35 +01:00
docker-compose.yml Added some extra information about auth (and included demo api credentials) 2024-03-27 08:30:35 +01:00
nest-cli.json Initial commit 2024-03-23 13:23:59 +01:00
package-lock.json Package cleanup 2024-03-26 22:27:41 +01:00
package.json Finalize the project 2024-03-26 22:34:44 +01:00
requests.http Added Authentication 2024-03-26 21:32:33 +01:00
tsconfig.build.json Chore: Renamed test directory to e2e-tests for added clarity 2024-03-23 14:09:33 +01:00
tsconfig.json Moved tests 2024-03-26 18:47:55 +01:00

README.md

MyFreight Assessment

How to run

Easiest way to run this project is using docker compose: docker compose up

It is possible that this will give some database connection issues on the first try, but after a couple of seconds, it should automatically reconnect.

Alternatively, it is possible to use your own mysql database, and run the code locally:

  1. Import the database/entrypoint/init.sql into your own database
  2. Update the .env file with the database credentials
  3. Run npm ci to install all npm packages
  4. Run npm run build to build the nestjs application
  5. Run npm run start:prod to start the nestjs application

After starting the application will run on http://localhost:3000/

Documentation

The full endpoint documentation can be found on http://localhost:3000/api. Here you can find which endpoints there are, and how to authenticate.

Authentication

For the Authentication I went with an base64 encoded authentication string consisting of 2 parts. The first part is the ApiKey, which is stored in the authentication database. The second part is a secret that is being used as a password.

In the database we have stored 2 values, the ApiKey and a digest. This digest is creating by using HMAC with the api secret as password, using a sha256 to hash the ApiKey.

This way there is no full api key stored in the database.

Demo example

In this demo you can use eG5nVnZGaWtCMFN6NjRRaWQ2TUJsUTJWaDpjeGg1R3FKRUl0UTlzSGRQdElGMGg0bFJp for the requests.

This decodes to xngVvFikB0Sz64Qid6MBlQ2Vh:cxh5GqJEItQ9sHdPtIF0h4lRi. The first part xngVvFikB0Sz64Qid6MBlQ2Vh is stored in the database, but the second part is not stored anywhere.

Receiving Tracking information

When receiving Tracking information, the following steps need to be completed to process the data

flowchart TD
    receiveTracking(["Receive Tracking"])
    findContainerAndShipment["SELECT container JOIN Shipment"]
    updateShipment[/Update shipment\]
    isArrivingSoon{{"Is arrival estimate between now and now + 24h?"}}
    hasArrived{{"Is arrival estimate <=now?"}}
    isDelayed{{Is arrival estimate > original arrival + 24h?}}
    sendNotification[/Send notification\]

    
    receiveTracking -- "`**Tracking data**
carrierName:**string**
destinationUnLoCode:**string**
departureDate:**string[_datetime_]**
arrivalDateEstimate:**string[_datetime_]**
containerNumber:**string**
`" -->  findContainerAndShipment
    findContainerAndShipment --> |WHERE containers.containerNumber = :trackingData.containerNumber| updateShipment
    updateShipment --> isArrivingSoon & hasArrived & isDelayed
    isDelayed -->|set delayed flag| sendNotification
    hasArrived  --> |set has arrived flag| sendNotification
    isArrivingSoon -->|set is arriving soon flag| sendNotification
    
%%    isArrivingSoon -->|yes| sendArriveSoon

Possible improvements

  • Sending the actual notification, there should be a more general way to setup notifiers
  • Moving some variables to config files
    • when is a shipment "arriving soon"
    • mock date
  • Use the uuid package
    • was not possible since the uuid's from the sample data were invalid uuid's
  • Add end-to-end tests as well
  • Get shipments should be paginated
    • Could use a package like typeorm-crud
  • Cleanup duplicate OpenApi decorators, perhaps consolidate them in a custom decorator