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

0장. 개요

5명이 모여 정확히 103일이 걸렸어요.
1기 1차였고, 시작 당시 한국에는 패스한 사람도 없었기에 모든 것이 막막했어요.

‘이게 진짜 끝이 나기는 할까?’ 싶었던 프로젝트였는데, 계속해서 시간과 에너지를 쏟으며 울고 또 웃다 보니 어쩌다 트렌센던스까지 통과를 하게 되었네요. libft를 시작할 때는 멀게만 느껴지던 공통 서클도 어쩌다 끝나버렸고요.

나누고 싶은 이야기들이 있습니다.

저희가 어쩌다 42에 오게 되었는지, 어쩌다 다른 교육 과정과 병행하기보다 42에 집중하기를 선택했는지, 기술 스택들이 대부분 처음이었던 트렌센던스를 어쩌다 통과하게 되었는지, 이런 이야기들이 다른 카뎃들에게 어떤 형태로든 도움이 될 거라고 여겼습니다.

트렌센던스를 시작하기 전에 알았으면 좋았을 것들, 공통 과정을 진행하면서 내내 고민했던 것들, 카뎃이 처음 되었을 때 읽고 싶었던 바로 그런 글을 쓰려고 했습니다.

기술적인 부분에서는 부족한 부분이 많지만, 오히려 그래서 42스럽다고 생각합니다. 동료학습의 좋은 레퍼런스가 되기를 바랍니다.


1장. 기술학습

트렌센던스는 크게 PSQL, 루비, 루비 온 레일즈, HTML, CSS, 자바스크립트(+jquery), Backbone(+underscore), Docker의 여덟 가지로 기술 스택이 구성되어 있습니다. 대부분 처음인 기술들이었고, 또 docker 역시 docker-compose를 이용하여 빌드하여야 하므로 학습할 영역이 추가로 있었습니다.

하면서 익히기엔 프로젝트의 규모가 컸습니다.

프로젝트 진행에 필요한 기술 스터디를 먼저 진행하였고, 100여 일의 전체 프로젝트 기간 중 초기 45일을 스터디(주 2회 온라인 정기 미팅)에 사용하였습니다. 학습 순서는 위의 스택 소개에서 기술한 순서와 같았습니다.

PSQL은 SQL부터 익혀야 했기에 아사이 아츠시의 “SQL 첫걸음”을 같이 읽었고, 레일즈는 구름 IDE의 컨텐츠를 학습한 후 야마다 요시히로의 “퍼펙트 루비 온 레일즈”와 레일즈 홈페이지의 레일즈 공식 가이드 중 각자 선택하여 심화 학습했습니다.

프론트 기초는 코드카데미에서, 자바스크립트는 웹페이지 “모던 자바 스크립트 튜토리얼”에서 학습했습니다. 백본은 애디 오스마니의 “Backbone.js 프로그래밍”과 웹 리서치 중 각자 편한 쪽으로 학습했습니다.

2장. 닌자 프로젝트

해당 기술 스택에 대한 학습과 프로젝트 경험을 가지고 시작하지 않았다면, 45일은 이 모든 기술을 소화하기에 턱없이 부족한 시간입니다. 저희는 그랬습니다.

가벼운 예제들은 따라서 해보면서 학습을 했지만, 해당 기술들을 이용하여 프로젝트를 한다고 생각하면 그냥 막막했습니다. 어디서부터 어떻게 해야 할지 모르겠다고 할까요.

API부터? UI부터? 아니면 테이블 스키마부터? 무엇을 먼저 해야 할지도 모르겠고, 무엇을 하더라도 어떻게 해야 할지 판단이 안 섰습니다.

또 팀원이 5명이고, 프로젝트 규모도 크기 때문에 모두가 함께 지켜야 할 규칙을 정리한 코드 컨벤션이 필요하다고 생각했습니다. 정작 뭘 써야 할지는 몰랐지만요.

