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

feat: 미션 내역 수정 구현 #123

Merged
merged 17 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public record MissionUpdateRequest(
@Size(min = 1, max = 30, message = "미션 내용은 1자 이상 30자 이하")
@Schema(description = "미션 내용", defaultValue = "default content")
String content,
@NotNull @Schema(description = "미션 공개여부", defaultValue = "ALL")
@NotNull(message = "미션 공개 여부가 null일 수 없습니다.")
@Schema(description = "미션 공개여부", defaultValue = "ALL")
MissionVisibility visibility) {}
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,20 @@
import com.depromeet.domain.mission.domain.Mission;
import com.depromeet.domain.mission.domain.MissionCategory;
import com.depromeet.domain.mission.domain.MissionVisibility;
import com.depromeet.global.error.exception.CustomException;
import com.depromeet.global.error.exception.ErrorCode;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

public record MissionUpdateResponse(
@Schema(description = "미션 ID", defaultValue = "1") Long missionId,
@Schema(description = "미션 이름", defaultValue = "default name") String name,
@Schema(description = "미션 내용", defaultValue = "default content") String content,
@Schema(description = "미션 카테고리", defaultValue = "STUDY") MissionCategory category,
@Schema(description = "미션 공개여부", defaultValue = "ALL") MissionVisibility visibility) {
public MissionUpdateResponse(Mission mission) {
this(
public static MissionUpdateResponse from(Mission mission) {
return new MissionUpdateResponse(
mission.getId(),
mission.getName(),
mission.getContent(),
mission.getCategory(),
mission.getVisibility());
validateVisibility();
}

@NotNull(message = "미션 공개여부는 null이 될 수 없습니다.")
private void validateVisibility() {
if (visibility == null) {
throw new CustomException(ErrorCode.MISSION_VISIBILITY_NULL);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public MissionUpdateResponse updateMission(
missionUpdateRequest.name(),
missionUpdateRequest.content(),
missionUpdateRequest.visibility());
return new MissionUpdateResponse(mission);
return MissionUpdateResponse.from(mission);
}

public void deleteMission(Long missionId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.depromeet.domain.missionRecord.api;

import com.depromeet.domain.missionRecord.dto.request.MissionRecordCreateRequest;
import com.depromeet.domain.missionRecord.dto.request.MissionRecordUpdateRequest;
import com.depromeet.domain.missionRecord.dto.response.MissionRecordFindOneResponse;
import com.depromeet.domain.missionRecord.dto.response.MissionRecordFindResponse;
import com.depromeet.domain.missionRecord.service.MissionRecordService;
Expand All @@ -15,6 +16,7 @@
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;
Expand Down Expand Up @@ -48,4 +50,11 @@ public List<MissionRecordFindResponse> missionRecordFind(
@RequestParam("yearMonth") YearMonth yearMonth) {
return missionRecordService.findAllMissionRecord(missionId, yearMonth);
}

@Operation(summary = "미션 기록 단건 수정", description = "미션 기록을 수정합니다.")
@PutMapping("/{recordId}")
public Long missionRecordUpdate(
@Valid @RequestBody MissionRecordUpdateRequest request, @PathVariable Long recordId) {
return missionRecordService.updateMissionRecord(request, recordId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,8 @@ public void updateUploadStatusComplete(String remark, String imageUrl) {
this.remark = remark;
this.imageUrl = imageUrl;
}

public void updateMissionRecord(String remark) {
this.remark = remark;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.depromeet.domain.missionRecord.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Size;

public record MissionRecordUpdateRequest(
@Size(min = 0, max = 200, message = "미션 기록 일지는 200자까지")
@Schema(description = "미션 기록 일지", defaultValue = "default missionRecord remark")
String remark) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.depromeet.domain.missionRecord.dto.response;

import com.depromeet.domain.missionRecord.domain.MissionRecord;
import io.swagger.v3.oas.annotations.media.Schema;

public record MissionRecordUpdateResponse(
@Schema(description = "미션 기록 ID", defaultValue = "1") Long recordId,
@Schema(description = "미션 기록 일지", defaultValue = "default missionRecord remark")
String remark) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정 후 상세로 다시 이동되나요? 아니면 캘린더 목록으로 이동되나요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상세로 다시 이동되는 걸로 알고 있습니당

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상세로 이동된다면
1.수정 후 프론트에서 단건 조회 API를 다시 콜하거나
2.updateResponse을 받아 바로 상세 페이지를 구성하는 경우
이렇게 두 가지가 있을 것 같아용

1번의 경우라면 recordId만 넘겨주는게 좋을 것 같아용
2번의 경우라면 해당 response에 ImageUrl도 필요할 것 같아용

이 부분은 프론트 담당자와 의논필요해보입니다!

public static MissionRecordUpdateResponse from(MissionRecord missionRecord) {
return new MissionRecordUpdateResponse(missionRecord.getId(), missionRecord.getRemark());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.depromeet.domain.missionRecord.domain.MissionRecord;
import com.depromeet.domain.missionRecord.domain.MissionRecordTTL;
import com.depromeet.domain.missionRecord.dto.request.MissionRecordCreateRequest;
import com.depromeet.domain.missionRecord.dto.request.MissionRecordUpdateRequest;
import com.depromeet.domain.missionRecord.dto.response.MissionRecordFindOneResponse;
import com.depromeet.domain.missionRecord.dto.response.MissionRecordFindResponse;
import com.depromeet.global.common.constants.RedisExpireEventConstants;
Expand Down Expand Up @@ -82,6 +83,19 @@ public List<MissionRecordFindResponse> findAllMissionRecord(
return missionRecords.stream().map(MissionRecordFindResponse::from).toList();
}

public Long updateMissionRecord(MissionRecordUpdateRequest request, Long recordId) {
MissionRecord missionRecord =
missionRecordRepository
.findById(recordId)
.orElseThrow(() -> new CustomException(ErrorCode.MISSION_RECORD_NOT_FOUND));

validateMissionRecordUserMismatch(
missionRecord.getMission(), memberUtil.getCurrentMember());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MemberUtil에 getCurrentMember 메소드가 호출 될때마다 쿼리를 날려서
의도적으로 상단에서 변수에 할당해놓으면 좋을거같아용

Suggested change
MissionRecord missionRecord =
missionRecordRepository
.findById(recordId)
.orElseThrow(() -> new CustomException(ErrorCode.MISSION_RECORD_NOT_FOUND));
validateMissionRecordUserMismatch(
missionRecord.getMission(), memberUtil.getCurrentMember());
final Member member = memberUtil.getCurrentMember();
MissionRecord missionRecord =
missionRecordRepository
.findById(recordId)
.orElseThrow(() -> new CustomException(ErrorCode.MISSION_RECORD_NOT_FOUND));
validateMissionRecordUserMismatch(
missionRecord.getMission(), member);


missionRecord.updateMissionRecord(request.remark());
return missionRecord.getId();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 Long 타입 반환하고 있어용,
MissionRecordUpdateResponse에 recordId만 가지도록하고 MissionRecordUpdateResponse로 반환하는게 좋아보입니당👍🏻

}

private void validateMissionRecordDuration(Duration duration) {
if (duration.getSeconds() > 3600L) {
throw new CustomException(ErrorCode.MISSION_RECORD_DURATION_OVERBALANCE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ public enum ErrorCode {
// Mission
MISSION_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 미션을 찾을 수 없습니다."),

MISSION_VISIBILITY_NULL(HttpStatus.BAD_REQUEST, "미션 공개 여부가 null입니다."),

// MissionRecord
MISSION_RECORD_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 미션 기록을 찾을 수 없습니다."),
MISSION_RECORD_USER_MISMATCH(HttpStatus.FORBIDDEN, "미션을 생성한 유저와 로그인된 계정이 일치하지 않습니다"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.depromeet.domain.mission.dto.response.MissionCreateResponse;
import com.depromeet.domain.mission.dto.response.MissionFindResponse;
import com.depromeet.domain.mission.dto.response.MissionUpdateResponse;
import com.depromeet.global.error.exception.CustomException;
import com.depromeet.global.util.MemberUtil;
import jakarta.persistence.EntityManager;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -173,32 +172,6 @@ void setUp() {
.isInstanceOf(DataIntegrityViolationException.class);
}

@Test
void 미션_공개여부_null값은_잘못된_요청이다() {
// given
MissionCreateRequest missionCreateRequest =
new MissionCreateRequest(
"testMissionName",
"testMissionContent",
MissionCategory.STUDY,
MissionVisibility.ALL);
MissionCreateResponse saveMission = missionService.createMission(missionCreateRequest);
MissionUpdateRequest missionUpdateRequest =
new MissionUpdateRequest("modifyName", "modifyContent", null);

// when
CustomException exception =
assertThrows(
CustomException.class,
() -> {
missionService.updateMission(
missionUpdateRequest, saveMission.missionId());
});

// expected
assertEquals(exception.getMessage(), "미션 공개 여부가 null입니다.");
}

@Test
void 미션이름_20자_초과하면_미션수정_실패한다() {
// given
Expand Down