Limsh.io

뱅크셀러드 인턴 회고


프로젝트 개요

배경

3년 전, BPL(Banksalad Product Library)이라는 디자인 시스템을 구축했지만, 시간이 지나며 재사용성과 유연성의 한계가 드러났습니다. 이에 BDS(Banksalad Design System)를 새롭게 개발했지만, 이미 전체 웹 프로젝트에 깊숙이 자리잡은 BPL 의존성으로 인해 마이그레이션이 쉽지 않았습니다. BPL은 웹팀의 모든 스택과 강하게 결합되어 있어, 변경 시 많은 시간과 리소스가 필요한 대표적인 기술 부채가 되었습니다.

목표

전체 코드베이스에서 BPL을 제거하고 BDS로 완전히 전환하는 것이 최종 목표였습니다. 이론적으로는 충분한 시간만 주어진다면 혼자서도 해낼 수 있는 작업이지만, 현실적으로 많은 시간을 투자할 수는 없었습니다. 저희 팀은 체계적인 계획과 효율적인 협업을 통해 약 3개월 만에 마이그레이션을 완료하며, 불가능해 보이던 작업도 올바른 접근 방식으로 해결할 수 있음을 증명했습니다.

기간

2024년 07월 28일 ~ 2025년 10월 27일 (3개월)

참여 인원

인턴 2명


주요 성과

1. 체계적인 점진적 마이그레이션 전략

단순히 코드를 옮기는 것이 아니라, 체계적이고 점진적인 프로세스를 수립했습니다. 3개월간의 마이그레이션은 크게 4단계로 나누어 진행되었습니다.

1단계: 초기 분석 및 도구 구축 (Week 1-2)

As-is:

  • 수작업으로 BPL 사용 현황을 파악하려니 며칠이 소요됨
  • 어떤 컴포넌트부터 마이그레이션해야 할지 불명확
  • 팀원마다 다른 방식으로 작업하여 일관성 부족

To-be:

  • find-bpl-web-simple.js 스크립트로 전체 사용 현황을 몇 초 만에 분석
  • 사용량 데이터 기반으로 우선순위 선정 (Button 87회, Modal 45회 등)
  • 표준화된 마이그레이션 가이드 문서 작성 (@bpl-web-to-bds-migration-mapping.md)
  • 자동화 도구로 반복 작업 최소화

find-bpl-web-simple.js 실행 결과

2단계: 기반 인프라 구축 (Week 3-5)

As-is:

  • 각 컴포넌트가 독립적으로 존재하여 중복 코드 발생
  • 모달/오버레이 관리 로직이 앱마다 다르게 구현됨
  • 백버튼 처리가 일관되지 않아 사용자 경험 저하

To-be:

  • overlay-kit 도입으로 모달/오버레이 통합 관리 시스템 구축
  • RootWithOverlayKit 컴포넌트로 앱 전체에서 일관된 오버레이 경험 제공
  • 백버튼 프로바이더 통합 인터페이스로 표준화된 네비게이션 구현
  • POC 테스트 페이지로 Edge Case 검증 환경 마련

3단계: 대량 마이그레이션 실행 (Week 6-10)

As-is:

  • 800+ 곳에서 사용되는 BPL 컴포넌트들
  • 레거시 코드와 새 코드가 혼재하여 유지보수 어려움
  • 마이그레이션 진행 상황을 파악하기 어려움

To-be:

  • 기본 컴포넌트부터 체계적으로 전환 (Button → Divider → SpacingHeight)
  • Modal/Dialog → overlay-kit 기반 BDS Modal로 전환
  • Toast → BDS BottomSnackbar로 일관되게 교체
  • 주간 진행률 리포트로 투명한 상황 공유 (예: "진행률 51%, 422회 남음")
  • 도메인별 PR 분리로 명확한 책임 소재 확립

4단계: 정리 및 최적화 (Week 11-12)

