파트너코드 소문자 입력 시 매칭 오류 3중 정규화로 해결
목차
파트너코드 입력 시 대문자 강제 변환 이슈
파트너 가입 화면에서 코드 입력 필드에 소문자를 쳤더니 그대로 저장되는 케이스를 발견함. 정책상 파트너코드는 전부 대문자(A-Z, 0-9)인데, 일부 사용자가 소문자로 입력하고 그대로 등록되니 조회·매칭 단계에서 어긋났음.
어떤 게 문제였나
- 프론트단에서
toUpperCase()변환을 입력 시점에 거는데, 모바일 자동완성으로 들어오는 값은 그 핸들러를 거치지 않음 - 서버단에서도 검증만 했지 정규화는 안 함. 그래서 클라이언트 우회하면 소문자가 그대로 들어감
- DB 컬럼은 collation이 case-sensitive라
abc123과ABC123이 다른 값으로 취급됨
검증 로직만 봤을 땐 "대문자/숫자만 허용"이라 막아주는 줄 알았는데, 실제로는 정규식이 [A-Za-z0-9]로 되어 있어서 소문자도 통과시키고 있었음.
어떻게 고쳤나
세 군데를 손봤음.
| 레이어 | 변경 내용 |
|---|---|
| 입력 필드 | oninput + 붙여넣기 이벤트에서 강제 대문자 |
| 서버 검증 | 정규식 [A-Z0-9]{6,12} 로 좁히고 사전 trim().toUpperCase() |
| 저장 직전 | 도메인 객체 생성 시점에 한 번 더 정규화 |
input.addEventListener('input', e => {
const pos = e.target.selectionStart;
e.target.value = e.target.value.toUpperCase();
e.target.setSelectionRange(pos, pos);
});
커서 위치 보존 안 하면 한국어 IME 환경에서 입력 중 커서가 끝으로 튀는 부작용이 있어서 selectionStart 챙김. 처음에 그냥 대입만 했다가 QA에서 바로 잡혔음.
기존 데이터는 어떻게 했나
이미 들어간 소문자 레코드가 17건 있었음. 그냥 update 치면 다른 테이블 외래키랑 안 맞으니 작업 순서가 중요했음.
- 영향받는 매핑 테이블 먼저 식별 (검색 로그, 정산 매핑, 알림 수신자)
- 각 테이블에서 해당 코드 사용 위치 조회
- 트랜잭션 안에서 자식 → 부모 순으로 일괄 대문자 변환
- 변환 후 검증 쿼리로 카운트 일치 확인
마이그레이션 SQL은 dry-run 먼저 돌려서 영향 행수 뽑고, 실제 적용은 운영 시간 외에 진행함.
배운 점
- "입력 정규화"는 항상 클라이언트 + 서버 + 도메인 3중으로 거는 게 안전함. 한 군데서 빠지면 우회됨
- 검증과 정규화는 다른 작업임. 검증만 하고 정규화 안 하면 통과한 값이 그대로 들어감
- DB collation을 case-insensitive로 바꿀까 잠깐 고민했는데, 다른 컬럼에 영향이 커서 보류함. 코드 정규화로 해결하는 게 범위가 작음
다음
- 가입 외 다른 코드성 컬럼(쿠폰코드, 추천인코드)도 같은 패턴인지 점검 필요
- 정규화 유틸을 공통 레이어로 빼서 중복 제거하는 작업 예정
끝.
댓글 0
첫 댓글 달아줘.