✍ Final Project 후기

4주간 나의 첫 팀 프로젝트




reciper_logo




Intro


우리팀은 토이 프로젝트 협업 툴을 만들기로 했다. 나는 프로젝트를 시작하기 전부터 개발자들 사이의 커뮤니티, 그리고 프로젝트 협업을 도울 수 있는 협업 툴에 관심이 많았다. 이유는 나 조차도 토이 프로젝트를 하려고 한다면 어떻게 누구랑 시작해야 될 지 잘 몰랐기 때문에, 이 부분에서 나와 같은 어려움을 겪는 개발자들에게 도움을 주고 싶은 서비스를 만들고 싶다는 생각을 했다.


스터디 그룹에서 나와 같이 협업 툴에 관심이 많은 분이 계셨고, 그 분과 만들고자 하는 프로젝트 아이디어가 비슷했기 때문에 SR 서비스 기획을 하는데에 큰 어려움을 느끼지 않았다.


대부분의 애자일 기반 프로젝트 협업 관리 툴 서비스는 기업을 대상으로 하다보니, 팀이 애초에 꾸려져 있어서, 협업 관리 툴 외에 별 다른 기능은 없었다.


반대로 개발자가 팀을 찾는 팀 모집 공고 서비스 같은 경우는 회사에서 팀을 모집하거나, 개발자가 토이 프로젝트의 팀원을 모집하는 서비스 외에는 별 다른 기능은 없었다.


우리는 주니어, 시니어 개발자 가릴 것 없이 토이 프로젝트를 하고 싶어하는 개발자들에게 초점을 맞췄다. 프로젝트를 하기 위해선 먼저 팀원이 필요하다. 그래서 팀원을 모집할 수 있는 서비스가 필요했고, 그 다음은 협업을 위해 협업 툴 서비스를 만들게 되었다.


이 모든 것을 갖춘 서비스라고 생각하면 된다.









📢 1. Reciper


reciper


팀원모집부터 프로젝트 협업 툴까지 한 번에 제공되는 서비스를 구현하였다. Reciper라는 이름은 내가 짓게 되었는데, 이렇게 지은 이유는 바로 개발자들에게 코드는 재료와도 같다고 생각했기 때문이다.


즉, 각 재료들을 모아 하나의 레시피를 만드는 것과 같이, 프로젝트도 각자의 코드들을 합쳐 하나의 완성 된 프로그램을 만드는 것이라고 생각했다. 레시피에는 만드는 과정과 방법들이 적혀있는 것과 같이, 프로젝트도 마찬가지이기 때문이다.


그래서 나는 Recipe + Developer 라는 뜻에서 Reciper라는 이름을 짓게 되었다.






📢 2. Landing Page


landing11


landing2


나는 랜딩페이지를 만들 때, 애니메이션을 엄청 강조했던 것 같다. 아무래도 랜딩페이지에서 기능 설명을 할 때 사용자의 눈길을 끌 만한 것은 설명에 적합한 애니메이션이라고 생각했기 때문이다.


애니메이션을 자주 사용할 것 같아서 hook으로 만들어 놓고, IntersectionObserver를 활용하여 사용자의 화면에 각 요소들이 들어왔을 때 알맞는 애니메이션이 실행되도록 구현하였다.



landing33


음.. 랜딩페이지에서 제일 시간을 많이 잡아 먹었던 부분이다 ㅠㅠ 저 때 svg를 실제로 처음 다뤄보기도 했고, 스크롤이 내려갈 때 마다 svg를 그려주는 계산을 했을 때는 정말.. 알고리즘을 푸는 것만 같았다… 나중에는 구현을 성공하고 나서 팀원들에게 소리쳤던 기억이…



view width


랜딩페이지를 다 만들고 나서 나중에 width를 싹 다 뜯어 고쳐야 하는 일이 생겼었다. 그 이유는 바로.. 내가 요소의 너비에 고정값(px)을 주는 바람에, 13인치를 쓰는 사용자는 화면이 아예 다 넘치는 현상이 생겼다. 그래서 가로 스크롤이 생기는 일이 발생했다.


프론트엔드로 개발을 하면서 사용자의 해상도를 신경을 쓰지 않은 것은 최대의 실수였다.. 나는 이 날 아침부터 밤까지 랜딩 페이지 너비를 수정하는데에 다 써야만 했다ㅠㅠ 아직 반응형을 구현하지 못했기 때문에 너비와 폰트 크기를 view width로 다 바꿔주어서 해상도에 맞게 사이즈가 나오도록 리팩토링하였다.