As-is:

  • 마이그레이션은 끝났지만 레거시 Provider와 코드가 남아있음
  • 불필요한 의존성이 여전히 프로젝트에 포함됨
  • 일부 deprecated 페이지도 마이그레이션되어 낭비 발생
  • 의존 관계가 있는 PR들이 인턴 기간 내에 모두 머지되지 못함

To-be:

  • 완료된 작업:

    • Deprecated 페이지 식별 및 마이그레이션 대상에서 제외 (약 40+ 페이지 작업 절감)
    • 주요 BPL 컴포넌트 마이그레이션 완료 (Button, Modal, Toast 등)
    • 최종 버그 수정 및 스타일 통일
  • 문서화하여 인계한 작업:

    • BPL 전역 Provider 제거: 의존 관계가 있는 여러 PR이 아직 리뷰/머지 대기 중
    • 레거시 react-query 계층 마이그레이션: 전체 앱에 영향을 주는 작업으로 추가 검증 필요
    • 최종 의존성 완전 제거: 일부 PR이 블로킹 상태로 인턴 기간 내 머지 불가
  • 인계 문서 작성:

    • 남은 작업 목록과 각 작업의 의존 관계 명시
    • 머지 대기 중인 PR 목록 및 우선순위 정리
    • 주의사항 및 테스트 체크리스트 작성
    • 후속 담당자가 바로 이어서 작업할 수 있도록 상세 가이드 제공

인계 문서 - 후속 담당자가 바로 작업을 이어갈 수 있도록 상세 가이드 작성 인계 문서 - 후속 담당자가 바로 작업을 이어갈 수 있도록 상세 가이드 작성

학습 포인트:

인턴 기간이라는 시간 제약 내에서 모든 것을 완료하는 것보다, 완료된 부분과 미완료된 부분을 명확히 구분하고 체계적으로 문서화하는 것이 중요함을 배웠습니다. 특히 의존 관계가 복잡한 대규모 마이그레이션에서는 작업을 명확히 정리하고 인계하는 것도 프로젝트의 중요한 일부입니다.

핵심 전략:

이러한 단계별 접근의 핵심은 **"점진적 개선"**이었습니다:

  1. 데이터 기반 의사결정: 직관이 아닌 실제 사용량 분석으로 우선순위 결정
  2. 인프라 우선 구축: 개별 컴포넌트 마이그레이션 전에 탄탄한 기반 마련
  3. 투명한 진행 상황 공유: 주간 메트릭으로 팀 동기부여 및 병목 조기 발견
  4. 철저한 정리: 마이그레이션만 하고 끝이 아니라 레거시 완전 제거

덕분에 대규모 마이그레이션을 안전하고 효율적으로 완료할 수 있었습니다.

2. 자동화 도구 개발을 통한 생산성 혁신

find-bpl-web-simple.js 스크립트 개발

며칠이 걸릴 수 있는 수동 분석 작업을 몇 초 만에 완료할 수 있는 자동화 스크립트를 개발했습니다.

주요 기능:

  • 전체 프로젝트의 BPL 사용 현황을 자동으로 분석
  • 도메인별 컴포넌트 간 복잡한 의존성을 시각적으로 파악
  • fzf 인터랙티브 메뉴를 통한 직관적인 사용자 경험

성과:

  • 팀원들이 zshrc에 bpl 명령어로 등록하여 일상적으로 활용
  • 범용성을 인정받아 ts-util로 분리하여 회사 전체에서 사용 가능하도록 확장
  • 제가 만든 도구가 팀을 넘어 회사 전역으로 확산되는 경험

전역 도구 확산

학습 포인트: 점진적 개선과 추상화

처음에는 개인적으로 사용하던 스크립트가 팀에 유용하다는 피드백을 받고, 점진적으로 개선하여 범용적인 도구로 발전시켰습니다. 특정 use case에서 시작하여 추상화를 통해 보편적으로 사용 가능한 도구로 확장하는 과정을 경험했습니다.

3. 데이터 기반 역할 분담과 병렬 작업

