WAF 프로젝트 회고

Minjae Kwon·2021년 1월 7일
1

🐋    Monologue

목록 보기
2/4
post-thumbnail

이 회고록은 영국 에든버러 대학의 툴킷을 참고하여, 다음의 4f 에 기반하여 작성되었습니다.

Facts 사실 | An objective account of what happened
Feelings 느낌 | The emotional reactions to the situation
Findings 교훈 | The concrete learning that you can take away from the situation
Future 앞으로 | Structuring your learning such that you can use it in the future

Facts (사실)

🍊 시작

네 명의 팀이 결성되고, 협업을 위한 깃플로우에 대한 공식 설명이 끝난 후에 구글 행아웃을 통해 첫 미팅을 가졌다. 2주 간의 프로젝트 기간에 미루어 약간 챌린징하다고 느껴진 냉장고 관리 Web app을 만들기로 했다. 프론트엔드와 백엔드를 두 명씩 나누고, 기술 스택은 새로운 것보다는, 네 달간 배운 것들을 집중 응용하는 것을 목적으로하여 react.js | node.js, express.js | sequelizer, mysql | Naver Oauth, Google Oauth | AWS S3, EC2, RDS 로 구성하였다.

나는 코드스테이츠에 들어오기 전부터 HTML5, CSS3, SASS, Javscript, React 를 별도의 udemy 강좌를 통해 학습하였는데, 클라이언트와 서버의 통신이 어떻게 이루어지는지와 인증과 배포에 대한 부분을 추가 보강할 필요성을 느끼고 있었기 때문에 백엔드에 지원하였다.

🍊 과정

SR(Software Requirements) 가이드라인에 따라 이틀 동안 다음 작업을 진행하였다.

프로젝트 기획 및 범위 설정
요구되는 최소페이지(로그인, 회원가입, 마이페이지, 로그아웃)들과 유저가 로그인 없이도 어플리케이션을 체험 가능하도록 해야 한다는 데에 역점을 두고 기능 페이지를 구성했다. 사용자가 마켓에서 장을 봐오고 나서 식재료를 우리 app의 input 창에 입력하면, app 상의 냉장고에 식재료를 넣고나서 식재료의 카테고리에 기반하여 그 소비기한을 알려주는 것이 핵심 기능이다. 그리고 그것을 미리 체험해 볼 수 있는 demo/tour 페이지를 만들기로 하고 (Bare minimum), 이후 여력이 남는다면 각 재료를 클릭했을 때 만들 수 있는 레시피를 youtube API 를 사용하여 동영상으로 보여주기로 하였다. (advanced). figma 툴을 이용하여 각 페이지가 하는 역할에 대해 의논하였고, 결과적으로 우리는 advanced 단계까지 구현을 마쳤다.

나는 API docs 작성을 했다. 우선 플레인 텍스트로 작성하여 github wiki 에 공유하였으나 가독성이 아쉬웠고, 다른 팀원분께서 gitbook 으로 리팩토링 해 주셨다.

프로젝트 태스크 카드, 마일스톤 작성
github repository 의 issues 와 projects 항목을 활용하여, 각 태스크 카드를 하나의 issue 로 발행하고, 가급적 하나의 태스크 카드가 하나의 커밋과 매핑될 수 있도록 세분화하고자 노력하였다. 마일스톤은 예상 소요 시간으로서, 코드스테이츠에서는 팀원들이 투입할 수 있는 공식시간 (8시간 5일 2주 * 4명 = 320 시간) 에 태스크 카드의 총합 시간이 맞아떨어지는 지 비교하여 프로젝트 규모를 예측 조절하기 위해, 미리 처음부터 끝까지 태스크 카드의 내용을 미리 써놓을 것을 권장하였다. 하지만 우리 경험치로는 처음부터 끝까지 세세히 예측하는데 어려움을 느껴, 대신 매일 할 일을 마치고 다음 날의 태스크 카드를 작성하는 것으로 대체하였다.

