안녕하세요. 김수보 멘토입니다. 
이 글은 2020.01월 피씬을 시작했던 1기 친구들의 "42공통써클 탈출기"입니다. 
글쓴이 eunhkim 님의 허락을 얻어 게재합니다.
"트랜샌더스"란 공통커리큘럼의 끝판왕 과제로, 복잡한 난이도의 웹게임입니다.
당시에는 백엔드로 Ruby on Rails 를 요구해서,지금과는 요구기술이 상이합니다.
다만, 난이도와 풀어가는 과정은 동일한데,이 팀은 좀 너어무 잘한 느낌이라...
암튼 도움이 되면 좋겠습니다.
1. 어쩌다 트랜센던스까지 #1(시작~개발환경)
2. 어쩌다 트랜센던스까지 #2(협업환경)
3. 어쩌다 트랜센던스까지 #3(구현,테스트,프랙티스)
4. 어쩌다 트랜센던스까지 #4(팀원들 회고)

10장. 협업환경 구성

사실 저희가 어떻게 협업했는가를 나누고 싶어서, 이 장 때문에 글을 쓰자고 처음 마음먹게 되었습니다. 얼마나 좋은 코드를 짰는가, 기술적으로 탁월한가를 알리고 싶었다면 코드를 자랑했을 거예요.

전문가의 직접적인 도움 없이 서로가 가진 지식과 경험을 나누고, 웹 레퍼런스를 통해 시행착오를 겪으며 꾸역꾸역 앞으로 나아온 이 이야기가 정말 42스럽다고 생각했습니다.

10.1. 용어 정의

코딩 컨벤션은 에어비앤비의 것을 따랐기 때문에 특별히 따로 논의할만한 것이 없었습니다. 서브젝트, 개발 과정에서 필요한 용어의 정의를 명확하게 공유하는 데 신경을 많이 썼습니다.

어떤 단어를 어떤 의미로 쓸 것인가. 비슷해 보이는 것들을 어떤 용어로 구분할 것인가. 같은 의미의 단어 중 어떤 것을 선택할 것인가. 이처럼 주요 용어들을 면밀하게 정의하려고 했습니다.

10.2. 기술적 차원의 협업규칙

이외에도 템플릿 html 디렉토리와 자바스크립트의 소스 디렉토리 구조 동기화, 비동기 처리 시 가독성을 위한 callback method 분리, 모듈 내에서 다른 모듈을 import하는 방식 통일, 각 뷰의 intiailize, render, close 메서드가 일관되게 가져야 할 책임 등 기술적으로 지켜야 할 협업 규칙들에 대해 논의했습니다.

당일 회의록에 기록된 사항 중 두 가지만 공유하겠습니다.

"모든 뷰에는 close 메서드가 구현되어야 한다. 각 뷰의 close 메서드가 기본적으로 져야 할 책임은 자신에게 종속된 모든 차일드뷰의 close 메서드를 호출하고, 자신이 on한 eventListener를 해제하고, 자신을 remove하는 것이다. 자신을 remove하지 않는 뷰(persistView)는 appView가 별도로 관리하도록 하자."
"모듈을 맡았을 때 그 모듈의 책임자가 자신의 책임을 수행한다는 것은 해당 모듈을 어떤 방식으로든 아무리 이용해도 누수 없이 정확하게 동작하고, 다른 모듈의 정확성에 영향을 미치지 않는 것이다. 그 과정에서 웹소켓을 이용한다면 적절하게 연결하고 해제하는 것이다."

10.3. 프로젝트 관리

프로젝트는 깃허브로 관리했습니다.

develop 브랜치를 두고, 모듈 단위로 브랜치를 따서 작업 후 PR하는 방식이었습니다. 여기에서 말하는 모듈 단위는 appView나 modalView를 제외하면 기본적으로 프론트에서의 화면 단위로, 단순히 프론트 영역만이 아니라 해당 뷰를 렌더링하는 과정에 필요한 백엔드의 API 구현까지 포함하는 범위입니다.

브랜치명은 ‘모듈명라벨명#카드번호’의 형식(e.g user_index_feat#2)을 채택했습니다. 어떤 모듈에 대한 어떤 작업이며, 대시보드의 몇 번 카드에서 관련 사항을 확인할 수 있는지 직관적으로 드러났기 때문입니다.