분석 데이터를 기반으로 각 팀원의 강점과 현재 작업 부하를 고려하여 역할을 분배했습니다. 명확한 계획이 있었기에 팀원 모두가 공통된 목표를 향해 효율적으로 나아갈 수 있었고, 예상보다 훨씬 빠르게 프로젝트를 완료할 수 있었습니다.

핵심 전략:

  • 작업과 머지/배포를 분리하여 개발자가 작업에만 집중할 수 있도록 독립
  • 도메인별로 작업을 나누어 병목 현상 방지
  • 정기적인 진행률 공유로 투명성 확보

4. 테스트 가능한 환경 구축: POC 페이지 도입

As-is:

  • 특정 조건(본인인증, 서버 데이터 등)이 충족되어야만 테스트 가능
  • Edge case를 재현하기 위해 복잡한 사용자 플로우를 매번 반복
  • 리뷰어가 실제 동작을 확인하기 어려움

To-be:

  • POC(Proof of Concept) 테스트 페이지 도입
  • 모든 edge case 모달을 버튼 클릭 한 번으로 테스트 가능
  • 깃 브랜치로 재현 가능성을 확보하여 리뷰어도 쉽게 확인

POC 테스트 페이지

학습 포인트: Testable한 환경의 중요성

단순히 테스트 코드를 작성하는 것만이 좋은 테스트가 아닙니다. 개발자와 리뷰어가 실제 화면을 쉽게 확인할 수 있는 환경을 만드는 것이 훨씬 더 실용적이고 효과적인 테스트 전략임을 배웠습니다.

5. 주도적인 문제 제기와 해결

이슈 사례 1: Deprecated 페이지 마이그레이션 방지

문제 상황:

  • 프로젝트 초기에 deprecated되거나 삭제 예정인 페이지까지 마이그레이션하는 불필요한 리소스 낭비 발생

주도적 해결:

  • 작업 중 의문을 가지고 TL에게 해당 페이지의 현재 상태 확인
  • 이슈를 제기하여 마이그레이션 대상 목록 재검토
  • 불필요한 작업 40+ 페이지 제외, 약 1주일 분량의 시간 절약

Slack에서 deprecated 페이지 이슈 제기 - 팀 논의를 통해 40+ 페이지 작업 절감

학습 포인트:

  • 주어진 작업을 맹목적으로 수행하기보다 "왜"를 질문하는 태도의 중요성
  • 비동기 커뮤니케이션(Slack, 이슈 트래커)을 통한 효율적인 문제 제기

이슈 사례 2: BDS Badge 컴포넌트 버그 발견 및 수정

마이그레이션 중 BDS Badge 컴포넌트의 defaultVariants 버그를 발견하고, Slack #chapter-web-migration 채널에 즉시 공유했습니다. 팀원들의 승인을 받아 빠르게 디자인 시스템 자체를 개선하며 문제를 해결했습니다.

BDS Badge 컴포넌트 defaultVariants 버그 수정 PR - 팀 협업으로 디자인 시스템 개선

학습 포인트:

  • 혼자 고민하지 않고 팀과 소통하는 것이 더 효율적
  • 적극적인 지식 공유로 다양한 관점의 피드백 획득

6. 투명한 메트릭 공유로 팀 동기부여

Slack과 Jira에 작업 내용을 꾸준히 기록하고, 주간 보고를 통해 구체적인 수치를 공유했습니다.

공유 예시:

  • "총 남은 사용 횟수 422회, 진행률 51%"
  • "이번 주 완료: Button 87회, Modal 45회"

팀원들의 동기부여와 집중도가 높아지고, 프로젝트 진행 상황을 투명하게 파악할 수 있었습니다.


기술적 도전과 학습

1. 3개월간의 성장: 워크플로우 이해에서 주도적 개선까지

1개월차: 워크플로우 학습

  • 하나의 완전한 워크플로우를 처음부터 끝까지 경험
  • Button 컴포넌트 마이그레이션을 통해 전체 프로세스 이해
  • 코드 변경 → PR 생성 → 리뷰 → 배포의 전체 사이클 체득

