파트너 포털에 공지사항 상세 모달과 Ajax 로딩 추가
목차
partner-portal 영역에 공지사항 상세 모달과 Ajax 동적 로딩을 붙이는 작업이었다. 변경 파일은 뷰/스타일 1개. 겉으로 보면 간단해 보이지만 늘 그렇듯이 한 레이어만 건드리고 끝나는 작업은 없었다.
왜 모달 + Ajax였나
공지사항 목록은 이미 있었다. 없던 건 상세 내용을 그 자리에서 바로 보여주는 흐름이었다. 페이지 이동으로 구현할 수도 있었지만 파트너 포털 특성상 목록-상세 간 컨텍스트 유지가 더 자연스럽고, 뒤로가기/브라우저 히스토리 오염도 피할 수 있어서 모달을 선택했다.
Ajax 로딩을 함께 넣은 이유는 간단하다. 모달을 열 때마다 전체 페이지를 다시 그리면 사용자 입장에서 어색하고, 미리 전체 데이터를 내려받는 건 목록이 늘어날수록 초기 로딩에 부담이 생긴다. 그래서 클릭 시점에 해당 공지 ID를 가지고 API를 찌르는 구조로 갔다.
구현 구조
기본 흐름은 목록 행 클릭 → Ajax 호출 → 응답 데이터를 모달에 바인딩 → 표시. JSP + jQuery 기반이라 크게 복잡하진 않다.
// 공지사항 행 클릭 이벤트
$(document).on('click', '.notice-row', function () {
var noticeId = $(this).data('id');
$.ajax({
url: '/partner/notice/detail',
data: { noticeId: noticeId },
success: function (res) {
$('#modalTitle').text(res.title);
$('#modalContent').html(res.content);
$('#noticeModal').modal('show');
},
error: function () {
alert('공지사항을 불러오는 데 실패했습니다.');
}
});
});
백엔드 엔드포인트는 /partner/notice/detail로 신규 추가. 권한 인터셉터를 통과해야 하므로 파트너 포털 공통 인터셉터 설정에 해당 URL 패턴이 포함되어 있는지 확인하는 게 첫 번째 체크포인트였다. 이걸 빠뜨리면 로그인 없이 직접 URL 접근이 가능해지거나, 반대로 정상 요청인데 403이 떨어지거나 둘 중 하나다.
사이드바 메뉴 활성화도 같이 처리했다. 공지사항 메뉴가 현재 활성 상태임을 표시하는 클래스 처리인데, 기존 뷰에서 requestURI를 비교하는 방식이었다. 신규 상세 API 경로가 생기면서 패턴 매칭이 깨질 수 있어서 확인 후 조정했음.
설계할 때 고려한 것들
단순 모달이라도 체크해야 할 지점이 생각보다 많다.
| 항목 | 내용 |
|---|---|
| 빈 데이터 처리 | 공지 내용이 null/빈 문자열일 때 모달이 비어 보이지 않도록 fallback 텍스트 처리 |
| 권한 없는 접근 | 인터셉터 외에 서비스 레이어에서도 파트너 권한 확인 |
| 중복 클릭 방어 | 빠르게 연속 클릭 시 Ajax 중복 발송 방지 - 요청 중 플래그 또는 버튼 비활성화 |
| XSS | 서버에서 내려오는 content를 .html()로 바인딩할 때 서버 측 이스케이프 여부 확인 |
| 쿼리 성능 | 상세 조회는 PK 단건이라 실행 계획 별도 확인 필요 없었지만, 목록 쿼리와 함께 인덱스 확인 |
실시간 갱신 여부는 초반에 잠깐 고민했다. 공지사항 특성상 관리자가 올리고 파트너가 보는 방향성이 명확해서 폴링이나 웹소켓을 넣을 이유가 없었고, 그냥 클릭 시 최신 데이터 요청으로 충분했다.
NULL 처리는 도메인을 가리지 않고 방어해야 한다. 특히 파트너 포털처럼 다수 파트너가 동시에 접속하는 환경에서, 특정 파트너에게만 특정 공지가 안 보이거나 모달이 깨지는 현상은 재현하기 어려운 버그가 된다. 그래서 서버 응답에 필드 하나라도 null이 섞일 수 있는 구조라면 프론트에서도 명시적으로 체크하는 게 맞다.
구현 후 직접 화면에서 동작 확인. 기존 목록 데이터가 그대로 유지되는지, 모달을 열고 닫았을 때 상태가 초기화되는지, 권한 인터셉터를 통과하는지 순서대로 돌아봤다.
사내 서비스를 만들다 보면 기능 하나가 단순히 화면에 버튼 하나 추가하는 것으로 끝나지 않는다는 걸 계속 체감한다. SQL 조회, 예외 처리, 화면 렌더링, 권한 체크가 전부 엮여 있어서 어느 하나만 빠뜨려도 특정 사용자에게 이상한 화면이 나타난다.
이번엔 비교적 단순한 케이스였지만 그래도 변경 전 동작을 먼저 메모해두고, 수정 후 같은 케이스로 확인하는 루틴을 지켰다. 관련 화면이 있으면 숫자 cross-check, 커밋 메시지는 "무엇을"보다 "왜"를 담으려고 노력. 이 루틴이 귀찮게 느껴질 때도 있는데, 나중에 문제 생겼을 때 히스토리 찾는 시간을 줄여주는 건 확실하다.
작은 단위로 커밋을 쪼개는 것도 계속 유지 중. 이번에도 백엔드 엔드포인트, 프론트 모달, 사이드바 처리를 각각 분리해서 넣었다. 한 번에 몰아서 커밋하면 나중에 어느 변경이 문제였는지 찾기가 훨씬 힘들어진다.
댓글 0
첫 댓글 달아줘.