📢 3. Login/Logout

Login


우리는 메일 로그인, 구글 로그인, 깃헙 로그인 등 총 3가지의 방법으로 로그인을 할 수 있도록 구현하였다.


로그인 기능은 나와 같이 프론트엔드를 맡아주신 분과 공동 작업으로 진행이 되었다. 배포를 담당하던 서버분께서 Refresh Token 요청을 처리하는 로직때문에 엄청 고생하셨던 걸로 기억한다.


클라이언트에서도 Refrech Token 요청 때문에 엄청 애를 먹었었는데, 결국 리덕스로 로그인의 현재 상태를 관리해주고, 로컬스토리지에 setInteval로 일정 주기마다 refresh Token을 요청하는 방식으로 해서 해결하였다.






📢 4. Profile


Profile


프로필 페이지는 전체적으로 내가 맡아서 했다. 프로필 수정 요청과 함께 리덕스로 상태 관리를 해주었다. 우리는 2주, 4주 프로젝트 둘 다 redux-tookit을 사용하였는데, 4주 프로젝트에서는 툴킷이 지원해주는 CreateAsyncThunk까지 활용해서 비동기 요청뿐만 아니라 비동기 요청의 pendding, fulfilled 상태까지 관리해 주었다.


redux는 뭐고, redux-toolkit은 뭐지? 할 수 있는데, redux-toolkit은 redux의 코드를 짧게 쓰기 위한 라이브러리이다.(실제로 어마어마하게 짧아짐!!)


내부적으로 immer라는 친구가 있어서 mutable한 메소드(push, splice) 등등을 자유롭게 쓸 수 있다는게 장점이며, 아까 설명한 CreateAsyncThunk 비동기 메소드까지 툴킷이 지원하는 메소드이다.







📢 5. 팀원 모집 페이지 및 모집글 작성

recruit2


recruit3


팀원 모집 페이지는 말 그대로 사용자가 프로젝트를 하기 위해서 팀원을 모집할 수 있는 페이지이다. 사용자가 모집글을 작성하거나, 모집글을 작성자와 연락할 수도 있다.


이 페이지는 다른 팀원분께서 맡아주셨다! 이 페이지에서 팀원 모집글 리스트가 나오기전에 스켈레톤 로딩이 나오는데, 이 부분이 진짜 마음에 들었다. 나도 꼭 구현해보고 싶은 기능이다.







📢 6. 프로젝트 생성


projectcreate


팀원을 모집했으면 이제 프로젝트를 본격적으로 시작하기에 앞서, 팀의 프로젝트를 만들 차례이다.


팀 이름을 정하고, 팀만의 고유 URL을 정할 수 있도록 구현하였다. 그리고 자신의 팀원 초대까지 완료가 되면 드디어 프로젝트를 생성할 수 있다!


이 페이지에서는 프로젝트를 생성할 때 프로젝트 카드 로고를 유저가 이미지 업로드하는 기능으로 구현할지에 대한 이야기가 있었다. 결국 깔끔하게 랜덤 색상을 지정해주기로 결정하였다. (수정 페이지도 구현하였다.)







📢 7. 채팅


Chat_1


드디어 워크스페이스 부분이다. 워크스페이스는 말 그대로 작업 공간인데, 팀 구성이 끝났으면 이제 팀원들끼리 협업을 할 수 있는 공간이라고 생각하면 된다.


워크스페이스의 가장 첫번째 기능인 채팅이다. 채팅에서는 실시간 채팅뿐만 아니라 채팅을 실시간으로 수정 및 삭제도 가능하며 드래그 앤 드랍으로 이미지 업로드 기능도 구현하였다.


socket을 처음 사용해봐서 많은 애를 먹었었다. 심지어 socket으로 채팅기능을 구현하면서 다양한 에러들을 아주 많이 만났다.. 지금 생각하면 그 많은 에러들을 어떻게 해결했는지.. 스스로 대단하다고 느낄 정도였다..


특히 채팅 기능을 구현할 때 정말 많은 어려움을 느꼈었는데, 팀원들에게 SOS 요청을 끊임없이 보낸 덕에..나는 살 수 있었다.. ㅠㅠ 감사합니다. 곽이정신팀 여러분..


