diff --git a/pom.xml b/pom.xml index 0e5a03a..4410c48 100644 --- a/pom.xml +++ b/pom.xml @@ -71,7 +71,13 @@ com.fasterxml.jackson.core jackson-databind - + + org.jetbrains + annotations + RELEASE + compile + + diff --git a/src/main/java/com/AgileTracker/tracker/TrackerApplication.java b/src/main/java/com/AgileTracker/tracker/TrackerApplication.java index cd969ed..3686b1d 100644 --- a/src/main/java/com/AgileTracker/tracker/TrackerApplication.java +++ b/src/main/java/com/AgileTracker/tracker/TrackerApplication.java @@ -2,11 +2,33 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.Arrays; +import java.util.Collections; @SpringBootApplication public class TrackerApplication { + @Bean + public CorsFilter corsFilter() { + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + // Don't do this in production, use a proper list of allowed origins + config.setAllowedOrigins(Collections.singletonList("*")); + config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept")); + config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + public static void main(String[] args) { SpringApplication.run(TrackerApplication.class, args); } diff --git a/src/main/java/com/AgileTracker/tracker/controller/OKRController.java b/src/main/java/com/AgileTracker/tracker/controller/OKRController.java new file mode 100644 index 0000000..6696bb0 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/controller/OKRController.java @@ -0,0 +1,134 @@ +package com.AgileTracker.tracker.controller; + +import com.AgileTracker.tracker.exceptions.GenericException; +import com.AgileTracker.tracker.model.*; +import com.AgileTracker.tracker.repository.OKRRepository; +import com.AgileTracker.tracker.repository.ProjectRepository; +import com.AgileTracker.tracker.repository.TaskRepository; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@RestController +@RequestMapping("/okr") +@JsonIgnoreProperties(value={"status", "actualEndDate"}, allowGetters = true) +@CrossOrigin(origins = { "http://localhost:8080" }, maxAge = 6000) +public class OKRController { + @Autowired + OKRRepository okr_repo; + + @PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE) + public OKR addOKR(@Valid @RequestBody OKR okr){ + okr.setState(enums.okrState.NOT_STARTED); + return okr_repo.save(okr); + } + + @GetMapping("/{id}") + public OKR getOKRById(@PathVariable(value="id") Long id) throws GenericException { + return okr_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + } + + @DeleteMapping("/delete/{id}") + public ResponseEntity deleteProject(@PathVariable(value="id") Long id) throws GenericException{ + OKR okr = okr_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting OKR object.")); + okr_repo.delete(okr); + return ResponseEntity.ok().build(); + } + +// @PostMapping("/edit/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) +// public Project editProject(@PathVariable(value="id") Long id, @Valid @RequestBody Project project) throws GenericException{ +// Project project_ = project_repo.findById(id).orElseThrow( +// () -> new GenericException("Error getting project.")); +// project_repo. +// return project; +// } + + @GetMapping("/all") + public List getOKR(){ + List okr = okr_repo.findAll(); + for(OKR o : okr) { + o.setProjects(new ArrayList()); + o.setTeams(new ArrayList()); + } + return okr; + } + + @GetMapping("/{id}/start") + public ResponseEntity beginReview(@PathVariable(value="id") Long id) throws GenericException{ + OKR okr = okr_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + if(okr.getState() != enums.okrState.NOT_STARTED) + throw new GenericException("Invalid operation!"); + okr.setState(enums.okrState.IN_PROGRESS); + okr_repo.save(okr); + return ResponseEntity.ok().build(); + } + + @GetMapping("/{id}/review-start") + public ResponseEntity endOKR(@PathVariable(value="id") Long id) throws GenericException{ + OKR okr = okr_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + if(okr.getState() != enums.okrState.IN_PROGRESS) + throw new GenericException("Invalid operation!"); + okr.setState(enums.okrState.FINISHED); + okr_repo.save(okr); + return ResponseEntity.ok().build(); + } + + public static Set convertListToSet(List list) + { + // create an empty set + Set set = new HashSet<>(); + + // Add each element of list into the set + for (T t : list) + set.add(t); + + // return the set + return set; + } + + @GetMapping("/{oid}/projects/all") + public List getAllProjects(@PathVariable(value="oid") Long oid) throws GenericException{ + OKR okr = okr_repo.findById(oid).orElseThrow( + () -> new GenericException("Error getting OKR.")); + List projects = (okr.getProjects()); + for(Project project : projects) + project.setOkr(null); + return projects; + } + + @PostMapping(value = "/{oid}/projects/add", consumes = MediaType.APPLICATION_JSON_VALUE) + public Project addProject(@PathVariable(value="oid") Long oid, + @Valid @RequestBody Project project) throws GenericException{ + OKR okr = okr_repo.findById(oid).orElseThrow( + () -> new GenericException("Error getting OKR.")); + project.setState(enums.projectState.NOT_STARTED); + okr.getProjects().add(project); + project.setOkr(okr); + okr_repo.save(okr); + return project; + } + + @GetMapping("/{oid}/projects/{pid}") + public Project getTask(@PathVariable(value="oid") Long oid, + @PathVariable(value="oid") Long pid) throws GenericException{ + OKR okr = okr_repo.findById(oid).orElseThrow( + () -> new GenericException("Error getting OKR.")); + for(Project project : okr.getProjects()){ + if(project.getId().equals(pid)) + return project; + } + throw new GenericException("Error getting project"); + } +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/controller/ProjectController.java b/src/main/java/com/AgileTracker/tracker/controller/ProjectController.java index 058d770..4c4ed15 100644 --- a/src/main/java/com/AgileTracker/tracker/controller/ProjectController.java +++ b/src/main/java/com/AgileTracker/tracker/controller/ProjectController.java @@ -1,9 +1,9 @@ package com.AgileTracker.tracker.controller; import com.AgileTracker.tracker.exceptions.GenericException; -import com.AgileTracker.tracker.model.Project; -import com.AgileTracker.tracker.model.enums; +import com.AgileTracker.tracker.model.*; import com.AgileTracker.tracker.repository.ProjectRepository; +import com.AgileTracker.tracker.repository.TaskRepository; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.ObjectIdGenerators; @@ -15,18 +15,9 @@ import javax.validation.Valid; import java.util.List; -enum projectState{ - NOT_STARTED, - STARTED, - FINISHED; -} - @RestController @RequestMapping("/project") -@JsonIgnoreProperties(value={"status", "startDate", "expectedEndDate", "actualEndDate"}, allowGetters = true) -@JsonIdentityInfo( - generator = ObjectIdGenerators.StringIdGenerator.class, - property = "id") +@JsonIgnoreProperties(value={"status", "actualEndDate"}, allowGetters = true) public class ProjectController { @Autowired ProjectRepository project_repo; @@ -51,12 +42,103 @@ public ResponseEntity deleteProject(@PathVariable(value="id") Long id) throws return ResponseEntity.ok().build(); } +// @PostMapping("/edit/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) +// public Project editProject(@PathVariable(value="id") Long id, @Valid @RequestBody Project project) throws GenericException{ +// Project project_ = project_repo.findById(id).orElseThrow( +// () -> new GenericException("Error getting project.")); +// project_repo. +// return project; +// } @GetMapping("/all") public List getAllProjects(){ -// System.out.println("aaaaa"); - return project_repo.findAll(); + List projects = project_repo.findAll(); + for(Project project: projects) + project.setOkr(null); + return projects; } + @GetMapping("/{id}/start") + public ResponseEntity beginProject(@PathVariable(value="id") Long id) throws GenericException{ + Project project = project_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + if(project.getState() != enums.projectState.NOT_STARTED) + throw new GenericException("Invalid operation!"); + project.setState(enums.projectState.STARTED); + project_repo.save(project); + return ResponseEntity.ok().build(); + + } + + @GetMapping("/{id}/review-start") + public ResponseEntity beginReview(@PathVariable(value="id") Long id) throws GenericException{ + Project project = project_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + if(project.getState() != enums.projectState.STARTED) + throw new GenericException("Invalid operation!"); + project.setState(enums.projectState.IN_REVIEW); + project_repo.save(project); + return ResponseEntity.ok().build(); + + } + + @GetMapping("/{pid}/tasks/all") + public List getAllTasks(@PathVariable(value="pid") Long pid) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + return project.getTasks(); + + } + @Autowired + TaskRepository task_repo; + + @PostMapping(value = "/{pid}/tasks/add", consumes = MediaType.APPLICATION_JSON_VALUE) + public Task addTask(@PathVariable(value="pid") Long pid, + @Valid @RequestBody Task task) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + project.getTasks().add(task); + task.setProject(project); + project_repo.save(project); + return task; + } + + @GetMapping("/{pid}/tasks/{tid}") + public Task getTask(@PathVariable(value="pid") Long pid, + @PathVariable(value="tid") Long tid) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + for(Task task : project.getTasks()){ + if(task.getId() == tid) + return task; + } + throw new GenericException("Error getting task"); + } + + @PostMapping("/{pid}/review") + public ProjectReview doReview(@PathVariable(value="pid") Long pid, + @Valid @RequestBody ProjectReview review) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + if(project.getState() != enums.projectState.STARTED) + throw new GenericException("Cant review a project not started."); + project.setReview(review); + project_repo.save(project); + return review; + } + + @GetMapping("/{pid}/review") + public ProjectReview getReview(@PathVariable(value="pid") Long pid) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + return project.getReview(); + } + + @GetMapping("/{pid}/sprints") + public List getSprints(@PathVariable(value="pid") Long pid) throws GenericException{ + Project project = project_repo.findById(pid).orElseThrow( + () -> new GenericException("Error getting project.")); + return project.getSprints(); + } } diff --git a/src/main/java/com/AgileTracker/tracker/controller/SprintController.java b/src/main/java/com/AgileTracker/tracker/controller/SprintController.java new file mode 100644 index 0000000..11d2fc6 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/controller/SprintController.java @@ -0,0 +1,65 @@ +package com.AgileTracker.tracker.controller; + +import com.AgileTracker.tracker.exceptions.GenericException; +import com.AgileTracker.tracker.exceptions.SprintNotFoundException; +import com.AgileTracker.tracker.exceptions.TaskNotFoundException; +import com.AgileTracker.tracker.model.*; +import com.AgileTracker.tracker.repository.SprintRepository; +import com.AgileTracker.tracker.repository.TaskRepository; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.awt.*; + +@RestController +@RequestMapping("/sprint") +@JsonIgnoreProperties(value = {"state"}, allowGetters = true) +public class SprintController { + @Autowired + SprintRepository sprint_repo; + + @Autowired + TaskRepository task_repo; + + @PostMapping(value = "/", consumes = MediaType.APPLICATION_JSON_VALUE) + public Sprint addSprint(@Valid @RequestBody Sprint sprint){ + sprint.setState(enums.sprintState.NOT_STARTED); + sprint_repo.save(sprint); + } + + @GetMapping("/{id}") + public Sprint getProjectById(@PathVariable(value="id") Long id) throws GenericException { + return sprint_repo.findById(id).orElseThrow(() -> new SprintNotFoundException()); + } + + @PostMapping(value = "/{id}/planning") + public Sprint startPlanning(@PathVariable(value="sid") Long sid, @Valid @RequestBody List task_list) + throws TaskNotFoundException { + Sprint sprint = sprint_repo.findById(sid).orElseThrow(() -> new SprintNotFoundException()); + + // todo -- add check so that if addition fails midway, the state changes are reverted + for(Long id : task_list){ + Task task = task_repo.findById(id).orElse(() -> new TaskNotFoundException()); + task.setState(enums.taskState.IN_PROGRESS); + sprint.getTasks().add(task); + task.setSprint(sprint); + } + + sprint.setState(enums.sprintState.IN_PLANNING); + sprint.setPlanning(new SprintPlanning()); + return sprint_repo.save(sprint); + } + + @PostMapping(value = "/{id}/planning/{comment}") + public Sprint addPlanningComment(@PathVariable(value="sid") Long sid, + @PathVariable(value = "comment") String comment) + throws TaskNotFoundException{ + Sprint sprint = sprint_repo.findById(sid).orElseThrow(() -> new SprintNotFoundException()); + sprint.getPlanning().setComments(comment); + return sprint_repo.save(sprint); + } + +} diff --git a/src/main/java/com/AgileTracker/tracker/controller/TaskController.java b/src/main/java/com/AgileTracker/tracker/controller/TaskController.java new file mode 100644 index 0000000..74d951e --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/controller/TaskController.java @@ -0,0 +1,13 @@ +package com.AgileTracker.tracker.controller; + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/project") +@JsonIgnoreProperties(value={"status", "actualEndDate"}, allowGetters = true) +public class TaskController { + +} diff --git a/src/main/java/com/AgileTracker/tracker/controller/TeamController.java b/src/main/java/com/AgileTracker/tracker/controller/TeamController.java new file mode 100644 index 0000000..7b1de3f --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/controller/TeamController.java @@ -0,0 +1,87 @@ +package com.AgileTracker.tracker.controller; + + +import com.AgileTracker.tracker.exceptions.GenericException; +import com.AgileTracker.tracker.model.OKR; +import com.AgileTracker.tracker.model.Project; +import com.AgileTracker.tracker.model.Team; +import com.AgileTracker.tracker.model.User; +import com.AgileTracker.tracker.repository.OKRRepository; +import com.AgileTracker.tracker.repository.TeamRepository; +import com.AgileTracker.tracker.repository.UserRepository; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@RestController +@RequestMapping("/team") +@JsonIgnoreProperties(value={"manager"}, allowGetters = true) +public class TeamController { + @Autowired + TeamRepository team_repo; + + @Autowired + UserRepository user_repo; + + @Autowired + OKRRepository okr_repo; + + @PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE) + public Team addTeam(@Valid @RequestBody Team team){ + return team_repo.save(team); + } + + @GetMapping("/{id}") + public Team getTeamById(@PathVariable(value="id") Long id) throws GenericException { + return team_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting Team.")); + } + + @DeleteMapping("delete/{id}") + public ResponseEntity deleteTeam(@PathVariable(value="id") Long id) throws GenericException{ + Team team = team_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting Team.")); + team_repo.delete(team); + return ResponseEntity.ok().build(); + } + + @PostMapping("{tid}/user") + public Team addUser(@Valid @RequestBody User user, + @PathVariable(value="tid") Long id) throws GenericException { + Team team = team_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting Team.")); + user.setManager(false); + team.getMembers().add(user); + user.setTeam(team); + return team_repo.save(team); + } + + @PostMapping("{tid}/manager/{uid}") + public Team setManager(@PathVariable(value="tid") Long tid, + @PathVariable(value="uid") Long uid) throws GenericException { + Team team = team_repo.findById(tid).orElseThrow( + () -> new GenericException("Error getting Team.")); + User manager = user_repo.findById(uid).orElseThrow( + () -> new GenericException("Error getting Team.")); +// team.setManager(); + return team; + } + + @PostMapping("{tid}/okr/{oid}") + public Team assingOkr(@PathVariable(value="tid") Long tid, + @PathVariable(value="oid") Long oid) throws GenericException { + Team team = team_repo.findById(tid).orElseThrow( + () -> new GenericException("Error getting Team.")); + OKR okr = okr_repo.findById(oid).orElseThrow( + () -> new GenericException("Error getting Team.")); + team.setOkr(okr); + okr.getTeams().add(team); + okr_repo.save(okr); +// team.setManager(); + return team; + } +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/controller/UserController.java b/src/main/java/com/AgileTracker/tracker/controller/UserController.java new file mode 100644 index 0000000..367b62c --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/controller/UserController.java @@ -0,0 +1,64 @@ +package com.AgileTracker.tracker.controller; + +import com.AgileTracker.tracker.exceptions.GenericException; +import com.AgileTracker.tracker.model.Project; +import com.AgileTracker.tracker.model.Task; +import com.AgileTracker.tracker.model.User; +import com.AgileTracker.tracker.repository.UserRepository; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/user") +@JsonIgnoreProperties(value={"manager"}, allowGetters = true) +public class UserController { + @Autowired + UserRepository user_repo; + + @PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE) + public User addUser(@Valid @RequestBody User user){ + user.setManager(false); + return user_repo.save(user); + } + + @GetMapping("/{id}") + public User getUserById(@PathVariable(value="id") Long id) throws GenericException { + return user_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting user.")); + } + + @DeleteMapping("/delete/{id}") + public ResponseEntity deleteUser(@PathVariable(value="id") Long id) throws GenericException{ + User user = user_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + user_repo.delete(user); + return ResponseEntity.ok().build(); + } + + @GetMapping("/{uid}/projects") + public List getUserProjects(@PathVariable(value="uid") Long id) throws GenericException { + User user = user_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + List projects = user.getTeam().getOkr().getProjects(); + for(Project project : projects) + project.setOkr(null); + return projects; + } + + @GetMapping("/{uid}/tasks") + public List getUserTasks(@PathVariable(value="uid") Long id) throws GenericException { + User user = user_repo.findById(id).orElseThrow( + () -> new GenericException("Error getting project.")); + + List tasks = user.getTeam().getOkr().getTasks(); + for(Task task : tasks) + task.setProject(null); + return tasks; + } +} diff --git a/src/main/java/com/AgileTracker/tracker/exceptions/SprintNotFoundException.java b/src/main/java/com/AgileTracker/tracker/exceptions/SprintNotFoundException.java new file mode 100644 index 0000000..c62e0e2 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/exceptions/SprintNotFoundException.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.exceptions; + +public class SprintNotFoundException extends GenericException { + public TaskNotFoundException(){ + super("Error!! Sprint not found!"); + } +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/exceptions/TaskNotFoundException.java b/src/main/java/com/AgileTracker/tracker/exceptions/TaskNotFoundException.java new file mode 100644 index 0000000..a849fc0 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/exceptions/TaskNotFoundException.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.exceptions; + +public class TaskNotFoundException extends GenericException { + public TaskNotFoundException(){ + super("Error!! Task not found!"); + } +} diff --git a/src/main/java/com/AgileTracker/tracker/model/OKR.java b/src/main/java/com/AgileTracker/tracker/model/OKR.java new file mode 100644 index 0000000..7a4ece4 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/OKR.java @@ -0,0 +1,73 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Entity +@Table(name = "okr") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class OKR { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + @NotBlank + private String name; + + @Getter + @Setter + private String details; + + @Getter + @Setter + private enums.okrState state; + + @Temporal(TemporalType.TIMESTAMP) + @Getter + @Setter + @CreatedDate + private Date startDate = new Date(); + + @Temporal(TemporalType.TIMESTAMP) + @Getter + @Setter + private Date expectedEndDate = new Date(); + + @Temporal(TemporalType.TIMESTAMP) + @Getter + @Setter + private Date actualEndDate = new Date(); + + @Setter + @Getter + @OneToMany(mappedBy = "okr", cascade = CascadeType.ALL) + private List projects; + + @Getter + @Setter + @OneToMany(mappedBy = "okr", cascade = CascadeType.ALL) + List teams; + + public List getTasks(){ + List tasks = new ArrayList(); + for(Project project : getProjects()){ + tasks.addAll(project.getTasks()); + } + return tasks; + } +} diff --git a/src/main/java/com/AgileTracker/tracker/model/Project.java b/src/main/java/com/AgileTracker/tracker/model/Project.java index e54034f..53bf546 100644 --- a/src/main/java/com/AgileTracker/tracker/model/Project.java +++ b/src/main/java/com/AgileTracker/tracker/model/Project.java @@ -1,17 +1,26 @@ package com.AgileTracker.tracker.model; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import lombok.Getter; import lombok.Setter; import net.minidev.json.annotate.JsonIgnore; import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.web.bind.annotation.GetMapping; import javax.persistence.*; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.util.ArrayList; import java.util.Date; +import java.util.List; +import java.util.Set; @Entity @Table(name = "projects") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") public class Project { @Getter @@ -47,4 +56,33 @@ public class Project { @Getter @Setter private Date actualEndDate = new Date(); + + @Setter + @Getter + @OneToMany(mappedBy = "project", cascade = CascadeType.ALL) + private List tasks; + + @Setter + @Getter + @OneToMany(mappedBy = "project", cascade = CascadeType.ALL) + private List sprints; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "okr_id", nullable = false) + private OKR okr; + +// @Setter +// @Getter +// @OneToOne +// private User manager; +// + @Setter + @Getter + @OneToOne(mappedBy = "project") + private ProjectReview review; + + + } diff --git a/src/main/java/com/AgileTracker/tracker/model/ProjectReview.java b/src/main/java/com/AgileTracker/tracker/model/ProjectReview.java new file mode 100644 index 0000000..a82873e --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/ProjectReview.java @@ -0,0 +1,33 @@ +package com.AgileTracker.tracker.model; + + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; + +@Entity +@Table(name = "projectreviews") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class ProjectReview { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private String comments; + + @Getter + @Setter + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(unique = true) + private Project project; +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/Sprint.java b/src/main/java/com/AgileTracker/tracker/model/Sprint.java new file mode 100644 index 0000000..60650cf --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/Sprint.java @@ -0,0 +1,66 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.util.List; + +@Entity +@Table(name = "sprints") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class Sprint { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + @NotBlank + private String name; + + @Getter + @Setter + @NotBlank + private enums.sprintState state = enums.sprintState.NOT_STARTED; + +// @Getter +// @Setter +// @OneToMany +// private Task tasks; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "project_id", nullable = false) + private Project project; + + @Setter + @Getter + @OneToOne(mappedBy = "sprint") + private SprintPlanning planning; + + @Setter + @Getter + @OneToMany(mappedBy = "sprint", cascade = CascadeType.ALL) + private List standups; + + @Setter + @Getter + @OneToOne(mappedBy = "sprint") + private SprintPlanning review; + + @Setter + @Getter + @OneToMany(mappedBy = "sprint", cascade = CascadeType.ALL) + private List tasks; + + +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/SprintPlanning.java b/src/main/java/com/AgileTracker/tracker/model/SprintPlanning.java new file mode 100644 index 0000000..2a6a1fd --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/SprintPlanning.java @@ -0,0 +1,37 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Table(name = "sprintplans") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class SprintPlanning { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private String comments; + + @Getter + @Setter + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(unique = true) + private Sprint sprint; + + @Setter + @Getter + @OneToMany(mappedBy = "sprint_plan", cascade = CascadeType.ALL) + private List tasks; +} diff --git a/src/main/java/com/AgileTracker/tracker/model/SprintReview.java b/src/main/java/com/AgileTracker/tracker/model/SprintReview.java new file mode 100644 index 0000000..4df743e --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/SprintReview.java @@ -0,0 +1,38 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Table(name = "sprintreviews") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class SprintReview { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private String comment; + +// @Setter +// @Getter +// @OneToMany(mappedBy = "review", cascade = CascadeType.ALL) +// private List task_accepted; + + @Getter + @Setter + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(unique = true) + private Sprint sprint; + +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/StandUp.java b/src/main/java/com/AgileTracker/tracker/model/StandUp.java new file mode 100644 index 0000000..227fa3a --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/StandUp.java @@ -0,0 +1,37 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Table(name = "standups") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class StandUp { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private String comment; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "sprint_id", nullable = false) + private Sprint sprint; + +// @Setter +// @Getter +// @OneToMany(mappedBy = "standup", cascade = CascadeType.ALL) +// private List task_accepted; +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/Task.java b/src/main/java/com/AgileTracker/tracker/model/Task.java new file mode 100644 index 0000000..9b1fa55 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/Task.java @@ -0,0 +1,89 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.util.Date; +import java.util.Set; + +@Entity +@Table(name = "tasks") +@EntityListeners(AuditingEntityListener.class) +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class Task { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + @NotBlank + private String name; + + @Getter + @Setter + private String details; + + @Getter + @Setter + private enums.taskState state; + + @Column(nullable = false, updatable = false) + @CreatedDate + @Temporal(TemporalType.TIMESTAMP) + @Getter + @Setter + private Date addDate = new Date(); + + @Temporal(TemporalType.TIMESTAMP) + @LastModifiedDate + @Getter + @Setter + private Date completedDate = new Date(); + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "project_id", nullable = false) + private Project project; + + @Getter + @Setter + @OneToOne(cascade = CascadeType.ALL) + private TaskAccept task_accepted; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "sprint_id", nullable = false) + private Sprint sprint; +// @Getter +// @Setter +// @ManyToOne(cascade = CascadeType.ALL) +// @JoinColumn(name = "sprint_id", nullable = false) +// private Sprint sprint_plan; +// +// @Getter +// @Setter +// @ManyToOne(cascade = CascadeType.ALL) +// @JoinColumn(name = "task_accepted", nullable = true) +// private StandUp standup; + +// @Getter +// @Setter +// @ManyToOne(cascade = CascadeType.ALL) +// @JoinColumn(name = "task_accepted_final", nullable = true) +// private StandUp review; + +} diff --git a/src/main/java/com/AgileTracker/tracker/model/TaskAccept.java b/src/main/java/com/AgileTracker/tracker/model/TaskAccept.java new file mode 100644 index 0000000..77e0c66 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/TaskAccept.java @@ -0,0 +1,25 @@ +package com.AgileTracker.tracker.model; + +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; + +@Entity +@Table(name = "taskaccepts") +public class TaskAccept { + @Getter + @Setter + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private Boolean status = false; + + @Getter + @Setter + @OneToOne(mappedBy = "task_accepted") + private Task task; +} diff --git a/src/main/java/com/AgileTracker/tracker/model/Team.java b/src/main/java/com/AgileTracker/tracker/model/Team.java new file mode 100644 index 0000000..67ab7d0 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/Team.java @@ -0,0 +1,68 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "teams") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class Team { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + private String name; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "okr_id", nullable = true) + private OKR okr; + +// @Getter +// @Setter +// @ManyToOne(cascade = CascadeType.ALL) +// @JoinColumn(name = "manager_id", nullable = true) +// private User manager; + + @Getter + @Setter + @OneToMany(mappedBy = "team", cascade = CascadeType.ALL) + private List members; + + + +// @Getter +// @Setter +// @NotBlank +// private String name; +// +// @Getter +// @Setter +// @OneToOne +// private Project project; +// +// @Getter +// @Setter +// @ManyToMany +// private User user; + + + + +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/User.java b/src/main/java/com/AgileTracker/tracker/model/User.java new file mode 100644 index 0000000..0e5da04 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/model/User.java @@ -0,0 +1,64 @@ +package com.AgileTracker.tracker.model; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import lombok.Getter; +import lombok.Setter; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.util.List; + +@Entity +@Table(name = "users") +@JsonIdentityInfo( + generator = ObjectIdGenerators.StringIdGenerator.class, + property = "id") +public class User { + @Getter + @Setter + @javax.persistence.Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long Id; + + @Getter + @Setter + @NotBlank + private String name; + + @Getter + @Setter + @NotBlank + private String email; + + @Getter + @Setter + private Boolean manager = false; + +// @Getter +// @Setter +// @OneToMany(mappedBy = "manager", cascade = CascadeType.ALL) +// private List managedTeams; + + @Getter + @Setter + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "team_id", nullable = true) + private Team team; + +// @Getter +// @Setter +// @ManyToMany +// private Team team; +// +// @Getter +// @Setter +// @ManyToOne +// private Task task; + + + + + + +} \ No newline at end of file diff --git a/src/main/java/com/AgileTracker/tracker/model/enums.java b/src/main/java/com/AgileTracker/tracker/model/enums.java index c424057..26e3c32 100644 --- a/src/main/java/com/AgileTracker/tracker/model/enums.java +++ b/src/main/java/com/AgileTracker/tracker/model/enums.java @@ -4,6 +4,27 @@ public class enums { public enum projectState{ NOT_STARTED, STARTED, + IN_REVIEW, + FINISHED; + } + + public enum taskState{ + PENDING, + IN_PROGRESS, + COMPLETED; + } + + public enum okrState{ + NOT_STARTED, + IN_PROGRESS, + FINISHED; + } + + public enum sprintState{ + NOT_STARTED, + IN_PLANNING, + STARTED, + IN_REVIEW, FINISHED; } } diff --git a/src/main/java/com/AgileTracker/tracker/repository/OKRRepository.java b/src/main/java/com/AgileTracker/tracker/repository/OKRRepository.java new file mode 100644 index 0000000..aa0cd31 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/repository/OKRRepository.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.repository; + +import com.AgileTracker.tracker.model.OKR; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface OKRRepository extends JpaRepository { +} diff --git a/src/main/java/com/AgileTracker/tracker/repository/SprintRepository.java b/src/main/java/com/AgileTracker/tracker/repository/SprintRepository.java new file mode 100644 index 0000000..6f5f7fd --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/repository/SprintRepository.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.repository; + +import com.AgileTracker.tracker.model.Sprint; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SprintRepository extends JpaRepository { +} diff --git a/src/main/java/com/AgileTracker/tracker/repository/TaskRepository.java b/src/main/java/com/AgileTracker/tracker/repository/TaskRepository.java new file mode 100644 index 0000000..a08ac69 --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/repository/TaskRepository.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.repository; + +import com.AgileTracker.tracker.model.Task; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TaskRepository extends JpaRepository { +} diff --git a/src/main/java/com/AgileTracker/tracker/repository/TeamRepository.java b/src/main/java/com/AgileTracker/tracker/repository/TeamRepository.java new file mode 100644 index 0000000..d26e8ed --- /dev/null +++ b/src/main/java/com/AgileTracker/tracker/repository/TeamRepository.java @@ -0,0 +1,7 @@ +package com.AgileTracker.tracker.repository; + +import com.AgileTracker.tracker.model.Team; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TeamRepository extends JpaRepository { +} diff --git a/src/main/java/com/AgileTracker/tracker/repository/UserRepository.java b/src/main/java/com/AgileTracker/tracker/repository/UserRepository.java index 42488c8..d22cb0c 100644 --- a/src/main/java/com/AgileTracker/tracker/repository/UserRepository.java +++ b/src/main/java/com/AgileTracker/tracker/repository/UserRepository.java @@ -1,4 +1,7 @@ package com.AgileTracker.tracker.repository; -public class UserRepository { +import com.AgileTracker.tracker.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 15d939c..1201784 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,6 +1,4 @@ spring.datasource.url=jdbc:mysql://localhost:3306/tracker?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false spring.datasource.username=root -spring.datasource.password=root spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect -spring.jpa.hibernate.ddl-auto=update - +spring.jpa.hibernate.ddl-auto=update \ No newline at end of file