We have recently added a simple reminder system to Personio. You have been allocated to be part of the team that supports this service.
As you are new to the team, a very simple task will be assigned to you so you have the chance to contribute to the codebase while getting familiar with the service.
The reminder service has a few requirements that have been already implemented and that are listed below for your better understanding.
The reminder is displayed on the dashboard on the day of the reminder at 00:00. Reminders must display the text entered by the employee, and have a “Done” button. Reminders marked as “done” will not appear anymore. Past reminders, not marked as done, must still appear.
Example: A reminder set for 2018-12-20 will first appear on the dashboard on 2018-12-20 at 00:00. On 2018-12-21, if not marked as “Done” by the employee, the reminder will still appear.
The employee can also optionally enter a time of day (in addition to the date). The reminder will be sent by email on that date & time to the employee’s email address, unless the reminder was already marked as ”done” prior to that time. The precision is 5 minutes (e.g. the employee can select e.g. 14:00, 14:05, 14:10, etc.). The email must be only sent once for each reminder, i.e. even if the reminder is not marked as done, and continue appearing in the dashboard, the email must not repeat every day.
The acceptable delay for sending the email is within 5 minutes of the chosen time.
We are serving employees in very different time zones. We want to make sure that the reminder email is always sent using the correct time zone of each employee.
In addition to one-time reminders described above, the employee is also able to optionally create a recurrence rule. The recurrence rule is limited to 2 parameters: Frequency (one of: DAILY, WEEKLY, MONTHLY or YEARLY) and Interval (an integer, e.g. every X days, every X months, etc.).
The recurrence is optional, and defined by the employee when they create the reminder. If a recurrence rule is set, a new copy (called occurrence) of the reminder will be created at the given frequency & interval. The employee must be able to mark each occurrence as “Done” independently of each other.
Example: A daily (freq=DAILY, interval=1) reminder “Buy milk” will appear every day on the dashboard. If the previous day’s reminder is not marked as done, then the employee will see two “Buy milk” reminders on his dashboard.
When combining recurring reminders with the “send email at a certain time” feature, the employee will receive one email per occurrence.
The service is written in Kotlin and uses Spring Boot as an underlying framework. We also use Flyway to manage database migrations and JOOQ for writing SQL queries.
In order to build and run this project, you need the following components:
- Java 17 (we recommend Eclipse Temurin 17)
- Docker (or a compatible container runtime)
The service strives to follow the clean architecture approach
(source: https://medium.com/swlh/clean-architecture-a-little-introduction-be3eac94c5d1)
All API endpoints are located in com.personio.reminders.api
package. The OpeanAPI documentation for the API is available in openapi.yaml.
Interfacing with external systems is limited to com.personio.reminders.infrastructure
package.
Use cases contain the application logic and depend only on domain entities.
Clone the service to your computer using the command below:
git clone [email protected]:personio/backend-coding-challenge.git
cd backend-coding-challenge
Generate the JOOQ classes from the database schema with the following command:
./gradlew generateJooq
You can also run the PostgreSQL database using the command below:
docker-compose up db
Import the service in your favourite IDE, i.e. IntelliJ IDEA and execute the main class com.personio.reminders.Application
to start the service.
Clone the service to your computer using the command below:
git clone [email protected]:personio/backend-coding-challenge.git
cd backend-coding-challenge
Generate the JOOQ classes from the database schema using the command below:
./gradlew generateJooq
Start/update the service using the command below:
./gradlew bootJar && docker-compose up -d --build
Stop the service using the command below:
docker-compose down
Watch the application logs using the command below
docker logs personio-reminders-service -f
Run the following cURL command to create a new reminder in the service.
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"employee_id": "de3ffa44-7b34-46a6-a329-d3b8fb95399e",
"text": "Remind me to buy some oat milk!",
"date": "2022-04-28T17:30:00.00Z",
"is_recurring": false
}' http://localhost:8080/reminders -v
Run the following cURL command to retrieve all the reminders of a specific employee.
curl "http://localhost:8080/reminders?employeeId=de3ffa44-7b34-46a6-a329-d3b8fb95399e" -v
Run the following cURL command to retrieve all the occurrences of a specific employee.
curl "http://localhost:8080/occurrences?employeeId=de3ffa44-7b34-46a6-a329-d3b8fb95399e" -v
Run the following cURL command to acknowledge a specific occurrence. Change the id in the URL by your occurrence's id.
curl -X PUT "http://localhost:8080/occurrences/ce0f42b3-0fdb-4f91-8ce3-a853c1f06c06" -v