Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

활동 그룹 게시판 API 수정 완료 #448

Merged
merged 7 commits into from
Aug 11, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public class ActivityGroupBoardController {
private final PageableUtils pageableUtils;

@Operation(summary = "[U] 활동 그룹 게시판 생성", description = "ROLE_USER 이상의 권한이 필요함<br><br>" +
"활동 그룹 게시판 카테고리별 requestDto에 들어가야 할 필수내용과 (선택)내용입니다.<br><br>" +
"공지사항, 주차별활동 : 카테고리, 제목, 내용, 첨부파일 경로 리스트(선택)<br>" +
"과제 : 부모 게시판(주차별활동), 카테고리, 제목, 내용, 마감일자, 첨부파일 경로 리스트(선택)<br>" +
"제출 : 부모 게시판(과제), 첨부파일 경로 리스트<br>" +
"피드백 : 부모 게시판(제출), 카테고리, 내용 , 첨부파일 경로 리스트(선택)"
"활동 그룹 게시판 카테고리별 requestDto에 들어가야 할 필수내용입니다.<br><br>" +
"공지사항, 주차별활동 : 카테고리 <br>" +
"과제 : 부모 게시판(주차별활동), 카테고리, 마감일자<br>" +
"제출 : 부모 게시판(과제), 카테고리<br>" +
"피드백 : 부모 게시판(제출), 카테고리"
)
@Secured({ "ROLE_USER", "ROLE_ADMIN", "ROLE_SUPER" })
@PostMapping("")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package page.clab.api.domain.activity.activitygroup.application;

import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand All @@ -19,7 +21,11 @@
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupBoardUpdateResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.AssignmentSubmissionWithFeedbackResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.FeedbackResponseDto;
import page.clab.api.domain.activity.activitygroup.exception.AssignmentBoardHasNoDueDateTimeException;
import page.clab.api.domain.activity.activitygroup.exception.FeedbackBoardHasNoContentException;
import page.clab.api.domain.activity.activitygroup.exception.InvalidParentBoardException;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberDetailedInfoDto;
import page.clab.api.domain.memberManagement.member.domain.Member;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
Expand All @@ -34,6 +40,7 @@

@Service
@RequiredArgsConstructor
@Slf4j
public class ActivityGroupBoardService {

private final ActivityGroupBoardRepository activityGroupBoardRepository;
Expand All @@ -52,10 +59,13 @@ public Long createActivityGroupBoard(Long parentId, Long activityGroupId, Activi
}

validateParentBoard(requestDto.getCategory(), parentId);

List<UploadedFile> uploadedFiles = uploadedFileService.getUploadedFilesByUrls(requestDto.getFileUrls());

ActivityGroupBoard parentBoard = parentId != null ? getActivityGroupBoardByIdOrThrow(parentId) : null;
ActivityGroupBoard board = ActivityGroupBoardRequestDto.toEntity(requestDto, currentMember, activityGroup, parentBoard, uploadedFiles);
board.validateEssentialElementByCategory();

if (parentId != null) {
parentBoard.addChild(board);
activityGroupBoardRepository.save(parentBoard);
Expand All @@ -69,19 +79,26 @@ public Long createActivityGroupBoard(Long parentId, Long activityGroupId, Activi
@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupBoardResponseDto> getAllActivityGroupBoard(Pageable pageable) {
Page<ActivityGroupBoard> boards = activityGroupBoardRepository.findAll(pageable);
return new PagedResponseDto<>(boards.map(ActivityGroupBoardResponseDto::toDto));
return new PagedResponseDto<>(boards.map(board -> {
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(board.getMemberId());
return ActivityGroupBoardResponseDto.toDto(board, memberBasicInfoDto);
}));
}

@Transactional(readOnly = true)
public ActivityGroupBoardResponseDto getActivityGroupBoardById(Long activityGroupBoardId) {
ActivityGroupBoard board = getActivityGroupBoardByIdOrThrow(activityGroupBoardId);
return ActivityGroupBoardResponseDto.toDto(board);
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(board.getMemberId());
return ActivityGroupBoardResponseDto.toDto(board, memberBasicInfoDto);
}

@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupBoardResponseDto> getActivityGroupBoardByCategory(Long activityGroupId, ActivityGroupBoardCategory category, Pageable pageable) {
Page<ActivityGroupBoard> boards = activityGroupBoardRepository.findAllByActivityGroup_IdAndCategory(activityGroupId, category, pageable);
return new PagedResponseDto<>(boards.map(ActivityGroupBoardResponseDto::toDto));
return new PagedResponseDto<>(boards.map(board -> {
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(board.getMemberId());
return ActivityGroupBoardResponseDto.toDto(board, memberBasicInfoDto);
}));
}

@Transactional(readOnly = true)
Expand All @@ -95,7 +112,7 @@ public PagedResponseDto<ActivityGroupBoardChildResponseDto> getActivityGroupBoar

List<ActivityGroupBoard> childBoards = getChildBoards(parentId);
Page<ActivityGroupBoard> boards = new PageImpl<>(childBoards, pageable, childBoards.size());
return new PagedResponseDto<>(boards.map(ActivityGroupBoardChildResponseDto::toDto));
return new PagedResponseDto<>(boards.map(this::toActivityGroupBoardChildResponseDtoWithMemberInfo));
}

@Transactional(readOnly = true)
Expand All @@ -107,9 +124,13 @@ public List<AssignmentSubmissionWithFeedbackResponseDto> getMyAssignmentsWithFee
.map(submission -> {
List<FeedbackResponseDto> feedbackDtos = submission.getChildren().stream()
.filter(ActivityGroupBoard::isFeedback)
.map(FeedbackResponseDto::toDto)
.map(board -> {
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(board.getMemberId());
return FeedbackResponseDto.toDto(board, memberBasicInfoDto);
})
.toList();
return AssignmentSubmissionWithFeedbackResponseDto.toDto(submission, feedbackDtos);
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(submission.getMemberId());
return AssignmentSubmissionWithFeedbackResponseDto.toDto(submission, memberBasicInfoDto, feedbackDtos);
})
.toList();
}
Expand All @@ -135,8 +156,11 @@ public Long deleteActivityGroupBoard(Long activityGroupBoardId) throws Permissio

@Transactional(readOnly = true)
public PagedResponseDto<ActivityGroupBoardResponseDto> getDeletedActivityGroupBoards(Pageable pageable) {
Page<ActivityGroupBoard> activityGroupBoards = activityGroupBoardRepository.findAllByIsDeletedTrue(pageable);
return new PagedResponseDto<>(activityGroupBoards.map(ActivityGroupBoardResponseDto::toDto));
Page<ActivityGroupBoard> boards = activityGroupBoardRepository.findAllByIsDeletedTrue(pageable);
return new PagedResponseDto<>(boards.map(board -> {
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getMemberBasicInfoById(board.getMemberId());
return ActivityGroupBoardResponseDto.toDto(board, memberBasicInfoDto);
}));
}

private ActivityGroupBoard getActivityGroupBoardByIdOrThrow(Long activityGroupBoardId) {
Expand All @@ -151,6 +175,14 @@ private List<ActivityGroupBoard> getChildBoards(Long activityGroupBoardId) {
return children;
}

public ActivityGroupBoardChildResponseDto toActivityGroupBoardChildResponseDtoWithMemberInfo(ActivityGroupBoard activityGroupBoard) {
MemberBasicInfoDto memberBasicInfo = externalRetrieveMemberUseCase.getMemberBasicInfoById(activityGroupBoard.getMemberId());
List<ActivityGroupBoardChildResponseDto> childrenDtos = activityGroupBoard.getChildren().stream()
.map(child -> toActivityGroupBoardChildResponseDtoWithMemberInfo(child))
.toList();
return ActivityGroupBoardChildResponseDto.toDto(activityGroupBoard, memberBasicInfo, childrenDtos);
}

private void validateParentBoard(ActivityGroupBoardCategory category, Long parentId) throws InvalidParentBoardException {
if ((category == ActivityGroupBoardCategory.NOTICE || category == ActivityGroupBoardCategory.WEEKLY_ACTIVITY)) {
if (parentId != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
import page.clab.api.domain.activity.activitygroup.dto.param.ActivityGroupDetails;
import page.clab.api.domain.activity.activitygroup.dto.param.GroupScheduleDto;
import page.clab.api.domain.activity.activitygroup.dto.request.ApplyFormRequestDto;
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupBoardResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupProjectResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupStatusResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.ActivityGroupStudyResponseDto;
import page.clab.api.domain.activity.activitygroup.dto.response.GroupMemberResponseDto;
import page.clab.api.domain.activity.activitygroup.exception.AlreadyAppliedException;
import page.clab.api.domain.activity.activitygroup.exception.InvalidCategoryException;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.domain.memberManagement.member.domain.Member;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.external.memberManagement.notification.application.port.ExternalSendNotificationUseCase;
Expand Down Expand Up @@ -69,10 +71,18 @@ public Object getActivityGroup(Long activityGroupId) {
.map(groupMember -> GroupMemberResponseDto.toDto(externalRetrieveMemberUseCase.findByIdOrThrow(groupMember.getMemberId()), groupMember))
.toList();

List<ActivityGroupBoardResponseDto> activityGroupResponseDtos =
details.getActivityGroupBoards().stream()
.map(board -> {
MemberBasicInfoDto memberBasicInfoDto = externalRetrieveMemberUseCase.getCurrentMemberBasicInfo();
return ActivityGroupBoardResponseDto.toDto(board, memberBasicInfoDto);
})
.toList();

if (details.getActivityGroup().isStudy()) {
return ActivityGroupStudyResponseDto.create(details.getActivityGroup(), details.getGroupMembers(), details.getActivityGroupBoards(), groupMemberResponseDtos, isOwner);
return ActivityGroupStudyResponseDto.create(details.getActivityGroup(), details.getGroupMembers(), activityGroupResponseDtos, groupMemberResponseDtos, isOwner);
} else if (details.getActivityGroup().isProject()) {
return ActivityGroupProjectResponseDto.create(details.getActivityGroup(), details.getGroupMembers(), details.getActivityGroupBoards(), groupMemberResponseDtos, isOwner);
return ActivityGroupProjectResponseDto.create(details.getActivityGroup(), details.getGroupMembers(), activityGroupResponseDtos, groupMemberResponseDtos, isOwner);
} else {
throw new InvalidCategoryException("해당 카테고리가 존재하지 않습니다.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import lombok.Setter;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import page.clab.api.domain.activity.activitygroup.dto.request.ActivityGroupBoardRequestDto;
import page.clab.api.domain.activity.activitygroup.dto.request.ActivityGroupBoardUpdateRequestDto;
import page.clab.api.domain.activity.activitygroup.exception.AssignmentBoardHasNoDueDateTimeException;
import page.clab.api.domain.activity.activitygroup.exception.FeedbackBoardHasNoContentException;
import page.clab.api.domain.memberManagement.member.domain.Member;
import page.clab.api.global.common.domain.BaseEntity;
import page.clab.api.global.common.file.application.UploadedFileService;
Expand Down Expand Up @@ -57,7 +60,6 @@ public class ActivityGroupBoard extends BaseEntity {
@Enumerated(EnumType.STRING)
private ActivityGroupBoardCategory category;

@Size(min = 1, max = 100, message = "{size.board.title}")
private String title;

@Column(columnDefinition = "TEXT")
Expand Down Expand Up @@ -116,4 +118,19 @@ public void validateAccessPermission(Member member, GroupMember leader) throws P
}
}
}

public void validateEssentialElementByCategory() {
if (this.isAssignment()) {
LocalDateTime dueDateTime = this.getDueDateTime();
if (dueDateTime == null) {
throw new AssignmentBoardHasNoDueDateTimeException();
}
}
if (this.isFeedback()) {
String content = this.getContent();
if (content.isEmpty()) {
throw new FeedbackBoardHasNoContentException();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import lombok.Getter;
import page.clab.api.domain.activity.activitygroup.domain.ActivityGroupBoard;
import page.clab.api.domain.activity.activitygroup.domain.ActivityGroupBoardCategory;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberDetailedInfoDto;
import page.clab.api.global.common.file.dto.response.UploadedFileResponseDto;

import java.time.LocalDateTime;
Expand All @@ -14,6 +16,8 @@
public class ActivityGroupBoardChildResponseDto {

private Long id;
private String memberId;
private String memberName;
private ActivityGroupBoardCategory category;
private String title;
private String content;
Expand All @@ -23,17 +27,19 @@ public class ActivityGroupBoardChildResponseDto {
private List<UploadedFileResponseDto> files;
private List<ActivityGroupBoardChildResponseDto> children;

public static ActivityGroupBoardChildResponseDto toDto(ActivityGroupBoard board) {
public static ActivityGroupBoardChildResponseDto toDto(ActivityGroupBoard board, MemberBasicInfoDto memberBasicInfoDto, List<ActivityGroupBoardChildResponseDto> childrenDtos) {
return ActivityGroupBoardChildResponseDto.builder()
.id(board.getId())
.memberId(memberBasicInfoDto.getMemberId())
.memberName(memberBasicInfoDto.getMemberName())
.category(board.getCategory())
.title(board.getTitle())
.content(board.getContent())
.dueDateTime(board.getDueDateTime())
.updatedAt(board.getUpdatedAt())
.createdAt(board.getCreatedAt())
.files(UploadedFileResponseDto.toDto(board.getUploadedFiles()))
.children(board.getChildren().stream().map(ActivityGroupBoardChildResponseDto::toDto).toList())
.children(childrenDtos)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import lombok.Getter;
import page.clab.api.domain.activity.activitygroup.domain.ActivityGroupBoard;
import page.clab.api.domain.activity.activitygroup.domain.ActivityGroupBoardCategory;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberBasicInfoDto;
import page.clab.api.domain.memberManagement.member.application.dto.shared.MemberDetailedInfoDto;
import page.clab.api.external.memberManagement.member.application.port.ExternalRetrieveMemberUseCase;
import page.clab.api.global.common.file.dto.response.UploadedFileResponseDto;

import java.time.LocalDateTime;
Expand All @@ -14,6 +17,8 @@
public class ActivityGroupBoardResponseDto {

private Long id;
private String memberId;
private String memberName;
private Long parentId;
private ActivityGroupBoardCategory category;
private String title;
Expand All @@ -23,9 +28,11 @@ public class ActivityGroupBoardResponseDto {
private LocalDateTime createdAt;
private LocalDateTime updatedAt;

public static ActivityGroupBoardResponseDto toDto(ActivityGroupBoard board) {
public static ActivityGroupBoardResponseDto toDto(ActivityGroupBoard board, MemberBasicInfoDto memberBasicInfoDto) {
return ActivityGroupBoardResponseDto.builder()
.id(board.getId())
.memberId(memberBasicInfoDto.getMemberId())
.memberName(memberBasicInfoDto.getMemberName())
.parentId(board.getParent() != null ? board.getParent().getId() : null)
.category(board.getCategory())
.title(board.getTitle())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ActivityGroupProjectResponseDto {
private LocalDateTime createdAt;

public static ActivityGroupProjectResponseDto create(ActivityGroup activityGroup, List<GroupMember> groupMembers,
List<ActivityGroupBoard> boards, List<GroupMemberResponseDto> groupMemberResponseDtos, boolean isOwner) {
List<ActivityGroupBoardResponseDto> boards, List<GroupMemberResponseDto> groupMemberResponseDtos, boolean isOwner) {
return ActivityGroupProjectResponseDto.builder()
.id(activityGroup.getId())
.category(activityGroup.getCategory())
Expand All @@ -50,7 +50,7 @@ public static ActivityGroupProjectResponseDto create(ActivityGroup activityGroup
.endDate(activityGroup.getEndDate())
.techStack(activityGroup.getTechStack())
.githubUrl(activityGroup.getGithubUrl())
.activityGroupBoards(boards.stream().map(ActivityGroupBoardResponseDto::toDto).toList())
.activityGroupBoards(boards)
.isOwner(isOwner)
.createdAt(activityGroup.getCreatedAt())
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class ActivityGroupStudyResponseDto {
private LocalDateTime createdAt;

public static ActivityGroupStudyResponseDto create(ActivityGroup activityGroup, List<GroupMember> groupMembers,
List<ActivityGroupBoard> boards, List<GroupMemberResponseDto> groupMemberResponseDtos, boolean isOwner) {
List<ActivityGroupBoardResponseDto> boards, List<GroupMemberResponseDto> groupMemberResponseDtos, boolean isOwner) {
return ActivityGroupStudyResponseDto.builder()
.id(activityGroup.getId())
.category(activityGroup.getCategory())
Expand All @@ -43,7 +43,7 @@ public static ActivityGroupStudyResponseDto create(ActivityGroup activityGroup,
.imageUrl(activityGroup.getImageUrl())
.groupMembers(groupMemberResponseDtos)
.curriculum(activityGroup.getCurriculum())
.activityGroupBoards(boards.stream().map(ActivityGroupBoardResponseDto::toDto).toList())
.activityGroupBoards(boards)
.isOwner(isOwner)
.createdAt(activityGroup.getCreatedAt())
.build();
Expand Down
Loading