Categories
나의 첫 엘리스 프로젝트를 마치며
엘리스 AI 트랙에 참여하게 된 지 어느덧 3개월, 학습한 지식을 바탕으로 직접 웹 페이지를 만들어보는 프로젝트를 진행했다. 지금까지 열심히 달려오고 있는 앨리스 AI 트랙 레이서들의 포트폴리오 웹 서비스를 구현하는 것이 프로젝트의 목표인데, 하나부터 열까지 혼자서 서비스를 구현해야 한다는 점이 너무 막막했지만 2주 간의 시행착오 끝에 결국에는 서비스를 구현 완료하였다.
프로젝트 진행 방식
일일 회고
아침에 일어나면 앨리스의 gitlab에서 wiki 기능을 활용하여 일일 회고록을 작성했다. 이를 이용하여 어제 무엇을 했고 에러가 발생했다면 어떻게 해결했는지를 회고하며 이전에 했던 작업들을 상기시키고, 이를 참조하여 오늘 할 작업 계획을 설계했다.
사진 1. gitlab 일일회고록
오피스아워
프로젝트 개발기간에는 격일마다 담당코치님에 의해서 진행되는 오피스아워 시간이 있다. 이 시간에 프로젝트 개발을 하며 막힌 문제나 기술 정보에 관해서 질문을 할 수 있다. 어떤 때는 문제 해결 하나 해결하느라 5시간이 걸려서 오피스아워 시간에 코치님께 여쭤본적이 있는데, 결국은 오타하나가 문제의 원인이었어서 뻘쭘했던 적도 있다 ㅎㅎ..
또한 매주 주말에는 코치님들이 레이서 개인마다의 코드를 리뷰해주신다. 어떤 코드를 쓰면 더 좋은 코드인지, 어떤 기술을 써야 좋은지 등을 봐주실 뿐만 아니라 세세한 오타까지 모두 신경써주시는 점에서 너무 감사했다. 코치님들이 너무 열정적으로 참여해주셔서 더 프로젝트를 할 힘이 나지 않았나 생각한다.
사진 2. 엘리스 플랫폼과 디스코드에서 열심히 오피스아워를 진행해주시는 코치님
프로젝트 개발시간
거의 하루 종일 개발에 몰두했다. 문제 해결이 잘 안 될 때는 새벽과 주말까지도 개발에 시간을 썼다. 프로젝트를 처음 하는 입장에서 구현할 기능 자체도 많아서 버거웠고 해당 기술을 연동하는 데에도 어려움이 있었다. 따라서 2주라는 개발 기간 동안 매일매일을 코딩했고 내가 원하는 기능들을 구현해낼 수 있었다.
프로젝트 선택
프로젝트 주제에는 직업 심리 검사 서비스, 도서관 대출 서비스, 레이서 포트폴리오 서비스가 있었고 각 주제마다 요구하는 기술이 달랐다. 이 중에서 나는 React, javascript, Flask, MySQL을 좀 더 깊게 학습하고 싶어 관련된 기술이 활용되는 레이서 포트폴리오 서비스를 선택했다. 구현해야 할 주요 기능은 로그인, 회원가입, 로그아웃, 유저정보 조회 및 수정, 검색 등이였다.
와이어프레임 확인과 스켈레톤 페이지 구현
프로젝트 진행에 앞서 venv나 프록시 설정 등 기본적인 react와 flask 개발환경을 구축했다. 이후 아래와 같이 기능 구현과 관련된 와이어프레임을 확인해서 필요한 페이지를 파악했고 총 네 개의 대표적인 페이지 뼈대를 react로 구현했다.
사진 3. 레이서 포트폴리오 와이어프레임
로그인 기능 구현
그리고 나서 로그인 기능을 구현했는데, 첫 단계부터 난관이었다. 로그인을 하고 나면 백엔드에서 로그인 아이디와 비밀번호가 매칭되는지 확인해주고, 확인 여부를 프론트엔드에 넘겨준다. 프론트엔드에서 로그인 정보 매치가 확인되었으면 메인페이지로 이동되게 로직을 짰다.
하지만 내가 설정한 목표와는 다르게 메인페이지에서 로그인 한 사용자의 정보를 기억 못하고 있어 해당 유저가 로그인을 했는지 안했는지 여부를 확인할 수 없었다.. ㅠ
프로젝트 2일차부터 이런 문제가 생겨서 구글링을 하루 종일 했고, 결국 찾아낸 방법이 jwt token을 이용한 방식이었다. React와 Flask 사용시 jwt token 관련해서 유용한 블로그와 요약 이미지를 아래에 소개한다. 아래 사진은 링크에서 가져왔다.
회원가입 기능 구현
회원가입 기능을 구현하기 위해서 3일간 정말 많은 노력을 했다. 사용자가 회원가입을 할 때 입력한 정보를 DB에 저장하기 위해서 mySQL을 썼는데, 프론트엔드(React)에서 입력한 정보를 백엔드(Flask)로 넘겨주는 것은 구현했으나 Flask에서 mySQL로 해당 정보들을 넘겨주는데 애를 많이 먹었다.
mySQL을 Flask에 연동하려면 우선 mySQL을 설치해서 사용할 데이터베이스와 사용자, 비밀번호를 지정해주어야 한다. 이후 해당 접속 정보를 app.config에 따로 적어서 Flask가 mySQL 유저 정보를 참조하여 연동할 수 있게 한다.
그런 다음 Flask에서 사용할 데이터 모델을 미리 만들어야 하는데, 나는 SQLAlchemy를 사용하였다. 이후 Flask에서 만든 데이터 모델을 mySQL에 그대로 옮겨준다(migration).
여기서 SQL 연동하는데 포트 설정과 오타로 인한 에러를 해결하느라 10시간 이상을 보냈다. 지금 생각하면 그 시간만큼 이러한 관련 이슈 문제 해결법은 확실하게 잊어버리지 않을 것 같다.
merge request
앨리스 AI 트랙에서 프로젝트 진행 기간동안에는 한 주에 한 번씩 master branch로 merge request하여 지금까지 작성한 코드들을 코치님들께 리뷰받아 중간점검하는 시간이 있다.
솔직히 주말에도 새벽까지 담당 코치님이 달아주시는 리뷰 코멘트를 보면서 정말 대단하다는 생각을 많이 했다. 세세하게 오타 하나하나까지도 모두 봐주시는 모습을 보면서 주말에 내가 쉴래야 쉴 수가 없었다 ㅋㅋㅋ..
달아주시는 코멘트에 맞춰서 코드를 다시 수정하고 리펙토링 하면서 어떤 코드가 좀 더 효율적이고 클린한 코드인지 알 수 있었고, 실제 프로젝트를 진행하며 스스로 깨닫는 내용보다 코치님들의 코멘트를 보고 코드를 직접 수정하면서 성장한 것이 더 컸다고 생각한다.
아래 사진처럼 이런식으로 코멘트를 몇 십개씩 달아주신다.
메인페이지, 네트워크페이지 구현
메인페이지와 네트워크페이지는 하나의 페이지에서 각각의 컴포넌트로 렌더링 되도록 구현하였다.
유저정보를 조회하는 UserDetail 컴포넌트를 따로 만들었는데, 이 컴포넌트에 props로 사용자의 아이디를 넣어주면 UserDetail 컴포넌트가 해당 아이디에 맞는 유저 정보를 백엔드에서 불러올 수 있도록 설계했다. 만약 props가 사용자 본인의 아이디라면 정보 수정이 가능하게 했고 그 외 아이디라면 정보 조회만 가능하도록 코드를 작성했다.
따라서 메인페이지에서는 redux state로 저장된 로그인한 사용자 ID를 UserDetail 컴포넌트에 props로 넣어줘서 사용자가 스스로 정보를 수정할 수 있게끔 했다.
네트워크페이지에서는 모든 user의 id를 UserDetail 컴포넌트에 props로 넣어줘서 매핑시켰다. 이렇게 매핑된 UserDetail 리스트들 중 원하는 정보만 검색할 수 있게 함으로써 검색을 좀 더 빠르게 할 수 있도록 설계했다.
최종 발표와 프로젝트 진행 소감
이후 내가 만든 프로그램을 엘리스 AI 트랙에서 지원해주는 Azure VM에 직접 배포했고, 배포된 도메인에 접속하여 구현한 기능들을 직접 시연해보며 최종발표를 진행했다. 사실 프로그램이 개발환경과 배포환경에서 다르게 작동할 수 있다는 점을 간과해서 제일 아쉽게 생각하고 있었는데, 평가하시는 코치님께서도 의도한 바와 다르게 작동되었던 기능에 대해서 깐깐하게 피드백해주셨다. 그래도 열심히 프로젝트에 임했는데 냉철하게 봐주시는 코치님이 조금 섭섭하기도 했지만, 지금은 나에게 해주셨던 말이 오랜 내공과 연륜에서 묻어나온 정말 값진 말씀이라고 생각하고 있다.
프로페셔널하게, 세세하게 코딩해라
이 말씀이 나의 단점을 일목요연하게 드러내준 정말 따끔한 말씀이었다.
항상 기억하며 어떤 일이든 임하려고 하고 있다.
마치며
엘리스 AI 트랙에서 프로젝트를 마치면서, 이제 트랙의 절반을 달려왔어도 이만큼이나 배우고 성장할 수 있게 해준 코치님들께 정말 감사했다. 아직 트랙의 절반이 더 남았으니 열심히 달려서 완주하고, 전보다 훨씬 성장한 개발자가 되고 싶다. :)