PPAK

[프로젝트 리뷰] 주어진 시간은 단 5일 (feat.핀플레인) 본문

프로젝트

[프로젝트 리뷰] 주어진 시간은 단 5일 (feat.핀플레인)

PPakSang 2022. 10. 8. 19:09

프로젝트 자료

GitHub 

Youtube

 

포스팅할 주제들은 산더미인데 프로젝트를 진행하며 전공 학습을 병행하느라 정돈된 글을 작성할 시간이 많이 부족한 것 같아서 아쉽습니다. 그래도 프로젝트 리뷰는 하루라도 빨리 써야 느낀 생각을 잘 남길 수 있을 것 같아서 조금 무리해서 작성합니다.

 

교내에서 학부 행사 겸 대회를 주최했습니다. 전공에 크게 관심이 없던 학생들도 교내 행사를 통해서 흥미를 붙이는 모습을 보아서 그런지 저는 정말 긍정적인 영향을 주는 행사라고 생각합니다.

 

주제는 주어진 대구 시 문제를 소프트웨어를 통해서 해결할 수 있는 방법을 모색하는 것입니다. 단 주제가 대회 마감 5일 전에 공개됩니다. 다시 말해 5일 간 기획부터 시연 제품 개발까지 완료해야하는 일종의 해커톤이라고 볼 수 있습니다.

 

멤버는 현재도 같이 프로젝트를 진행하고 있는 윤슥 과 아양 (뮌지는 아쉽게도 석사생이라서 참여를 못했습니다,,) 그리고 디자인과 곽나 님께서 고맙게도 팀원으로 합류해주셨습니다.

 

사실 서버보단 클라이언트 개발을 맡은 윤슥이 더 와닿겠지만 저의 경우에는 디자이너와의 협업 자체가 처음이라서 같은 전공자들 끼리가 아닌 다른 분야의 전공자와 같이 프로젝트를 한다는 것이 너무 기대됐습니다.

 

따라서 본 포스팅에서는 팀원들과 5일 간 프로젝트를 진행하며 수행한 활동 기록들과 느낀점을  남겨보려고 합니다.

 

1일. 기획 및 기능 선정

약 10 가지의 아이디어 중 하나 였던 기존의 민원 관리 서비스를 개선한 새로운 형태의 서비스를 만드는 것으로 선정이 되었고, 최대한 기간 안에 컴팩트한 제품을 만들기 위해서 아래와 같이 크게 도메인과 대표 사용 기술을 적어보았습니다.

 

서비스 개요: 지도에 핀을 꽂아 민원을 작성하고 의견을 공유하는 간편 민원 관리 서비스

 

1. 계정 관리 (spring security, kakao login, redis)

2. 민원 관리 (kakao map)

3. 민원 별 감정 표현 (redis)

4. 이미지 관리 (gcp storage)

 

사용자 인증

민원을 작성하기 위해선 사용자 인증이 필수적으로 선행되어야 했었기 때문에 oAuth 를 통해 발급된 access/refresh token 을 redis 로 캐싱하는 방식으로 사용자 인증을 구현하기로 계획을 하였습니다.

 

민원  관리

민원 관리의 경우 서버에서 직접적으로 서드파티 API 를 호출할 일은 없지만 해당 클라이언트가 필요한 (위도, 경도) 정보를 저장할 필요가 있었고 이를 고려한 테이블, API 설계를 진행하였습니다.

 

감정 표현

민원 별 감정 표현은 이용자들간의 공감 횟수를 카운팅하기 위해서 추가하였습니다. 핵심 요구사항은 하나의 민원에 대해 두 개 이상의 감정 표현이 불가능하다는 것이였습니다.

 

좋아요와 같은 코멘트성 기능들은 컨텐츠(민원) 에 포함된 데이터는 맞지만 운영시에 트래픽의 차이가 존재하는 영역이라고 판단하여 별도의 도메인으로 분리하였습니다.

 

컨텐츠와 코멘트

컨텐츠는 사용자 한명(작성자) 이 수정할 수 있기 때문에 그 데이터 자체는 정적이라고 판단할 수 있고 캐싱이 매우 효율적으로 적용될 수 있는 영역이라고 생각합니다. 반대로 코멘트성 기능들은 컨텐츠보다 확실히 동적입니다. 하나의 컨텐츠에 여러 사용자가 코멘트를 남길 수 있고 생성과 수정이 잦습니다. 따라서 컨텐츠로부터 코멘트를 분리하여 데이터를 주고받는 것이 호출 시점이 다른 두 데이터를 관리하는 효율적인 방법이라고 판단했습니다.

 

이슈