팀룰 설정
커밋 규칙, 브랜치 규칙, 변수이름, 디자인 패턴, 그리고 개발 환경을 공통적으로 가져가기 위해 VS code에 깔린 prettier, eslint 등을 다같이 사용/미사용으로 합의하였다.

🍊 진행

평일에는 아침 10시에서 저녁 6시까지 진행하고, 다시 저녁 8시부터 이르면 저녁 11시 혹은 다음 날 새벽 1시를 남짓하여 마무리하였다. 주말에는 오후 3시부터 저녁 7시까지 진행하였다. 2020년 12월 21일부터 새해 2021년 1월 7일까지 24시간 off 는 크리스마스 당일과 새해 당일뿐..!

항상 네 명 모두 구글 행아웃에 모여서 실시간 의견을 주고 받고, 클라이언트와 서버 각자 코딩을 해야 할 때에는 별도의 줌 미팅방을 만들어서 진행했다. 서버의 경우 코드량 보다는 초기 세팅이나 배포 과정 등에서, MVC 패턴에 입각하여 어떻게 폴더를 구조화할지, 라우트를 어떻게 그룹핑할지, EC2, RDS 설치 시 세팅은 어떻게 할 지 의논이 계속 필요했기 때문에, 주로 화면을 공유하며 페어프로그래밍 형식으로 이루어졌다. 나는 VS code 상에서 driver 역할을 하며 구글 Oauth 를 사용한 로그인 인증 후 회원정보를 가져오는 일을 담당하였고, 다른 백엔드 팀원 분께서 AWS 상에서 driver 로서 작업하시면서 네이버 Oauth 를 담당해주셨다.

MVC 패턴
처음 몇 개의 핵심 route 만 가지고 세팅할 때는, index 파일에서 routes, controller 폴더로 이어지는 구조가 과해보였다. 그러나 결과적으로 앱 사이즈가 커짐에 따라 기능을 추가해야 할 때, 이미 각 기능들이 독립적으로 구조화되어 있어 새로운 기능을 추가하기가 훨씬 용이했고, 수정이 필요할 때도 필요한 기존 기능에 매치되는 파일을 찾기 쉬웠다.

서버 환경변수 처리
로컬에서는 .env 파일로 관리했다. 단, 이 파일은 깃헙에 올리지 않으므로 배포시에는 환경변수를 어떻게 변경 적용할지 조사해보았다. 환경 변수가 아주 많지는 않아서 EC2 터미널에 직접 export 하는 것으로 처리했다. 배포에서 문제가 잦다고 들어, 프로젝트 초기부터 Hello World 배포, 기본적인 페이지 구현이 끝나면 postman 으로 http 요청을 보내 작동이 잘 되는지 자주 점검했다.

의외의 복병: Sequelize 마이그레이션 기능
기초적인 데이터베이스였지만, 초기에 sequelize 와 sequelize-cli 를 사용해 mysql에 테이블/모델 생성하는 일을 수도 없이 번복했다. 처음 sequelize-cli 를 통해 생성한 테이블에서 항상 고쳐야 할 부분이 하나 두개씩 튀어나왔는데, sequelize 에서 사용하는 migration 은 하나의 커밋과 같아서 항상 migration 파일을 기반으로 sequelize 명령어를 사용하여 migration:undo 또는 undo:all을 해야 했다. 성미에 못 이겨, migration 파일을 직접 삭제하고 터미널에서 직접 mysql 로 접속 후 sql 문을 작성하여 테이블을 삭제 또는 필드를 수정해버리면.. 비록 수정된 데이터베이스가, 남아있는 migration 파일 상태와 일치하는 듯 보이더라도, 이제까지 생성한 migration 기록은 꾸준히 남아있고 이건 수정되지 않았기 때문에, 향후 migration 작업 시에 에러를 띄우게 된다. 예를 들어, 나는 undo를 하고 싶지만, undo 명령에 기반이 되어야 할 migration 파일이 없는 상태라면 에러를 띄운다. sequelize는 다 기억하고 있다. 그리고 어떻게든 로컬 환경에서 돌아가는 것으로 만족하고, migration 파일 관리를 엉망으로 하면 어차피 EC2 가상 머신에서 다시 에러를 마주하게 되므로 sequelize 를 사용한다면 '제대로' 동작법을 익히는 것이 좋다.