모던 자바스크립트 튜토리얼을 읽을 때 닌자 코드에 관한 내용이 있었습니다.

닌자라고 불리던 전설 속 개발자들의 코드에 관한 얘기였죠. 코드는 가능한 한 짧게 쓰고, 변수명은 글자 하나만 쓰고, 약어를 사용하고, 명사는 포괄적으로, 철자는 유사하게, 동의어도 쓰고, 변수명도 재사용하고, 형용사는 과장하고, 외부변수를 덮어쓰고, 함수에 다양한 기능을 넣는 코드들을 의미했습니다.

지향해야 할 멋진 코드인 것처럼 풍자했는데, 문득 그 얘기가 생각나서 그대로 결심했습니다.

좋은 규칙을 모르겠으면, 마음대로 닌자 프로젝트를 해보자. 코드를 한 번 망쳐보자. 그러다보면 알게 되겠지.

닌자 프로젝트에는 7일의 시간을 소요했습니다.

프로그램의 구조나 코드 스타일에 대해 거의 토론하지 않았고, 대부분의 사항을 ‘닌자 프로젝트니까’라는 말로 작업자가 빠르게 결정했습니다.

정교한 브랜칭이나 리뷰도 없이 push & merge했고, 서브젝트의 요구사항만 신경 쓸 뿐 그 이외에는 정말로 아무것도 신경 쓰지 않는 코딩을 했습니다.

그렇게 했음에도 일주일의 시간 동안 회원 가입과 로그인, 유저 상세 페이지, 길드 목록 페이지, 게임 페이지 정도를 구현하는 데 그쳤습니다.

그러나 닌자 프로젝트라는 관점에서는 매우 성공적이었습니다.

팀원들은 backbone을 이용하여 웹페이지를 동적으로 제어할 줄 알게 되었고, 레일즈와 API를 이용하여 요청/응답을 주고받을 수 있게 되었습니다.

또 게임을 구현하면서 액션 케이블(레일즈에서 웹소켓을 처리하는 방식)도 어느 정도 이해하게 되었습니다. 비로소 설계를 위한 최소한의 준비가 된 것이죠.

3장. 핵심가치 결정

닌자 프로젝트도 끝났으니 이제 프로젝트를 할 수 있겠다.
무엇부터 해야 할까? 결론은 핵심 가치였습니다.

UI, DB, API 설계부터 시작해서 구현, 그 과정에서의 협업 방식까지 당장 수많은 의사 결정을 해야 할 텐데 의사 결정의 기준이 먼저 제대로 있어야 한다고 판단했습니다.

핵심 가치가 공유되지 않으면 끔찍한 일들이 일어납니다. 우선 논의를 위해 시간은 시간대로 잡아먹습니다. 끝에 가면 개별적으로는 그럴듯하지만 전체적으로는 일관되지 않은 코드를 만나게 됩니다.

프로그램을 목적 달성을 위한 객체의 협력이란 관점에서 보면 정말 좋지 않은 일입니다. 그렇다고 딱히 팀원들이 더 감정적으로 행복해진 것도 아니죠.

중요한 것은 목적 달성을 위해 가치의 우선순위를 정하는 것입니다.

우리의 맥락에서 어떤 가치가 어떤 가치보다 얼마나 중요하게 다루어져야 하는가를 정하면 우선 의사결정이 쉬워지며, 일관성을 가지고, 목적에도 더 부합하게 됩니다.

의사결정을 할 때는 어떤 가치들이 충돌하고 있는지를 해석하고, 우선순위를 잘 달성하는 문제해결 방식이 무엇인가를 디자인하는 데 집중할 수 있습니다.

감정과 시간의 소모가 확연히 줄어듭니다. 관련한 커리어 경험을 가진 구성원들도 있어서, 이런 의견이 더 잘 공감대를 얻고 실행될 수 있었습니다.