이외에도 ‘develop 브랜치가 최신화될 때마다 가능한 빠르게 pull하여 동기화할 것’과 같은 프로젝트 관리와 관련된 약속을 정했고, commit message와 feature/issue는 template을 이용하여 형식을 맞췄습니다.

프로젝트 관리 전략 중 중반에 새롭게 추가된 원칙은 PR 단위입니다.

처음에는 모듈과 PR 단위를 맞췄습니다. 그랬더니 backend에서 구현해야 할 API의 코드 양이나 프론트에서 지원하는 실시간 처리의 양에 따라 PR 코드가 2,000줄까지도 올라가는 상황이 벌어졌고, 리뷰에 따라 변경된 코드가 많을 경우 처음부터 다시 테스트하고 리뷰해야 하는 스트레스가 있었습니다.

그래서 적정 PR 코드 양이 얼마인지에 대한 리서치 및 학습을 진행하고, Develop 브랜치에는 여전히 모듈 단위로 PR하되, 모듈의 메인 브랜치를 만들어 300~400줄 단위로 해당 모듈 브랜치에 PR하는 방식으로 브랜칭 및 PR 전략을 변경했습니다.

10.4. 대시보드

대시보드 관리는 미리 세워놓은 버저닝 계획에 맞춰 매주 화요일에 1주일 분량의 task 카드를 생성하고, not_started/progress/review/complete 네 흐름에 걸쳐 관리하는 칸반을 적용했습니다.

급하지 않은 이슈들은 backlog에 남겼고, 라벨은 세 종류로 나눴습니다.

각각 작업자를 표시하는 멤버 라벨, 작업 성격을 정의하는 bug/feature/refactor 라벨, 작업 영역을 결정하는 front/back/extra 라벨입니다.

카드 내부에는 구현 체크리스트와 팀원들에게 알려야 할 사항을 템플릿으로 관리했습니다.

10.5. 디스코드

흥미롭게도, 저희는 103일에 달하는 기간 동안 프로젝트를 목적으로는 한 번 만났습니다. 온라인으로 만나서 스터디를 시작했고, 53일째 되는 날 처음 만났습니다. 닌자 프로젝트를 끝내고 본격적인 킥오프를 하는 날이었죠.

서비스의 책임을 분할하여 더 작은 책임을 진 객체들의 협력 관계로서 프로그램을 설계하는, 이른바 책임 주도 설계를 처음 진행해야 하는 상황에서 온라인으로는 감당이 안 될 것 같았습니다.

화이트보드를 몇 번씩 지워가며 종일 객체 설계를 진행했고, 그날 뒤로는 역시 모든 과정을 온라인으로 진행했습니다.

어떻게 그럴 수 있었을까요? 코로나 시대에서는 온라인 협업이 커뮤니케이션의 부족과 생산성 저하로 이어질 위험이 많은데도, 저희는 정말로 성공적인 협업을 진행했습니다.

일등 공신은 바로 디스코드였는데요. 자체적인 디스코드 채널을 구축하고, 거기에 몇 가지 커뮤니케이션 규칙들을 더해 운영했습니다.

우선 매일 11시에 짧게는 15분씩, 길게는 1시간씩 매일 오전에 미팅을 했습니다.

모든 모듈 작업은 가능한 2명 이상이 라이브쉐어로 작업해 혼자 팀 커뮤니케이션으로부터 분리되는 일이 없도록 했고, 평일 오전 11시에서 오후 7시 사이에는 가능한 디스코드 상시접속을 유지하도록 했습니다.

3개의 링크 채널은 학습 링크를 공유하기 위한 목적입니다. 처음에는 ‘유용한 링크’ 채널에 올렸고, 분야별로 쪼개어서 디테일하게 채널을 만들었더니 구분하는 일이 새로운 task가 되어서 불편함을 주었습니다.

그래서 front, back, build로 세 가지 링크 채널만 만들어서 공유하는 방식으로 정착했습니다. 여덟 개의 채팅 채널 이름은 다음과 같습니다.

채널은 중요성이나 확인 빈도가 잦은 순서대로 정렬했습니다.

“모두-꼭-확인해요”는 모두가 반드시 읽어야 할 내용(PR 공유, 중요한 지식 공유)들을 올리고, 가능한 한 빠르게 확인하고 이모지로 읽었음을 응답할 책임이 모두에게 있는 채널입니다.