2개월차: 점진적 컨텍스트 확장

  • 다양한 컴포넌트(Modal, Form, Input 등)로 작업 범위 확대
  • 컴포넌트 간 의존성과 전역 상태 관리 이해
  • 팀 내 코딩 컨벤션과 리뷰 프로세스 숙지

3개월차: 주도적 문제 해결자

  • 스스로 이슈를 발견하고 해결 방안 제시
  • 자동화 도구 개발로 팀 생산성 기여
  • as-is → to-be 스토리를 세워 문제를 구조화하고 해결

3개월 성장 타임라인 - 학습자에서 주도적 기여자로의 여정

2. 질문의 중요성과 15분 규칙

해결하기 어려운 기술적 문제(모달 스크롤, 자동 포커스 등)에 직면했을 때, 혼자서 오랜 시간 고민하는 것이 항상 최선은 아니라는 것을 깨달았습니다.

15분 규칙:

  • 15분간 스스로 고민하고 해결 시도
  • 15분이 지나도 해결되지 않으면 즉시 동료나 TL에게 질문
  • 불필요한 시간 낭비 방지 및 다른 관점의 해결책 획득

3. 대규모 마이그레이션의 핵심: 데이터 기반 의사결정

직관이나 추측이 아닌 실제 데이터를 기반으로 의사결정하는 것의 중요성을 배웠습니다.

적용 사례:

  • 사용량 분석을 통한 우선순위 결정
  • 의존성 그래프를 통한 작업 순서 최적화
  • 진행률 메트릭으로 리소스 재분배 판단

4. 로컬라이징 vs 라이브러리화 판단 기준

모든 컴포넌트를 라이브러리로 만들 필요는 없습니다. 다음 기준으로 판단했습니다:

로컬라이징 선택:

  • 특정 도메인에서만 사용되는 컴포넌트
  • 비즈니스 로직이 강하게 결합된 컴포넌트
  • 빠른 변경이 예상되는 컴포넌트

라이브러리화 선택:

  • 여러 앱에서 공통으로 사용하는 컴포넌트
  • 재사용성이 높은 atomic 컴포넌트
  • 안정적인 API를 가진 컴포넌트

5. 비동기 커뮤니케이션의 효율성

구두 커뮤니케이션:

  • 긴급하고 복잡한 문제
  • 실시간 피드백이 필요한 경우

문서 커뮤니케이션:

  • 지속적으로 참조해야 하는 정보
  • 팀 전체에 공유해야 하는 결정사항
  • 추후 검색 가능성이 중요한 내용

문서화를 통해 같은 질문을 반복하지 않고, 새로운 팀원의 온보딩 시간을 크게 단축할 수 있었습니다.


개선이 필요한 부분

1. 마이그레이션 규칙 문서 미숙지로 인한 반복적인 리뷰 지적

문제 상황:

@design-system-rules.md@twx-migration.md 문서를 작업 전에 제대로 숙지하지 않고 시작했습니다. 특히 프로젝트 특수 규칙을 간과했습니다:

  • spacing은 숫자 그대로 px로 변환 (Tailwind 기본 규칙 X)
  • BDS semantic color 사용 필수
  • 컴포넌트 네이밍 컨벤션

동일한 지적을 여러 차례 받아 불필요한 커뮤니케이션 비용과 리뷰어의 시간을 낭비했습니다.

개선 방안:

  1. 작업 시작 전 체크리스트 작성

    - [ ] @design-system-rules.md 정독
    - [ ] @twx-migration.md 핵심 규칙 메모
    - [ ] 자주 실수하는 패턴 별도 정리
    
  2. 첫 PR 피드백 문서화

    • 첫 PR에서 받은 피드백을 별도 문서로 정리
    • 이후 작업 시 매번 참고하여 동일 실수 방지
  3. AI 프롬프트에 규칙 반영

As-is:

BPL 컴포넌트를 BDS로 마이그레이션 해줘

To-be:

다음 규칙을 반드시 지켜서 BPL을 BDS로 마이그레이션 해줘:

