diff --git a/docs/Test.postman_collection.json b/docs/Test.postman_collection.json
new file mode 100644
index 0000000..af7f6b7
--- /dev/null
+++ b/docs/Test.postman_collection.json
@@ -0,0 +1,422 @@
+{
+ "info": {
+ "_postman_id": "46d4fbb1-6fba-4a9e-afae-b98ccd86217d",
+ "name": "Test",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
+ "_exporter_id": "1035454"
+ },
+ "item": [
+ {
+ "name": "User",
+ "item": [
+ {
+ "name": "get all users",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/users/ADMIN",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "users",
+ "ADMIN"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "get user by id",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/users/1/ADMIN",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "users",
+ "1",
+ "ADMIN"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "save users",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\":\"123\",\r\n \"username\":\"123\",\r\n \"password\":\"234\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/users/ADMIN",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "users",
+ "ADMIN"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "update users",
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\":\"123\",\r\n \"username\":\"123\",\r\n \"password\":\"234\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/users",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "users"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "delete user",
+ "request": {
+ "method": "DELETE",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/users/123/ADMIN",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "users",
+ "123",
+ "ADMIN"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Tasks",
+ "item": [
+ {
+ "name": "get all tasks",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/tasks",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "tasks"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "get tasks by id",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/tasks/1",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "tasks",
+ "1"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "save tasks",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\": \"123\",\r\n \"title\": \"test\",\r\n \"description\": \"erty\",\r\n \"status\": \"erty\",\r\n \"project_id\": \"234\",\r\n \"user_id\": \"324\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/tasks/PRODUCT_OWNER",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "tasks",
+ "PRODUCT_OWNER"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "update tasks",
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\": \"123\",\r\n \"title\": \"test\",\r\n \"description\": \"erty\",\r\n \"status\": \"erty\",\r\n \"project_id\": \"234\",\r\n \"user_id\": \"324\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/tasks/PRODUCT_OWNER",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "tasks",
+ "PRODUCT_OWNER"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "delete tasks",
+ "request": {
+ "method": "DELETE",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/tasks/123",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "tasks",
+ "123"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ },
+ {
+ "name": "Projects",
+ "item": [
+ {
+ "name": "pagination",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api?pageIndex=0&pageSize=3&sortDirection=ASC&q=Nikhila",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api"
+ ],
+ "query": [
+ {
+ "key": "pageIndex",
+ "value": "0"
+ },
+ {
+ "key": "pageSize",
+ "value": "3"
+ },
+ {
+ "key": "sortDirection",
+ "value": "ASC"
+ },
+ {
+ "key": "q",
+ "value": "Nikhila"
+ }
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "get projects",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/projects",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "projects"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "get projects by id",
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "http://localhost:8082/api/v1/projects/1",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "projects",
+ "1"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "save projects by admin",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\":\"1\",\r\n \"name\":\"Test\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/projects/ADMIN",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "projects",
+ "ADMIN"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "update projects",
+ "request": {
+ "method": "PUT",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\r\n \"id\":\"1\",\r\n \"name\":\"Test\"\r\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8082/api/v1/projects",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8082",
+ "path": [
+ "api",
+ "v1",
+ "projects"
+ ]
+ }
+ },
+ "response": []
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index b0a6389..4365294 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,8 +27,27 @@
spring-boot-starter-test
test
-
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ mysql
+ mysql-connector-java
+
+
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/constants/Status.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/constants/Status.java
new file mode 100644
index 0000000..f26a4db
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/constants/Status.java
@@ -0,0 +1,5 @@
+package com.accenture.codingtest.springbootcodingtest.constants;
+
+public enum Status {
+ NOT_STARTED, IN_PROGRESS, READY_FOR_TEST, COMPLETED
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java
new file mode 100644
index 0000000..f6a00c7
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/ProjectController.java
@@ -0,0 +1,82 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+import com.accenture.codingtest.springbootcodingtest.model.Role;
+import com.accenture.codingtest.springbootcodingtest.service.ProjectService;
+
+@RestController
+@RequestMapping("/api")
+public class ProjectController {
+ @Autowired
+ private ProjectService projectService;
+
+ @GetMapping("/v1/projects")
+ public ResponseEntity> getAllProjects() {
+ return projectService.getAllProjects();
+ }
+
+ @PostMapping("/v1/projects/{role}")
+ public ResponseEntity saveProject(@RequestBody Project project,
+ @PathVariable("role") String role) {
+ ResponseEntity response;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = projectService.saveProject(project);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @GetMapping("/v1/projects/{project_id}")
+ public ResponseEntity getProjectById(@PathVariable("project_id") String project_id) {
+ return projectService.getProjectById(project_id);
+ }
+
+ @PutMapping("/v1/projects")
+ public ResponseEntity updateProject(@RequestBody Project project) {
+ return projectService.updateProject(project);
+ }
+
+ @DeleteMapping("/v1/projects/{project_id}")
+ public ResponseEntity deleteProjectById(@PathVariable("project_id") String project_id) {
+ return projectService.deleteProject(project_id);
+ }
+
+ @GetMapping
+ public Page getProjects(@RequestParam(value = "q", required = false) String searchKeyword, @RequestParam(value = "pageIndex", defaultValue = "0") int pageIndex, @RequestParam(value = "pageSize", defaultValue = "3") int pageSize,
+ @RequestParam(value = "sortBy", defaultValue = "name") String sortBy, @RequestParam(value = "sortDirection", defaultValue = "ASC") String sortDirection) {
+
+ Sort.Direction direction = Sort.Direction.ASC;
+ if (sortDirection.equalsIgnoreCase("DESC")) {
+ direction = Sort.Direction.DESC;
+ }
+
+ Sort sort = Sort.by(direction, sortBy);
+ PageRequest pageRequest = PageRequest.of(pageIndex, pageSize, sort);
+
+ if (searchKeyword != null && !searchKeyword.isEmpty()) {
+ return projectService.searchProjectsByName(searchKeyword, pageRequest);
+ } else {
+ return projectService.getAllProjects(pageRequest);
+ }
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java
new file mode 100644
index 0000000..d897f2b
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/TaskController.java
@@ -0,0 +1,70 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import java.util.List;
+
+import com.accenture.codingtest.springbootcodingtest.model.Role;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Task;
+import com.accenture.codingtest.springbootcodingtest.service.TaskService;
+
+@RestController
+@RequestMapping("/api")
+public class TaskController {
+ @Autowired
+ private TaskService taskService;
+
+ @GetMapping("/v1/tasks")
+ public ResponseEntity> getAllTasks() {
+ return taskService.getAllTasks();
+ }
+
+ @PostMapping("/v1/tasks/{role}")
+ public ResponseEntity saveTask(@RequestBody Task task, @PathVariable("role") String role) {
+ ResponseEntity response = null;
+ if(Role.PRODUCT_OWNER.toString().equalsIgnoreCase(role)) {
+ response = taskService.saveTask(task);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @GetMapping("/v1/tasks/{task_id}")
+ public ResponseEntity getTaskById(@PathVariable("task_id") String task_id) {
+ return taskService.getTaskById(task_id);
+ }
+
+ @PatchMapping("/v1/tasks/{role}")
+ public ResponseEntity updateTask(@RequestBody Task task,
+ @PathVariable("userId") String userId,
+ @PathVariable("role") String role) {
+ ResponseEntity response = null;
+ if(Role.PRODUCT_OWNER.toString().equalsIgnoreCase(role)) {
+ response = taskService.updateTask(task, userId);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @PutMapping("/v1/tasks/{role}")
+ public ResponseEntity updateTask(@RequestBody Task task, @PathVariable("role") String role) {
+ ResponseEntity response = null;
+ if(Role.PRODUCT_OWNER.toString().equalsIgnoreCase(role)) {
+ response = taskService.updateTask(task);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+
+ @DeleteMapping("/v1/tasks/{task_id}")
+ public ResponseEntity deleteTaskById(@PathVariable("task_id") String task_id) {
+ return taskService.deleteTask(task_id);
+ }
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java
new file mode 100644
index 0000000..65099d1
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/UserController.java
@@ -0,0 +1,77 @@
+package com.accenture.codingtest.springbootcodingtest.controller;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import com.accenture.codingtest.springbootcodingtest.model.Role;
+import com.accenture.codingtest.springbootcodingtest.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api")
+public class UserController {
+
+ @Autowired
+ private UserService userService;
+
+ @GetMapping("/v1/users/{role}")
+ public ResponseEntity> getAllUsers(@PathVariable("role") String role) {
+ ResponseEntity> response = null;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = userService.getAllUsers();
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @GetMapping("/v1/users/{user_id}/{role}")
+ public ResponseEntity getUserById(@PathVariable("user_id") String user_id,
+ @PathVariable("role") String role) {
+ ResponseEntity response = null;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = userService.getUserById(user_id);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @PostMapping("/v1/users/{role}")
+ public ResponseEntity saveUser(@RequestBody User user, @PathVariable("role") String role) {
+
+ ResponseEntity response = null;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = userService.saveUser(user);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @PutMapping("/v1/users")
+ public ResponseEntity updateUser(@RequestBody User user, @PathVariable("role") String role) {
+ ResponseEntity response = null;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = userService.updateUser(user);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+
+ @DeleteMapping("/v1/users/{user_id}")
+ public ResponseEntity deleteUserById(@PathVariable("user_id") String user_id,
+ @PathVariable("role") String role) {
+ ResponseEntity response;
+ if(Role.ADMIN.toString().equalsIgnoreCase(role)) {
+ response = userService.deleteUser(user_id);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
+ }
+ return response;
+ }
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/package-info.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/controller/package-info.java
deleted file mode 100644
index e69de29..0000000
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java
new file mode 100644
index 0000000..1fb7065
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Project.java
@@ -0,0 +1,47 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "Project")
+public class Project {
+
+ @Id
+ private String id;
+ private String name;
+
+ public Project() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Project(String id, String name) {
+ super();
+ this.id = id;
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "Project [id=" + id + ", name=" + name + "]";
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java
new file mode 100644
index 0000000..a45c8a2
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/Task.java
@@ -0,0 +1,87 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "Task")
+public class Task {
+ @Id
+ private String id;
+ private String title;
+ private String description;
+ private String status;
+ private String project_id;
+ private String user_id;
+
+ public Task() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public Task(String id, String title, String description, String status, String project_id, String user_id) {
+ super();
+ this.id = id;
+ this.title = title;
+ this.description = description;
+ this.status = status;
+ this.project_id = project_id;
+ this.user_id = user_id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getProject_id() {
+ return project_id;
+ }
+
+ public void setProject_id(String project_id) {
+ this.project_id = project_id;
+ }
+
+ public String getUser_id() {
+ return user_id;
+ }
+
+ public void setUser_id(String user_id) {
+ this.user_id = user_id;
+ }
+
+ @Override
+ public String toString() {
+ return "Task [id=" + id + ", title=" + title + ", description=" + description + ", status=" + status
+ + ", project_id=" + project_id + ", user_id=" + user_id + "]";
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java
new file mode 100644
index 0000000..cea7fd5
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/entity/User.java
@@ -0,0 +1,60 @@
+package com.accenture.codingtest.springbootcodingtest.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+@Entity
+@Table(name = "User")
+@JsonSerialize
+public class User {
+
+ @Id
+ private String id;
+ private String username;
+ private String password;
+
+ public User() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public User(String id, String username, String password) {
+ super();
+ this.id = id;
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Role.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Role.java
new file mode 100644
index 0000000..7348574
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/model/Role.java
@@ -0,0 +1,7 @@
+package com.accenture.codingtest.springbootcodingtest.model;
+
+public enum Role {
+ ADMIN,
+ PRODUCT_OWNER
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java
new file mode 100644
index 0000000..893af7c
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/ProjectRepository.java
@@ -0,0 +1,13 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+
+public interface ProjectRepository extends JpaRepository {
+
+ Page findByNameContainingIgnoreCase(String name, Pageable pageable);
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java
new file mode 100644
index 0000000..2cba613
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/TaskRepository.java
@@ -0,0 +1,7 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Task;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface TaskRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java
new file mode 100644
index 0000000..046e205
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/repository/UserRepository.java
@@ -0,0 +1,7 @@
+package com.accenture.codingtest.springbootcodingtest.repository;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface UserRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java
new file mode 100644
index 0000000..42972ba
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/ProjectService.java
@@ -0,0 +1,77 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+import com.accenture.codingtest.springbootcodingtest.repository.ProjectRepository;
+
+@Service
+public class ProjectService {
+ @Autowired
+ private ProjectRepository projectRepository;
+
+ public ResponseEntity saveProject(Project project) {
+ ResponseEntity response = null;
+ if (project != null) {
+ response = new ResponseEntity<>(projectRepository.save(project), HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ return response;
+ }
+
+ public ResponseEntity> getAllProjects() {
+ return new ResponseEntity<>(projectRepository.findAll(), HttpStatus.OK);
+ }
+
+ public ResponseEntity getProjectById(String id) {
+ return new ResponseEntity<>(projectRepository.findById(id).get(), HttpStatus.OK);
+ }
+
+ public ResponseEntity updateProject(Project project) {
+ ResponseEntity updatedProject = null;
+ String id = project.getId();
+ Optional oldProjectOp = projectRepository.findById(id);
+
+ if (oldProjectOp.isPresent()) {
+ Project oldProject = oldProjectOp.get();
+
+ oldProject.setName(project.getName());
+ // oldProject.setProject_id(project.getProject_id());
+
+ updatedProject = new ResponseEntity<>(projectRepository.save(oldProject), HttpStatus.OK);
+ } else {
+ updatedProject = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+
+ return updatedProject;
+ }
+
+ public ResponseEntity deleteProject(String id) {
+ ResponseEntity response = null;
+ if (projectRepository.existsById(id)) {
+ projectRepository.deleteById(id);
+ response = new ResponseEntity<>(HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ return response;
+ }
+
+ public Page searchProjectsByName(String searchKeyword, Pageable pageable) {
+ return projectRepository.findByNameContainingIgnoreCase(searchKeyword, pageable);
+ }
+
+ public Page getAllProjects(Pageable pageable) {
+ return projectRepository.findAll(pageable);
+ }
+
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java
new file mode 100644
index 0000000..ab0747e
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/TaskService.java
@@ -0,0 +1,83 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import com.accenture.codingtest.springbootcodingtest.constants.Status;
+import com.accenture.codingtest.springbootcodingtest.entity.Task;
+import com.accenture.codingtest.springbootcodingtest.repository.TaskRepository;
+
+@Service
+public class TaskService {
+
+ @Autowired
+ private TaskRepository taskRepository;
+
+ public ResponseEntity saveTask(Task task) {
+ ResponseEntity response = null;
+ if (task != null) {
+ //initial status
+ task.setStatus(Status.NOT_STARTED.toString());
+ response = new ResponseEntity<>(taskRepository.save(task), HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ return response;
+ }
+ public ResponseEntity> getAllTasks() {
+ return new ResponseEntity<>(taskRepository.findAll(), HttpStatus.OK);
+ }
+
+ public ResponseEntity getTaskById(String id) {
+ return new ResponseEntity<>(taskRepository.findById(id).get(), HttpStatus.OK);
+ }
+
+ public ResponseEntity updateTask(Task task) {
+ ResponseEntity updatedTask = null;
+ String id = task.getId();
+ Optional oldTaskOp = taskRepository.findById(id);
+
+ if(oldTaskOp.isPresent()) {
+ Task oldTask = oldTaskOp.get();
+
+ oldTask.setDescription(task.getDescription());
+ oldTask.setTitle(task.getTitle());
+ oldTask.setStatus(task.getStatus());
+ oldTask.setUser_id(task.getUser_id());
+ // oldTask.setProject_id(task.getProject_id());
+
+ updatedTask = new ResponseEntity<>(taskRepository.save(oldTask), HttpStatus.OK);
+ } else {
+ updatedTask = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+
+ return updatedTask;
+ }
+ public ResponseEntity updateTask(Task task, String userId) {
+ ResponseEntity response = null;
+ Optional taskRes = taskRepository.findById(task.getId());
+ if (taskRes.isPresent()) {
+ if (taskRes.get().getUser_id().equalsIgnoreCase(userId)) {
+ taskRes.get().setStatus(task.getStatus());
+ response =new ResponseEntity<>(taskRepository.save(taskRes.get()), HttpStatus.OK);
+ }
+ }
+ return response;
+ }
+
+ public ResponseEntity deleteTask(String id) {
+ ResponseEntity response = null;
+ if (taskRepository.existsById(id)) {
+ taskRepository.deleteById(id);
+ response = new ResponseEntity<>(HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ return response;
+ }
+}
diff --git a/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java
new file mode 100644
index 0000000..9230755
--- /dev/null
+++ b/src/main/java/com/accenture/codingtest/springbootcodingtest/service/UserService.java
@@ -0,0 +1,67 @@
+package com.accenture.codingtest.springbootcodingtest.service;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+import com.accenture.codingtest.springbootcodingtest.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class UserService {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ public ResponseEntity saveUser(User user) {
+ ResponseEntity response = null;
+ if (user != null) {
+ response = new ResponseEntity<>(userRepository.save(user), HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ return response;
+ }
+
+
+ public ResponseEntity> getAllUsers() {
+ return new ResponseEntity<>(userRepository.findAll(), HttpStatus.OK);
+ }
+
+ public ResponseEntity getUserById(String id) {
+ return new ResponseEntity<>(userRepository.findById(id).get(), HttpStatus.OK);
+ }
+
+ public ResponseEntity updateUser(User user) {
+ ResponseEntity updatedUser = null;
+ String id = user.getId();
+ Optional oldUserOp = userRepository.findById(id);
+
+ if(oldUserOp.isPresent()) {
+ User oldUser = oldUserOp.get();
+
+ oldUser.setUsername(user.getUsername());
+ oldUser.setPassword(user.getPassword());
+
+ updatedUser = new ResponseEntity<>(userRepository.save(oldUser), HttpStatus.OK);
+ } else {
+ updatedUser = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+
+ return updatedUser;
+ }
+
+ public ResponseEntity deleteUser(String id) {
+ ResponseEntity response = null;
+ if (userRepository.existsById(id)) {
+ userRepository.deleteById(id);
+ response = new ResponseEntity<>(HttpStatus.OK);
+ } else {
+ response = new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ }
+ return response;
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8b13789..9991ffb 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,11 @@
+spring.datasource.url=jdbc:mysql://localhost:3306/test
+#spring.datasource.driverClassName=com.mysql.jdbc.Driver
+spring.datasource.username=root
+spring.datasource.password=123456
+
+
+
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
+spring.jpa.hibernate.ddl-auto= update
diff --git a/src/test/java/com/accenture/codingtest/springbootcodingtest/ProjectCreationTest.java b/src/test/java/com/accenture/codingtest/springbootcodingtest/ProjectCreationTest.java
new file mode 100644
index 0000000..5b0a747
--- /dev/null
+++ b/src/test/java/com/accenture/codingtest/springbootcodingtest/ProjectCreationTest.java
@@ -0,0 +1,39 @@
+package com.accenture.codingtest.springbootcodingtest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import com.accenture.codingtest.springbootcodingtest.entity.Project;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class ProjectCreationTest {
+
+ @LocalServerPort
+ private int port;
+
+ private final TestRestTemplate restTemplate = new TestRestTemplate();
+
+ @Test
+ public void createProjectAndAssignUsersTest() {
+ // Prepare the request body for creating a project
+ Project project = new Project("123", "Sample project");
+
+ // Send the POST request to create a project
+ ResponseEntity createProjectResponse = restTemplate
+ .postForEntity(getBaseUrl() + "/api/v1/projects/ADMIN", project, Project.class);
+
+ // Assert the response status code is 200 OK
+ assertEquals(HttpStatus.OK, createProjectResponse.getStatusCode());
+
+ }
+
+ private String getBaseUrl() {
+ return "http://localhost:" + port;
+ }
+}
diff --git a/src/test/java/com/accenture/codingtest/springbootcodingtest/TaskStatusChangeTest.java b/src/test/java/com/accenture/codingtest/springbootcodingtest/TaskStatusChangeTest.java
new file mode 100644
index 0000000..27d22d5
--- /dev/null
+++ b/src/test/java/com/accenture/codingtest/springbootcodingtest/TaskStatusChangeTest.java
@@ -0,0 +1,35 @@
+package com.accenture.codingtest.springbootcodingtest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class TaskStatusChangeTest {
+
+ @LocalServerPort
+ private int port;
+
+ private final TestRestTemplate restTemplate = new TestRestTemplate();
+
+ @Test
+ public void changeTaskStatusTest() {
+ // Create a user
+ User user = new User("123", "test@example.com", "test");
+ ResponseEntity createUserResponse = restTemplate.postForEntity(getBaseUrl() + "/api/v1/users/ADMIN", user,
+ User.class);
+ assertEquals(HttpStatus.OK, createUserResponse.getStatusCode());
+
+ }
+
+ private String getBaseUrl() {
+ return "http://localhost:" + port;
+ }
+}
diff --git a/src/test/java/com/accenture/codingtest/springbootcodingtest/UserCreationTest.java b/src/test/java/com/accenture/codingtest/springbootcodingtest/UserCreationTest.java
new file mode 100644
index 0000000..655c9c2
--- /dev/null
+++ b/src/test/java/com/accenture/codingtest/springbootcodingtest/UserCreationTest.java
@@ -0,0 +1,44 @@
+package com.accenture.codingtest.springbootcodingtest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import com.accenture.codingtest.springbootcodingtest.entity.User;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class UserCreationTest {
+
+ @LocalServerPort
+ private int port;
+
+ private final TestRestTemplate restTemplate = new TestRestTemplate();
+
+ @Test
+ public void createUserTest() {
+ // Prepare the request body for creating a user
+ User user = new User("123", "abc@example.com", "test");
+
+ // Send the POST request to create a user
+ ResponseEntity response = restTemplate.postForEntity(getBaseUrl() + "/api/v1/users/ADMIN", user,
+ User.class);
+
+ // Assert the response status code is 201 Created
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+
+ // Assert the response body contains the created user
+ User createdUser = response.getBody();
+ assertEquals(user.getUsername(), createdUser.getUsername());
+ assertEquals(user.getPassword(), createdUser.getPassword());
+ }
+
+ private String getBaseUrl() {
+ return "http://localhost:" + port;
+ }
+
+}