어떤 기준들이 필요할까에 대해 먼저 논의한 뒤, 후보를 추려 1~5점 척도로 구글 설문을 진행 후 통계를 내는 방식으로 정했습니다. 결정된 가치 우선순위는 다음과 같았습니다.

결정된 가치 우선순위
1. 서브젝트(요구사항 충족)
2. 안정성(예외처리)
3. 구성원의 만족
4. 가독성
5. 일관성
6. 객체 지향성
7. 단순성
8. 유저 경험
9. 신속성(작업시간 단축)
10. 통제 가능성
11. 학습 가능성
12. 취업 적용 가능성

이렇듯 목록화된 가치는 우리가 무엇을 어떻게 만들어야 하는지, 의사결정이 필요한 상황에서 어떻게 해야 하는지를 직관적으로 알 수 있게 해줍니다.

저희 팀의 경우 흥미롭게도 취업, 학습, 시간 단축과 같은 개인적 가치보다 가독성, 일관성, 예외처리와 같이 코드의 품질에 대한 가치들이 선명하게 높았습니다.

4장. 서브젝트 분석

개발자는 예술가가 아닙니다. 적어도 일이라는 맥락을 놓고 볼 때 개발자는 만들고 싶은 프로덕트와 기능을 만들 수 없습니다. 고객이 원하는 것을 만들어야 합니다. 비즈니스란 고객을 위해 존재하는 것이니까요.

그리고 42에서는 서브젝트가 고객입니다. 현장보다 나은 점이 한 가지 있다면, 변덕이 심하지 않고 자신이
무엇이 원하는지를 잘 아는 고객이란 점이겠죠.

그런 맥락에서 팀 가치 우선순위 결정에서 서브젝트가 1번으로 평가되지 않았다면 그게 더 이상한 일이었을 겁니다. 서브젝트를 대충 읽은 뒤 구현하고, 뒤늦게 ‘서브젝트에 이런 게 있었네’하고 수정하는 일은 피해야 합니다.

효율성이나 42서울에서 서브젝트가 가지는 무게 때문이 아니라, 클라이언트의 요구를 대충 훑어 보고 개발을 시작하는 태도가 가지는 부적절함 때문입니다.

프로젝트를 시작한 지 50일이 넘어서고, 본격적인 개발 프로세스에 착수하면서 서브젝트 분석을 심도 있게 진행했습니다.

여기에서 말하는 ‘심도 있음’의 의미는, 서브젝트에 존재하는 단어 하나에도 의문이 남지 않고, 다각적 해석이 가능한 모든 경우를 검토하고, 팀원의 이해에 충돌이 있으면 협의하여 오해 없는 하나의 구체적인 프로그램을 공유하는 것을 의미합니다.

서브젝트 자체는 카뎃이라면 누구나 열람할 수 있기 때문에 따로 언급하지 않겠습니다. 대신 서브젝트를 분석한다는 의미를 더 정확하게 공유하기 위해 실례를 몇 개 언급하겠습니다.

- '모든 예외는 적절하게 핸들링 되어야 한다'는 항목에서 '적절한 핸들링'이란 무엇을 의미할까? '에러'도 적절히 핸들링 된다면 괜찮은가? 에러와 예외는 어떻게 구분할까?
- '패스워드를 암호화한다'는 항목에서 암호화 정도는 어느 정도이며, 암호화되는 위치는 어디여야 할까?
- 유저나 멤버십의 포지션에 그레이드가 있다고 할 때, 각 포지션에 대해 허락되는 권한의 범위는 정확하게 어디까지인가? 동일한 레벨의 포지션에 대해 자신의 권한을 행사할 수 있는가?
- 현재 소속된 길드가 다른 길드와 전쟁을 치르고 있을 때, 진행 중인 전투가 발생한다면 전쟁 페이지는 실시간으로 새로고침 되어야 할까?