그리고 채팅의 기록이 무수히 많을 경우, 한 번에 불러올 수 없으니 인피니티 스크롤 기능을 구현하였다.


인피니티 스크롤 자체의 기능은 어렵지 않았지만, 인피니티 스크롤 후 스크롤의 위치를 잡는데에 어려움을 느꼈었다. 스크롤 위치가 0이 되면 데이터를 불러옴과 동시에 스크롤 위치는 다시 중간쯤으로 가야한다.


데이터를 불러오는 시간이 필요해서 setTimeout을 사용하면서 스크롤의 위치를 내가 원하는 위치로 구해주었더니 해결할 수 있었다. 아니.. 내가 이런 생각을 !?!?!?!?



Chat_2


그 다음은 채팅방을 조회, 추가, 수정 및 삭제할 수 있는 기능이다. 채팅방이 하나만 있으면 불편할 것이다. 예를 들어 자료 공유하는 방, 공지 사항 방, 소통하는 방 이런식으로 나누어져 있으면 유저가 사용하기에도 편리하다고 느낄 것이다.


이 부분을 구현했을 때, 나는 아직도 useEffectsocket의 이해가 많이 부족하다고 느꼈다. 이 기능을 구현하면서 저 두 가지에 대해서 많이 알아갔던 것으로 기억한다.


useEffect에는 의존성 배열을 넣는 부분이 있는데, 이 친구의 역할은 정말 정말 정말 중요하다!! 이 친구 하나로 기능이 완성됐다, 안 됐다를 구분 짓기도 한다. 의존성 배열은 프로젝트 4주 내내 나를 울리고, 웃게 했다.







📢 8. 칸반보드

kanban1


칸반보드는 beautiful-dnd라이브러리를 사용했으며, 칸반보드도 실시간으로 구현하였다. 칸반보드 기능 자체는 금방 구현하였지만, 실시간으로 구현했을 경우 A라는 유저가 칸반보드를 수정하고 있을 때 B라는 유저가 그 칸반보드를 사용못하게 Drag Block기능을 구현해야만 했다.
(왼쪽 이미지에서 드래그할 때 오른쪽 이미지의 칸반보드는 회색처리 되는 기능)


내가 구현한 부분이 아니라 디테일하게 설명하긴 어렵지만, 클라이언트에서는 socket을 통하여 Block 요청을 보냈을 때 서버에서 엄청 고생한 걸로 기억한다..


kanban2


칸반보드 Task를 수정 및 삭제하는 기능이다. 팀원간 협업이 이루어져야 하기 때문에 Task 마다 댓글을 달 수 있으며, 참여한 팀원을 걸어둘 수도 있다. 이외에도 내용 추가, 날짜 설정, 컬러 변경, 체크리스트 등등이 있다.


아무래도 Task가 담고 있는 내용이 많다보니 디자인에서 엄청 힘들었던 것으로 기억한다.







📢 9. 캘린더


calendar


마지막 기능인 캘린더이다. 캘린더는 조금 더 특별한 기능이다. 그 이유는 칸반보드와 이어져있기 때문이다. 칸반보드에서 이슈를 추가하면 캘린더에서 한 눈에 볼 수 있는 기능이다.


그리고 칸반보드를 수정하면 동시에 캘린더의 내용도 같이 변경된다. 캘린더 디자인이 정말 이쁘게 되어서 매우매우 만족하는 부분이다!







🔧🔨 Stack


project stack


우리는 공통으로 사용된 스택은 타입스크립트가 있다. 왜 타입스크립트를 썼을까? 요새 안쓰는 회사가 없어서? 대세라서? 맞다.. 일단 대세라서 공부해봤다. 선도입 후감상이다.


타입스크립트를 잘 몰랐을 때는 그냥 타입만 추가하는게 뭐가 그리 대단한거지? 라고 생각했는데, 컴파일 단계에서 에러를 잡아주는 기능은 정말 좋다는 것을 몸소 깨달았다. 에러를 잡아주지 않았다면 4주 안에 배포는 불가능 했을지도..


그리고 프로젝트를 하다 보면 팀원의 코드를 봐야 하는 경우도 있는데 이 때!! 타입이 적혀 있으면 팀원이 무엇을 하려고 하는지 의도를 명확히 알 수 있었다. 그리고 이 변수가 어떻게 쓰이는지도 명확히 알 수 있었다는 점은 분명한 매력 포인트이다.