1. spacing은 숫자 그대로 px 변환 (예: margin="16" → className="m-[16px]")
2. color는 반드시 BDS semantic color 사용 (예: primary, secondary, gray-50)
3. 컴포넌트명은 PascalCase, 파일명은 kebab-case
4. 반복적으로 지적받은 내용: [이전 리뷰 내용]

마이그레이션 후 자동으로 셀프 리뷰를 진행하고, 위 규칙을 모두 준수했는지 체크리스트를 출력해줘.

학습 포인트:

AI를 활용한 코드 작성 시에도 원본 프롬프트에 프로젝트 규칙과 이전 피드백을 명시적으로 학습시켜야 합니다. 단순히 코드 생성만 요청하는 것이 아니라, 셀프 리뷰까지 수행하도록 프롬프트를 설계하는 것이 중요합니다.

2. 셀프 리뷰 부족으로 인한 코드 품질 저하

문제 상황:

PR을 올릴 때 draft 상태에서 셀프 리뷰를 하지 않고 바로 리뷰 요청을 보냈습니다. 오타, 불필요한 코드, 규칙 위반 등 셀프 체크로 잡을 수 있는 실수들이 리뷰어를 통해 발견되었습니다.

최근 작업에서는 이러한 부주의로 인해 실제 배포까지 이루어져 장애가 발생하는 사례도 있었습니다.

개선 방안:

  1. PR 제출 전 셀프 리뷰 체크리스트

    - [ ] 규칙 문서 확인
    - [ ] Draft PR에서 코드 한 줄씩 읽으며 리뷰
    - [ ] 로컬 환경에서 테스트 완료
    - [ ] POC 페이지에서 edge case 확인
    - [ ] 불필요한 console.log, 주석 제거
    - [ ] 변수명, 함수명이 명확한지 확인
    
  2. AI 셀프 리뷰 프롬프트 활용

    다음 코드를 @design-system-rules.md와 @twx-migration.md 규칙에 맞게 리뷰해줘.
    특히 다음 항목을 중점적으로 체크:
    - spacing 변환 규칙 준수
    - semantic color 사용
    - 네이밍 컨벤션
    - 불필요한 코드 존재 여부
    
    [코드]
    
  3. 린터 규칙 강화

    • 자주 실수하는 패턴을 ESLint 커스텀 규칙으로 추가
    • Pre-commit hook으로 자동 체크

학습 포인트:

리뷰어의 시간은 코드 디자인과 아키텍처에 집중되어야 합니다. 기본적인 실수는 스스로 제거하여 리뷰 품질을 높이고, 더 의미 있는 피드백을 받을 수 있습니다.

3. Code Owner 미확인으로 인한 배포 프로세스 혼선

문제 상황:

프로젝트 초기에 작업 단위(PR)를 도메인별로 명확히 나누지 않아 여러 도메인이 하나의 PR에 엮였습니다. 이로 인해:

  • 배포 담당자 지정이 어려움
  • 배포 후 문제 발생 시 책임 소재 불명확
  • 특정 도메인만 롤백하기 어려움

개선 방안:

  1. PR 생성 전 CODEOWNERS 확인

    # automation-tool에 추가 가능한 스크립트
    git diff --name-only | xargs -I {} grep {} .github/CODEOWNERS
    
  2. 도메인별 PR 분리 원칙

    • 하나의 PR은 하나의 도메인만 다룸
    • 여러 도메인 수정이 필요한 경우 별도 PR로 분리
    • PR 제목에 도메인 명시: [Product] BPL Button → BDS Button 마이그레이션
  3. 배포 담당자 자동 지정

    • CODEOWNERS 정보를 기반으로 PR에 자동으로 reviewer 할당
    • 배포 체크리스트에 담당자 명시

4. 의존성 파악 미흡으로 인한 프로덕션 에러

문제 상황:

전역 콘텍스트를 마이그레이션하면서 해당 콘텍스트를 사용하는 모든 코드를 제거했다고 생각했지만, 실제로는 하나의 PR이 아직 머지되지 않은 상태였습니다. 전역 콘텍스트 코드를 삭제하는 PR이 먼저 머지되어 프로덕션 환경에서 센트리 에러가 발생했습니다.

근본 원인:

  • 전역 콘텍스트를 사용하는 모든 코드의 의존성을 완전히 파악하지 못함
  • PR 간의 의존 관계를 명확히 표시하지 않음
  • 삭제 PR과 사용처 제거 PR의 머지 순서를 관리하지 못함

개선 방안:

  1. 의존성 분석 도구 활용

    # 전역 콘텍스트 사용처 전체 검색
    bpl search "GlobalContext"
    
    # 또는
    grep -r "GlobalContext" apps/ libs/
    
  2. PR 의존 관계 명시

    ## Dependencies
    
    This PR depends on:
    - #1234 (Remove GlobalContext usage in Product domain)
    - #1235 (Remove GlobalContext usage in Card domain)
    
    ⚠️ **DO NOT MERGE** until all dependent PRs are merged.
    
  3. 블로킹 라벨 활용

    • 의존성이 있는 PR은 [blocked] 또는 [do-not-merge] 태그로 표시
    • GitHub Actions로 블로킹 태그가 있으면 자동 머지 방지
  4. 단계적 삭제 프로세스

    Step 1: Deprecated 표시 및 경고 추가
    Step 2: 모든 사용처 제거 PR 머지
    Step 3: 1주일 모니터링 기간
    Step 4: 실제 코드 삭제
    

학습 포인트:

전역적으로 사용되는 코드를 삭제할 때는 반드시 전체 의존성을 파악하고, 단계적으로 제거해야 합니다. 급하게 삭제하기보다는 안전한 프로세스를 따르는 것이 중요합니다.

5. BPL CSS와 BDS 컴포넌트 충돌

문제 상황:

이미 만들어진 BDS 컴포넌트로 마이그레이션하는 과정에서 기존 BPL의 전역 CSS와 충돌이 발생했습니다. 특히 z-index, position, margin 등의 스타일이 예상과 다르게 동작하여 디버깅에 많은 시간을 소비했습니다.

개선 방안:

  1. CSS 격리 전략

    • BDS 컴포넌트에 CSS Module 또는 CSS-in-JS 적용
    • 특정 페이지에서만 BPL 전역 CSS 비활성화
  2. 마이그레이션 단계에서 스타일 테스트

    • 마이그레이션 전후 시각적 비교를 통한 스타일 검증
    • 브라우저별, 디바이스별 동작 확인

마치며

3개월간의 BPL → BDS 마이그레이션 프로젝트는 단순히 코드를 옮기는 작업이 아니었습니다. 체계적인 분석, 자동화 도구 개발, 테스트 가능한 환경 구축, 그리고 무엇보다 팀과의 적극적인 소통을 통해 3년간 쌓인 기술 부채를 2개월 만에 해결할 수 있었습니다.

이 과정에서 가장 중요했던 것은:

  1. 데이터 기반 의사결정: 직관이 아닌 실제 사용량 분석
  2. 자동화: 반복 작업을 스크립트로 해결
  3. 점진적 개선: 작은 도구에서 시작해 범용 도구로 확장
  4. 주도적 문제 해결: 주어진 작업만 하는 것이 아니라 "왜"를 질문
  5. 투명한 커뮤니케이션: 진행 상황과 문제를 적극적으로 공유

앞으로도 이러한 경험을 바탕으로 더 나은 개발 문화와 프로세스를 만들어가고 싶습니다. 특히 신규 팀원이 빠르게 적응할 수 있는 환경, 실수를 사전에 방지하는 자동화 시스템, 그리고 지식이 개인에게 종속되지 않는 문서화 문화를 구축하는 데 기여하고자 합니다.

긴 글 읽어주셔서 감사합니다. 혹시 비슷한 경험이 있으시거나 질문이 있으시다면 댓글로 공유해주세요! 🙂