Skip to content

Commit

Permalink
Merge pull request #2 from szymonpoltorak/collaborators
Browse files Browse the repository at this point in the history
Collaborators
  • Loading branch information
szymonpoltorak authored Oct 12, 2023
2 parents 9561d7d + 5bebe61 commit ccceeac
Show file tree
Hide file tree
Showing 18 changed files with 323 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package razepl.dev.todoapp.api.collaborator;

import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
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 razepl.dev.todoapp.api.collaborator.data.CollaboratorRequest;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorResponse;
import razepl.dev.todoapp.api.collaborator.interfaces.CollaboratorController;
import razepl.dev.todoapp.api.collaborator.interfaces.CollaboratorService;
import razepl.dev.todoapp.entities.user.User;

import java.util.List;

import static razepl.dev.todoapp.api.collaborator.constants.CollaboratorMappings.ADD_USER_AS_COLLABORATOR;
import static razepl.dev.todoapp.api.collaborator.constants.CollaboratorMappings.ASSIGN_COLLABORATOR_TO_TASK;
import static razepl.dev.todoapp.api.collaborator.constants.CollaboratorMappings.COLLABORATOR_ENDPOINT_MAPPING;
import static razepl.dev.todoapp.api.collaborator.constants.CollaboratorMappings.GET_COLLABORATORS_OF_TASK;
import static razepl.dev.todoapp.api.collaborator.constants.CollaboratorMappings.GET_LIST_OF_COLLABORATORS_MAPPING;