프로젝트를 하면서 나도 처음 써봤는데 처음에 적응기간은 3~4일 정도 소요되는 것 같다.(3~4일 동안은 타입 무한 에러 지옥의 맛을 본다.) 그 뒤로는 없으면 이상한 기분이 들었고, 이제는 없어선 안 될 친구다.


그 다음 사용 스택의 특이점은 redux-toolkit이다. redux 특성상 코드가 엄청 길어지는데, 이 툴킷을 사용하면 코드량을 2배 가까이 줄일 수 있다. 실제로 실험을 해봤는데 redux가 200줄이 됐을 때, 툴킷을 사용하면 100줄 채 안되는 마법을 볼 수 있을 것이다.


redux는 비동기 요청을 지원하지 않는다. 하지만 툴킷에서 createAsyncThunk 라는 비동기 메소드도 지원해서 편리하게 사용하였다. 툴킷을 쓴 건 정말 좋았다.







🚬 프로젝트를 하면서 어려웠던 점


정말 어려웠던 점을 뽑으라고 한다면 SR 디자인 단계였다. 나는 프론트엔드를 맡았기 때문에 다른 프론트엔드분과 같이 피그마를 활용해서 디자인 작업을 열심히 했다. 하지만 취향이라는 것은 존재하고, 이 부분은 디자인쪽에서 명확히 드러났다.


내가 만들고 싶은 디자인의 의견과 다른 분의 의견 충돌이 페이지 하나 만들 때마다 발생했다. 사실 이럴 때마다 정말 난감했다. 당장 정답을 찾기 힘든 문제라고 생각했기 때문이다. 서로 생각하는 디자인이 이쁘다고 생각하니까.


각자 만들고 싶은 디자인을 구현해서 팀원들에게 투표를 얻는 방식도 했지만, 4명이다보니 이렇게도 해결이 안될 때가 많았다.


이럴 때 나는 내가 만들고 싶어 하는 디자인과 유사한 웹을 찾아서 레퍼런스로 보여드리며 설득을 했다. 이렇게 해서 원하는 결과를 얻은 적도 있지만 그렇지 않은 경우가 사실 더 많았다.


그래서 나는 생각을 조금 바꿔 보았다. 다른 분이 내주신 의견의 디자인을 유심히 관찰하고, 그 의견의 레퍼런스를 직접 찾아서 어떤지를 관찰했다. 그랬더니 꼭 내가 생각하는 것만이 정답이 아니라는 것을 깨달았다.


실제로 다른 프론트엔드 분이 내주셨던 디자인 의견이 더 괜찮은 경우도 많이 있었다. 이 때부터 나는 다른 프론트엔드 분의 의견을 많이 수긍하는 계기가 된 것 같다. SR 기획이 전부가 아니다. 실제로 개발을 하다 보면 디자인을 수정하는 경우도 많이 생기는데, 이 때 디자인에서 많은 역할을 해주셨다.


후에 이러한 생각은 나의 코딩 실력을 성장하는데에도 정말 많은 기여를 하였다. 팀원 모두가 나의 성장을 칭찬해주셨을 정도였다!🙏


자신있고 욕심이 생기는 분야면 다른 사람의 의견을 수긍하기란 쉽지 않지만, 나는 프로젝트를 하면서 많은 부분을 배워갔다고 생각한다. 특히 협업에서는 팀원의 의견을 수긍하는 자세도 필요하다고 생각한다. 이 부분은 직접 경험하지 않으면 어려운 것 같다.







🙏 팀원들에게 감사한 점


나를 제외한 3명의 팀원은 이 부트캠프 안에서 코딩 실력이 뛰어나셨던 분들이다. 처음에는 잘하시는 분들이랑 하는게 겁이 났고, 내가 잘 따라갈 수 있을까 하는 걱정이 많았다.


4주가 지난 지금 저 생각들은 정말 한심한 생각이였다는 것을 깨달았다. 나는 팀원들 덕분에 많은 성장을 할 수 있었고, 내 스스로가 성장 했다는 것이 느껴져서 프로젝트가 끝날 무렵 정말 행복했다.


여기서 성장을 했다고 느낀건 분명 2주차 때 컴포넌트 하나 분리하기 어려워했던 내가 4주차 때, 여러 개의 페이지, 여러개의 기능도 뚝딱 만들어 낼 실력을 갖추고 프로젝트를 마무리했기 때문이다.


