Skip to content

Commit

Permalink
Merge pull request #39 from Central-MakeUs/dev
Browse files Browse the repository at this point in the history
[CI/CD] 메모 기능 배포
  • Loading branch information
dainnida authored Jan 23, 2025
2 parents 7e405a5 + 0a5fe55 commit 450a3da
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 0 deletions.
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 src/main/java/com/cmc/mercury/domain/memo/service/MemoService.java
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;
}
}

0 comments on commit 450a3da

Please sign in to comment.