Back to Projects
logo

팔레트 (Palette)

2024.04 - 2024.11
thumb

뮤지션이 음악 서비스 판매자가 되어, MR/BEAT와 같은 음악을 업로드하여 판매하거나, 자신의 음악적 재능을 서비스화하여 판매할 수 있는 재능 거래 플랫폼 입니다.

Team & Role

FE 1명, BE 1명, 기획자 1명

Front-end

Tech Stack

CoreReactNext.js 14 (Page Router)TypeScriptTurborepo
StylingTailwindCSS
State ManagementTanstack-QueryZustand

참여 활동

  • 기획 단계에서 Admin/Client 디자인 시스템 통합을 위해 Turborepo를 활용한 MonoRepo 구성
  • axios interceptors를 활용한 유저 Refresh Token 인증 로직 구현 및 간편화
  • 사이트 내 전역적인 음악 재생을 위해 useContext를 활용한 음악 플레이어 개발
  • 검색엔진 최적화(SEO)를 위한 랜딩 페이지, 판매 상품 페이지 SSR, ISR 구성
  • 서버의 부하를 줄이며, 사용자의 대용량 파일 업로드를 보장하기 위한 AWS S3 멀티파일 업로드 구현
  • 사용 서비스 실시간 문의, 답변을 위해 socket.io-client를 활용한 채팅 UI 시스템 구현
  • 나이스페이먼츠 PG사 계약을 통한 결제 모듈 추가 (결제 요청 - 결제 - 결제 검증 단계 구현)
  • 빌드 환경 분리를 위한 웹서버(Vercel) 빌드 Shell 스크립트 작성
  • 개발 과정, QA, 코드 리뷰 시스템의 체계화를 위한 Google Sheets, Templates(Issue, PR) 문서 작성

성과

MAU

1.1천+

유저 350명+ 전환

거래 규모

800만+

거래 게시물 350건+

DB 확보

350GB

약 380곡, 뮤지션 250명 확보

Google CTR

43.0%

총 클릭 230+, 노출 520+

Naver CTR

38.2%

총 클릭 110+, 노출 290+

트러블 슈팅

# S3 - 클라이언트 멀티파트 업로드 구현

Problem

정식 출시 3일 전, 베타 서비스 운영 중 파일 업로드 API 호출 이후 서버가 다운되는 현상이 발견되었습니다. 예상한 크기보다 용량이 큰 파일이 업로드되어, 서버 인스턴스의 메모리 사용이 용량을 초과했기 때문입니다.

Solution

업로드 과정에서 서버의 리소스를 사용하는 것이 아닌 클라이언트의 리소스를 직접 사용하기 위해, 서비스의 저장공간인 AWS S3와 연결하였습니다. 해당 과정에서 AWS에서 권장하는 멀티파트 업로드(Multipart Upload) 방식을 도입하여 문제를 해결했습니다.

✨ 개선 결과

  • 클라이언트 직접 업로드 방식을 사용하여 서버 리소스 사용 비율을 극적으로 줄이고 기존보다 빠른 업로드 속도를 달성했습니다.
  • 멀티파트 업로드 구현 과정에서 진행 상황을 보여줄 수 있도록 Progress Bar를 추가하여 UI를 직관적으로 개선했습니다.
  • 테스트 과정에서 S3, CloudFront의 URL에 누구나 접근할 수 있던 취약점을 발견하고 권한을 수정하여 서비스 운영 안정성을 높였습니다.

Before

서버 메모리 초과 (다운)

After

서버 부하 0 (직접 업로드)

Learned
  • 처음으로 Next.js의 api 기능을 통해 간단한 서버 사이드 코드를 작성했으며, Next.js 백엔드를 활용할 수 있게 되었습니다.
  • 멀티파트 업로드의 원리와 방식에 대해 공부할 수 있었으며, 대용량 업로드의 에러 핸들링을 경험했습니다.
  • 실제 고객을 만나기 전에 리소스 사용에 대한 부분을 테스트하는 부분에 대해 관심을 가지고, 테스트 코드에 대해서 알아보게 되었습니다.
팔레트 서비스 업로드 에러 발생 당시 서버 모니터링 화면
고객에게 받은 업로드 파일이 서버 메모리를 초과하여 발생한 에러 상황
개선 이후 업로드 진행 상황을 보여주는 UI 화면
멀티파트 업로드 방식으로 개선된 업로드 진행 상황을 보여주는 UI 화면

# 자체 음악 플레이어 제작하기

Problem

음악 플레이어를 구축하며, 페이지 이동(라우팅)에 따라 컴포넌트가 마운트/언마운트되어 플레이어가 초기화되고 음악이 끊기는 문제에 직면하였습니다. 또한, 플레이어 외부의 특정 버튼으로도 플레이어에 이벤트를 전달할 수 있는 전역적인 구조가 필요했습니다.

Solution

useContext를 이용하여 전역적으로 이벤트와 상태를 공유하였으며, 이를 Custom Hook으로 감싸 플레이어의 이벤트와 상태 전달이 필요한 컴포넌트에서 플레이어와 연동하여 사용할 수 있도록 구조를 재설계했습니다.

✨ 개선 결과

  • App Component 최상단에 Provider를 위치시켜, 페이지 라우팅 시에도 끊기지 않고 백그라운드에서 재생되는 자체 플레이어를 구현했습니다.
  • 전역적으로 정보를 공유하여 개별 게시물 컴포넌트에서도 플레이어의 재생 여부 확인과 재생/정지 이벤트를 매끄럽게 제어할 수 있게 되었습니다.
  • 서버에서 받아오는 랜덤 플레이리스트 정보를 전역 상태 변수로 관리하여, 라우팅마다 발생하던 불필요한 서버 요청(API Call)을 대폭 줄였습니다.

Before

페이지 이동 시 음악 끊김

After

끊김 없는 백그라운드 재생

Learned
  • useContext와 Provider의 역할에 대해 깊게 고민해볼 수 있었으며, 실제 코드에 사용해보며 Context API를 완벽히 이해하고 적용할 수 있게 되었습니다.
  • 라이브러리 사용 과정에서 선정 기준과 기능에 대한 장·단점을 톺아보고 논리적인 선택을 가져갈 수 있었습니다.
  • 타 프로젝트(Youtube Music)를 통해 구현할 수 있는 한계점을 파악하고 원리를 찾아보는 과정을 체득하게 되었습니다. (새로고침 과정에서 플레이어가 유지될 수 없는 이유 등)
전역 상태 적용 전 플레이어 구조
라우팅 시 컴포넌트 초기화로 인해 음악이 끊기던 기존 구조의 문제점
개선된 전역 음악 플레이어 UI
useContext 기반의 전역 상태 관리로 페이지 이동 간에도 끊김 없이 재생되는 플레이어