CSS 이후 배포
서버 구성이 비교적 단순한 편이라 1주 차에 대부분을 마무리하고, 2주차 초반에 Oauth 조사 및 구현까지 완료하고 나서부터는 프론트엔드 코드를 읽어보았다. 우선 기능적인 부분을 구현하고 CSS는 마지막 2-3일에 걸쳐 네 명이 함께 진행했다. 어려움은 곳곳에 있었다.

모든 페이지의 CSS가 어느 정도 입혀진 후 첫 배포를 했다. 그런데 Oauth 상 redirection url 를 포함하여 서버 주소가 localhost:4000 기반으로 하드코딩되어 있어 수시로 로컬 환경에서 수정하고, 또 배포 환경에서도 점검할 때마다 서버 주소를 로컬 주소에서 EC2 주소로 변경해야 하는 불편함이 있었다. 클라이언트에서도 서버 주소를 환경변수 처리하여 적용해 볼 수 있을지 궁금하다.


문제 탐구: props drilling 의 한계
리액트에는 리액트 라우트가 접목되어, 어떤 비동기 처리가 끝나면 this.props.history.push 를 통해 강제적으로 페이지 이동을 시키는 경우가 종종 있었는데 이 때 props 전달이 되지 않는다는 문제가 있었다. 이 문제를 프론트엔드 팀장님께서는 localStorage 를 사용하여 해결하셨다. 다만, 그럼에도 불구하고 로그아웃이 되지 않는다는 마지막 문제가 있었다. 나는 이 문제에 혼자 저녁 8시부터 새벽 1시까지 매달렸다. 모든 컴포넌트의 종속관계를 그려보고, 페이지 전환이 this.props.history.push 를 통해 이루어지는지 아니면 상위 컴포넌트에서 조건식으로 필터링되어 이루어지는지 구분하고, 페이지를 전환할 때마다 필요한 데이터가 props 나 this.props.history.push 를 통해 끝까지 전달이 되는지 추적하여 마침내 해결을 했다. 하지만, 이후에 CSS 를 통해 코드가 추가 변경되자 다시 같은 문제에 빠졌고, 결국 팀장님께서 로그아웃은 강제로 메인페이지로 이동하는 것으로 해결하셨다. 이 때 로컬스토리지도 아예 비워버리자고 제안하여, 로그아웃 완성. props 로 전달되는 데이터를 추적하는데 분명 한계가 있었다.