이 때 핵심 요구사항이였던 두 개 이상의 감정표현을 어떻게 막을지에 대한 고민을 하였습니다. 컨텐츠의 경우 단순 key - value 구조의 데이터 캐싱이 가능하지만 좋아요의 경우 중복 검증을 위해서는 "민원에 대해 사용자어떤 감정을 남겼는지" 에 대한 데이터를 캐싱할 수 있어야 합니다. 핵심은 풀스캔을 하지 않고 상수 시간 내에 위와 같은 검증 정보를 얻을 수 있어야한다는 것입니다.

 

해결

위와 같은 요구사항을 만족하기 위해 저희는 redis 의 Hashes 자료구조를 사용했습니다. [key field value] 구조를 가지는 Hashes 자료구조는 [민원id 사용자id 감정] 을 기록하기에 적합하였습니다.

덕분에 각 민원에 사용자가 어떤 감정 정보를 남겼는지에 대한 데이터를 민원과 같이 상수 시간에 구할 수 있게 되었고, 해당 데이터를 통해서 데이터 중복 방지, 데이터 존재 여부 등등을 판단하는 로직을 구현했습니다.

 

2일. 개발 환경 셋팅 

컨셉이 확정된 후에는 윤슥과 곽나님이 인터페이스 설계를 해주었고 서버 쪽은 개발 환경에 대한 고민을 잠깐 했습니다.

어디까지 자동화 해야하나?

직전의 프로젝트는 개발 예상 기간이 한달이 넘는 비교적 널널한 일정이였기 때문에 개발 환경을 꼼꼼하게 마련하는 것에 이견이 없었습니다. 하지만 이번 프로젝트는 4일 남짓의 시간 동안 제품을 완성해야 했기 때문에 자칫 잘못 결정했다간 배보다 배꼽이 더 커질 수 있는 결정들이 많았습니다.

 

우선 저희 팀의 목표 자체가 동작하는 MVP 제품 이였기 때문에 배포는 필수였고 이에 따라서 여러가지 고민이 생겼습니다.

1. https 배포

2. 배포 자동화

3. file logging

4. 코드 템플릿

외에도 여러가지가 있었는데 본 프로젝트에서는 1, 2, 3 을 적용했습니다.

 

지난 프로젝트에서 마련한 인프라 구성을 그대로 가져갔기 때문에 반나절만에 모든 개발환경을 구성한 것도 있지만, 확실히 동작과정을 이해하고 인프라를 셋팅하니 속도가 잘 붙었던 것 같습니다.

 

배포환경

GCP Storage Connection 이 추가되긴 했지만 기존과 유사한 인프라를 새로운 VM 에 형성하는 것도 정말 의미있었던 것 같습니다. 그 과정에서 제가 과거에 포스팅한 내용을 참고하는 것이 정말 큰 도움이 되었고 다시 한번 기록의 중요성에 대해 생각할 수 있었습니다.

 

두달 전만 해도 1~2 주는 골머리를 앓으며 셋팅한 환경을 단기간에 설정하니 그 메리트는 정말 컸습니다.

 

빠르게 원격 서버를 마련하니 혼자서 클라이언트를 개발하는 윤슥님이 로컬 환경에서 편하게 작업할 수 있었고, 젠킨스님은 그 과정에서 개발 서버의 배포를 무려 40회 해주셨습니다. . . 사실 매 순간 완벽하게 배포 과정을 수행할 수 있다면 인프라를 마련안하는 것이 단기간에 시간을 조금 더 아끼는 길일 수 있습니다. 하지만 수동으로 하는 작업인 만큼 리스크있는 행동을 전체 기간 동안 가져가기 보다는 안정적인 환경을 만드는 것이 좋다고 판단하여 아래와 같이 수행했습니다.

 

로깅은 이젠 필수 불가결의 개발 환경이 된 것 같습니다. 서버 스펙의 예외에서 못잡는 에러로 윤슥님이 무슨 문제인가 궁금해할 때면 로깅 파일의 request, response, stacktrace 에 대부분의 정답이 있었습니다. 사실 이번 프로젝트에서 가장 큰 이슈는  Multipart File 을 포함하는 요청을 RequestWrapper 클래스가 필터를 진행하는 과정에서 업캐스팅 문제로 parts 를 못 불러오는 문제가 있었는데(현재 파악된 부분) 우선은 wrapper 클래스로 감싸기 전에 parts 를 초기화하는 방식으로 문제를 해결하긴 했습니다. 시간이 날 때 더 자세히 살펴봐야겠습니다.

3~5일. 개발 또 개발