특히나 같이 프론트엔드를 맡아주신 분께 정말 감사하다. 프로젝트 초기에 나는 잘 하고 있는 팀원들의 흐름을 망치고 싶지 않아서, 내가 막히는 부분을 내 스스로 어떻게든 해결을 하려고 했다.


하지만 오히려 막히는 것을 혼자 해결하려고 했던 것이 더 민폐였다는 것을 깨닫는데에 오랜 시간이 걸리지 않았다. 다른 프론트엔드분이랑 같이 막힌 부분에 대해서 풀어 나갈 때에는 혼자 7시간을 해도 안 풀렸던 것을 1시간도 안되서 해결한 적이 무척이나 많았다..ㅜㅜ


그 이후로 나는 막힐 땐 팀원들에게 물어보곤 했다. 당연히 조금 막히자마자 물어본 것은 아니고, 나름 마지노선을 정해놓고(3시간 정도로 기능 구현이 안 풀렸을 때로 잡았다.) 더 이상 안 풀릴때, 내가 어떻게 노력했는지 말을 하면서 왜 안되는지를 설명하는 방식으로 물어보곤 했다.


내가 질문을 하면 기다렸다는 듯이 3명이 슈퍼맨 처럼 줌에 바로 달려 들었다… 단합력은 진짜.. 감동 그 자체ㅜㅜ 새벽 5시까지 본의아니게 4명 페어도 해보고 진짜 재밌었던 기억이 많이 남는 프로젝트였다.


협업의 힘은 정말 대단했고, 왜 기업에서 소프트 스킬을 강조하는지도 깨닫게 되는 프로젝트였다. 내가 어디서 막혔는지 무슨 도움이 필요한지 명확히 잘 말했을 때 안 도와줄 팀원은 없었고, 팀의 분위기는 프로젝트 내내 중요했다.


한달동안 정말 힘들었을텐데.. 나까지 이끌고 간 팀원들에게 너무너무 감사하다. 내가 어려움을 느꼈을 때, 항상 잘 알려주셨던 곽이정신팀 모든 분들에게 감사의 말씀을 전하고 싶다!







🌱 드디어 수료식!


수료를 한 현 시점에서 나는 마치 막 세상 밖을 나온 새싹같은 기분이 든다.. 아직도 개발자로써 취업한다는게 믿기지가 않고, 내가 과연 할 수 있을까? 라는 의문이 많이 남지만 계속 성장하고 싶은 욕구가 넘치기에 끝까지 도전해보고 싶다.


나는 사실 기수 이동을 한 적이 있었다. (원래는 프리코스 9기 였…) 그만큼 작년12월의 나는 코딩에 대해서 아무것도 몰랐다. 하지만 이 만큼 성장할 수 있었던 것은 코드스테이츠에서 만난 동기들 덕분이라고 생각한다.


코드스테이츠 6개월을 하면서 좋으신 분들을 만나 스터디 그룹도 해보고, 잘하는 사람들을 만나 프로젝트를 하면서 성장의 맛도 느껴보고, 내 인생을 바꾼 6개월이라고 생각한다. 코드스테이츠 중간 중간에는 잘 몰랐는데 돌이켜 생각해보면 코드스테이츠 오길 정말 잘한 것 같다. 개발뿐만아니라 좋은 인연들까지 많이 만들어가는 것 같다.


아니…!! 심지어 수료후에도 취업할 때까지 취업을 도와준다고? 선배 기수들이 잡서칭 잡서칭 해서 뭐가 그렇게 좋은지 몰랐는데… 막상 혼자 하기 두려운 취업의 문을 같이 두드려 주신다는 점에서 정말 감사한 일이다… 특히 이력서 피드백은…!!! 크으 ~ 👍😭
앞으로 더 바쁘게 해드려야겠다는 생각이 들었다.


나와 함께한 코드스테이츠 동기분들 수고하셨다는 말씀 드리고 싶고, 중간에 DM을 언제 보내든 항상 많은 도움을 주신 엔지니어분들도 정말 감사하다는 말씀 드리고 싶다!!


이제 코드스테이츠 안녕!!!!!!!!!!!!


하고 싶지만.. 코스가 2주 더 추가되었다..ㅠㅠ 왜 인지는 비밀이지만.. 그래서 잡서칭 기간을 조금 더 미루고 코드스테이츠에서 2주 더 공부하게 되었다! 그러니 앞으로 더 이 악물고 열심히하자!