바나나 B2B 리뉴얼

이커머스 SaaS 플랫폼으로 제작된 기존 B2B 사이트의 유지보수 및 관리가 어려운 점을 개선하기 위해 Next.js, TypeScript를 활용하여 리뉴얼을 진행하였습니다.

프로젝트 기간
사이트 링크
기여도프론트70%백엔드40%
사용 기술
TypeScript
TypeScript
Next.js
Next.js
Sass
Sass
Recoil
SWR
SWR
MariaDB
MariaDB
상세 내용

프로젝트 개요

이커머스 SaaS 플랫폼으로 제작된 기존 B2B 사이트는 유지보수 및 관리의 어려움이 있었습니다. 이를 개선하기 위해 Next.jsTypeScript 기반으로 전면 리뉴얼을 진행했으며, 프로젝트 초기 기획부터 구조 설계, 개발 전반을 주도적으로 참여했습니다.

프론트엔드뿐만 아니라 백엔드 개발에도 유연하게 참여하며 풀스택 개발자로서 프로젝트 진행 속도 향상에 기여했습니다.

주요 역할 및 기여

프로젝트 주도 및 풀스택 개발

  • 프론트엔드 외에도 백엔드 개발에 참여하며 프로젝트 진행 속도 향상에 기여
  • PG 결제 승인/취소/환불까지 포함한 결제 도메인 풀스택 구축 및 운영
  • 대량주문/바나나페이/주문관리/마이페이지 등 비즈니스 핵심 기능 구현

공통 라이브러리 구축 및 관리

  • UI 컴포넌트 및 유틸 함수를 공용 라이브러리로 구성
  • 디자인 시스템 기반으로 공통 Input/Button/Modal등 컴포넌트를 표준화하여 UI 일관성과 재사용성을 확보
  • Git Submodule로 관리하여 프로젝트 간 재사용성과 유지보수성 개선

사용자 경험 개선

  • CSS TransitionrequestAnimationFrame을 활용한 부드러운 UI 인터랙션 직접 구현
  • CSS 미디어 쿼리로 데스크톱/태블릿/모바일 반응형 UI를 구성해 다양한 환경에서 일관된 사용 경험 제공
  • 상품 상세 페이지 이미지 전환에 View Transition API를 적용해 전환을 자연스럽게 만들고, UI 인터랙션의 체감 품질을 개선

회원 유형별 UI 분기 및 접근 제어

  • 일반/판매자/관리자 유형에 따라 동일 페이지 내에서 다른 UI를 제공하도록 컴포넌트 분기 구조 설계
  • getServerSideProps를 통해 회원 유형과 권한을 확인해 접근 불가 시 리다이렉트되도록 처리
  • 가격 노출/마이페이지 메뉴처럼 역할에 따라 달라지는 로직은 컴포넌트 단위로 분리해 변경 사항이 생겨도 영향 범위를 최소화

기술적 도전 및 성과

1. 카테고리 API 로딩 속도 개선(3초대 → 1초대)

문제 상황

문제 상황 판매자가 상품을 등록할 때 선택할 수 있도록 다양한 카테고리를 미리 구성해두었고, 실제 상품이 등록된 카테고리만 노출되도록 구현했습니다. 하지만 상품 수가 증가하면서 카테고리 API 응답 시간이 점점 느려졌고(약 3초), 초기 화면 로딩에도 영향을 주기 시작했습니다.

기존 로직은 상위 카테고리부터 하위 카테고리를 재귀적으로 조회하는 구조였으며, 이 과정에서 함수 호출마다 DB 조회가 반복(N+1 형태) 되어 병목이 발생했습니다.

// 기존 코드 (재귀 호출로 DB 접근이 반복되는 구조)
const getCategoryChildren = (categoryId) => {
  // categoryId 하위 카테고리 중 상품이 등록된 항목만 DB 조회
  const children = [10, 12, ...] // DB로 조회된 카테고리 목록
 
  return children.map(child => ({
    ...child,
    children: getCategoryChildren(child.id),
  }))
}
 
const rootCategories = [1, 2, ...] // DB에서 루트 카테고리 호출
const allCategories = rootCategories.map(rootCategory => getCategoryChildren(rootCategory))

