방은수

1999.01.21

Introduce

안녕하세요. 만 27세 1년 10개월의 경력을 가진 프론트엔드 개발자 방은수입니다.

Typescript와 React, Next를 기반으로 개발을 하고 있습니다. 주요 업무는 디자이너로부터 화면 레이아웃을 받아 공용 컴포넌트 및 페이지를 설계하고 구현합니다. 또한 백엔드와의 API 연동을 통해 필요한 기능을 개발할 뿐만 아니라, 사용자 경험을 고려한 자연스러운 흐름과 성능 최적화까지 염두에 두며 개발을 진행하고 있습니다.

업무 중 발생하는 문제는 팀원들과의 원활한 커뮤니케이션으로 해결하고자 하며, 프로젝트의 완성도와 사용자 경험까지 고려한 방향으로 개선하고 있습니다.

서비스 구축에서 가장 중요한 것은 비즈니스와 개발자 간의 소통이라 생각합니다. 이를 위해 적극적으로 의견을 나누고, 피드백을 열린 자세로 수용하고 있습니다. 앞으로도 꾸준한 학습과 경험을 통해, 완벽한 프로덕트를 만드는 개발자가 되겠습니다.

Experience

(주)원더라운드

2025.04.14 ~ 현재

327일째 근무 중
1

