블로그로 돌아가기
Design

관리자 대시보드 설계기 — 데이팅 앱 운영을 위한 어드민 UX

신고 처리부터 푸시 알림 세그먼트 타겟팅까지, 썸블링 어드민 대시보드를 Next.js + Tailwind 다크 테마로 설계하면서 겪은 UX 의사결정을 공유합니다

Team Somebling ·
#어드민 #대시보드 #UX #푸시 알림

관리자도 사용자다

서비스를 만들 때 우리는 대부분 최종 사용자, 즉 앱을 쓰는 일반 회원의 경험에 집중합니다. 하지만 서비스를 운영하는 관리자도 매일 이 인터페이스를 사용합니다. 느리고 불친절한 어드민 툴은 운영 효율을 갉아먹고, 결국 서비스 품질에 영향을 줍니다.

썸블링의 관리자는 매일 어떤 일을 할까요? 크게 네 가지입니다. 신고된 회원을 검토하고 처리하기, 신규 가입자와 이탈 회원을 파악하기, 매칭 알고리즘이 잘 돌아가고 있는지 모니터링하기, 그리고 이벤트나 공지를 위한 푸시 알림 발송하기. 이 네 가지 업무를 효율적으로 지원하는 인터페이스를 만드는 것이 어드민 UX의 핵심 목표였습니다.


대시보드 첫 화면: 무엇을 보여줄 것인가

어드민 대시보드에 처음 접속했을 때 관리자가 가장 먼저 알고 싶은 것은 무엇일까요? “지금 서비스가 잘 돌아가고 있나?”입니다. 이 질문에 답하기 위해 7개의 핵심 지표를 선정했습니다.

총 회원수오늘 가입자 수는 성장 지표입니다. 매일 몇 명이 새로 들어오는지 추세를 파악할 수 있습니다. 활성 매칭 수는 서비스의 핵심 기능이 얼마나 활발히 작동하는지를 보여줍니다. 오늘 매칭 생성 수는 배치 스케줄러가 정상 실행됐는지 확인하는 운영 지표이기도 합니다. 대기 중인 신고 수는 즉각적인 주의가 필요한 항목으로, 숫자가 클수록 색상을 강조해 시선을 끌도록 했습니다. 마지막으로 활성 구독자 수오늘 매출은 비즈니스 건전성을 확인하는 지표입니다.

7개 지표를 카드 형태로 나열할 때 중요한 설계 결정은 “우선순위”입니다. 왼쪽 위에서 오른쪽 아래로 읽히는 시선 흐름에 따라, 가장 긴급한 지표(대기 신고)를 시각적으로 강조하고, 성장 지표는 그 다음에 배치했습니다. 대기 신고가 0건이면 회색으로, 5건 이상이면 노란색 배경으로 자동 변환되어 운영자의 눈에 바로 들어옵니다.

flowchart LR
    subgraph KPI["대시보드 KPI 카드"]
        direction TB
        K1["👥 총 회원수<br/>성장 지표"]
        K2["📈 오늘 가입자<br/>성장 지표"]
        K3["💜 활성 매칭 수<br/>서비스 핵심"]
        K4["🔄 오늘 매칭 생성<br/>운영 지표"]
        K5["🚨 대기 신고 수<br/>긴급 항목"]
        K6["⭐ 활성 구독자<br/>비즈니스"]
        K7["💰 오늘 매출<br/>비즈니스"]
    end

    K5 -->|5건 이상| ALERT["⚠️ 노란색 강조<br/>즉각 주의 필요"]

    style K5 fill:#FF6B9D,stroke:#FF6B9D,color:#fff
    style ALERT fill:#FF6B9D,stroke:#FF6B9D,color:#fff

테이블 vs 카드: 데이터 밀도에 따른 선택

관리자 페이지에서 가장 자주 마주치는 UX 딜레마는 “테이블로 보여줄까, 카드로 보여줄까”입니다. 썸블링 어드민에서는 콘텐츠의 성격에 따라 다르게 접근했습니다.

회원 관리 페이지는 테이블을 선택했습니다. ID, 닉네임, 이메일, 성별, 나이, 상태, 가입일, 관리 액션까지 8개 컬럼을 한 줄에 보여야 합니다. 정보 밀도가 높고 비교가 중요한 데이터는 테이블이 유리합니다. 관리자는 여러 회원을 빠르게 훑으면서 이상한 패턴을 찾아야 하는데, 카드 방식으로는 스크롤 거리가 너무 길어집니다.

