Repository navigation
feat: 내 템플릿 수정 API (#52) - #53
Conversation
chjpooh2002
left a comment
There was a problem hiding this comment.
리뷰 남긴 사항 한 번만 확인 부탁드립니다~!
| Template template = templateQueryService.getActiveTemplate(command.userId(), command.templateId()); | ||
|
|
||
| TemplateTitle title = TemplateTitle.create(command.title()); | ||
| Shortcut shortcut = Shortcut.create(command.shortcut()); | ||
| validateShortcutAvailable(command.userId(), shortcut, template.getId()); | ||
| TemplateContent content = TemplateContent.create(command.content()); | ||
|
|
||
| template.edit(title, shortcut, content, LocalDateTime.now(clock)); | ||
|
|
||
| return TemplateUpdateResult.from(save(template)); | ||
| } |
There was a problem hiding this comment.
조회와 저장 사이에 다른 탭에서 휴지통으로 옮기면, 휴지통 템플릿에 수정이 들어가고 200이 나갈 것 같은데 맞을까요?!
창이 아주 짧아서 지금은 허용해도 될 것 같은데, 허용한다면 주석에 한 줄 남겨 주면 좋겠습니다! 막으려면 UPDATE 조건에 deleted_at IS NULL을 거는 방법도 방법 고려해주시면 좋을 거 같아요!
There was a problem hiding this comment.
@chjpooh2002 말씀해 주신 부분으로 다시한번 보니까 일어날수 있는 상황인것 같습니당 👏
... templateQueryService.getActiveTemplate(command.userId(), command.templateId());
해당 라인이 실행이 되어서 조회 후에 마지막 return 사이에 발생할수 있는 문제 인걸로 이해 했습니다
조회와 저장 사이에 휴지통으로 옮기면 200이 동작은 서비스 이용에는 큰 문제는 없을것 같은 생각이기도 하구
@DynamicUpdate로 deleted_at은 되돌아가지 않아서 삭제한 게 다시 풀리지는 않고, 구간이 짧아서 괜찮을 것 같습니다.
deleted_at IS NULL 조건은 변경 감지 대신 @Modifying으로 바꿔야 해서 넣지 않았고, 주석에 남겨 두려고 하는데 다른 의견 있으시면 남겨주세여 !
There was a problem hiding this comment.
저도 그 판단이 맞다고 봅니다! 휴지통 템플릿은 단축어 점유가 풀려 있어서 충돌도 없고, 복구하면 고친 내용이 남는 정도라 실제 피해가 거의 없네요.
말씀대로 제가 처음 말한 조건부 UPDATE는 변경 감지를 버려야 해서 과했던 것 같아요. 나중에 막아야 하는 상황이 오면 수정용 조회만 FOR UPDATE로 잠그는 방법이 있어서, 변경 감지는 그대로 두고 휴지통 이동이 먼저 끝난 경우 404_2를 낼 수 있어요. 주석에 그 선택지도 같이 적어 두면 좋겠습니다!
…at/52-template-update
관련 이슈
작업 내용
명세 11번
PUT /api/v1/templates/{templateId}를 구현했습니다. #50의getActiveTemplate으로 404를 나누고, 저장은 기존save()로 해서 유니크 위반을TEMPLATE409_1로 바꿉니다.커밋별로 보기
Template에@DynamicUpdate추가 (아래 리뷰어에게 1번)TemplateCommandService.update, 자기 자신을 뺀 중복 조회,TemplateUpdateCommand,TemplateUpdateResultPUT /{templateId},TemplateUpdateRequest,TemplateUpdateResponse,TEMPLATE200_3동작 규칙
edited_at·updated_at유지TEMPLATE409_1TEMPLATE404_1TEMPLATE404_2수정은 개수가 바뀌지 않으므로
lockUser를 부르지 않고, 같은 필드를 동시에 수정하면 나중 저장이 덮어씁니다.명세와 달라진 점
TEMPLATE404_1설명에 "휴지통에 있는 템플릿"이 남아 있어 같은 표의TEMPLATE404_2, 비고와 어긋납니다. #50과 같이 내 휴지통은TEMPLATE404_2, 다른 회원의 휴지통은TEMPLATE404_1로 구현했습니다. 이 PR에서docs/는 고치지 않았습니다@DynamicUpdate로 요청마다 바뀐 필드만 쓰므로 서로 다른 필드를 고친 두 수정은 합쳐집니다. A가 이름만, B가 본문만 고치면 둘 다 남습니다. 같은 필드는 나중 저장이 덮어씁니다. 단축어의shortcut·shortcut_key는 함께 저장되어 어긋나지 않습니다테스트
TemplateUpdateControllerTest(테스트컨테이너 MySQL)no-store, DB 값,editedAt·updated_at갱신,lastUsedAt유지editedAt·updated_at·암호문 유지409_1(자모 분리형·대소문자 포함)404_1, 내 휴지통404_2, 다른 회원의 휴지통404_1TEMPLATE400_1~7과 검증 순서(이름 → 단축어 → 내용), 토큰 없음COMMON401_1, 본문 암호화 저장TemplateUpdateUniqueViolationTest: 중복 조회를 통과한 뒤 실제 유니크 위반이 나도409_1이고 수정이 남지 않음TemplateCommandServiceTest(모키토): 주요 분기, 호출 순서,lockUser를 쓰지 않음TemplateRepositoryTest: 수정 UPDATE가 읽은 뒤 기록된last_used_at·deleted_at을 되돌리지 않음확인 체크리스트
./gradlew build통과global공통 코드 변경 없음리뷰어에게
Template에@DynamicUpdate를 넣었습니다: 없으면 수정의 UPDATE가 전체 컬럼을 써서, 읽은 뒤 기록된 휴지통 이동과 사용 시각을 옛 값으로 되돌립니다. 휴지통으로 옮긴 템플릿이 조용히 복구될 수 있습니다404_2가 아니라 200을 돌려줍니다. 행은 휴지통에 남고 내용만 바뀝니다. 잠금을 쓰지 않는 방침이라 그대로 뒀습니다existsByUserIdAndActiveShortcutKeyAndIdNot은excludeTemplateId가 있을 때 그대로 쓰면 됩니다🤖 Generated with Claude Code