개선 방안

  • SQL 재귀 CTE(Recursive CTE) 를 활용해, 상품이 존재하는 카테고리를 한 번에 조회한 뒤 트리 구조로 재구성하도록 쿼리를 튜닝했습니다.
  • 조회 결과는 Recoil에 캐싱하여 카테고리가 필요한 화면에서 초기 로딩 시 재호출을 줄이고 즉시 렌더링될 수 있도록 구성했습니다.

성과

카테고리 API 응답 시간이 약 3초 → 약 1초로 개선되어, 카테고리 데이터가 필요한 주요 화면의 초기 로딩 체감 성능을 크게 향상시켰습니다.

2. 결제 시스템 구축 (PG 연동)

PG 연동을 통해 취소/교환/환불 플로우를 구현하고, 결과 반영은 DB 트랜잭션으로 처리해 주문·상품 데이터 정합성을 보장하였습니다.

프론트에서는 다양한 주문 상태를 정확하고 유지보수하기 쉽게 관리하기 위해, 주문/취소/교환/환불 상태에 따라 사용자가 수행할 수 있는 클레임 액션을 유형별 컴포넌트로 분리하고 enum 기반으로 상태별 가능 액션을 매핑해 버튼 노출을 관리했습니다.

환불 테스트 화면

3. 디자인 시스템 기반 공통 컴포넌트 제작

쇼핑몰/파트너/어드민 등 여러 서비스가 함께 운영되는 환경에서 UI 일관성과 개발 효율을 높이기 위해 Button, Input, Tooltip 등 반복적으로 사용하는 컴포넌트를 디자인 시스템 기준으로 표준화하여 공통 컴포넌트 라이브러리로 구축했습니다.

라이브러리는 Git submodule로 각 서비스에 연동해 동일 컴포넌트를 재사용 가능하게 했고, variant/size/color 등 확장 가능한 API로 설계하여 중복 코드를 줄이고 유지보수성과 UI 일관성 높이고자 하였습니다.

4. 바나나페이/엑셀 대량주문 등 비즈니스 핵심 기능 구현

💲 바나나페이 구현

바나나페이는 사용자가 가상계좌로 입금하여 쇼핑몰 내에서 포인트처럼 사용할 수 있는 충전 수단으로, PG사에 가상계좌 발급 요청(은행/금액 등 파라미터 전달)처리하고 발급 결과 및 처리 상태를 API를 통해 저장했습니다.

가상계좌 입금 결과를 PG사 웹훅으로 수신하면 충전 상태를 업데이트하고, 이후 주문 결제에서 사용할 수 잇도록 잔액/사용 가능 상태를 반영하였습니다.

바나나페이의 충전/사용 상태와 주문 내역 매핑 정합성을 확보하기 위해 기존 DB 스키마를 개선하고, 정확한 데이터 반영과 추적/재처리가 가능하도록 수정했습니다.

바나나페이 충전/인출/사용 전체 플로우를 풀스택으로 구현하고, 관리자가 어드민에서 사용자별 잔액 변동 이력과 상태(충전/사용/인출)를 추적할 수 있도록 관리 페이지를 구현하였습니다.

📂 엑셀 대량주문 기능 구현

엑셀 대량주문 기능은 사용자가 제공된 엑셀 양식에 맞춰 파일을 업로드하면, 서버에서 파일 내용을 파싱하여 유효한 포맷인지 확인하고 주문 가능 여부(상품 옵션 존재여부, 재고 확인)를 판단하여 1차 검증을 로직을 구현하였습니다.

검증을 통과한 데이터는 주문서 화면으로 전달하여 사용자가 최종 확인 후 주문을 확정할 수 있도록 했고, PG사를 통한 결제 처리까지 연동하여 대량주문 플로우를 풀스택으로 완성하였습니다.

검증 과정에서 오류가 발생한 경우, 사용자가 원인을 즉시 파악할 수 있도록 오류 정보를 화면에 표시하여 재업로드 비용을 줄이고 사용성을 개선하였습니다.

BNN B2B 대량주문 이미지

기술 스택

  • Frontend: Next.js, TypeScript, Sass, Recoil, SWR
  • Backend: MariaDB