반면 신고 관리 페이지는 접기/펼치기 카드 방식을 택했습니다. 신고 건은 처리 상태(PENDING/REVIEWED/DISMISSED)가 중요하고, 각 건의 상세 내용(신고자, 피신고자, 신고 사유, 상세 설명)을 선택적으로 볼 필요가 있습니다. 기본 상태는 접혀 있어 목록을 빠르게 스캔할 수 있고, 클릭하면 상세가 펼쳐집니다. 테이블로 구현하면 행 높이가 일정해야 해서 긴 설명 텍스트를 담기 어렵습니다.

상태 색상 코딩도 신경 썼습니다. PENDING은 노란색(주의), REVIEWED는 초록색(완료), DISMISSED는 회색(종결). 색상만 봐도 처리 여부를 즉시 파악할 수 있습니다. 다크 테마 위에서도 충분한 대비를 확보하는 색조를 골랐습니다.


푸시 알림: 세그먼트 타겟팅의 설계

푸시 알림 시스템은 썸블링 어드민에서 가장 복잡한 기능입니다. 단순히 메시지를 입력하고 보내는 것이 아니라, 누구에게 보낼지 세밀하게 지정할 수 있어야 합니다.

세그먼트 타겟팅 조건은 네 가지입니다. 성별 (남성/여성/기타), 나이 범위 (최소 나이 ~ 최대 나이), 구독 티어 (FREE/PLUS/PREMIUM), 회원 상태 (ACTIVE/DORMANT/WITHDRAWN). 이 조건들을 조합하면 “30대 여성 PLUS 구독자”나 “최근 가입한 활성 남성 회원”처럼 구체적인 대상에게 맞춤 메시지를 보낼 수 있습니다.

여기서 중요한 UX 요소가 대상 수 미리보기입니다. 조건을 설정하면 실시간으로 “현재 조건에 해당하는 회원이 몇 명인지”를 보여줍니다. 이 기능이 없으면 관리자는 설정한 조건이 너무 좁거나 너무 넓은지 알 수 없어서 불안합니다. “아, 이 조건으로 보내면 247명에게 가는구나”를 확인하고 나서 발송 버튼을 누르는 것과 막연하게 보내는 것은 심리적으로 완전히 다른 경험입니다.

발송 방식은 즉시 발송예약 발송 두 가지를 지원합니다. 예약 발송은 스케줄러가 매 분 예약 목록을 확인하여 지정 시각에 실행합니다. 예약된 알림은 발송 전까지 취소할 수 있고, 이미 발송된 알림은 SENT 상태로 고정됩니다. 알림 이력 목록에서 상태별 필터링이 가능하고, 발송 성공 수와 실패 수도 함께 표시해 발송 품질을 모니터링할 수 있습니다.

flowchart TD
    A["세그먼트 조건 설정"] --> B["성별 · 나이 · 구독 · 상태"]
    B --> C["대상 수 미리보기<br/>실시간 카운트"]
    C --> D{발송 방식}
    D -->|즉시 발송| E["Firebase Push 전송"]
    D -->|예약 발송| F["스케줄러 등록"]
    F --> G["매분 예약 목록 확인"]
    G --> E
    E --> H["발송 이력 기록<br/>성공/실패 수 추적"]

별도 포트(8081)로 분리한 이유

썸블링의 어드민 API는 메인 API(8080)와 별도 포트(8081)로 운영합니다. 이 결정에는 두 가지 이유가 있습니다.

보안이 첫 번째입니다. 어드민 포트는 외부 인터넷에 직접 노출하지 않고, VPN이나 내부 네트워크에서만 접근할 수 있도록 방화벽 규칙을 설정할 수 있습니다. 메인 API와 같은 포트를 쓰면 이런 분리가 어렵습니다.

독립 배포가 두 번째입니다. 어드민 기능을 업데이트할 때 메인 서비스를 재시작할 필요가 없습니다. 반대로 메인 서비스에 장애가 발생해도 어드민은 독립적으로 동작할 수 있어, 장애 상황에서도 운영 작업을 계속할 수 있습니다.

