개발 slecs

파트너 포털 사이드바 정렬 버그 수정

목차

파트너 포털 사이드바 메뉴 순서가 특정 조건에서 뒤섞이는 버그를 수정했다. 겉으로 보면 "메뉴 순서가 좀 이상하네" 수준이지만, 뚜껑을 열어보면 SQL 집계 조건부터 프론트 렌더링까지 레이어가 전부 엮여 있는 유형이었다.

변경된 파일은 뷰/스타일 4개, SQL 매퍼 1개. 단순 UI 수정처럼 보이는데 매퍼가 끼어 있다는 게 이미 단서였다.

어디서 터졌고, 왜 터졌나

사이드바 메뉴 순서는 DB에 저장된 sort_order 값을 기준으로 조회해서 렌더링하는 구조였다. 문제는 특정 파트너 계정에서 메뉴 항목이 부분적으로만 존재할 때, 즉 전체 메뉴 목록과 파트너에게 노출되는 메뉴 목록이 일치하지 않는 엣지 케이스에서 SQL 집계 결과가 의도와 다르게 나왔다.

대략 이런 형태의 쿼리가 문제를 만들고 있었다.

-- 수정 전 (단순화한 예시)
SELECT m.id, m.sort_order, m.label
FROM   menus m
       LEFT JOIN partner_menu pm ON pm.menu_id = m.id
WHERE  pm.partner_id = #{partnerId}
ORDER  BY m.sort_order ASC

파트너에게 연결된 항목만 가져오는데, LEFT JOIN 조건이 WHERE절로 내려오면 실질적으로 INNER JOIN처럼 동작한다. 거기다 집계 함수나 서브쿼리와 섞이면 특정 상황에서 행이 누락되거나 순서가 뒤틀렸다.

-- 수정 후 (단순화한 예시)
SELECT m.id, m.sort_order, m.label
FROM   menus m
       LEFT JOIN partner_menu pm
              ON pm.menu_id = m.id
             AND pm.partner_id = #{partnerId}
WHERE  m.use_yn = 'Y'
ORDER  BY COALESCE(pm.sort_order, m.sort_order) ASC

ON 절로 파트너 조건을 이동하고, 파트너 전용 순서가 없으면 기본 순서를 fallback으로 쓰도록 바꿨다. 쿼리 한 줄 차이지만 결과가 완전히 달랐다.

고친 것들, 그리고 확인한 것들

SQL 매퍼만 고치면 끝날 것 같았는데, 렌더링 쪽에도 손을 대야 했다. 프론트에서 받은 메뉴 목록을 다시 클라이언트 측에서 정렬하는 로직이 있었는데, 이게 서버에서 이미 정렬된 순서를 덮어쓰고 있었다. 그래서 서버를 고쳐도 화면에서 다시 섞이는 일이 생겼다.

수정 범위를 정리하면 이렇다.

파일 유형 변경 내용
SQL 매퍼 JOIN 조건 이동, COALESCE fallback 추가
뷰 (사이드바 렌더링) 클라이언트 재정렬 로직 제거
스타일 관리 페이지 UI 정비
뷰 (관리 페이지) 항목 상태 표시 수정

관리 페이지 UI 정비는 버그와 직접 관련은 없지만, 이번에 같은 화면을 들여다보면서 정렬 순서를 관리하는 인터페이스가 헷갈리게 구성되어 있다는 게 눈에 들어왔다. 순서를 바꿔도 저장됐는지 안 됐는지 피드백이 없는 구조였다. 버그를 고치면서 같이 손댔다.

버그를 재현한 다음 수정하고, 같은 조건으로 다시 재현을 시도해서 더 이상 발생하지 않음을 확인했다. 관련 화면에서 숫자를 cross-check하는 것도 습관처럼 하는데, 이번에도 사이드바에 표시되는 항목 수와 관리 페이지에서 보이는 항목 수가 일치하는지 맞춰봤다.

체크 목록으로 쓰면 이런 순서다.

  • 버그를 동일 조건으로 재현 가능한지 먼저 확인
  • SQL 변경이면 EXPLAIN 또는 직접 실행으로 결과셋 검증
  • 같은 패턴이 다른 매퍼나 경로에도 존재하는지 grep
  • 수정 후 정상 케이스가 깨지지 않는지 기존 화면 확인
  • 연관 화면 숫자 일치 여부 cross-check

비슷한 LEFT JOIN 패턴이 다른 매퍼에도 있는지 훑었는데, 이번 건만 조건 위치가 잘못되어 있었다. 다른 곳은 문제없어서 이번 수정 범위만으로 마무리했다.

파트너 포털 작업할 때 유독 신경 쓰게 되는 것들

파트너 포털이라는 도메인 자체가 까다롭다. 각 파트너마다 노출 메뉴, 권한, 데이터 범위가 다르다. 전체 관리자 화면에서는 정상으로 보이는데 특정 파트너 계정으로 들어가면 이상하게 동작하는 버그가 종종 이 구조에서 나온다.

기능 하나가 화면에 버튼 하나 추가하는 것으로 끝나지 않는다는 걸 이런 작업할 때마다 다시 실감한다. SQL 집계, 상태, 예외 처리, 렌더링, 권한 체크가 모두 물려 있어서 어느 하나만 빠뜨려도 숫자가 틀리거나 특정 계정에서 이상한 화면이 나온다.

금융이나 결제 관련 수치가 얽힌 화면이라면 더 그렇다. 숫자 하나 다르면 신뢰 문제로 번지기 때문에 "대충 맞는 것 같다"로 넘기는 선택지가 없다. 지금 10분 더 들여서 제대로 확인하는 게 나중에 같은 버그로 다시 돌아오는 시간보다 훨씬 싸다.

커밋은 논리적으로 독립된 단위로 쪼개서 자주 남기려고 한다. SQL 수정, 렌더링 수정, UI 정비를 하나의 커밋으로 묶으면 나중에 어느 변경에서 문제가 생겼는지 추적하기 어려워진다. 메시지도 "무엇을 바꿨다"보다 "왜 바꿨다"를 담으려는 편이다. 3개월 뒤에 git log 볼 때 "sort_order JOIN condition fixed"보다 "파트너별 메뉴 순서가 누락되던 엣지 케이스 처리"가 맥락을 훨씬 빠르게 복원해준다.

댓글 0

첫 댓글 달아줘.