문제 탐구: 냉장고 위에 재료 이미지들 반응형으로 구현
다른 날은 반응형 CSS를 구현하기 위해 이미지 아이템을 flexbox 로 적용하는 문제로 혼자 새벽 2시까지 지새웠다. 도전 과제인 즉슨 냉장고 일러스트 위에, 사용자의 냉장고에 담긴 재료에 해당하는 일러스트 이미지를 냉장고 비율 (냉장고, 냉동고의 선반)에 맞게 겹쳐 올리는 것이었다. 이미 프론트엔드 팀에서는 여러 시행착오 끝에 position: absolute 로 해결하기로 일단락 했지만, 나는 아무리 생각해도 flexbox 를 쓰면 반응형이 가능할 것 같았다. 여기서 나의 첫 번째 과제는 이미지를 flex item 으로 설정하였음에도 꼼짝도 하지 않는 재료 이미지를 움직이는 것이었다. 검색 결과 flexbox 와 이미지는 그렇게 궁합이 좋지 않으며, 만약 img 태그를 쓰고 싶다면 div 에 감싸고 그 div 를 flex item 으로 조절하라는 stackoverflow 의 공통된 답변을 얻었다. 나는 먼저 기존에 div에 background-image 로 구현되어 있었던 일러스트 부분을, screen reader 사용자들의 접근성을 고려하여 이미지는 모두 img 태그에 담은 후, div 에 감싸는 것으로 리팩토링했다. 결과적으로 각 재료를 냉장고 칸에 맞게 flex-basis 비율로 할당하여 반응형을 흉내내는 소기의 목적은 이루었지만, 원하는 기능 구현은 실패했다. 화면을 정대각선으로 줄여줘야만 내가 설정한 비율이 유지되고, 만약 가로나 세로 방향으로만 화면을 조절하면 img 를 감싼 div의 크기와 img 의 크기가 다르기 때문에 줄어드는 비율이 달라서 결국 img 가 냉장고 밖으로 튀어나오게 되었다. 잠깐 좋다가 말았지만, 적어도 '왜 안 되는지'에 대해 충분히 이해하는 수준이었기 때문에 우선은 의미있는 실패로 기록할 수 있게 되었다.

🍊 결과

마지막 2-3일을 CSS에 갈아넣은 효과가 있었다. 네 명이서 메인 색깔을 선정하고 모든 페이지의 테이블과 버튼의 테두리 하나 하나, 위치 하나 하나 의논한 보람이 있는 만큼 전체적으로 통일성이 있고 완성도가 급 상승하였다. 집단 지성의 힘이 발휘되어, 배포 점검을 할 때 문제가 발생하면 어디서 어떤 문제가 있는지 실시간으로 의견 교환을 하며, 서버와 클라이언트를 아울러 에러 핸들링을 할 수 있어서 문제 해결도 수월했다.

Feelings (느낌)

이번 2주는 오롯이 밥 먹는 시간, 자는 시간, 그리고 프로젝트 하는 시간으로 구성되었다. 그런데 신기하게도 그다지 힘들지 않았다. 팀 분위기 덕분이었다고 생각한다. 페어프로그래밍 때부터 잘 맞아서 프로젝트를 함께 하기로 약속했던 분과 같이 진행하게 되기도 했고, 새로운 분들도 모두 쾌활하여 항상 밝은 분위기 속에 프로젝트가 진행되었다. 다들 시간가는 줄 몰라 '벌써 저녁 시간이야? 벌써 00시네' 는 모두의 단골 멘트였다.

어떤 문제에 대해 다각도로 해결책을 고민해보는 것도 늘 재밌었다. 무엇보다 다른 분들이 내가 미처 생각해보지 못한 창의적인 해결책을 제시하실 때면 새롭게 좋아하는 과일, 장소, 취미를 발견했을 때와 같은 짜릿함을 느꼈고, 그 기분들은 나의 에너지 원동력으로 작용했다.

물론 어떤 문제에 대해 집요하게 파고들어서, 그 문제가 해결됬을 때 혹은 해결되지 않더라도 스스로 그 원인과 다음 시도의 방향성을 잡을 수 있는 단계에 다다랐을 때에도 짜릿했다. 백엔드를 맡았지만, 프론트엔드에서 작성한 코드 리뷰를 하며 withRouter 기능이나 localStorage 사용법을 익히고, 소비기한 계산 함수를 비롯한 몇 가지 기능 구현을 함께 고민해 볼 수 있어서 좋았다. 그저 감사함을 느낀다.

Findings (교훈)

꼼꼼한 프로젝트 기획
시스템 아키텍쳐 설계와 와이어 프레임 작성이 초반에 디테일하게 작성되지 않아, 후반에 어려움을 겪었던 부분들이 있어 다음 프로젝트 때에는 SR 기간을 늘리더라도 가능한 디테일한 설계를 해야 겠다.