프론트엔드에서는 이 분리를 adminApi.ts라는 별도 클라이언트 파일로 구현했습니다. NEXT_PUBLIC_ADMIN_API_URL 환경 변수로 어드민 API 엔드포인트를 분리 관리하고, fetch 기반으로 JWT 인터셉터를 구현했습니다. 코드를 보면 주소만 다를 뿐 인증 구조는 메인 API 클라이언트와 동일합니다.


낙관적 업데이트: 빠른 응답 느낌 만들기

회원 상태 변경(ACTIVE → DORMANT)이나 신고 처리(REVIEWED/DISMISSED) 같은 액션은 서버 응답을 기다리면 약간의 딜레이가 느껴집니다. 특히 여러 건을 연속으로 처리할 때 이 딜레이가 쌓이면 답답합니다.

낙관적 업데이트는 서버 응답 전에 UI를 먼저 바꾸는 방식입니다. 회원 상태를 변경하면 즉시 드롭다운이 새 상태로 표시됩니다. 서버에서 성공 응답이 오면 그대로 유지되고, 실패하면 원래 상태로 롤백됩니다. 실패율이 낮은 내부 관리 도구에서는 낙관적 업데이트가 UX를 크게 개선합니다.

구현은 간단합니다. 상태 변수에 현재 값을 저장해두고, 액션 시 먼저 업데이트한 뒤 API를 호출합니다. 실패 시 저장해둔 원래 값으로 되돌립니다. 성공/실패 모두 간단한 토스트 메시지로 피드백을 줍니다.


페이지네이션 설계

어드민 테이블의 페이지네이션은 15건/페이지, 최대 5개의 페이지 버튼을 표시합니다. 이 숫자들도 의도적인 선택입니다.

15건은 대부분의 화면 해상도에서 스크롤 없이 한 화면에 보이는 양입니다. 너무 많으면 스크롤이 필요하고, 너무 적으면 페이지 전환이 잦아집니다. 5개 페이지 버튼은 현재 페이지를 중심으로 앞뒤 2페이지를 보여주는 방식입니다. 첫 페이지와 마지막 페이지 버튼은 항상 표시하고, 중간에 생략 부호(…)를 넣어 전체 맥락을 유지합니다.

페이지 버튼 외에 “전체 N건, 대기 N건” 같은 요약 정보를 상단에 표시했습니다. 특히 신고 관리에서 “대기 중인 신고가 몇 건 있는지”를 페이지 이동 없이 바로 파악할 수 있어야 운영 우선순위를 잡기 좋습니다.


다크 테마 어드민의 장점

썸블링의 메인 앱이 다크 테마이기 때문에 어드민도 자연스럽게 다크 테마를 선택했습니다. 결과적으로 장시간 사용하는 관리자 입장에서 눈의 피로가 적고, 데이터 테이블의 행 구분이 명확하다는 장점이 있었습니다.

Tailwind CSS의 다크 테마 구현은 bg-[#0F0E17], bg-[#232136] 같은 커스텀 색상을 직접 사용했습니다. 메인 앱과 동일한 디자인 토큰을 공유하기 때문에 일관성이 자연스럽게 유지됩니다. 테이블 헤더는 bg-[#1a1928], 행 호버는 hover:bg-[#2a2845]처럼 배경보다 약간 밝은 톤으로 레이어를 구분했습니다.


마치며

어드민 대시보드는 화려하지 않아도 됩니다. 하지만 빠르고, 명확하고, 실수를 막아주어야 합니다. 신고 건을 잘못 처리하거나, 의도하지 않은 회원에게 푸시 알림이 발송되는 사고는 서비스 신뢰를 직접 훼손합니다.

썸블링 어드민을 설계하면서 가장 신경 쓴 부분은 “확인”입니다. 대상 수 미리보기, 상태 변경 확인 토스트, 예약 취소 가능 시간 표시. 관리자가 액션 전에 충분한 정보를 확인할 수 있게 하면, 실수로 인한 운영 사고를 예방할 수 있습니다. 사용자 경험만큼이나 운영자 경험도 서비스의 질을 결정합니다.

댓글

GitHub 계정으로 로그인하여 댓글을 남길 수 있습니다. 허위사실, 욕설, 사칭 등의 댓글은 통보 없이 삭제될 수 있습니다.

블로그로 돌아가기