나머지 기간 동안은 요구사항을 구현하고 제품 설명자료를 만드는데 모든 시간을 투자했습니다. 고맙게도 곽나님께서 집을 제공해주신 덕분에 약 3일 간 팀원 모두 방안에 갇혀서(?) 개발하고, 컨셉을 더욱 구체화 시키는 토의를 여러번 거치면서 제품을 개발했었습니다. 

 

저에게 있어서 spring 을 사용한 첫 도전은 oAuth, gcp storage connection 정도가 있었는데 두 개 모두 레퍼런스를 따라서 구현을 완료했습니다. 소셜 로그인 완료 시 kakao login 에서 넘겨 받은 refresh token 은 사용자의 브라우저 쿠키로 저장하고 access token 을 response body 로 발급하는 로직으로 하고 refresh token - access token 을 access token 기간 동안 캐싱해놓는 방식으로 인증 정보를 저장하고 있습니다.

 

이 외에 나머지 부분은 상기 요구사항 그대로 개발을 완료하였고, 서비스 완성 화면은 아래와 같습니다. 더 자세한 것은 본 포스팅 상단의 시연 영상을 참고해주시면 될 것 같습니다.

 

메인 화면

민원 조회의 경우에는 로그인 없이도 가능하지만, 이 외의 경우에는 모두 로그인이 선행되어야 서비스를 이용할 수 있습니다.

로그인은 카카오 소셜 로그인을 통해 간편하게 수행할 수 있습니다.

 

민원 조회 화면

민원의 카테고리를 나누었고, 현재 사용자가 보고있는 지도의 위도, 경도 정보를 바탕으로 민원을 불러옵니다.

핀의 경우 지도가 일정 거리만큼 축소가 되면 클러스터 처리가 되고, 클러스터화 된 민원들을 개별적으로 조회할 수도 있습니다.

 

민원 작성 화면

카테고리별 민원 작성이 가능하며 이미지를 첨부할 수 있습니다.

작성 시 해당 핀의 위치 정보가 포함된 민원이 생성됩니다.

 

마무리

5일 간의 짧은 기간 내에 하나의 온전한 제품을 만들기 위해서 정말 많은 고민을 했던 것 같습니다. 무엇보다 그 고민의 중심에는 "내가 할 수 있는 것을 하는 것" 이 핵심이였기 때문에 제가 현 시점에서 어떤 역량을 가지고 있는지 파악하는데에도 큰 도움이 되었던 것 같습니다. 현재는 교내 학습과 기존에 진행하던 프로젝트를 마무리해야하기 때문에 여유가 많진 않지만 언제든 부족한 부분을 보강할 수 있게 리스트업을 해놓을 필요가 있다고 생각했습니다.

 

또 한가지 곽나님으로부터 얻은 인사이트이자 한 가지 딜레마인 것이 기술 중심의 제품 개발인가를 고려하자는 것입니다. 디자인을 하며 사용자 경험의 측면에서 고민의 시간이 많았던 곽나님의 생각을 개발 간 듣는 것은 큰 도움이 되었습니다. 물론 기술이 없으면 제품도 없긴 하지만 여기서 핵심은 기술만으로는 제품이 완성되지 않는다는 것입니다. 아무래도 전공자들끼리 대화를 하다보면 이런저런 기술들을 사용해보고 싶고 기술 자체를 고도화 시켜나가는 것에 흥미가 생길 수 있지만 그것은 어디까지나 학습할 때에 적용되는 이야기지 제품을 만들 때는 이런 저런 경험을 쌓는 것 보다도 목표를 정확하게 달성하는 방법을 알 필요가 있다는 것입니다. 그래도 여전히 제가 딜레마라고 표현한 까닭은 아기 개발자인 저에게 새로운 경험은 늘 관심사여서 그 사이에서 잘 조절할 필요가 있겠다라고 생각했기 때문입니다.

 

작일 공개 SW 개발자 대회 멘토링을 진행중에 손영수 멘토님이 하신 말씀 중 하나가 "제품은 예산 안에서 설계되고 이루어져야한다" 입니다. 이는 언뜻보면 당연한 이야기입니다. 하지만 여기서 멘토님께서 하시고 싶으셨던 말씀은 예산에 종속된 개발을 하라는 것보단 주어진 환경에서 컴팩트한 제품을 만들어 내는 것이 얼마나 중요한 역량인지를 강조하고자 하셨다고 볼 수 있습니다. 꼭 마음에 새겨 두어야 겠습니다...

 

아무튼 짧은 기간 정말 고생한 팀원들에게 무한한 감사를 드립니다 !!

하나~ 둘~ 셋~ 리팩토링 하자 ㅋㅋ !!

Comments