이처럼 서브젝트의 지문이 불충분하고, 해석이 모호한 영역들에 대해서는 가능한 한 엄격하게 판단했습니다. 엄격함이라는 관점에서 판단할 수 없는 문제들에 대해서는 가능한 사용자 경험을 중점에 놓고 판단했습니다.

5장. 책임 설계

객체지향적인 프로그램의 설계를 위해 조영호님의 “객체지향과 사실과 오해”를 같이 읽었습니다. 웹서버를 할 때는 클래스부터 설계했었는데, 책에서는 클래스가 중요한 것이 아니라고 말하더군요.

단일한 책임을 지는 애플리케이션을 먼저 가정하고, 연관성 높은 책임을 나눈 뒤 서로 다른 객체에 할당하면서 나아갈 때 협력하는 객체들의 공동체로서 프로그램을 잘 디자인할 수 있다는 얘기가 크게 와닿았습니다.

어쩐지 먼저 해야 할 것만 같았던 API 설계도, 사실 프론트 엔드와 백 엔드에서 협력을 위해 어떤 객체들이 어떤 책임을 질지가 명확해진 뒤에야 가능하다고 판단했습니다.

저희가 이해한 수준에서 API란 결국 적절한 책임을 할당받은 객체들이 협력을 위해 주고받는 메시지의 양식이었기 때문입니다.

핵심은 사용자 경험이 일어나는 프론트였습니다.

몇 개의 뷰, 모델, 컬렉션, 헬퍼가 필요한가. 또 그것들이 어떻게 관계 맺어야 하는가. 라우터의 책임은 어디까지인가. 메뉴를 눌렀을 때 들어가는 페이지와 해당 페이지에서 클릭하여 들어가는 페이지들의 관계는 어떻게 설정할 것인가. 한 페이지 안에서도 어떤 객체들이 어떻게 협력하도록 할 것인가와 같은 주제들을 고민하며 디자인했습니다.

아래와 같이 고객 여정을 따라가면서 서비스의 책임들을 목록화하는 작업도 시도하면서, 100여 개의 프론트 객체들을 생성하고 책임을 할당했습니다.

애자일과 안 맞는 것처럼 보이지만, 닌자프로젝트를 통해 시행착오를 겪은 뒤였고 고객(서브젝트)의 니즈가 명확히 드러난 상태였기에 가능하다고 판단했습니다.

프로젝트 이후 검토했을 때 달라진 부분은 20% 이하였고, 그마저도 전체적인 구조 변경은 없었습니다. 좋은 선택이었던 셈이죠

6장. API 설계

책임이 미리 설계되어 있지 않으면, 나중에 서로의 작업을 검토했을 때 ‘이 작업을 왜 거기서 했어?’, ‘이건 내 쪽에서 처리했는데?’와 같은 대화들이 많이 일어납니다.

이런 갈등을 여러 번 겪으면 작업을 하면서도 ‘이걸 여기서 해도 되나?’와 같은 고민이 시간을 지연시키게 만듭니다.

minishell이나 webserv와 같이 2~3인 체제에서는 충분한 소통으로 그때 그때 극복할 수 있었지만, transcendence의 과제 규모와 5인이라는 인원수는 그게 어렵다고 생각했습니다.

종일 회의를 하는지, 개발하는지, 충돌을 해결하는지 헷갈리는 시간을 보낼 수는 없었습니다.

책임만이 아니라, API까지 설계해야 했습니다. 책임이 명확하면 자기가 맡은 객체/작업 모듈을 의심 없이 구현할 수 있고, 핵심가치가 명확하면 자기 영역에서 발생한 문제에 대해서도 의심 없이 판단할 수 있겠죠.

그러나 앞서 얘기했듯 프로그램이란 결국 독립적인 객체들의 ‘모음’이 아니라 ‘협력’이라고 생각했습니다.

