코드 리뷰 → 지라 티켓 초안

신규 백엔드 시니어 코드 리뷰 공유 기반 · 총 5건 (티켓 4는 하위 2건)

P1 보안 P2 버그 P3 개선 부채/리팩터 전제
등록 순서  ·  바로 등록: 티켓 1(비동기 버그) · 2(토큰) · 3(Response)
리팩터 트랙  ·  티켓 5(안전망) → 티켓 4-1 setPriceData(app) → 4-2 MemberService(admin)  — 5가 4의 전제
티켓 1

[버그] 엑셀 업로드 비동기 — 지정 스레드풀 미사용

P2

[요청 내용] 필수

채널톡 엑셀 업로드(POST /api/channeltalk/excel/upload)용으로 excelTaskExecutor 스레드풀(core 5 / max 10 / queue 500)을 설정해 두었으나 실제로는 사용되지 않음. ChannelTalkFacadeService.uploadExcel()에서 @Async 스레드가 한 일은 supplyAsync 호출로 future를 만들고 즉시 반납하는 것뿐이며, supplyAsync에 executor를 넘기지 않아 실제 처리는 JVM 공용 ForkJoinPool.commonPool()에서 실행됨. 설정한 풀이 죽어 있는 상태.

[처리 기준] 필수

  • 실제 처리가 excelTaskExecutor에서 실행되도록 통일. A/B 중 택1
    • A) @Async("excelTaskExecutor")만 사용, 본문에서 직접 처리 후 completedFuture 반환
    • B) @Async 제거, supplyAsync(task, excelTaskExecutor)로 풀 명시
  • 반환 타입 제네릭 명시(CompletableFuture<String>)
  • 동시 다건 시 지정 풀에서 실행되는지 로그(스레드명 ExcelUpload-)로 확인

[기대효과] 선택

엑셀 업로드가 commonPool을 잠식해 JVM 전역 병렬 작업을 느리게 만드는 문제 제거. 큐/스레드 상한이 실제로 적용됨.

[논의사항] 옵션

A안(코드 단순) 권장. 실패 시 재시도 정책도 이 참에 정리할지 논의.

티켓 2

[보안] access 토큰 만료 6개월 → 단축 + refresh 도입

P1

[요청 내용] 필수

현재 로그인(access) 토큰 만료가 발급일로부터 6개월로 설정되어 있음. 토큰 탈취 시 최대 6개월간 무효화 없이 재사용 가능. 카드/PII 등 민감정보를 다루는 서비스 특성상 노출 리스크가 큼.

[처리 기준] 필수

  • access 토큰 만료를 단기(예: 30~60분)로 단축
  • refresh 토큰 발급·회전(rotation) 흐름 도입 → access 만료 시 재로그인 없이 갱신
  • refresh 없이 만료만 줄이면 사장님 앱에서 잦은 재로그인 발생 → 반드시 refresh와 세트로 처리
  • 만료·갱신 시나리오(정상 갱신 / refresh 만료 / 강제 로그아웃) 동작 확인

[기대효과] 선택

탈취 토큰의 유효 창을 6개월 → 수십 분으로 축소. 로그인 UX 회귀 없이 세션 보안 강화.

[논의사항] 옵션

  • 문서상 "6개월 = access"로 파악됨. 실제 발급부 코드에서 access/refresh 중 어느 값이 6개월인지 1차 확인 필요
  • refresh 저장 위치(모바일 secure storage / 서버 화이트리스트) 및 로그아웃 시 무효화 정책 결정

[산출물] 옵션

토큰 만료·갱신 정책 정리, 발급부 코드 변경분

티켓 3

[개선] Response<?> 와일드카드 → 구체 응답 타입 명시

P3

[요청 내용] 필수

일부 컨트롤러 응답 타입이 Response<?> 와일드카드로 되어 있어(예: GET /api/point/main) Swagger 문서에서 data가 비어 보임. 프론트가 응답 구조를 코드를 직접 열어봐야 알 수 있어 협업 비용 발생.

[처리 기준] 필수

  • 전면 일괄 교체가 아니라 2단계로 진행
    • 신규/수정 API는 구체 타입(Response<List<GradeResponse>> 등) 명시를 PR 리뷰 룰로 합의
    • 현재 프론트가 실제로 막혀 있는 엔드포인트를 우선 조사·수정
  • 수정 엔드포인트는 Swagger에서 data 필드가 펼쳐지는지 확인

[기대효과] 선택

프론트가 API 호출 전에 응답 구조 파악 가능 → 코드 열람/문의 감소.

[논의사항] 옵션

와일드카드 사용 엔드포인트 전수 목록화 후 우선순위 산정. 79개 전면 교체는 지양.

티켓 4

[리팩터] God class 분해 (부모 / 에픽)

부채

하위 태스크를 app-api / admin-api 담당으로 분리. 공통 전제는 티켓 5(테스트 안전망).

[요청 내용] 필수

