## 관련 명세 - `docs/s1-api-spec.md` 12번 `DELETE /api/v1/templates/{templateId}` (MYT-07, MYT-08, 정책표 7) - `TEMPLATE200_4` 템플릿을 휴지통으로 옮겼습니다. - `TEMPLATE404_1` 템플릿을 찾을 수 없어요. ## 작업 내용 내 템플릿을 휴지통으로 옮긴다 (소프트 삭제). 30일 뒤 정리 배치가 영구 삭제한다. - `TemplateController`: `DELETE /api/v1/templates/{templateId}` → `TemplateDeleteResponse`(`templateId`, `title`, `deletedAt`, `purgeAt`) - `TemplateCommandService`: 삭제 쓰기 메서드 (`@Transactional`) - `Template.moveToTrash`: 이미 휴지통인 템플릿에 부르면 `IllegalStateException` (#15에서 미룬 휴지통 상태 검사) ### 동작 규칙 | 구분 | 내용 | | --- | --- | | 시각 | `deleted_at`만 `Clock` 현재 시각. `edited_at`·`last_used_at`은 그대로, `updated_at`은 바뀐다 (확장 동기화 기준) | | 예정 시각 | `purgeAt`은 `TrashRetention.purgeAt(deletedAt)` (+30일) | | 404 | 없는 ID·다른 회원(휴지통 포함)·**내 휴지통** 모두 `TEMPLATE404_1` (9·11·14번과 달리 `404_2`가 아님) | | 단축어 | 삭제 즉시 점유 해제 (생성 컬럼 `active_shortcut_key`가 NULL) | | 개수 | 활성 개수 1 감소. 한도 검사 없음 | | 잠금 | 회원 잠금 여부를 판단해 동시성 테스트로 확인 (같은 템플릿 동시 삭제, 비우기·복구와 겹침) | ## 완료 조건 - [ ] 성공 응답·`no-store`·`+09:00`, 명세 순서의 필드 - [ ] `deleted_at` 현재 시각, `purgeAt` = `deletedAt` + 30일, `edited_at`·`last_used_at` 유지, `updated_at` 갱신 - [ ] 삭제 후 휴지통 목록(15번)에 나오고 내 템플릿 목록(8번)에서 빠짐, 활성 개수 감소 - [ ] 같은 단축어로 새 템플릿 생성 가능, 50개에서 삭제 후 생성 가능 - [ ] 없는 ID·다른 회원·내 휴지통·다른 회원 휴지통 `404_1`, 숫자가 아닌 ID `COMMON400_1`, 토큰 없음 `COMMON401_1` - [ ] 삭제 후 9·11·14번이 `404_2` - [ ] 동시 삭제 2건이면 1건 성공·1건 `404_1`, 비우기·복구와 겹쳐도 500 없음 (실제 커밋) - [ ] 엔티티·서비스 단위 테스트 - [ ] `./gradlew build` 통과 ## 참고 - #80(14번 사용 기록) 위에 쌓는다. 13번 단축어 확인이 같은 컨트롤러·성공 코드를 이어서 건드린다
Activity
feat: 휴지통 템플릿을 다시 휴지통으로 옮기지 못하게 막음 (#82)
feat: 템플릿 삭제(휴지통 이동) API 구현 (#82)
test: 삭제가 동시 삭제·비우기·복구와 겹쳐도 500 없이 끝남을 검증 (#82)
test: 삭제 동시성 테스트의 비우기를 실제 휴지통 비우기 호출로 교체 (#82)
Merge pull request #84 from SnipText-Developer/feat/82-template-delete