@RestController
@RequestMapping(value = COLLABORATOR_ENDPOINT_MAPPING)
@RequiredArgsConstructor
public class CollaboratorControllerImpl implements CollaboratorController {
private final CollaboratorService collaboratorService;

@Override
@GetMapping(value = GET_LIST_OF_COLLABORATORS_MAPPING)
public final List<CollaboratorResponse> getListOfCollaborators(@AuthenticationPrincipal User user) {
return collaboratorService.getListOfCollaborators(user);
}

@Override
@GetMapping(value = GET_COLLABORATORS_OF_TASK)
public final List<CollaboratorResponse> getCollaboratorsAssignedToTask(@RequestParam long taskId,
@AuthenticationPrincipal User user) {
return collaboratorService.getCollaboratorsAssignedToTask(taskId, user);
}

@Override
@PostMapping(value = ADD_USER_AS_COLLABORATOR)
public final CollaboratorResponse addUserAsCollaborator(@RequestParam String collaboratorUsername,
@AuthenticationPrincipal User user) {
return collaboratorService.addUserAsCollaborator(collaboratorUsername, user);
}

@Override
@PatchMapping(value = ASSIGN_COLLABORATOR_TO_TASK)
public final CollaboratorResponse assignCollaboratorToTask(@RequestBody CollaboratorRequest collaboratorRequest) {
return collaboratorService.assignCollaboratorToTask(collaboratorRequest);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package razepl.dev.todoapp.api.collaborator;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorRequest;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorResponse;
import razepl.dev.todoapp.api.collaborator.interfaces.CollaboratorMapper;
import razepl.dev.todoapp.api.collaborator.interfaces.CollaboratorService;
import razepl.dev.todoapp.entities.collaborator.Collaborator;
import razepl.dev.todoapp.entities.collaborator.interfaces.CollaboratorRepository;
import razepl.dev.todoapp.entities.task.Task;
import razepl.dev.todoapp.entities.task.interfaces.TaskRepository;
import razepl.dev.todoapp.entities.user.User;
import razepl.dev.todoapp.entities.user.interfaces.UserRepository;
import razepl.dev.todoapp.exceptions.tasks.TaskDoesNotExistException;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class CollaboratorServiceImpl implements CollaboratorService {
private final CollaboratorRepository collaboratorRepository;
private final TaskRepository taskRepository;
private final UserRepository userRepository;
private final CollaboratorMapper collaboratorMapper;

@Override
public final List<CollaboratorResponse> getListOfCollaborators(User user) {
List<Collaborator> collaborators = collaboratorRepository.findCollaboratorsByUser(user);

log.info("Finding collaborators for User : {}", user.getUsername());
log.info("Found '{}' collaborators", collaborators.size());

return collaborators
.stream()
.map(collaboratorMapper::toCollaboratorResponse)
.toList();
}

@Override
public final List<CollaboratorResponse> getCollaboratorsAssignedToTask(long taskId, User user) {
log.info("Getting collaborators associated with task of id '{}' by the user '{}'", taskId, user.getUsername());

Task task = taskRepository.findById(taskId)
.orElseThrow(() -> new TaskDoesNotExistException("Task does not exist!"));

log.info("Task that was found : {}", task);

return task
.getCollaborator()
.stream()
.map(collaboratorMapper::toCollaboratorResponse)
.toList();
}

@Override
public final CollaboratorResponse addUserAsCollaborator(String collaboratorUsername, User user) {
if (collaboratorUsername.equals(user.getUsername())) {
log.error("Username : {}", collaboratorUsername);

throw new UsernameNotFoundException("User cannot add himself as collaborator!");
}
log.info("Adding user : {} as collaborator for user : {}", collaboratorUsername, user.getUsername());

User collaboratorUser = userRepository.findByUsername(collaboratorUsername)
.orElseThrow(() -> new UsernameNotFoundException("User does not exist!"));

Collaborator collaborator = Collaborator
.builder()
.fullName(collaboratorUser.getFullName())
.username(collaboratorUsername)
.user(user)
.build();
collaborator = collaboratorRepository.save(collaborator);

log.info("Mapping to respone collaborator: {}", collaborator);

return collaboratorMapper.toCollaboratorResponse(collaborator);
}

@Override
public final CollaboratorResponse assignCollaboratorToTask(CollaboratorRequest collaboratorRequest) {
log.info("Received request : {}", collaboratorRequest);

Task task = taskRepository.findById(collaboratorRequest.taskId())
.orElseThrow(() -> new TaskDoesNotExistException("Task has not been found in repository!"));
log.info("Found task : {}", task);

Collaborator collaborator = collaboratorRepository.findByUsername(collaboratorRequest.collaboratorUsername())
.orElseThrow(() -> new UsernameNotFoundException("Collaborator does not exist!"));
log.info("Found collaborator : {}", collaborator);
log.info("Number of collaborators before : {}", task.getCollaborator().size());

task.getCollaborator().add(collaborator);

task = taskRepository.save(task);

log.info("Number of collaborators after : {}", task.getCollaborator().size());

return collaboratorMapper.toCollaboratorResponse(collaborator);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package razepl.dev.todoapp.api.collaborator.constants;

public final class CollaboratorMappings {
public static final String COLLABORATOR_ENDPOINT_MAPPING = "/api/collaborator";

public static final String GET_LIST_OF_COLLABORATORS_MAPPING = "listOfCollaborators";

public static final String GET_COLLABORATORS_OF_TASK = "collaboratorsOfTask";

public static final String ADD_USER_AS_COLLABORATOR = "addCollaborator";

public static final String ASSIGN_COLLABORATOR_TO_TASK = "assignToTask";

private CollaboratorMappings() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package razepl.dev.todoapp.api.collaborator.data;

public record CollaboratorRequest(long taskId, String collaboratorUsername) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package razepl.dev.todoapp.api.collaborator.data;

import lombok.Builder;

@Builder
public record CollaboratorResponse(String fullName, String username, long collaboratorId) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package razepl.dev.todoapp.api.collaborator.interfaces;

import razepl.dev.todoapp.api.collaborator.data.CollaboratorRequest;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorResponse;
import razepl.dev.todoapp.entities.user.User;

import java.util.List;

public interface CollaboratorController {
List<CollaboratorResponse> getListOfCollaborators(User user);

List<CollaboratorResponse> getCollaboratorsAssignedToTask(long taskId, User user);

CollaboratorResponse addUserAsCollaborator(String collaboratorUsername, User user);

CollaboratorResponse assignCollaboratorToTask(CollaboratorRequest collaboratorRequest);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package razepl.dev.todoapp.api.collaborator.interfaces;

import org.mapstruct.Mapper;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorResponse;
import razepl.dev.todoapp.entities.collaborator.Collaborator;

@Mapper(componentModel = "spring")
public interface CollaboratorMapper {
CollaboratorResponse toCollaboratorResponse(Collaborator collaborator);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package razepl.dev.todoapp.api.collaborator.interfaces;

import razepl.dev.todoapp.api.collaborator.data.CollaboratorRequest;
import razepl.dev.todoapp.api.collaborator.data.CollaboratorResponse;
import razepl.dev.todoapp.entities.user.User;

import java.util.List;

public interface CollaboratorService {
List<CollaboratorResponse> getListOfCollaborators(User user);

List<CollaboratorResponse> getCollaboratorsAssignedToTask(long taskId, User user);

CollaboratorResponse addUserAsCollaborator(String collaboratorUsername, User user);

CollaboratorResponse assignCollaboratorToTask(CollaboratorRequest collaboratorRequest);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
public class GroupsServiceImpl implements GroupsService {
private static final int PAGE_SIZE = 10;
private static final int PAGE_NUMBER = 0;

private final GroupRepository groupRepository;
private final GroupMapper groupMapper;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
import razepl.dev.todoapp.api.tasks.data.TaskUpdate;
import razepl.dev.todoapp.api.tasks.interfaces.TaskMapper;
import razepl.dev.todoapp.api.tasks.interfaces.TasksService;
import razepl.dev.todoapp.entities.groups.Group;
import razepl.dev.todoapp.entities.groups.interfaces.GroupRepository;
import razepl.dev.todoapp.entities.task.Task;
import razepl.dev.todoapp.entities.task.interfaces.TaskRepository;
import razepl.dev.todoapp.entities.user.User;
import razepl.dev.todoapp.exceptions.tasks.TaskDoesNotExistException;

import java.time.LocalDate;
import java.util.List;
import java.util.NoSuchElementException;

import static razepl.dev.todoapp.api.tasks.constants.Constants.PAGE_SIZE;

Expand All @@ -27,20 +30,27 @@
public class TasksServiceImpl implements TasksService {
private static final String TASK_ERROR_MESSAGE = "Task of id '%s' does not exist!";
private final TaskRepository taskRepository;
private final GroupRepository groupRepository;
private final TaskMapper taskMapper;

@Override
public final TaskResponse createNewTask(TaskRequest taskRequest, User taskAuthor) {
log.info("Received request with data : {}", taskRequest);
log.info("Request is from user : {}", taskAuthor.getUsername());

Group group = groupRepository.findByGroupName(taskRequest.groupName())
.orElseThrow(() -> new NoSuchElementException("Given group does not exist!"));

log.info("Group found in repository : {}", group);

Task newTask = Task
.builder()
.title(taskRequest.title())
.description(taskRequest.description())
.dueDate(LocalDate.parse(taskRequest.dueDate()))
.priority(taskRequest.priority())
.user(taskAuthor)
.group(group)
.build();
Task repoTask = taskRepository.save(newTask);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package razepl.dev.todoapp.api.tasks.constants;

public final class Constants {
public static final int PAGE_SIZE = 30;
public static final int PAGE_SIZE = 40;

private Constants() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import lombok.Builder;

@Builder
public record TaskRequest(String title, String description, int priority, String dueDate) {
public record TaskRequest(String title, String description, int priority, String dueDate, String groupName) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package razepl.dev.todoapp.entities.collaborator;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import razepl.dev.todoapp.entities.user.User;

import static razepl.dev.todoapp.entities.collaborator.constants.CollaboratorConstants.COLLABORATORS_TABLE_NAME;
import static razepl.dev.todoapp.entities.task.constants.TaskConstants.USER_ID_COLUMN_NAME;

@Data
@Entity
@Builder
@Table(name = COLLABORATORS_TABLE_NAME)
@NoArgsConstructor
@AllArgsConstructor
public class Collaborator {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long collaboratorId;

private String fullName;

@Column(unique = true)
private String username;

@ManyToOne
@JoinColumn(name = USER_ID_COLUMN_NAME)
private User user;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package razepl.dev.todoapp.entities.collaborator.constants;

public final class CollaboratorConstants {
public static final String COLLABORATORS_TABLE_NAME = "Collaborators";

public static final String COLLABORATOR_ID_COLUMN = "collaborators_task_id";

private CollaboratorConstants() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package razepl.dev.todoapp.entities.collaborator.interfaces;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import razepl.dev.todoapp.entities.collaborator.Collaborator;
import razepl.dev.todoapp.entities.user.User;

import java.util.List;
import java.util.Optional;

@Repository
public interface CollaboratorRepository extends JpaRepository<Collaborator, Long> {
List<Collaborator> findCollaboratorsByUser(User user);

Optional<Collaborator> findByUsername(String username);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface GroupRepository extends JpaRepository<Group, Long> {
Page<Group> findGroupsByUserOrderByGroupName(User user, Pageable pageable);

Optional<Group> findByGroupIdAndUser(long groupId, User user);

Optional<Group> findByGroupName(String groupName);
}
Loading

0 comments on commit ccceeac

Please sign in to comment.