핵심 서비스 클래스가 한 메서드/한 클래스에 너무 많은 책임을 담고 있어 변경·리뷰·테스트가 어려움. 방향은 "서비스 = 동작 단위 / 헬퍼 = 기능 단위"로 분해. 회귀 위험이 크므로 각 하위 태스크는 테스트 안전망(티켓 5) 확보 후 착수.

[처리 기준] 필수

  • 각 하위 태스크는 동작 보존 테스트 확보 후 구조 분리(로직 개선은 별도)
  • 분해 전후 동일 입력 → 동일 결과 회귀 검증

[논의사항] 옵션

  • 담당이 app-api / admin-api로 갈려 하위 태스크로 분리(배포·리뷰 독립)
  • 착수 순서: setPriceData(app, 돈 사고 리스크) → MemberService(admin, 구조 부채)

app-api4-1 · OrderService.setPriceData() 분해

[요청 내용]

setPriceData() 한 메서드에 쿠폰 중복검사·타입 그룹핑·면세 비율 배분(CART/SELLER/PRODUCT)·프랜차이즈 마진·최소주문금액 검증이 모두 들어 있음. 결제 최종 금액 산출부라 오류 시 고객이 잘못된 금액을 결제하는 직접 리스크. 중첩 forEach + 다수 가변 Map/AtomicInteger로 변경·검증 난이도 높음.

[처리 기준]

  • 선행(필수): characterization test 확보(쿠폰 3타입 × 면세 유무 × 프랜차이즈 유무 조합). 안전망 없이 코드 이동 금지
  • 기능 단위 분리: 쿠폰 검증 / 면세 할인 배분 / 마진·단가 계산 / 최소주문금액 검증
  • 분해 전후 동일 입력 → 동일 금액(1원도 차이 없음) 회귀 검증

[논의사항]

God class 중 최우선(피해 = 돈). 면세 CART 잔여 배정 등 엣지 로직 있어 범위는 "구조 분리"로 한정, 로직 개선은 별도 티켓.

admin-api4-2 · MemberService 분해

[요청 내용]

MemberService가 79개 메서드·46개 주입 의존성의 God class. modifyMemberInformation()은 비밀번호·추천인·마진·사이렌 할인·프랜차이즈 매핑·최소주문금액·슬랙 알림 구현부가 154줄로 노출됨. 회원 조회+예외 처리도 표준/예외타입 상이/메시지 상이로 최소 5곳에 흩어짐.

[처리 기준]

  • 선행: modifyMemberInformation 동작 보존 테스트 확보(할인/마진/프랜차이즈 = 돈 분기 포함)
  • 서비스=동작 / 헬퍼=기능으로 분해 (예: ModifyMemberInfoService + MemberPasswordHelper / RecommenderHelper / MemberDiscountHelper / FranchiseMappingHelper / MinOrderAmountHelper / MemberInfoSlackHelper)
  • 흩어진 회원 조회+예외를 MemberSearchHelper.getOrThrow()로 통일(예외 타입·메시지 표준화)
  • 본문이 "목차처럼" 읽히도록 구현부를 헬퍼로 하향

[논의사항]

  • 전체 일괄 분해는 위험 → modifyMemberInformation 한 흐름부터 파일럿 후 확장
  • 예외 메시지 통일 시 기존 응답이 API 계약(프론트 의존)에 노출되는지 확인
티켓 5

[테스트] 실 DB 기반 테스트 컨벤션 + 리팩터 대상 안전망

티켓 4 전제

[요청 내용] 필수

현재 테스트에 세 패턴이 관찰됨: (1) 저장 후 로직 없이 바로 조회하는 트리비얼 테스트, (2) 서비스 내부 식을 테스트에 복붙해 로직이 두 곳(서비스+테스트 복제본)에 존재, (3) 서비스 테스트에서 레파지토리를 mock/stub 처리해 여러 레파지토리가 엮인 실제 케이스를 놓침. 이 상태에서는 회귀를 못 잡아 God class 리팩터(티켓 4)의 안전망 역할을 못 함.

[처리 기준] 필수

  • 개별 "테스트 전부 고치기"가 아님 → 컨벤션 합의 + PR 리뷰 룰로 처리
    • 서비스 로직은 테스트에 복붙하지 않고, 실제 로직(헬퍼/클래스)을 호출해 검증
    • 서비스 테스트는 stub 대신 @SpringBootTest + @Transactional(롤백)로 실 insert 후 호출
    • JPA 쿼리 메서드(findBy...) 검증 테스트는 유지 OK
  • 선행 작업: 티켓 4 대상 모듈(setPriceData / modifyMemberInformation)에 한해 실 DB 기반 characterization test 우선 확보

[기대효과] 선택

여러 레파지토리 조합 케이스를 잡는 테스트 확보 → 리팩터 시 회귀 조기 발견. 로직 이중 관리 제거.

[논의사항] 옵션

  • 실 DB 기반 테스트의 CI 실행 시간/전용 DB 준비 방식 결정 필요
  • 트리비얼 getter/생성자 테스트는 신규 작성 지양으로 합의할지