[CRM 개발일지 #4] 상담사 고객 관리와 관리자 대시보드 UI 구축

2026. 5. 10. 22:48·SpringBoot
728x90

🚀 TODAY WORK

백엔드

  • 상담사 고객 목록 API 구조 설계
  • 상담사 전용 Controller 생성
  • 상담사 고객 조회 DTO 생성
  • 로그인 상담사 기준 고객 조회 로직 설계
  • Spring Security Authentication 구조 이해 및 적용
  • JWT 기반 로그인 사용자 조회 흐름 정리
  • 담당 상담사 기준 고객 필터링 구조 설계
  • CUSTOMER_STATUS 상태 변경 API 구조 검토

프론트엔드

  • 상담사 전용 레이아웃(/consultant) 구성
  • 상담사 권한 접근 제어 적용
  • 상담사 사이드바 메뉴 구성
  • 상담사 고객 목록 페이지 생성
  • 상담사 고객 목록 API 연동
  • 로그인 상담사 기준 고객 조회 구현
  • 고객 상태 변경 Select UI 추가
  • 고객 상태 저장 버튼 UI 추가
  • 상담사 대시보드 UI 구성
  • 관리자 대시보드 UI 구성
  • 로그인 페이지 UI 리디자인
  • 공통 Dashboard/Card/Table 스타일 작업
  • CSS Module 구조 적용

🚨 TODAY ISSUE

상담사 전용 고객 조회 구조 분리

관리자 고객 조회는 전체 고객 기준이었지만,
상담사 화면은 로그인 상담사 기준으로만 고객 조회가 필요했다.

기존 구조:

관리자 → 전체 고객 조회

변경 구조:

상담사 → 본인 담당 고객만 조회

JWT 인증 기반으로 로그인 사용자를 가져와 담당 상담사 기준 조회 구조로 변경했다.

 

1-1) Controller - 로그인 상담사 정보 조회

JWT 인증 정보를 기반으로 현재 로그인한 상담사 이메일을 가져온 뒤,
해당 사용자 ID 기준으로 담당 고객 목록 조회를 요청했다.

@GetMapping
public ApiResponse<List<ConsultantCustomerResponseDto>> getCustomers(
        Authentication authentication
) {
    String email = (String) authentication.getPrincipal();

    User user = userRepository.findByEmail(email)
            .orElseThrow(() -> new RuntimeException("User not found"));

    return ApiResponse.success(
            customerService.getConsultantCustomers(user.getUserId())
    );
}

 

1-2) Service - 상담사 담당 고객 DTO 변환

상담사 ID 기준 고객 목록을 조회한 뒤,
프론트에서 사용할 DTO 형태로 데이터를 변환했다.

public List<ConsultantCustomerResponseDto> getConsultantCustomers(Long userId) {
    return customerRepository.findByCounselor_UserId(userId)
            .stream()
            .map(customer -> ConsultantCustomerResponseDto.builder()
                    .customerId(customer.getCustomerId())
                    .name(customer.getName())
                    .phone(customer.getPhone())
                    .interestCourse(customer.getInterestCourse())
                    .status(customer.getStatus())
                    .customerTag(customer.getCustomerTag())
                    .leadSource(customer.getLeadSource())
                    .lastActivityAt(customer.getLastActivityAt())
                    .build())
            .toList();
}

 

1-3) Repository - 담당 상담사 기준 조회

JPA 메서드 네이밍 기반으로
상담사 ID = 로그인 사용자 ID 조건 조회를 구성했다.

List<Customer> findByCounselor_UserId(Long userId);

Spring Security Authentication 이해

처음에는 Authentication 객체와 CustomPrincipal 구조 이해가 어려웠다.

정리한 핵심 흐름:

로그인
→ JWT 인증 성공
→ Spring Security Context 저장
→ Authentication 에 현재 로그인 사용자 보관
→ Controller 에서 사용자 정보 조회

현재 로그인 사용자 기준 데이터 조회 흐름을 이해했다.

@GetMapping("/me")
public Map<String, Object> me(Authentication authentication) {
    String email = (String) authentication.getPrincipal();

    User user = userRepository.findByEmail(email)
            .orElseThrow(() -> new RuntimeException("User not found"));

    String role = authentication.getAuthorities()
            .stream()
            .findFirst()
            .map(GrantedAuthority::getAuthority)
            .orElse("ROLE_USER");

    return Map.of(
            "email", user.getEmail(),
            "name", user.getName(),
            "role", role
    );
}

핵심은 Authentication이 직접 만든 클래스가 아니라, Spring Security가

현재 로그인 사용자 정보를 담아서 Controller에 넘겨주는 객체라는 점이었다.


Dashboard UI 공통 스타일 정리

상담사/관리자 대시보드 디자인 계열을 통일했다.

  • Sidebar 구조 정리
  • Stats Card UI 구성
  • Dashboard Layout 정리
  • 공통 Table 스타일 구성
  • 버튼/Badge 스타일 통일