한 객체가 다른 객체에 어떤 도움을 어떻게 요청하고 또 어떻게 응답할 것인가에 대한 디자인, 바로 API가 제대로 마련되지 않으면 개별적인 객체들은 문제가 없어 보이지만 병합하는 과정에서 충돌이 빈번해질 게 뻔히 보였습니다.

메서드나 URI, 인자나 응답의 개수, 순서, 형식이 소통 없이 시시때때로 바뀌는 사태가 일어났을 테니까요.

문제는 다들 경험이 많지 않았기에, API를 어떤 형식으로 디자인하고 정리할 것인가였습니다.

선택은 포스트맨Postman이었습니다. 웹서버를 진행할 때는 엑셀이나 노션에 정리하는 것으로 그쳤지만, 단순히 요청과 응답을 정리하는 것 이상을 해보고 싶었습니다.

마침 포스트맨을 통해 API 목업 서버를 구축할 수 있음을 알게 되었고, 프론트나 백엔드의 어느 한쪽이 구현되지 않은 상태에서도 비동기적으로 개발할 수 있다는 게 매력적이었습니다.

또 브라우저를 여러 번 조작하지 않고 즉각적으로 필요한 요청을 보내고 받을 수 있다는 장점도 있었죠. 한 쪽의 데이터에 영향을 미치지 않고 필요한 기능을 테스트할 수 있다는 것도 장점이었고요.

가능한 RESTful하게 URI를 노션Notion에 정의한 뒤, POST맨에 옮기는 형태로 API 목업 서버를 구축하였습니다.

7장. 데이터베이스 설계

책임이 데이터를, 행동이 상태를 결정한다고 배웠습니다. 끄덕이며 동의했고요. 그에 따르면, 프론트의 객체들에 책임이 할당되었고, 백엔드와 주고받는 메시지에 대한 API가 정의된 지금이 바로 테이블을 설계할 때였습니다.

처음에는 프론트에서 요청하는 자원의 형태 그대로 백엔드에서 가지고 있으면 편하겠다 싶었고, 그게 당연하다고도 생각했습니다.

그러나 현재 요청들에 전적으로 대응하여 자원을 설계하는 것은 오늘만 보는 설계라는 아쉬움이 들었고, 확장에 유연하게 대응하기 위해서는 더 작은 자원들로 분할하는 것이 좋지 않을까싶었습니다.

실제로도 프론트에서 요청하는 자원을 그대로 백엔드에서 하나의 모델로 구현하기에는 다소 개념이 크고 책임도 커객체지향에 어울리지 않는다고 판단, 정규화를 진행했습니다.

다들 데이터베이스 설계 경험이 없는 것은 아니었지만, 온라인으로 ERD 툴을 사용해서 설계를 진행한 경험은 대부분 처음이었습니다. 덕분에 ERD 서비스가 하나의 큰 시장이라는 것도 알 수 있었죠.

저희는 무료로 사용할 수 있는 서비스 중 협업자간 실시간 렌더링을 지원하는 곳을 찾아 헤매다가 루시드앱Lucid.app이라는 서비스를 이용하게 되었습니다.

필요한 곳에 메모를 넣는 등 유연하게 사용할 수 있는 기능들도 많아서, 저희에게는 여러모로 적합한 서비스였어요.

프론트에서 요청한 리소스를 테이블로 만들고 정규화해가는 과정을 진행하였고, 모든 도메인이 원자값임을 보장하는 1NF, 기본키가 아닌 모든 속성이 기본키에 완전 종속하도록 하는 2NF, 기본키에 속하지 않는 모든 속성이 기본키에 이행적 종속하지 않도록 하는 3NF까지 진행하여 19개의 테이블을 확보했습니다.

이렇게 만들어진 모델 19개는 몇몇 컬럼의 추가만 있었을 뿐 프로젝트가 끝날 때까지 테이블 자체의 내용 변화는 없었습니다.

8장. UI 디자인

