This project implements a CRM solution for a shop with Users, Admins and Customers.
This project is being developed with:
- Gradle
- SpringBoot + Kotlin
- PostgreSQL
- Flyway
- Docker compose
- Run the script
./scripts/create-docker-image.shwhich will create a local docker image of the app. - Run
docker-compose upwhich will spin up a dockerized Posgres database and then the Spring boot application. - Run
docker-compose downat any moment to stop both containers.
- Load the Environment variables defined in the file
.envinto your environment. - Run
docker-compose up postgres_dbto spin up the PSQL database docker container.- Changing the values in the
.envfile will affect both to docker compose and the Spring app, so feel free to modify and customize it to your machine.
- Changing the values in the
- Run
./gradlew bootRun. - Your application should be running and listening on the port 8080.
- This project is using TestContainers, which will spin up a PSQLContainer at the start of the test cycle using a random port.
- Run
./gradlew test
You can find some examples to the different API endpoints under /docs/postman.
Image uploading for rest APIs is a challenge itself since they are supposed to operate with JSON, therefore multipart files uploads are not so easy (as they require multipart/form-data header for requests). After some investigation I found out that a common way to handle file uploads through Base64 encoded strings, which can be part of a valid JSON body request. This encoded string tends to be quite consume around a 25% extra bandwidth, but in this case I weighed design over performance.
Also, to avoid sending a huge request at the moment of creating a customer, the image can be uploaded in a request beforehand and have it ready to be attached on customer creation.
Therefore, in this application the flow to upload a picture to a Customer is the following:
- Upload a picture MIME Base64 encoded String through a POST request to
/pictures.- Its up to the client to create the Base64 encoded string with MIME headers. It will be validated before saving it.
- Answer from this request will include a
pictureId.
- At this point, when creating or updating a Customer the picture can be attached to it including the
pictureIdin the request body.- This field is optional, meaning that customers can be created without a Picture. That can be easily changed, but I decided to keep customer creation making pictures not mandatory.
- This has the drawback of having uploaded pictures not attached to any Customer entity. An easy solution for this would be a scheduled job cleaning those from time to time.
Assumptions are that users have access to all customer's pictures.