Skip to content

feat: 단축어 확인 API (#101) - #102

Open
oTAETAEo wants to merge 1 commit into
developfrom
feat/101-shortcut-availability
Open

oTAETAEo wants to merge 1 commit into
developfrom
feat/101-shortcut-availability

Conversation

@oTAETAEo

@oTAETAEo oTAETAEo commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

관련 이슈

작업 내용

명세 13번 GET /api/v1/templates/shortcuts/availability. 단축어 입력이 멈추면 화면이 부르는 실시간 확인 API입니다. 형식 오류·예약어·중복도 에러가 아니라 200 + available: false + reason으로 내려줍니다.

구분 내용
성공 TEMPLATE200_5 단축어 확인에 성공했습니다. result: shortcut, available, reason(사용 가능하면 null)
검사 순서 저장과 같다: NFC 정규화 → 형식 → 예약어(/톤교정) → 중복
빈 값 ?shortcut=·?shortcut=/는 200 + INVALID_FORMAT (확인 API에는 빈 값 사유가 없음)
중복 내 활성 템플릿(휴지통 제외)의 비교 키(소문자) 기준. 기존 existsByUserIdAndActiveShortcutKey(...AndIdNot) 그대로 사용
자기 자신 제외 excludeTemplateId가 있으면 그 ID만 빼고 판정. 남의 ID·휴지통 ID·없는 ID도 에러 없음
에러 shortcut 없음·excludeTemplateId가 숫자 아님 COMMON400_1, 토큰 없음 COMMON401_1 (스프링 기본 처리, global 변경 없음)
기타 TemplateQueryService(readOnly), 회원 잠금 없음, 캐시 no-store
  • 응답 사유 ShortcutUnavailableReason(template/entity): INVALID_FORMAT / RESERVED / DUPLICATED. 내부 값 ShortcutViolation은 from()으로 바꿔 내보냅니다 (EMPTY → INVALID_FORMAT)
  • 규칙은 Shortcut 한 곳: 위반은 findViolation, 비교 키는 Shortcut.create. 형식이 틀린 입력도 정규화한 값으로 돌려주려고 Shortcut.normalize를 public으로 바꿨습니다 (정규식·예약어 복사 없음)

명세와 달라진 점

없음. 명세에 없어 정한 것은 아래 "리뷰어에게" 1·2번입니다 (1번은 확정).

테스트

  • 전체 1165개 통과, 실패 0 (./gradlew build)
  • TemplateShortcutAvailabilityControllerTest (통합, 24개): 필드 순서·no-store, 명세 예시처럼 인코딩한 주소, 자모 분리형(NFD)이 완성형과 같게 판정, NFD로 11자를 넘는 입력도 정규화 후 형식 검사, 휴지통 단축어는 사용 가능, 다른 회원의 같은 단축어는 중복 아님, 대소문자만 다른 중복, 자기 자신 제외, 다른 내 템플릿·남의·휴지통·없는 ID 제외, 형식 오류 8가지(빈 값·/ 포함)·예약어, excludeTemplateId= 빈 값, shortcut 없음·숫자 아닌 ID COMMON400_1, 토큰 없음 COMMON401_1
  • TemplateQueryServiceTest (모키토): 사용 가능, 형식 오류·빈 값·/만·예약어(레포지토리 호출 없음), 중복, 대소문자만 다른 중복(소문자 키로 조회), 자기 자신 제외, NFD 정규화
  • ShortcutUnavailableReasonTest(상수 이름 = 명세 값, 변환), ShortcutTest(normalize)

확인 체크리스트

  • ./gradlew build 통과
  • 테스트 포함
  • 변경 400줄 안팎 → 약 580줄 (본 코드 약 135줄, 테스트 약 440줄)
  • 병합된 마이그레이션 수정 안 함
  • 비밀 값·개인정보 없음
  • global 공통 코드 변경 없음

리뷰어에게

  1. 응답 shortcut은 NFC 정규화한 값(대소문자는 입력 그대로)으로 확정했습니다. 명세는 "확인한 단축어"라고만 되어 있어 팀에서 정했습니다.
    • 근거: 명세 5장 "저장·표시는 NFC 정규화한 값", 생성·수정·상세·목록 응답도 모두 정규화한 값이고, 판정도 정규화한 값으로 합니다. 형식이 틀려도 정규화만 하고 공백 등은 그대로 돌려줍니다.
    • 화면이 응답을 입력값과 문자열로 맞춰 본다면 NFD 입력은 NFC로 바꾼 뒤 비교해야 합니다.
    • 명세는 고치지 않았습니다.
  2. excludeTemplateId가 숫자가 아니면 COMMON400_1(경로 변수 ID와 같은 처리), 빈 값(excludeTemplateId=)은 없는 것으로 봅니다.
  3. 남의 ID·휴지통 ID는 내 활성 템플릿이 아니라 빼도 결과가 같아 소유 확인을 따로 하지 않습니다.

🤖 Generated with Claude Code

@oTAETAEo oTAETAEo added feature 기능 개발 template 내 템플릿·휴지통 labels Nov 12, 2026
@oTAETAEo oTAETAEo self-assigned this Nov 12, 2026
@oTAETAEo oTAETAEo changed the title [feat] 단축어 확인 API feat: 단축어 확인 API (#101) Nov 12, 2026
@oTAETAEo
oTAETAEo marked this pull request as ready for review November 12, 2026 17:59

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

명세 13번과 대조해 봤는데 경로, 파라미터, TEMPLATE200_5, 응답 필드, 빈 값과 파라미터가 없을 때의 처리까지 명세와 같습니다. 판정에 Shortcut.findViolation과 기존 중복 조회 메서드를 그대로 써서 저장 API와 규칙이 어긋날 여지가 없는 점이 좋습니다. 테스트도 자모 분리형, 대소문자, 휴지통, 다른 회원, 자기 자신 제외까지 잘 챙겨 주신 거 같아요!
수고하셨습니다~~

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