diff --git a/pom.xml b/pom.xml
index 17fd7ad..65a95e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,6 +27,10 @@
org.springframework.boot
spring-boot-starter-data-jdbc
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
org.springframework.boot
spring-boot-starter-web
@@ -49,6 +53,11 @@
spring-boot-starter-test
test
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
diff --git a/src/main/java/com/zoomcare/candidatechallenge/controller/EmployeeController.java b/src/main/java/com/zoomcare/candidatechallenge/controller/EmployeeController.java
new file mode 100644
index 0000000..c4b7c10
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/controller/EmployeeController.java
@@ -0,0 +1,32 @@
+package com.zoomcare.candidatechallenge.controller;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.zoomcare.candidatechallenge.dto.EmployeeDTO;
+import com.zoomcare.candidatechallenge.service.EmployeeService;
+
+@RestController
+@RequestMapping(path = "/employees")
+public class EmployeeController {
+
+ @Autowired
+ EmployeeService employeeService;
+
+ @GetMapping("/toplevel")
+ public List getTopLevelEmployees(){
+ return employeeService.getTopLevelEmployees();
+ }
+
+ @GetMapping("/{id}")
+ public EmployeeDTO getById(@PathVariable("id") Long employeeId) {
+ return employeeService.getEmployeeByID(employeeId);
+ }
+
+
+
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/dto/EmployeeDTO.java b/src/main/java/com/zoomcare/candidatechallenge/dto/EmployeeDTO.java
new file mode 100644
index 0000000..e7b031d
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/dto/EmployeeDTO.java
@@ -0,0 +1,59 @@
+package com.zoomcare.candidatechallenge.dto;
+
+import java.util.List;
+import java.util.Map;
+
+public class EmployeeDTO {
+
+ private Long id;
+
+ private Long supervisorId;
+
+ private Map properties;
+
+ private List employees;
+
+ public EmployeeDTO(Long id, Map properties, List employees) {
+ this.id = id;
+ this.properties = properties;
+ this.employees = employees;
+ }
+
+ public EmployeeDTO() {
+
+ }
+
+ public Map getProperties() {
+ return this.properties;
+ }
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public List getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(List employees) {
+ this.employees = employees;
+ }
+
+ public void setProperties(Map properties) {
+ this.properties = properties;
+ }
+
+ public Long getSupervisorId() {
+ return supervisorId;
+ }
+
+ public void setSupervisorId(Long supervisorId) {
+ this.supervisorId = supervisorId;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java b/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java
new file mode 100644
index 0000000..6d31a02
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/entity/Employee.java
@@ -0,0 +1,70 @@
+package com.zoomcare.candidatechallenge.entity;
+
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+
+@Entity
+public class Employee {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ @Column(name = "supervisor_id")
+ private Long supervisorId;
+
+ @OneToMany
+ @JoinColumn(name = "employee_id")
+ private List properties;
+
+ @OneToMany
+ @JoinColumn(name = "supervisor_id")
+ private List employees;
+
+ public Employee(Long id, Long supervisorId) {
+ this.id = id;
+ this.supervisorId = supervisorId;
+ }
+
+ public Employee() {
+ }
+
+ public Long getSupervisorId() {
+ return supervisorId;
+ }
+
+ public void setSupervisorId(Long supervisorId) {
+ this.supervisorId = supervisorId;
+ }
+
+ public Long getEmployee_id() {
+ return id;
+ }
+
+ public void setEmployee_id(Long employee_id) {
+ this.id = employee_id;
+ }
+
+ public List getProperties() {
+ return properties;
+ }
+
+ public void setProperties(List properties) {
+ this.properties = properties;
+ }
+
+ public List getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(List employees) {
+ this.employees = employees;
+ }
+
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/entity/EmployeeProperty.java b/src/main/java/com/zoomcare/candidatechallenge/entity/EmployeeProperty.java
new file mode 100644
index 0000000..0636ff7
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/entity/EmployeeProperty.java
@@ -0,0 +1,46 @@
+package com.zoomcare.candidatechallenge.entity;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "property")
+public class EmployeeProperty implements Serializable {
+
+ @Id
+ @GeneratedValue
+ private Long employee_id;
+
+ private String key;
+
+ private String value;
+
+ public Long getEmployeeId() {
+ return employee_id;
+ }
+
+ public void setEmployeeId(Long employeeId) {
+ this.employee_id = employeeId;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java b/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java
new file mode 100644
index 0000000..85020eb
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/repository/EmployeeRepository.java
@@ -0,0 +1,20 @@
+package com.zoomcare.candidatechallenge.repository;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import com.zoomcare.candidatechallenge.entity.Employee;
+
+@Repository
+public interface EmployeeRepository extends JpaRepository {
+
+ List findAll();
+
+ Optional findById(Long id);
+
+ List findAllBySupervisorIdIsNull();
+
+}
diff --git a/src/main/java/com/zoomcare/candidatechallenge/service/EmployeeService.java b/src/main/java/com/zoomcare/candidatechallenge/service/EmployeeService.java
new file mode 100644
index 0000000..88a892f
--- /dev/null
+++ b/src/main/java/com/zoomcare/candidatechallenge/service/EmployeeService.java
@@ -0,0 +1,48 @@
+package com.zoomcare.candidatechallenge.service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.zoomcare.candidatechallenge.dto.EmployeeDTO;
+import com.zoomcare.candidatechallenge.entity.Employee;
+import com.zoomcare.candidatechallenge.entity.EmployeeProperty;
+import com.zoomcare.candidatechallenge.repository.EmployeeRepository;
+
+@Service
+public class EmployeeService {
+
+ @Autowired
+ EmployeeRepository employeeRepository;
+
+ public List getTopLevelEmployees() {
+ return employeeRepository.findAllBySupervisorIdIsNull().stream()
+ .map(this::toEmployeeDTO)
+ .collect(Collectors.toList());
+ }
+
+ public EmployeeDTO getEmployeeByID(Long employeeId) {
+ Optional employee = employeeRepository.findById(employeeId);
+ if (employee.isPresent()) {
+ return toEmployeeDTO(employee.get());
+ } else {
+ return null;
+ }
+ }
+
+ private EmployeeDTO toEmployeeDTO(Employee employee) {
+ EmployeeDTO dto = new EmployeeDTO();
+ dto.setId(employee.getEmployee_id());
+ dto.setSupervisorId(employee.getSupervisorId() != null ? employee.getSupervisorId() : null );
+ dto.setProperties(employee.getProperties().stream().distinct()
+ .collect(Collectors
+ .toMap(EmployeeProperty::getKey, EmployeeProperty::getValue)));
+ dto.setEmployees(employee.getEmployees()
+ .stream()
+ .map(this::toEmployeeDTO).collect(Collectors.toList()));
+ return dto;
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..e439ebd
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.main.allow-bean-definition-overriding=true