개발 slecs

계좌 인증과 포인트 충전 페이지 신규 추가

목차

계좌 인증과 포인트 충전 페이지, 두 기능을 한 커밋에서 같이 붙였다. 신규 페이지라서 기존 코드를 건드리지 않는 게 핵심이었는데, 그게 생각보다 신경 쓸 게 많았다.

슬랙 메시지 한 줄로 끝날 것 같은 작업인데 실제로 건드린 레이어가 빌드 설정부터 컨트롤러, 비즈니스 로직, SQL 매퍼까지 전방위였고, 파일 수는 6개. 규모는 작지만 여러 레이어가 다 걸쳐 있으니 흐름 전체를 머릿속에 그려두고 시작하지 않으면 한 군데 빠뜨리기 쉬운 구조였다.

왜 계좌 인증이 포인트 충전과 묶이나

포인트 충전 요청이 들어왔을 때 "이 계좌가 실제로 본인 것인지" 먼저 검증하지 않으면, 이후 정산이나 환급 로직에서 허점이 생긴다. 충전 신청 자체는 받을 수 있어도 출금 처리나 실패 환불 흐름에서 계좌 귀속이 불명확해지는 상황이 나온다. 두 기능이 별개 페이지처럼 보여도 순서가 있는 플로우고, 계좌 인증이 선행 조건이었기 때문에 같은 타임라인에서 함께 붙이는 게 맞았다.

UI 레벨에서도 사용자 동선이 연결되어야 했다. 인증 없이 충전 페이지로 바로 진입하는 경로를 막고, 인증 완료 상태에 따라 충전 폼의 활성화 여부가 바뀌는 구조. 컨트롤러 두 개가 서로 상태를 공유하지 않고도 이걸 처리할 수 있도록 설계하는 게 주된 고민이었다.

기존 패턴을 따르되, 완전히 격리

slecs 레포는 전형적인 Java MVC 구조다. 컨트롤러에서 요청을 받고, 유틸/서비스 레이어에서 비즈니스 로직을 처리하고, SQL 매퍼로 DB를 찌르고, JSP나 JSON 응답으로 결과를 돌려주는 흐름. 이 패턴이 코드베이스 전반에 이미 자리 잡혀 있어서, 신규 기능도 같은 결대로 짰다.

가장 신경 쓴 원칙은 "격리"였다. 기존 엔드포인트에 파라미터 하나 얹거나 기존 쿼리 ID를 조건분기로 재사용하면 단기적으로 편하다. 하지만 나중에 어느 기능이 어느 조건에서 이 코드를 타는지 추적이 어려워지고, 기존 쿼리를 수정할 때 사이드 이펙트가 어디까지 퍼지는지 가늠하기도 힘들어진다. 그래서 새 엔드포인트, 새 쿼리 ID를 각각 분리해서 만들었다.

<!-- SQL 매퍼 네이밍 예시 (실제 ID는 내부 규칙) -->

<!-- 기존 잔액 조회 -->
<select id="selectUserBalance" ...>
  SELECT balance FROM user_account WHERE user_id = #{userId}
</select>

<!-- 신규: 계좌 인증 상태 조회 - 별도 ID로 분리 -->
<select id="selectAccountVerifyStatus" ...>
  SELECT verify_yn, verify_dt FROM user_account_verify WHERE user_id = #{userId}
</select>

<!-- 신규: 포인트 충전 요청 등록 -->
<insert id="insertPointChargeRequest" ...>
  INSERT INTO point_charge_log (user_id, amount, status, reg_dt)
  VALUES (#{userId}, #{amount}, 'PENDING', NOW())
</insert>

쿼리 ID 네이밍은 기존 코드베이스의 prefix 규칙을 맞추면서, 기능 단위로 읽히도록 했다. 매퍼 파일 전체를 검색해서 기존 ID와 충돌 없는지 확인하는 게 선행이었다. 이름이 비슷하게 생겼으면 MyBatis가 어떤 걸 실행하는지 디버깅이 복잡해진다.

컨트롤러 레벨에서는 권한 체크 로직이 빠지면 안 됐다. 기존 컨트롤러들이 어노테이션 기반이든 세션 검증 방식이든 이미 패턴을 가지고 있으면, 새로 만든 진입점에서도 같은 방식을 그대로 따르는 게 원칙이다. 신규 기능에서만 권한 체크가 누락되는 일이 생각보다 흔하다. 새 파일을 만들다 보면 "이 로직은 공통이니 알아서 적용되겠지" 하고 건너뛰는 순간이 온다. 기존 컨트롤러 한두 개를 옆에 열어두고 비교하면서 작업한 이유가 그거였다.

체크 항목 접근 방식
엔드포인트 권한 기존 컨트롤러 패턴 그대로 적용
SQL 쿼리 ID 충돌 매퍼 파일 전체 검색 후 신규 ID 확정
빌드 설정 변경 최소 변경, 기존 설정 불개입
기존 기능 영향 작업 전/후로 기존 화면·API 전체 재확인
엣지 케이스 빈 결과, 미인증 상태 접근 직접 체크

빌드 설정 파일은 최소한으로만 손댔다. 새 기능에 필요한 것만 추가하고, 기존 설정 블록은 건드리지 않는 게 원칙이었다. 빌드 설정 하나 잘못 바꿔서 전체가 깨지는 상황은 만들기 싫었고, 그게 가장 고칩쪽이 좁은 영역이기도 하다.

검증 루틴

기능을 붙이기 전에 기존 화면과 API가 정상 동작하는 걸 먼저 확인하고 시작했다. 당연해 보이지만 바쁠 때 이 순서를 건너뛰고 개발하다 보면 "내가 깬 건지 원래 깨진 건지" 불명확한 상황이 생긴다. 기준선을 잡는 게 먼저다.

새 기능 붙인 다음에는 브라우저 직접 접근이랑 API 툴로 실제 요청을 날려봤다. DB 쪽은 실행 결과를 직접 조회해서 기대값과 맞는지 눈으로 확인했다. 엣지 케이스는 크게 두 가지였다.

  • 계좌 인증 전 상태에서 충전 페이지에 접근했을 때 응답이 의도대로 막히는지
  • 인증은 됐지만 충전 요청 금액이 0이거나 음수일 때 서버가 제대로 거르는지

자동화 테스트가 없는 환경에서 신규 기능을 붙일 때 이 정도 수작업 체크는 최소 루틴이다. 회귀는 없었다. 기존 기능이 영향 없이 그대로 돌아가는 걸 확인하고 커밋했다.


작업 자체가 어렵다기보다는, 신규 기능 추가가 오히려 더 꼼꼼하게 봐야 하는 작업이라는 걸 다시 확인한 커밋이었다. 기존 기능을 수정하면 변경 범위가 명확하지만, 새로 추가하는 건 "잘 붙었는지"뿐 아니라 "기존을 안 건드렸는지"까지 동시에 검증해야 한다. 격리 원칙을 처음부터 지키면 그 검증이 훨씬 단순해진다. 공유 쿼리나 공유 엔드포인트를 건드리는 순간부터 검증 범위가 기하급수적으로 늘어나기 때문에, 조금 더 코드가 길어지더라도 분리하는 쪽이 낫다.

댓글 0

첫 댓글 달아줘.