42에서 진행했던 모든 서브젝트들은 백엔드에서 일어나는 일들 만을 다뤘습니다. 누가 어떤 객체 혹은 메서드를 구현할지, 상호간의 인터페이스를 어떻게 할지 약속하는 것만으로 충분했죠.

그러나 트렌센던스는 실제 서비스를 만들고, 더군다나 SPA이기 때문에 ‘UI’라는 새로운 개념이 중요하게 등장했습니다.

UI 디자인을 끝내놓고 구현에 들어가야 한다고 판단했습니다.
이유는 많았습니다. 우선 브랜드 컬러는 어떻게 가져갈까, 버튼의 크기는 얼마가 적당할까, 섹션간 마진은 얼마로 놓을까, 어디까지 반응형으로 처리할 것인가 등 CSS 처리에 있어서 필요한 일관성만 수십가지였습니다.

또 가령 길드의 멤버 프로필과 랭킹의 유저 프로필이 동일하다면, 이것들은 반복 구현할 필요가 없고 재사용 가능한 동일 컴포넌트입니다. 그러나 그런 판단을 내리려면 우선 실제로 그림을 그려봐야 했습니다.

다른 개념이나 객체처럼 느껴졌던 것들이 실제로 그림을 그려보았을 때 동질성을 가지고 있고, 추상화 가능하다는 판단을 내리게 해주었습니다. 반대로 머릿속에서는 되었지만 그림을 그려보면 문제가 드러나는 것들도 많았죠.

무엇보다 객체를 정의하고 책임을 할당하는 과정에서 일차적으로 각각의 뷰가 관리할 DOM 요소들의 윤곽이 드러나긴 했지만, 혼자 코딩하는 것이 아니기에 명확한 하나의 그림을 모두가 공유해야 온전히 구현에만 집중할 수 있겠다고 생각했습니다.

42서울의 이호준 멘토님이 ‘개발은 그림을 제대로 그려야 한다. 코딩은나중 일이다.’라고 말씀해주셨었는데, 여러 번 새겨야 할 명제라고 생각합니다.

말씀을 따라 웹서버를 진행할 때 설계에 제대로 시간을 써서 구현 기간을 단축했던 경험이 팀원들에게 있었기 때문에, 의견을 모으는 데 따로 힘이 들지는 않았습니다.

Adobe XD를 이용해 디자인을 진행했습니다.

와이어 프레임을 먼저 그리고, 세부 화면 디자인을 진행하는 2단계 방식으로 진행했습니다. 와이어 프레임 역시 프로그램 차원에서 뷰가 가지는 위계에 따라 등급 및 역할을 구분하여, 단순히 화면을 디자인하는 것이 아니라 화면 혹은 화면의 각 요소를 담당하는 뷰 객체들의 협력 관계가 드러날 수 있도록 디자인했습니다. 아래는 앱 전체의 프레임입니다.

전체적으로 하나의 AppView를 놓고, 그 안에서 상단의 NavView, 우측의 AppearanceView, 메인 영역인 MainView로 영역을 분할했습니다.

특정 화면에 속하지 않는 8개의 모달 뷰는 AppView가 관리하고, 그 외의 모든 책임은 MainView 컨테이너에 올 수 있는 View 객체들이 지도록 했습니다. 아래의 경우 그룹 채팅을 진행하는 ChatRoomView의 와이어 프레임입니다.

와 이 어 프 레 임 을 보 면 C h a t R o o m V i e w 라 는 하나의 객체가 ChatAppearanceView, CVhatMessageListView, ChatRoomMenuView, ChatInputView를 통제하고 각 자식 뷰들이 또 다른 뷰들을 관리하는 구조를 볼 수 있습니다.

하나의 전체 앱 와이어 프레임에 더하여 화면 단위로 이런 와이어 프레임 작업 20개를 진행하였습니다.

와이어 프레임 작업 이후에는 세부적인 화면 디자인까지 진행하였습니다.

