Skip to content

feat: 템플릿 삭제(휴지통 이동) API (#82) - #84

Merged
oTAETAEo merged 4 commits into
developfrom
feat/82-template-delete
Nov 12, 2026
Merged

oTAETAEo merged 4 commits into
developfrom
feat/82-template-delete

Conversation

@oTAETAEo

@oTAETAEo oTAETAEo commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

작업 내용

명세 12번 DELETE /api/v1/templates/{templateId}. 템플릿을 휴지통으로 옮깁니다 (소프트 삭제).

구분 내용
성공 TEMPLATE200_4 템플릿을 휴지통으로 옮겼습니다. result: templateId, title, deletedAt, purgeAt(+09:00, 명세 순서)
404 없는 ID·다른 회원(휴지통 포함)·내 휴지통 모두 TEMPLATE404_1 (9·11·14번과 달리 404_2가 아님)
시각 deleted_at·updated_at은 Clock 현재 시각, edited_at·last_used_at은 그대로
예정 시각 purgeAt은 TrashRetention.purgeAt(deletedAt) (+30일)
단축어·개수 삭제 즉시 단축어 점유 해제(생성 컬럼 active_shortcut_key NULL), 활성 개수 1 감소. 한도 검사 없음
잠금 회원 행을 먼저 잠근다 (아래 1번)
  • TemplateCommandService.delete: 메서드에 @Transactional. 변경 감지로 쓰고 @DynamicUpdate라 UPDATE에는 deleted_at·updated_at만 들어갑니다
  • 조회는 findByIdAndUserId + 휴지통이면 거름 → 404_1. 새 레포지토리 메서드를 만들지 않았고, getActiveTemplate(휴지통이면 404_2)은 쓰지 않습니다
  • Template.moveToTrash: 이미 휴지통이면 IllegalStateException (#15에서 미룬 휴지통 상태 검사). 덮어쓰면 30일 기한이 다시 시작되기 때문입니다. 서비스가 먼저 404_1로 막으므로 정상 경로에서는 나오지 않습니다 (코드 실수, 500)

커밋

  1. 42ecdd7 엔티티 휴지통 상태 검사
  2. 98c42e5 삭제 API (컨트롤러·서비스·dto, 서비스·통합 테스트)
  3. 6d69494 동시성 테스트
  4. 리뷰 반영: 동시성 테스트의 비우기를 실제 trashCommandService.empty로 교체

테스트

  • 전체 1118개 통과 (develop 기준) (./gradlew clean build)
  • TemplateDeleteControllerTest (통합): 성공 응답·no-store·+09:00·필드 순서, purgeAt = deletedAt + 30일, deleted_at·updated_at 갱신과 edited_at·last_used_at·created_at·이름·단축어·본문 유지, 휴지통 목록(15번)에 나오고 목록(8번)에서 빠짐·활성 개수 감소, 같은 단축어(대소문자만 다른 것 포함)로 새로 생성, 50개에서 403_1 → 삭제 → 생성 성공, 삭제 뒤 9·11·14번 404_2, 404 네 경우(내 휴지통은 deleted_at·updated_at 그대로), 숫자가 아닌 ID COMMON400_1, 토큰 없음 COMMON401_1
  • TemplateDeleteConcurrencyTest (실제 커밋): 같은 템플릿 동시 삭제, 앞 삭제가 커밋 전일 때 뒤 삭제, 삭제↔비우기·삭제↔복구 양쪽 순서, 셋이 같은 순간에 오는 경우. 5번 반복해 모두 통과
  • TemplateCommandServiceTest(모키토), TemplateTest(이미 휴지통이면 예외, deleted_at 그대로)

확인 체크리스트

  • ./gradlew build 통과
  • 테스트 포함
  • 변경 400줄 안팎 → 약 770줄 (본 코드 약 100줄, 테스트 약 670줄). 통합·동시성 테스트 때문이고 기능은 나눌 수 없어 그대로 뒀습니다
  • 병합된 마이그레이션 수정 안 함
  • 비밀 값·개인정보 없음
  • global 공통 코드 변경 없음
  • 명세와 달라진 점 없음

리뷰어에게

  1. 삭제도 회원 행을 먼저 잠급니다 (lockUser → 조회). 먼저 잠금 없이 구현해 동시성 테스트를 돌린 결과입니다.
    • 잠금이 없으면 같은 템플릿 동시 삭제가 ["SUCCESS", "SUCCESS"]였습니다. 뒤 요청이 커밋 전 스냅샷에서 활성 템플릿을 보고 행 잠금만 기다렸다가 deleted_at을 덮어써, 30일 기한이 다시 시작됐습니다.
    • 비우기·복구와 겹치는 경우는 잠금 없이도 500이 나지 않았습니다.
    • 템플릿 행만 FOR UPDATE로 잠가도 위 문제는 막히지만, 복구·영구 삭제·비우기(feat: 휴지통 템플릿 복구 API (#67) #69·feat: 휴지통 템플릿 영구 삭제 · 비우기 API #78)와 같은 순서(회원 행 → 템플릿 행)로 맞췄습니다. 같은 회원의 생성·복구와 줄을 서는 비용은 작습니다.
  2. 동시성 테스트의 비우기는 실제 trashCommandService.empty를 부릅니다 (리뷰 반영). 처음에는 기준(feat: 템플릿 사용 기록 API (#79) #80)에 18번이 없어 JDBC로 흉내 냈습니다.
  3. 엔티티를 읽으므로 본문 복호화에 실패하는 행은 삭제도 500입니다 (수정·사용 기록과 같음).
  4. 정리 배치(00:10)와는 배치가 휴지통 행만, 삭제가 활성 행만 건드려 같은 행을 두고 다투지 않습니다.
  5. 사용량 API(6번)가 아직 없어 활성 개수는 레포지토리로 확인했습니다.
  6. 13번 단축어 확인이 같은 TemplateController·TemplateSuccessCode를 이어서 건드립니다 (200_5는 200_4와 200_6 사이).

🤖 Generated with Claude Code

@oTAETAEo oTAETAEo added feature 기능 개발 template 내 템플릿·휴지통 labels Nov 10, 2026
@oTAETAEo oTAETAEo self-assigned this Nov 10, 2026
@oTAETAEo
oTAETAEo marked this pull request as ready for review November 12, 2026 05:47
@oTAETAEo oTAETAEo linked an issue Nov 12, 2026 that may be closed by this pull request
9 tasks
chjpooh2002
chjpooh2002 previously approved these changes Nov 12, 2026

@chjpooh2002 chjpooh2002 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

삭제 시 회원 행부터 잠그는 순서, 이미 휴지통에 있는 템플릿을 엔티티에서 한 번 더 막는 처리, 동시성 테스트로 덮어쓰기 문제를 직접 확인한 부분까지 깔끔하게 정리돼 있네요.

리마인드 하나만 남겨요!
#80 병합 후 기준 브랜치를 develop으로 바꿀 때, TemplateDeleteConcurrencyTest의 emptyTrash()(276~280줄)를 실제 trashCommandService.empty(userId) 호출로 바꿔 주세요. 지금은 흉내 낸 버전과 동작이 같지만, 나중에 비우기 로직이 바뀌면 이 테스트가 그 변경을 따라가지 못합니다. 이것까지 반영한 뒤 병합 부탁드려요!!

Base automatically changed from feat/79-template-usage to develop November 12, 2026 15:29
@oTAETAEo
oTAETAEo dismissed chjpooh2002’s stale review November 12, 2026 15:29

The base branch was changed.

@oTAETAEo
oTAETAEo force-pushed the feat/82-template-delete branch from 540ad74 to e3154a3 Compare November 12, 2026 15:34
@oTAETAEo
oTAETAEo requested a review from chjpooh2002 November 12, 2026 15:35
@oTAETAEo

Copy link
Copy Markdown
Contributor Author

@chjpooh2002 말씀 주신 부분 반영 했습니다 !

@chjpooh2002 chjpooh2002 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

수고하셨습니다~!

@oTAETAEo
oTAETAEo merged commit f5b81bc into develop Nov 12, 2026
1 check passed
@oTAETAEo
oTAETAEo deleted the feat/82-template-delete branch November 12, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature 기능 개발 template 내 템플릿·휴지통

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 템플릿 삭제(휴지통 이동) API

2 participants