✨ TODAY RESULT

상담사 고객 목록

  • 고객 상태 Select UI
  • 상태 저장 버튼
  • 공통 테이블 스타일
  • 상담사 전용 조회 구조
@GetMapping
public ApiResponse<List<ConsultantCustomerResponseDto>> getCustomers(
        Authentication authentication
) {

    String email =
            (String) authentication.getPrincipal();

    User user =
            userRepository.findByEmail(email)
                    .orElseThrow(() ->
                            new RuntimeException("User not found"));

    return ApiResponse.success(
            customerService.getConsultantCustomers(
                    user.getUserId()
            )
    );
}

상담사 대시보드

  • 담당 고객 현황 카드 UI 완료.
  • 최근 상담 고객 테이블
  • 고객 목록 이동 버튼
<div className={styles.statsGrid}>
  <div
    className={`${styles.statsCard} ${styles.activeCard}`}
  >
    <div className={styles.statsTop}>
      <span className={styles.statsLabel}>
        전체 담당 고객
      </span>

      <span className={styles.statsIcon}>
        👥
      </span>
    </div>

    <h2 className={styles.statsValue}>
      24
    </h2>
  </div>
</div>

관리자 대시보드

  • 운영 현황 카드 UI 완료
  • 사용자/고객 관리 진입 영역
  • Dashboard 레이아웃
<div className={styles.statsCard}>
  <div className={styles.statsTop}>
    <span className={styles.statsLabel}>
      활성 상담사 수
    </span>

    <span className={styles.statsIcon}>
      👨‍💼
    </span>
  </div>

  <h2 className={styles.statsValue}>
    12
  </h2>
</div>

 


로그인 페이지

기존 단순 로그인 화면에서 적용해 CRM 스타일 로그인 화면으로 개선했다.

Card UI
Input Focus
에러 박스
Button Hover

🔥 NEXT TODO

  • 고객 상태 변경 PATCH API 연결
  • 상태 저장 기능 연동
  • 상담 기록 상세보기 페이지
  • 고객 상세 페이지(/customers/[id])
  • Dashboard 통계 API 연결
  • Dashboard 카드 실데이터 연동
  • 공통 Modal 컴포넌트 작업
  • 공통 Table 컴포넌트 분리 검토
728x90

'SpringBoot' 카테고리의 다른 글

[CRM 개발일지 #6] 상담 신청 기능 구현 (고객 생성, ActivityLog 자동 저장)  (0) 2026.05.12
[CRM 개발일지 #5] 상담 신청 기능 구조 설계  (0) 2026.05.11
[CRM 개발일지 #3] 관리자 고객 관리 API 연동 작업  (0) 2026.05.08
[CRM 개발일지 #2] 공통 코드 상태 관리 구조 개선 + Zustand 적용  (0) 2026.05.07
[CRM 개발일지 #1] 관리자 사용자 API 연결 및 응답 구조 개선  (0) 2026.05.06
'SpringBoot' 카테고리의 다른 글
  • [CRM 개발일지 #6] 상담 신청 기능 구현 (고객 생성, ActivityLog 자동 저장)
  • [CRM 개발일지 #5] 상담 신청 기능 구조 설계
  • [CRM 개발일지 #3] 관리자 고객 관리 API 연동 작업
  • [CRM 개발일지 #2] 공통 코드 상태 관리 구조 개선 + Zustand 적용
PUSH → MERGE → DEPLOY
PUSH → MERGE → DEPLOY
데이터 흐름과 운영 자동화를 설계하는 백엔드 개발자
  • PUSH → MERGE → DEPLOY
    Coding Dongin
    PUSH → MERGE → DEPLOY
  • 전체
    오늘
    어제
    • MEUN
      • 코테(Solved.ac + Programmers)
      • BootCamp(JAVA)
      • JAVA
      • SpringBoot
      • JavaScript
      • JSP
      • DB(SQL)
      • React
      • HTML_CSS
      • jQuery
      • SCSS
      • GSAP
      • 설치 + 꿀팁
      • 정보처리기사 오답노트
      • 정보처리기사 기출문제
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GIT
  • 공지사항

  • 인기 글

  • 태그

    자료구조
    브루트포스
    정렬
    구현
    java
    정보처리기사
    기출문제
    코딩테스트
    배열
    dp
    level1
    Level2
    수학
    level0
    실기
    정처기오답노트
    완전탐색
    알고리즘
    자바
    정처기
    solved.ac
    백준
    정처기실기
    정보처리기사 실기 기출문제
    시뮬레이션
    피보나치
    백엔드개발자
    springboot
    프로그래머스
    문자열
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.4
PUSH → MERGE → DEPLOY
[CRM 개발일지 #4] 상담사 고객 관리와 관리자 대시보드 UI 구축
상단으로

티스토리툴바