-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from Central-MakeUs/dev
[CI/CD] 메모 기능 배포
- Loading branch information
Showing
2 changed files
with
159 additions
and
0 deletions.
There are no files selected for viewing
59 changes: 59 additions & 0 deletions
59
src/main/java/com/cmc/mercury/domain/memo/controller/MemoController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.cmc.mercury.domain.memo.controller; | ||
|
||
import com.cmc.mercury.domain.memo.dto.MemoCreateRequest; | ||
import com.cmc.mercury.domain.memo.dto.MemoResponse; | ||
import com.cmc.mercury.domain.memo.dto.MemoUpdateRequest; | ||
import com.cmc.mercury.domain.memo.service.MemoService; | ||
import com.cmc.mercury.global.response.SuccessResponse; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.HashMap; | ||
|
||
@RestController | ||
@RequestMapping("/records/{recordId}/memos") | ||
@RequiredArgsConstructor | ||
@Tag(name = "MemoController", description = "메모 관련 API") | ||
public class MemoController { | ||
|
||
private final MemoService memoService; | ||
|
||
@PostMapping | ||
@Operation(summary = "메모 추가", description = "메모를 생성합니다.") | ||
public SuccessResponse<MemoResponse> createMemo( | ||
@RequestParam("userId") Long testUserId, | ||
@PathVariable Long recordId, | ||
@RequestBody @Valid MemoCreateRequest request | ||
) { | ||
return SuccessResponse.created( | ||
memoService.createMemo(testUserId, recordId, request) | ||
); | ||
} | ||
|
||
@PatchMapping("/{memoId}") | ||
@Operation(summary = "메모 수정", description = "특정 메모를 수정합니다.") | ||
public SuccessResponse<MemoResponse> updateMemo( | ||
@RequestParam("userId") Long testUserId, | ||
@PathVariable Long recordId, | ||
@PathVariable Long memoId, | ||
@RequestBody MemoUpdateRequest request | ||
) { | ||
return SuccessResponse.ok( | ||
memoService.updateMemo(testUserId, recordId, memoId, request) | ||
); | ||
} | ||
|
||
@DeleteMapping("/{memoId}") | ||
@Operation(summary = "메모 삭제", description = "특정 메모를 삭제합니다.") | ||
public SuccessResponse<?> deleteMemo( | ||
@RequestParam("userId") Long testUserId, | ||
@PathVariable Long recordId, | ||
@PathVariable Long memoId | ||
) { | ||
memoService.deleteMemo(testUserId, recordId, memoId); | ||
return SuccessResponse.ok(new HashMap<>()); | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/com/cmc/mercury/domain/memo/service/MemoService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package com.cmc.mercury.domain.memo.service; | ||
|
||
import com.cmc.mercury.domain.memo.dto.MemoCreateRequest; | ||
import com.cmc.mercury.domain.memo.dto.MemoResponse; | ||
import com.cmc.mercury.domain.memo.dto.MemoUpdateRequest; | ||
import com.cmc.mercury.domain.memo.entity.Memo; | ||
import com.cmc.mercury.domain.memo.repository.MemoRepository; | ||
import com.cmc.mercury.domain.record.entity.Record; | ||
import com.cmc.mercury.domain.record.entity.RecordDetail; | ||
import com.cmc.mercury.domain.record.repository.RecordRepository; | ||
import com.cmc.mercury.global.exception.CustomException; | ||
import com.cmc.mercury.global.exception.ErrorCode; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class MemoService { | ||
|
||
private final MemoRepository memoRepository; | ||
private final RecordRepository recordRepository; | ||
|
||
@Transactional | ||
public MemoResponse createMemo(Long testUserId, Long recordId, MemoCreateRequest request) { | ||
|
||
// Record와 RecordDetail을 함께 조회 (Record가 없으면 RecordDetail도 없음) | ||
Record record = recordRepository.findByIdAndUser_TestUserId(recordId, testUserId) | ||
.orElseThrow(() -> new CustomException(ErrorCode.RECORD_NOT_FOUND)); | ||
|
||
RecordDetail recordDetail = record.getRecordDetail(); | ||
|
||
// Memo 생성 (아직 연관관계 설정 전) | ||
Memo memo = Memo.builder() | ||
.content(request.content()) | ||
.gauge(request.gauge()) | ||
.build(); | ||
|
||
// 연관관계 설정 | ||
recordDetail.addMemo(memo); | ||
|
||
// 메모의 gauge로 RecordDetail의 updatedGauge 업데이트 | ||
recordDetail.updateGauge(request.gauge()); | ||
|
||
Memo savedMemo = memoRepository.save(memo); | ||
|
||
// save()로 인해 즉시 updatedAt 설정됨 => flush 필요없음 | ||
// 메모의 updatedAt으로 record와 recordDetail 업데이트 | ||
record.updateLastModifiedDateWithDetail(savedMemo.getUpdatedAt()); | ||
|
||
return MemoResponse.from(savedMemo, recordId); | ||
|
||
} | ||
|
||
@Transactional | ||
public MemoResponse updateMemo(Long testUserId, Long recordId, Long memoId, MemoUpdateRequest request) { | ||
|
||
Memo memo = validateAndGetMemo(testUserId, recordId, memoId); | ||
|
||
memo.updateContent(request.content()); | ||
|
||
// db에 updatedAt이 바로 반영되어 응답하도록 | ||
memoRepository.flush(); | ||
|
||
Record record = memo.getRecordDetail().getRecord(); | ||
record.updateLastModifiedDateWithDetail(memo.getUpdatedAt()); | ||
|
||
return MemoResponse.from(memo, recordId); | ||
} | ||
|
||
@Transactional | ||
public void deleteMemo(Long testUserId, Long recordId, Long memoId) { | ||
|
||
Memo memo = validateAndGetMemo(testUserId, recordId, memoId); | ||
|
||
memo.getRecordDetail().getMemos().remove(memo); | ||
|
||
memoRepository.delete(memo); | ||
} | ||
|
||
private Memo validateAndGetMemo(Long testUserId, Long recordId, Long memoId) { | ||
|
||
// Record와 RecordDetail을 함께 조회 (Record가 없으면 RecordDetail도 없음) | ||
Record record = recordRepository.findByIdAndUser_TestUserId(recordId, testUserId) | ||
.orElseThrow(() -> new CustomException(ErrorCode.RECORD_NOT_FOUND)); | ||
|
||
RecordDetail recordDetail = record.getRecordDetail(); | ||
|
||
Memo memo = memoRepository.findById(memoId) | ||
.orElseThrow(() -> new CustomException(ErrorCode.MEMO_NOT_FOUND)); | ||
|
||
if (!memo.getRecordDetail().getId().equals(recordDetail.getId())) { | ||
throw new CustomException(ErrorCode.MEMO_NOT_BELONG_TO_RECORD); | ||
} | ||
|
||
return memo; | ||
} | ||
} |