아래는 각각 모달 뷰들이 렌더링 된 상황의 화면과 상대 길드에 전쟁을 요청하는 전쟁 요청 뷰의 화면 디자인입니다.

모든 팀원이 UI 디자인에 대해 학습을 진행하는 것은 비효율적이라고 판단해 스케치나 제플린까지는 사용하지 않았고, 역시 Adobe XD를 이용해 같은 그림을 공유하는 정도의 목적만 달성할 수 있게 진행했습니다.

9장. 개발환경 구성

minishell이나 webserver에서는 컴파일러 버전 정도만 맞춰주면 문제가 없었습니다.

그러나 트렌센던스는 저희와 같은 카뎃 수준에서 규모가 매우 큰 프로젝트였습니다. 루비 온 레일즈와 같은 웹 프레임워크를 본격적으로 다루는 것은 모두 처음이었지만, 개발환경을 맞추는 것의 중요성에 대해 주변에서 많이 들었기 때문에 최대한 신경 쓰려고 했습니다.

다행히 모두 맥북을 사용했기 때문에 큰 산 하나는 쉽게 넘었고, 각자 로컬의 번들러 버전과 도커 버전을 먼저 맞췄습니다. 에디터는 라이브쉐어를 위해 VS Code를 선택했고, 코드 포매터는 eslint & prettier를 이용했습니다. 코딩 컨벤션은 airbnb의 ruby & javascript 가이드를 선택했습니다.

또 Gemfile로 인한 이슈를 닌자 프로젝트에서 많이 겪었었기 때문에, 될 수 있으면 미리 세팅해두려고 디버깅(pry), 데이터베이스 관리(active-admin), 페이지네이션 처리(kaminari)에 관한 gem들을 미리 Gemfile에 세팅했습니다. yarn package로는 jquery, backbone, underscore를 설치했고요.

돌이켜볼 때 개발환경 구성에 있어서 가장 잘했다고 평가할만한 것은 도커라이징을 먼저 하기로 선택한 것이었습니다. ft_server 나 ft_service를 거쳐오긴 했지만, 실제 웹 서비스를 도커 컨테이너에서 개발한다고 생각하니 처음에는 어렵게 느껴졌습니다.

그냥 로컬에서 개발한 뒤 마지막에 도커라이징을 하는 게 편하지 않겠냐는 생각이 들었고, 찾아보니 도커라이징은 선택의 문제라는 아티클들이 꽤 보였습니다.

그러나 엄격하게 판단했을 때, 아무리 같은 맥이고 ruby나 bundler 버전을 맞춘다고 하여 코드를 공유하는 과정에서 문제가 발생하지 않는다는 보장이 없었습니다.

또 어떻게 하나의 프로덕트를 만든다고 해서 해당 프로덕트를 도커라이징하려고 할 때, 수정이 많이 필요하거나 아예 뒤집어엎어야 하는 상황이 벌어지지 않는다는 보장도 없었습니다.

그래서 처음부터 도커라이징을 진행하였고, srcs 폴더에 대해 volume을 local과 공유하여 소스 코드의 수정은 vscode로도 진행할 수 있게 하였습니다.

이렇게 환경을 세팅했더니, 에디터로 수정한 코드가 컨테이너 안에서 돌아가고 있는 서버에도 즉각적으로 반영되어서 우려했던 일을 피할 수 있었습니다.

또 PR 단위를 작게 가져갔기 때문에 리뷰를 위해 브랜치를 변경해야 할 일이 잦았는데, 이럴 때에도 소스 코드만 변경되었기 때문에 다시 컨테이너를 빌드할 필요 없이 run만 진행하여 쉽게 스위칭할 수 있었습니다.

그 외에 테스트는 Rspec, Faker, Factory_bot을 활용하여 진행했습니다. 학습 비용을 잘못 예측하여 처음부터 구성하지는 못했고, 중반 이후부터 공식적으로 채택했습니다.

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