“미팅에서-얘기해요”는 전체 미팅에서 논의해야 할 아젠다들이 휘발되지 않도록 생각날 때 올릴 수 있도록 만든 채널이고, 시간되면-말해줘요는 다른 모듈을 작업하는 팀 간에 대화를 신청하거나, 같은 팀이라도 식사 시간이나 개인 일정으로 시간이 어긋났을 때 팀 일정에 대한 마이크로 싱크를 맞추기 위한 채널입니다.

“github”은 webhook을 연결해 커밋이나 PR 내역, PR 리뷰 및 리뷰에 대한 커멘트 등록들을 빠르게 확인할 수 있도록 했습니다. 맡은 작업보다 PR 리뷰를 우선하도록 하는 원칙이 잘 작동할 수 있을 때는 해당 채널이 큰 역할을 했습니다.

“랜덤”은 슬랙의 랜덤과 같은 일반적인 대화 채널이고, 개인 일정은 디스코드에 접속할 수 없는 사정이 있을 때 사전 공유하는 채널입니다. liveshare의 경우 하루에도 몇 번씩 라이브 쉐어 채널이 공유되는데, 랜덤에 해당 링크가 섞이다 보니 작업자 이외의 팀 동료가 필요할 때 찾는 데 이슈를 겪어서 별도 관리했습니다.

“에러를-모아보아요”는 처음에 채널의 필요성을 인지하지 못하고 있었는데, 수많은 에러에 빠지며 시행착오를 겪다 보니 노하우가 생겼습니다. 에러는 ‘무슨 에러가 왜 발생하는지’를 공유하면 안 된다는 것입니다. 언뜻 생각하면 오히려 그것을 공유해야 하는 것 아닌가 싶지만, 사실 초기 단계에서 에러에 대한 명명은 주관적이고 이유는 가설일 뿐이었습니다.

대부분 틀렸습니다. ‘어떻게 해야 해당 에러를 재연할 수 있는지, 콘솔이나 서버에 뜨는 에러 메시지가 정확히 무엇인지’를 공유해야 합니다. 그래서 재연 방법, 에러 메시지나 현상이 포함된 스크린샷을 그대로 공유하는 에러를-모아보아요 채널을 만들어서 운용했습니다.

같은 채널이라도 처음부터 이런 이름은 아니었습니다. ‘모두-꼭-확인해요’는 notice나 공지사항, ‘미팅에서 얘기해요’는 의제 발의와 같은 formal한 이름들을 고려하고 그중 몇몇은 실제로 그렇게 사용했었습니다.

그러나 이것이 팀 문화나 에너지를 고려하지않은 접근이고, 더 말랑말랑한 이름들이 좋겠다 싶어서 변경했습니다.

10.6. 역할배분

협업 환경 구성의 메인 주제 중 하나는 역할 배분이었습니다.

퍼블리싱, 프론트엔드, 백엔드, 데이터베이스, 프로젝트 매니징으로 역할을 전담하여 개발하는 것이 가장 효율적이라는 생각이 먼저 들었습니다.

자기가 맡은 영역에 대해서만 학습을 심층적으로 진행하면 될 것이고, 또 작업자가 자기 영역의 모든 코드를 이해하고 있기 때문에 일관성이나 이슈 대응 등 유리한 점도 많을 테니까요. 현업에서라면 고민할 필요도 없는 이슈였습니다.

그러나 한 가지 차이가 있다면 우리는 ‘일하기 위해 모인 사이’가 아니라 ‘학습하기 위해 모인 사이’라는 것이었습니다.

누구도 데이터베이스만, 퍼블리싱만 맡기를 원하지 않았습니다. 이런 상황에서 단순히 프로젝트를 빨리 끝내기 위해 역할을 나눌 수는 없었습니다.

결과적으로 저희는 기술 영역에 대한 전담은 없이 가고, 모든 구성원이 해당 프로젝트를 수행하는 데 필요한 모든 기술을 학습한다는 결정을 내렸습니다. 스터디에 많은 시간을 썼지만, 결과적으로 그만한 가치가 있는 결정이었습니다.

1. 어쩌다 트랜센던스까지 #1(시작~개발환경)
2. 어쩌다 트랜센던스까지 #2(협업환경)
3. 어쩌다 트랜센던스까지 #3(구현,테스트,프랙티스)
4. 어쩌다 트랜센던스까지 #4(팀원들 회고)