UI 목업 제작
프로젝트 후반, 즉 CSS를 시작하는 시점에서 다같이 UI 디자인을 했는데 이 부분을 초기 기획 단계에 꼭 포함시켜도 좋을 것 같다. 특히 리액트 공식문서의 'Thinking in React' 편을 보면, 이렇게 UI를 먼저 디자인한 후에, 각 UI 부분을 컴포넌트화 할 것을 추천하고 있는데 UI와 컴포넌트를 1:1로 매핑하여 종속 관계를 구조화하는 것이, 리액트로 컴포넌트 구성을 하기에 수월하기 때문일 것이라고 생각한다. 그 이유에 대해서는 이전 블로그에도 작성한 바가 있다.

깃헙 readme, wiki
CSS가 프로젝트의 완성도를 보여줬다면, 우리의 코드 저장소인 github의 비주얼 담당을 할 read.me 와 wiki 에 기록된 내용들을 예쁘게 정리해 볼 필요성을 느낀다. 아, 여러 내용을 notion 이나 여러 채널에 분산하지 않고 github wiki 에 모아 소스를 일원화 한 것은 매우 좋은 선택이었다.

상태관리의 필요성
어느 날 잠들 무렵 생각해보니, 우리가 localStorage 를 사용해야했던 이유는 모든 컴포넌트에서 접근이 가능해야 하는 상태값이 존재했기 때문이다. 이걸 바로 Redux 가 해결해주고 있는 것이었다! 그런데 요새는 React hooks 를 통해서도 상태관리가 가능하여 Redux 가 조만간 사장될 수도 있다는 (다른 팀원분들 피셜) 얘기가 들린다고 한다. 어떤 툴을 사용하든지 간에, 어디서든 특정 상태값에 접근할 수 있는 방법 구현은 반드시 필요하다.

소셜 로그인 분기
네이버와 구글 Oauth 를 구현하며 클라이언트 단에서 두 소셜 로그인 후, uri 에서 authorization code 를 추출하여 redirect url 로 설정된 서버의 /callback 라우트로 전송했는데, 서버에서는 네이버에서 온 요청인지 구글에서 온 요청인지 확인할 방법이 없었다. 결국 차선책으로 각 authorization code 의 길이가 다른 점에 착안하여, 길이가 짧으면 네이버 요청 건으로, 길이가 길면 구글 요청 건으로 분기하여 access token 교환을 요청했다. 하지만 authorization code 의 길이란 외부 서버에서 hash 로직을 바꾸거나 묘종의 이유로 변경 사항이 생길 경우, 즉 우리가 통제할 수 없는 변수로 인해 에러를 발생시킬 수 있기 때문에 가급적 우리가 컨트롤 할 수 있는 방안을 찾고 싶었지만 모두 머리를 맞대도 묘수가 떠오르지 않았다. 프로젝트를 마치고 다른 팀에 물어보니, access code 를 전송해오는 서버가 구글인지 네이버인지를 확인해서, 서버의 구분된 라우트 /googleCallback, /naverCallback 로 구분하여 처리했다고 한다. 유레카!

Future (앞으로)

우선 이 블로깅을 작성하며 첫 프로젝트를 처음부터 끝까지 되돌아본 것이 future 부분의 큰 시작이다. 블로그 작성 현재 이미, 4주간 지속될 final project 의 팀 배정과 아이디어 선정이 끝난 상태이며 이번에는 프론트엔드를 맡게 된 만큼 findings 에서 발견한 개선점들을 접목해 볼 것이다.

4주간 새로운 프로젝트에 매달리겠지만, 이후에는 첫 프로젝트 코드를 리팩토링 해서 반응형 CSS 를 꼭 실현해보고 싶다.

WAF 로 냉장고 관리 Start 🥦

냉장고 관리 종결앱 - What's in my fridge?

profile
Front-end Developer. 자바스크립트 파헤치기에 주력하고 있습니다 🌴

0개의 댓글