직무 전환 - React Native (CLI) 기반 자사 모바일 애플리케이션 개발 및 유지보수

    2

    자사 여행 콘텐츠 예약 및 결제 플랫폼의 관리자 페이지 개발

    1. 상품 / 패키지의 생성 및 수정 폼 페이지 개발
      • tiptap 에디터와 react-hook-formFormField를 결합하여, 다국어별로 입력되는 제목과 설명, 이미지를 탭 형태로 구현하여 각 언어별로 개별 입력이 가능하도록 개발 (한국어, 영어, 일본어, 중국어 간체, 중국어 번체)

      • 날짜 기간별 데이터를 관리하는 폼을 구현하고, 특정 날짜 또는 공휴일을 선택해 일괄적으로 데이터를 수정할 수 있는 기능을 개발

      • zustand로 상품/패키지 폼 데이터를 관리하고 localStorage에 저장하여 페이지 이탈 후에도 복구가 가능한 임시저장 기능 개발. JSON 파싱을 Zod 스키마로 검증해 안정성을 높임

      • Problem

        react-hook-formuseFieldArray 로 관리되는 데이터에서, 서버에서 주는 데이터의 iduseFieldArray 자체 key인 id가의 충돌로 인해 기존 데이터와 새로 추가된 데이터가 구분되지 않아, 잘못된 데이터가 전달될 위험 발생

        Solution

        useFieldArraykeyName에 커스텀 ID를 부여해 데이터 기존 / 새 데이터를 명확히 구분하고, 사용자가 수정한 데이터를 정확하게 반영하도록 구현

      • Problem

        각각의 다국어 이미지 등록 시, 영어를 기준으로 이미지를 복사해 다른 언어의 이미지에도 업로드하도록 구현했으나, 동일한 이미지의 업로드 API 요청이 복사된 언어의 수만큼 중복 호출되는 문제가 발생

        Solution

        영어 버전 이미지의 ID를 다른 언어들과 공유하도록 구조를 변경하여, 동일 이미지의 중복 업로드 문제를 완화함. 또한 이미지를 교체할 때는 공유된 이미지 ID를 기준으로 연동된 모든 언어의 이미지가 함께 교체되도록 처리하여 일관성을 유지함

    2. i18next를 활용한 다국어 기능 개발 (영어, 중국어 간체 / 번체)
      • zod validation의 에러 메세지 + dayjs 시간 포메팅 표현을 다국어로 구현

      • Problem

        모든 번역 JSON 파일을 한 번에 번들링하면 초기 로딩 속도가 느려지는 성능 문제가 발생

        Solution

        resourcesToBackend를 활용해 필요한 언어와 namespace만 동적으로 import하는 lazy loading 방식으로 개선하여 로딩 성능 최적화

      • Problem

        zod의 refine 등을 활용한 커스텀 에러 메시지는 react 초기화 시점에 메시지 값이 고정되어 버리고, 언어를 변경해도 에러 메시지의 언어가 변경되지 않는 문제에 직면

        Solution

        검증 로직에서는 에러 메시지의 번역 키만 저장하고, 화면 렌더링 시점에 번역 로직을 적용하도록 개선하여, 언어 변경 시 기존 에러 메시지도 실시간으로 변경되도록 구현

    3. 예약 상세 내역 조회 페이지 개발
      • 환불할 금액을 퍼센트 단위로 선택해 부분 환불 또는 전체 환불이 가능한 폼 구현

    3

    Wix로 제작된 여행 플랫폼 웹사이트를 Next.js 환경으로 전환

    1. 데스크톱, 태블릿, 모바일 환경에 대응하는 반응형 디자인 구현
    2. Docker, ECR, GitHub Actions를 이용한 CI/CD 파이프라인 구축
    4

    자사 애플리케이션 관리자 페이지 시스템 고도화 및 유지보수

    1. 기존 관리자 페이지 기능 리뉴얼
      • 리스트 페이지에서 특정 아이템 선택 시, 이미지 및 종속 하위 데이터들을 포함한 값을 생성 폼에 사전 입력되게하는 복사 기능 개발

      • 중요 콘텐츠 수정 시, 각 필드의 변경 전후 값을 JSON 형태로 시각화하여 변경 이력을 추적하는 UI 구현

      • Toast UI EditorTiptap Editor로 교체, 에디터 내부의 이미지 업로드 로딩 및 업로드 중 삭제 처리 등의 기능 확장

      • react-easy-crop으로 이미지 편집(Crop/Zoom) UI를 구현

    2. 트레픽 / 유저 활동 / 콘텐츠 데이터를 활용한 대시보드 페이지 기획 및 구현
      • Recharts 라이브러리를 도입하여 라인 / 바 / 파이 차트 UI를 구현하고, 각 차트별로 레이블, 축, 툴팁 등을 커스터마이징하여 UI 구현

      • 각 연도의 월별 데이터를 집계하여 평균값으로 계산하고, 이를 차트에 시각화하여 한눈에 연간 추세와 월별 변화를 파악할 수 있도록 기능 구현

      • 기간을 선택하여 데이터를 조회할 시, 선택한 기간과 동일한 이전 기간 데이터를 비교하여 나타내는 기능 개발 (예: 최근 7일 vs 그 이전의 7일)

      • Problem

        7일 전 / 14일 전 등의 Select 박스를 통해 기간을 선택할 수 있도록 구현했지만, 매 선택 시마다 새로운 데이터를 호출을 위해 전체 화면이 다시 렌더링되는 UX 이슈 발생

        Solution

        Select 옵션에 대응하는 데이터셋을 사전에 prefetch하여, 선택 시 화면 전환 없이 즉각적으로 데이터를 교체할 수 있도록 구성해 UX를 개선

      • Problem

        원하는 날짜 기간을 선택하여 통계 데이터를 조회할 때, 의도하지 않은 다른 쿼리까지 함께 다시 호출되는 현상이 발생

        Solution

        고정된 데이터 쿼리와 기간별 통계 데이터를 분리시켜 정의함으로써 쿼리 단위로 명확하게 캐시를 구분. API 호출을 최소화하여 문제 보완

    3. vitest를 도입하여 관리자 페이지 전반적인 기능에 대한 TDD 테스트 코드 작성
      • Problem

        기존에 설계된 React Router 기반 컴포넌트들이 테스트 환경(Vitest + JSDOM)에서 정상적으로 화면이 렌더링되지 않거나 이동되지 않는 현상 발생

        Solution

        MemoryRouterTanstack Query Provider를 포함한 커스텀 렌더링 유틸을 구성. 중첩 라우팅과 라우팅 상태를 mock 방식으로 구성하여 테스트 환경을 실제 실행 환경과 유사하게 설계하여 문제를 해결

      • Problem

        Dropdown, ModalPortal을 사용하는 특정 컴포넌트들이 테스트 환경에서 트리거 요소의 클릭 이벤트를 감지하지 못하고, 실제 UI 흐름과 다른 방식으로 렌더링됨

        Solution

        테스트 환경의 화면 플로우를 실제 유저 처럼 매끄럽게 트리거하는 userEvent를 도입하여 해결

    Next

    한국글로벌널리지네트웍(주)

    2024.03.11 ~ 2025.03.21

    1년 10일 근무
    1

    기존 자사 플랫폼의 전용 관리자 사이트 개발

    1. 퀴즈에 필요한 문제 은행 관리 기능 개발
      • Problem

        보기 순서를 변경할 때, API 요청 시 각 보기의 ID가 필요했지만, 보기를 추가·수정·삭제하는 과정에서 새로운 보기와 기존 보기를 구분하기 어려운 문제에 직면

        Solution

        보기의 추가·수정·삭제 직후 문제 데이터를 최신 상태로 유지하기 위해 Tanstack QueryinvalidateQueries 기능을 활용하여 데이터를 자동으로 갱신. 이후, 최신 상태의 보기 데이터를 기반으로 정렬 후 보기 순서 변경 API를 요청하여 정확성을 보장

    2. 강의의 정보를 구성하는 챕터와 섹션, 섹션에 할당하는 vod, 퀴즈, 실습 등 컨텐츠 들의 관리 기능 개발
      • Problem

        실습, vod 등에 따라 요구되는 설정 값이 달라 일관된 폼을 제공하기 어려웠고, UI 복잡성이 증가하는 문제가 발생

        Solution

        각 컨텐츠 유형별로 독립적인 폼을 구성하고, 선택된 유형에 따라 동적으로 렌더링하도록 개선하여 UI 복잡성을 완화하고 사용성을 개선

    3. 출석부 달력 컴포넌트 & 선택한 연도, 월, 주차에 따른 출석 현황을 보여주는 기능 개발
      • 주간 / 월간별 보기 모드 구현

      • 사용자가 특정 연도, 월, 주차를 선택할 수 있는 팝업 컴포넌트 개발

    2

    외부 기업 전용 강의 수강 사이트 / 관리자 & 운영자 사이트 개발

    1. WebSocket을 활용하여 실시간 강의 중 강사와 수강생들의 즉각적인 상호작용이 가능한 돌발 퀴즈 기능 개발
      • Problem

        실시간 데이터 기반 차트가 매우 빠른 속도로 갱신되어 실제 데이터 값을 렌더링하지 못하는 문제 발생

        Solution

        결과 데이터 상태 값에 throttle을 적용하여 불필요한 업데이트를 줄이고, 데이터 유실없이 안정적으로 렌더링되도록 개선. 1000ms당 최대 n회 (실시간 미팅에 접속 중인 인원 수, 약 1500명) --> throttle 적용 후 50ms 당 한번씩 결과를 적용토록 함, 이후 cpu 사용률 20%감소

      • Problem

        돌발퀴즈 바로 시작 직전에 네트워크가 끊겼다가 다시 연결되면, 방금 진행한 돌발퀴즈가 뜨지 않는 문제에 직면

        Solution

        재연결 로직을 추가. 기존 웹소켓 핑퐁의 count 값을 비교하고, 개수가 다른체 웹소켓이 연결이 되었으면 재연결이라고 판단. 이후 진행중인 돌발퀴즈를 다시 불러오도록 api를 호출하여 문제 해결

      • Problem

        다수의 유저가 동시에 재연결 시도할 경우, 서버 부하가 발생할 가능성이 있음

        Solution

        재연결 시도에 지수 백오프를 적용하고, 약간의 오차를 주는 랜덤성을 추가하여 동시에 발생하는 요청을 분산시켜 서버 부하를 최소화. n 동시 재연결 요청 수 최대 n회 (실시간 미팅에 접속 중인 인원 수, 약 1500명) -> 최대 동시 재연결 요청 수 약 1/10 으로 감소

      • 실시간 데이터 처리는 단순히 기술 도입뿐만 아니라, 서버 부하와 안정성을 고려해야 한다는 점을 배움. 특히, 네트워크 상태가 좋지 않은 환경에서도 안정적으로 메시지를 주고받을 수 있도록 재연결 및 오류 처리 로직을 구현하는 것이 중요함을 깨달음

    2. 관리자와 운영자의 역할에 맞는 기능 및 권한을 구분한 UI 설계
      • Problem

        특정 권한이 필요한 url에 접근할 때, 접근 전 사용자의 권한을 확인하는 미들웨어를 React Router Domloader를 이용해 구현했는데, 사용자 정보가 로드되기 전에 실행이 완료되는 문제가 있었음

        Solution

        권한이 필요한 페이지에 접근할 때 인증된 사용자인지 먼저 확인하는 미들웨어를 React Router DomMaps를 이용해 직접 구현. 이후 권한이 허용되면 페이지로 이동하고, 아닐 경우 접근을 차단하도록 처리

    3

    기존 플랫폼의 고도화 및 유지보수

    1. 무한 스크롤 / Drag & Drop 이 가능한 테이블 컴포넌트 개발
      • Problem

        무한 스크롤에서 각 row 높이의 측정값이 일정하지 않아 가상화된 테이블에서 스크롤 시 데이터가 보이지 않거나 UI가 밀리는 문제 발생

        Solution

        초기 row 높이를 추정하는 estimateSize 값을 설정하고, 이후 실제 렌더링된 row의 높이를 측정하여 동적으로 업데이트하여 문제 해결

    2. 강의별 학습 진행 상태와 성과를 시각화하여 분석할 수 있는 관리자 페이지 개발
      • 단순히 그래프를 추가하는 것뿐만 아니라, 다양한 데이터 종류에 따라 UX 설계가 달라져야 함을 깨달음

    4

    코딩테스트 전용 플랫폼 개발

    1. `React-Code Mirror`를 커스터마이징하여 문제풀이가 가능한 코딩 에디터 개발
      • 라이브러리에 기본적으로 존재하는 class를 활용하여 css 스타일을 커스터마이징하고, 다크모드에서도 사용할 수 있도록 테마를 구성

      • 코드의 line이 folding (접히는) 상태이거나, 커스텀 placeholder 스타일을 적용해야 하는 경우, css 가상 요소를 활용해 다양한 요구사항에서도 디자인 구현

      • 테블릿 환경에서도 원할하게 사용할 수 있도록 flexgrid 의 관련된 속성들을 조합하여 반응형 디자인 적용

    2. 유저가 직접 코딩 테스트 문제를 풀고, 답안을 제출 하여 정답 여부 결과를 확인할 수 있는 UI 및 기능 개발
      • Problem

        유저가 작성한 코드를 지속적으로 저장하도록 zustand의 persist (localStorage) 활용했으나, 문제와 언어별로 데이터가 많아질수록 관리가 어려워짐

        Solution

        문제의 id를 객체의 key로 두고, 언어별로 중첩하여 유저 코드를 JSON 문자열로 저장, 저장 공간 최소화를 위해 최신 10개의 문제만 유지하도록 구현

      • Problem

        제출한 문제의 채점 시간이 길어져 UX가 저하되는 문제 발생

        Solution

        대기 시간 동안 스켈레톤 UI를 보여주어 사용자가 대기 중임을 인지할 수 있도록 개선

    3. 유저가 자유롭게 관리할 수 있는 커스텀 테스트 케이스 기능 개발
      • Problem

        사용자가 입력한 테스트 케이스가 문제에서 지정한 데이터 타입(int, float, boolean, 이중 배열 등)과 일치하지 않거나, JSON 형식에서 올바르지 않은 따옴표를 사용하여 실행 중 오류가 발생하는 문제 발생

        Solution

        입력값을 사전에 검증하는 유효성 검사 로직을 적용하여 문제에서 지정한 데이터 타입과 일치하는지 확인하고, JSON 문자열 입력 시 싱글 따옴표가 포함된 경우 경고 메시지를 띄운 후 입력을 거부하도록 처리. 이를 통해 입력 단계에서 오류를 방지하고, 실행 중 예기치 않은 데이터 타입 오류를 최소화

    4. React Hook Form과 Zod를 활용해 문제를 관리하는 관리자 페이지 개발
      • Problem

        문제의 상세 내용 / 언어 선택 및 메모리 제한과 시간 제한 선택 / 기본 테스트 케이스를 하나의 폼으로 구성해야하다 보니 UI가 복잡해지고 유지보수가 어려웠음

        Solution

        관련 항목을 3가지 주요 탭으로 나누고, 각 탭 이동시 유효성 검사를 사전에 실행하도록 개선. 유효성 검사 로직은 전역 스토어에서 관리하며, 각 탭이 마운트될 때 해당 탭의 검증 함수를 설정하여 일관된 로직을 유지

    5

    타사의 소개 및 지원서 사이트 개발

    1. 타사의 특장점을 소개하는 정적 페이지 제작
    2. 컴포넌트의 네임스페이스 패턴을 기반으로 만든 form을 통해 지원서 양식 개발
    6

    LMS 개발

    1. 프로젝트 설계, 공통 레이아웃과 컴포넌트 구조화, 기능 모듈화
      • Problem

        이전 프로젝트는 기능을 단위별로 유지보수하기 어려워 확장성에 문제가 있다는 피드백을 받음

        Solution

        효율적으로 컴포넌트와 기능을 모듈화하는 FSD 폴더 구조를 채택하여 개발. 기능의 한 단위를 "entity" 로 정의하고 api, schema, type, global state 를 통합 관리하여 확장성을 향상 시킴

    2. 시험 평가 & 과제 제출 & 설문 조사 & 마이페이지 등 주요 기능 개발
      • Problem

        문제를 풀때, "제출하기" 버튼 하나로 답안지 생성과 선택한 문제 체크까지 api전송을 한번에 하면 비효율적이었으며, 시험 도중 네트워크가 끊기면 데이터가 유실되는 문제가 발생

        Solution

        시험 페이지 입장 시 미리 사용자의 답안지를 생성하는 api를 전송하도록 하고, 사용자가 답안을 체크할 때마다 서버에 PATCH 요청을 보내 시험 진행 상황을 실시간으로 저장하도록 개선. 시험 진행 도중 데이터 유실률 약 50건 중 10건 --> 0건으로 감소

      • 단순히 사용자가 입력한 데이터를 전송하는 데 그치는 것이 아니라, 안정적으로 저장하고 복구할 수 있는 UX를 고민하는 것이 중요함을 배움

    7

    온라인 IT 교육 사이트 자사 플랫폼 개발

    1. 프로젝트 설계, 공통 레이아웃과 컴포넌트 구조화
    2. 강의 리스트, 마이페이지, QnA 게시판, 퀴즈 페이지 개발
    3. 토스 페이먼츠와 연동한 결제 기능 도입
    4. tiptap 라이브러리를 활용하여 텍스트 에디터 커스터마이징
      • Problem

        댓글 창의 애니메이션을 구현하기 위해 도입한 Framer Motion 라이브러리에서, 애니메이션을 적용한 요소가 다른 UI 요소와 겹치면서 의도하지 않은 레이아웃 변경이 발생

        Solution

        애니메이션의 상태를 컴포넌트의 key에 주입하거나, AnimatePresence로 컴포넌트를 감싸 레이아웃 변경을 감지하여 해결

    5. Front End 테스트를 위한 jest 도입, 페이지 단위로 테스트 코드 작성

    Skills

    Languages

    • - JavaScript (ES6+)
    • - TypeScript
    • - HTML5 / CSS3
    • - Java
    • - C#

    Libraries & Frameworks

    • - React.js (vite)
    • - Next.js
    • - React Native (CLI)
    • - Tailwind CSS
    • - Tanstack Query
    • - Zustand
    • - Recoil
    • - Shadcn
    • - Express

    Backend

    • - Prisma
    • - Drizzle
    • - Neon
    • - Supabase
    • - Vercel
    • - Docker
    • - GitHub Actions
    • - EC2
    • - S3

    Tools

    • - Git & GitHub
    • - Jira
    • - Notion
    • - Figma
    • - Slack

    Portfolio

    Bread And Source

    Next.jsTypeScriptTailwind CSSNeonDrizzleZustandTanstack QueryFramer motion

    Eunsutory

    Next.jsTypeScriptTailwind CSSPrisma

    Scrama

    Next.jsTypeScriptTailwind CSSCheerio

    Wasd Rental System

    React.jsTypeScriptExpress.jsTailwind CSSZustandTanstack Query

    Eunimation

    Next.jsTypeScriptTailwind CSSFramer MotionZustand

    Eunsuread

    Next.jsTypeScriptTailwind CSSClerkMongoose

    Education

    2022.03.02 ~ 2024.02.28

    명지전문대학교 소프트웨어 콘텐츠학과

    • 학점 4.26 졸업
    • 웹 개발 동아리 운영 (부장) 및 프로젝트 개발 주도 (2022.06 ~ 2024.02)
    • 기자재 대여 시스템 사이트 / 주변 맛집 등 명소를 찾는 사이트 / 2D 로그라이크 앱 게임 등 개발

    Certification

    • 정보처리산업기사
    • 컴퓨터 활용능력 1급
    • 워드프로세서
    • TOEIC (815점) (2023.07.19 취득)