Skip to content

feat: 갤러리 템플릿 내 템플릿으로 저장 API (#62) - #63

Merged
chjpooh2002 merged 2 commits into
developfrom
feat/62-gallery-save
Nov 6, 2026
Merged

chjpooh2002 merged 2 commits into
developfrom
feat/62-gallery-save

Conversation

@chjpooh2002

@chjpooh2002 chjpooh2002 commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

작업 내용

갤러리 템플릿을 내 템플릿으로 복사 저장하는 API (POST /api/v1/gallery/templates/{galleryTemplateId}/save, 명세 21번)

  • GalleryCommandService.saveToMyTemplates(GallerySaveCommand)
    • GalleryQueryService.getGalleryTemplate로 원본 조회(자체 조회 트랜잭션, 없거나 비공개면 GALLERY404_1) → 끝난 뒤 TemplateCommandService.createFromGallery 호출
    • 클래스·메서드에 @Transactional을 붙이지 않음. createFromGallery는 회원 잠금이 트랜잭션 첫 조회여야 해서 바깥 트랜잭션이 있으면 예외를 던짐 (서비스 readOnly 규칙의 예외, 클래스 주석에 이유 기록)
    • 결과는 GallerySaveResult로 감싸 컨트롤러가 template 도메인 결과 객체에 묶이지 않게 함
  • GalleryController에 저장 엔드포인트 추가 (@LoginUser Long userId), 클래스 주석을 조회(공개 캐시)/저장(로그인·캐시 금지)으로 구분
  • GallerySuccessCode.GALLERY_TEMPLATE_SAVED (201, GALLERY201_1, "내 템플릿에 저장되었습니다.")
  • 응답 필드: templateId, title, shortcut, originalShortcut, shortcutChanged (명세 그대로)
  • 보안·캐시 설정 변경 없음: 기존 설정이 GET /api/v1/gallery/**만 허용·공개 캐시라 POST는 이미 인증 필수 + no-store (테스트로 확인)

테스트

  • GallerySaveControllerTest (통합, 테스트컨테이너 MySQL, 클래스 트랜잭션 없음 → 저장 성공 자체가 "트랜잭션 없이 호출" 증명)
    • 201 + 응답 필드 5개, 단축어 그대로 shortcutChanged=false
    • 충돌 시 /견적2, originalShortcut 원본, shortcutChanged=true
    • 같은 템플릿 두 번 저장 → 2개 생성, 둘 다 source_gallery_template_id 기록
    • 활성 50개에서 TEMPLATE403_1, 개수 유지
    • 없는 ID·비공개 → GALLERY404_1, 내 템플릿 생성 안 됨
    • 토큰 없음 → COMMON401_1
    • 성공·에러 모두 Cache-Control: no-store
    • TEMPLATE409_2 에러 응답 변환 (findActiveShortcutKeys 스파이로 후보 전부 사용 중 처리)
  • GalleryCommandServiceTest (모키토): 원본 값 그대로 전달, 404면 저장 호출 안 함
  • 49→50 성공, 휴지통 제외, 바깥 트랜잭션 예외, 번호 소진 세부 규칙은 기존 TemplateCreateFromGalleryTest에서 검증됨

명세와 달라진 점

없음

확인

  • ./gradlew build 통과 (테스트 917개 전부 성공)

@chjpooh2002 chjpooh2002 self-assigned this Nov 4, 2026
@chjpooh2002 chjpooh2002 added feature 기능 개발 template 내 템플릿·휴지통 labels Nov 4, 2026
oTAETAEo
oTAETAEo previously approved these changes Nov 5, 2026

@oTAETAEo oTAETAEo 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.

고생하셨습니다 👍

몸이 조큼 아팠어서 리뷰가 늦었네여 간단 의견 적어 두었습니다 시간 괜찮으실때 확인 부탁 드려요 !

Comment on lines +125 to +132
@Test
@DisplayName("없는 갤러리 템플릿 ID면 GALLERY404_1이고 내 템플릿이 생기지 않는다")
void missingGalleryTemplate() throws Exception {
expectError(save(galleryTemplateId + 1_000), 404, "GALLERY404_1", "갤러리 템플릿을 찾을 수 없어요.");

assertThat(myTemplates()).isEmpty();
}

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.

해당 부분은 큰 문제는 없을것 같은데 galleryTemplateId + 1_000 방식이 테스트 환경에 따라서 실패할수도 있을것 같다는 생각 입니다 !

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

말씀대로 지금 구조에서는 번호가 계속 커져서 실제로 깨질 일은 거의 없지만, "그 번호에 행이 없다"는 DB 상태를 전제로 하는 건 맞는 것 같아요. 템플릿 쪽 테스트에서 쓰는 방식에 맞춰 Long.MAX_VALUE로 바꿨습니다.
GalleryControllerTest에도 같은 패턴이 있어서 그건 따로 정리하겠습니다!

Comment on lines +117 to +119
IntStream.rangeClosed(1, 50)
.forEach(number -> templateRepository.save(TemplateFixture.template(userId, "/t" + number)));

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.

해당 부분은 테스트 데이터를 넣어주는 기능이라고 이해 했습니다 !

임시 데이터를 saveAll 한 번으로 넣어도 좋을것 같은 생각입니당

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

클래스는 @Transactional이 없어서 save가 50번 각각 커밋되고 있었는데, saveAll로 바꾸면 한 트랜잭션으로 묶여서 더 깔끔하네요. 다만 ID가 IDENTITY 방식이라 INSERT 자체는 50번 나가서 속도 차이는 크지 않습니다.
의도가 더 잘 보여서 반영했습니다!

@chjpooh2002

chjpooh2002 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

고생하셨습니다 👍
몸이 조큼 아팠어서 리뷰가 늦었네여 간단 의견 적어 두었습니다 시간 괜찮으실때 확인 부탁 드려요 !

리뷰 감사합니다! 말씀하신 두 부분 모두 반영하였습니다!

@oTAETAEo oTAETAEo 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.

확인 했습니다 고생하셨어여 😊

@chjpooh2002
chjpooh2002 merged commit c2b8d9e into develop Nov 6, 2026
1 check passed
@chjpooh2002
chjpooh2002 deleted the feat/62-gallery-save branch November 6, 2026 06: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