정글 우수 프로젝트에 선정되서 정글 홈페이지에 저희팀 프로젝트 발표영상이 업로드되었습니다.!!!
CodeSync 프로젝트 회고
프로젝트 개요: 실시간 코드 리뷰 및 협업 툴 개발
크래프톤 정글의 마지막 프로젝트로, 우리 팀은 GitHub PR 리뷰에서 느꼈던 불편함을 해결하고자 CodeSync라는 실시간 코드 리뷰 및 협업 툴을 개발했습니다. 기존 GitHub PR 리뷰 방식은 제한적이었기 때문에, 우리는 이를 더 실시간으로, 더 직관적으로 개선하고자 했습니다. 이 프로젝트는 단순히 코드 리뷰 도구를 넘어, 실시간 소통과 문서화까지 지원하는 협업 툴로 확장되었습니다.
- 프로젝트 기간: 2024.10.11 ~ 2024.11.16
- 기술 스택: React, TypeScript, YJS, Socket.io, Peer.js, Tailwind, Zustand, Excalidraw, Block Note, Monaco Editor
🛠 주요 기능 구현
GitHub PR 데이터 가져오기
- 사용자가 GitHub PR 주소를 입력하면, 해당 PR의 변경된 파일 목록과 댓글 데이터를 가져옵니다.
- PR에서 변경된 파일들을 디렉토리 트리 구조로 보여주고, 각 파일에 남겨진 댓글과 코드 변경 내역을 확인할 수 있습니다.
- 변경 전 파일에 달린 댓글에 Outdated 처리 기능을 추가하여, 최신 상태의 댓글을 구분할 수 있도록 했습니다.
실시간 코드 동시 편집 (YJS + Monaco Editor)
- 사용자가 같은 파일을 열면, YJS와 Monaco Editor를 사용해 실시간으로 동시 편집이 가능합니다.
- 각 사용자의 커서 위치가 실시간으로 공유되며, 상대방이 보고 있는 화면을 따라갈 수 있는 기능도 제공했습니다.
화상 통화 및 채팅
- 실시간 화상 통화와 채팅 기능을 통해 코드 리뷰 중에도 즉각적인 피드백이 가능합니다.
- 리뷰 중 발견한 문제나 개선 사항을 바로 논의할 수 있어 협업 효율이 높아졌습니다.
Draw Board (그림판)
- YJS와 연동된 그림판을 통해, 코드 리뷰 중 시각적 소통이 가능하도록 했습니다.
- 코드 리뷰 과정에서 설명이 필요한 부분을 그림판에 동시에 그리며 강조할 수 있습니다.
Block Note (마크다운 편집기)
- 노션 스타일의 마크다운 편집기를 제공하여, 코드 리뷰 과정에서 필요한 메모나 문서화를 할 수 있습니다.
- 작성된 메모는 YJS를 통해 실시간으로 공유 및 동시편집되며, 협업 중 작성한 모든 내용을 다운로드할 수 있습니다.
HTML to Image
- Monaco Editor의 현재 화면을 이미지로 캡처하여 그림판에 바로 제공하여, 그림판에서 다른 사용자와 같이 확인하며 그림을 그릴 수 있습니다.
폴더 구조 UI
- PR에서 변경된 파일의 디렉토리 구조를 트리 형태로 보여주어, 파일 위치와 변경 사항을 한눈에 확인할 수 있도록 했습니다.
내가 구현한 주요 기능 (프론트엔드)
GitHub PR 데이터 핸들링
- 사용자가 입력한 GitHub PR 주소를 통해 PR 정보, 변경 파일, 댓글 데이터를 처리
- 변경된 파일 리스트를 디렉토리 트리 구조로 시각화하여 구조적 파악 용이
- 삭제되거나 위치가 변경된 파일에 작성된 댓글을 대상으로 Outdated 예외 처리 로직 구현
실시간 코드/그림판 동시 편집 (YJS + Monaco Editor + Draw Board)
- Monaco Editor, Draw Board, YJS를 연동하여 실시간 동시 편집 및 데이터 동기화 기능
- 상대방이 보고 있는 파일을 실시간 observing하고, 버튼 클릭 시 자동 이동 기능
- Awareness 기반 커서 스타일 커스터마이징으로 사용자별 커서 식별 기능
- Spotlight 기능 구현: Draw Board에서 상대방 커서를 따라가는 실시간 동기화 기능
- 에디터 화면을 이미지로 캡처하여 Draw Board에 자동 전송 및 이동 기능
📎 폴더 구조 UI
- PR에서 변경된 파일 목록을 폴더 트리 구조로 시각화하여 파일 위치 및 변경사항을 한눈에 확인 가능
트러블슈팅 사례
문제 1: 병합된 PR의 브랜치 접근 문제
문제 상황:
- PR이 병합되고 소스 브랜치가 삭제된 경우, 기존 코드에서는 파일 내용을 정상적으로 조회할 수 없는 문제가 발생했습니다.
원인 분석:
- 브랜치 기반 접근 방식에서 브랜치가 삭제되면, GitHub API 호출 시 해당 브랜치의 파일 내용을 조회할 수 없었습니다.
해결 방법:
- 브랜치 기반 파일 조회 로직을 커밋 해시(SHA) 기반 파일 조회 로직으로 변경했습니다.
문제 2: 실시간 협업 중 커서 잔상 문제
문제 상황:
- 사용자가 파일을 전환할 때 이전 파일에 커서가 남는 문제가 발생했습니다. 이로 인해 UI가 혼란스러워지는 상황이 생겼습니다.
원인 분석:
- 이전 파일에서의 Awareness 상태가 초기화되지 않아 커서 스타일이 제거되지 않았습니다.
해결 방법:
- Awareness 상태를 초기화하고, 이전 파일에 남아 있는 커서 스타일을 모두 제거하는 로직을 추가했습니다.
- 파일 전환 시마다 새로운 스타일을 동적으로 생성하여, 현재 보고 있는 파일에만 커서가 표시되도록 했습니다.
문제 3: 실시간 상태 동기화 문제
문제 상황:
- 초대받은 사용자가 PR 주소를 직접 입력하지 않았기 때문에 PR 데이터를 가져오지 못하는 문제가 발생했습니다.
- 방을 만든 사용자와 초대받은 사용자가 각각 별도로 GitHub API 호출을 해야 했고, 이로 인해 API 호출 횟수 증가와 로딩 시간 지연 문제가 나타났습니다.
원인 분석:
- 방을 만든 사용자의 PR 정보를 초대받은 사용자와 실시간으로 동기화하지 않았기 때문에 발생한 문제였습니다.
해결 방법:
- YJS의 공유 문서(Y.Doc)를 활용하여, 방 생성 시 PR 정보를 Y.Doc에 저장하고 초대받은 사용자와 실시간으로 동기화하도록 변경했습니다.
- 이를 통해 초대받은 사용자가 별도의 API 호출 없이 PR 데이터를 자동으로 가져올 수 있도록 했습니다.
개선 효과:
- GitHub API 호출 횟수를 절반으로 줄여 API 제한 문제를 완화했습니다.
문제 4: GitHub API에서 'removed' 처리 문제
문제 상황:
- PR 병합 과정에서 컴포넌트의 위치를 변경하는 작업 중, 팀원들이 이미 수정한 동일 컴포넌트가 다른 위치에 존재하는 상황이 발생했습니다. 코드 정리를 위해 중복된 컴포넌트를 삭제했음에도 GitHub API가 이를 'removed'로 인식하지 않고 응답에서 제외시키는 현상이 있었습니다.
연쇄 문제:
- 리뷰어가 삭제된 컴포넌트에 남긴 댓글이 있을 때, GitHub UI에서는 해당 파일명과 댓글이 표시되는데 REST API 응답에서는 파일 정보가 누락되고 댓글만 포함되는 문제가 발생했습니다.
원인 분석:
- GitHub는 파일이 삭제되어도 동일한 내용이 다른 위치에 존재하면 이를 'removed'로 처리하지 않고 Outdated처리를 합니다. 'Outdated'는 리뷰 시점 이후 파일 내용이 변경된 경우에만 적용되었습니다.
해결 방법:
커밋 해시를 사용해 이전 버전 파일을 조회하는 방법과 PR 데이터를 활용하여 댓글 데이터와 비교해 파일이 존재하지 않을 경우 Outdated 상황을 설명하는 안내 메시지를 제공하는 방법을 논의한 결과, 두 번째 방안을 선택했습니다.
"이 댓글은 파일의 이전 버전에 작성된 내용으로, 현재 파일에서는 열 수 없습니다"라는 명확한 안내 메시지를 제공하여 문제를 해결했습니다.
개선 효과:
- 불필요한 API 호출을 줄이면서도 사용자에게 명확한 상황 설명을 제공할 수 있었습니다.
기술 스택 선택 이유
| 기술 | 사용 목적 | 프로젝트에 적합한 이유 |
|---|
| React | UI 라이브러리 | 컴포넌트 재사용, 가상 DOM을 통한 성능 최적화 |
| TypeScript | 정적 타입 검사 | 코드 안정성 확보, 대규모 프로젝트 유지보수 용이 |
| YJS | 실시간 협업 도구 | 충돌 없는 데이터 동기화, 네트워크 상태 무관한 일관성 유지 |
| Socket.io | 실시간 양방향 통신 | 저지연 통신, 자동 재연결, 이벤트 기반 통신 |
| Peer.js | P2P 통신 | WebRTC 기반 미디어 전송, 서버 부하 감소 |
| Tailwind CSS | CSS 프레임워크 | 빠른 스타일링, 디자인 일관성 유지, 반응형 지원 |
| Zustand | 상태 관리 라이브러리 | 가벼운 전역 상태 관리, Selector로 성능 최적화 |
| Block Note | 블록 기반 에디터 | 블록 단위 콘텐츠 편집 기능 제공 |
| Excalidraw | 화이트보드 협업 도구 | 실시간 다이어그램 생성, 사용자 경험 향상 |
| Monaco Editor | 코드 에디터 | 코드 자동 완성, 다양한 언어 지원, 커스터마이징 가능 |
앞으로의 개선 방향
- WebRTC 기능 확장: 화면 공유.
- Github: 현재는 이용중 pr 내용 변경시 깃헙에는 반영되지는 않지만 추후 반영되는 기능
프로젝트를 통해 배운 점
- 실시간 협업의 어려움과 중요성을 크게 배움.
- GitHub API의 한계를 이해하고, 이를 보완하는 로직을 설계함.
- UI/UX 개선을 위해 사용자 경험을 최우선으로 고려함.
크래프톤 정글에서의 마지막 프로젝트였던 CodeSync는 단순히 기능 구현에 그치지 않고, 협업 과정에서의 문제 해결 능력을 키우고 사용자 중심의 서비스를 개발하는 데 집중했던 값진 경험이었습니다.
주요 성과
댓글 기능 효율성 개선
- 자체 리뷰 시스템을 도입한 결과, 팀 내 PR 리뷰에서 불필요한 댓글이 대폭 감소하여 평균 댓글 수가 69% 줄어드는 성과를 거두었습니다. 기존 평균 댓글 수는 285개였으나, 시스템 도입 후 89개로 줄어들어 리뷰 과정이 더욱 효율적으로 개선되었습니다.
🏆 프로젝트 선정