🫧 FESTINO?
한국공학대학교 축제 정보를 제공한 웹사이트이다.
2024년 6월 ~ 2024년 9월 13일(약 두달 반)동안 기획, 개발, 배포까지 ✨성공적으로 마무리한 프로젝트✨이다.
9/11 ~ 9/13 3일 동안 3천명의 사용자와 8만회의 조회수를 달성했다.
🫧 팀원 모집
개발 소모임인 DEV-TINO(https://github.com/DEV-TINO) 팀장님에게 프로젝트 아이디어를 듣고
재학생으로써 학교 학생들을 위한 웹 사이트를 만들고자 프론트엔드 팀장으로 참여하게 되었다.
팀원은 디자이너 3 + 프론트엔드 4 + 백엔드 5 => 총 12명의 인원으로 팀이 구성되었고 모두 한국공학대학교 학생들(졸업생 포함)이다.
지금까지는 4-5명 정도의 인원으로 프로젝트를 해왔었는데
12명이라는 많은 인원과 디자이너가 있는 프로젝트는 처음이라 프로젝트 결과물이 너무 기대됐다.
학교 축제가 9월 11일~13일에 진행되어서 5월부터 팀원을 모집하고 본격적인 회의는 6월 2일에 시작되었다.
🫧 프로젝트 기획
1. 레퍼런스
'우리 학교 축제 정보를 제공하는 웹 사이트를 만들자' 라는 아이디어가 나오고 나서 레퍼런스를 많이 찾아보았다.
다른 학교에서도 축제 정보를 제공하는 웹 사이트를 많이 만들어서 레퍼런스를 찾는게 어렵지는 않았다.
많은 사이트 중에, 가장 많이 참고한 사이트는 동국대학교 2024 봄 대동제 사이트였다!
축제가 종료되어서 실제 정보가 있는 화면은 보지 못했지만, 기본적인 틀은 잡는데는 도움이 많이 되었다.
2. 기능회의
어쩌면 개발보다 힘들었던게 기능회의였다.
매주 일요일마다 정기회의를 진행했는데, 정말 시간가는 줄 모르고 저녁늦게까지 했던 기억이 난다..
기능을 확정한 후, 학과와 미팅을 진행하면서 추가된 기능들도 정말 많았다.
기능 회의를 약 한 달 동안 진행했고, 이후는 한 달 반의 기간동안은 개발과 테스트를 반복했다.
(1) 메인 기능
⏰ 타임테이블
축제 3일동안 동아리와 연예인 공연 정보를 시간 별로 제공했다.
🎈 부스 정보 제공
학교 안에서 진행하는 부스와 푸드트럭에 대한 정보를 지도와 함께 제공했다.
상세 보기 페이지에서 부스 상세 정보와 메뉴 정보를 추가로 확인할 수 있다.
⌛️ 테이블링
야간부스(주점)를 예약할 수 있는 기능을 제공했다.
* 사용하는 학과에 한해서 *
💸 주문
야간부스(주점)에서 음식을 주문할 수 있는 기능을 제공했다.
테이블에 부착된 QR 코드를 통해 주문 페이지에 접근하고 메뉴를 주문할 수 있다.
또한 주문한 메뉴를 조회할 수 있다.
* 사용하는 학과에 한해서 *
(2) 어드민 기능
✏️ 부스 정보 수정
부스 기본적인 정보와 메뉴 정보, 그리고 야간 부스의 경우 예약/주문 기능 사용 여부를 선택할 수 있는 기능을 제공했다.
🪑 테이블 커스텀
주문 기능 사용 시, 테이블 개수와 테이블의 이름을 지정할 수 있는 기능을 제공했다.
⌛️ 예약 관리
테이블링 기능 사용 시, 예약 현황을 관리할 수 있는 기능을 제공했다.
추가로 예약한 사람에게 문자를 보낼 수 있는 기능도 추가했다.
🧾 주문 조회
주문 기능 사용 시, 주문을 조회하고 주문 내역을 관리할 수 있는 기능을 제공했다.
날짜 별로 주문의 수량을 볼 수 있는 통계 기능도 추가했다.
💌 커스텀 메시지
예약이 완료 됐을 때, 입장이 완료 됐을 때, 예약이 취소 되었을 때 3가지 경우에 문자가 자동으로 발송된다.
이 때, 어떤 문자를 보낼 지 수정할 수 있는 기능을 제공했다.
✔️ 주문 추가
어드민 사용자가 직접 주문을 넣고 싶은 경우, 주문을 넣을 수 있는 기능을 제공했다.
서비스 주문을 선택하면 주문의 가격이 0원으로 들어가도록 했다.
3. 와이어프레임 제작 및 API 명세 작성
기능들을 확정한 후에 와이어프레임을 제작했다.
화면에 어떤 정보가 들어갈 지, 어느 위치에 들어갈 지를 정하는 작업이다.
위의 사진과 같이 와이어프레임을 작성한 후, API 명세서를 작성했다.
와이어프레임을 작성으로 어떤 정보를 API로 주고 받을지 명확해져서 API 명세서를 작성하는데 많은 도움이 됐다.
🫧 프로젝트 진행 중 이슈
1. 총학생회와 컨택하였지만 실패
학교의 축제 정보를 제공하다보니 총학생회와 협업을 하면 좋겠다고 생각을 했다.
총학생회 측과 컨택하여 협업을 시도하였지만,, 실패했다,,
컨택에 실패한 이유는 우리의 기획만 보고는 결과물이 어떻게 나올 지 확신을 못해서였다.
학교에 등록된 정식 동아리가 아닌 점과 우리가 제대로 완성시키지 못할 경우 총학생회 측에서 안고 갈 위험이 너무 크다는 판단하에 내려진 결론 같았다.
너무너무 아쉬웠지만 그래도 우리끼리 열심히 해보자!!라는 마음으로 열심히 개발했다.
2. 연예인 정보 제공 못하게 되었음
위의 이슈와 이어지는 이슈이다,,
축제 일주일 전 문제가 발생했다.
타임테이블에 연예인 정보를 기재한다는 전제 하에 모든 개발을 마쳤는데 연예인 정보는 총학생회만 기재가 가능하다는 연락을 받았다.
총학생회와 기획사가 계약을 할 때, 연예인 관련 정보는 총학생회 측에서만 기재하도록 계약을 해서 정보 사용이 불가능하다는 것이였다.
따라서 연예인 관련 정보는 모두 삭제하고 동아리 공연을 강조하는 방향으로 수정했다.
축제의 하이라이트는 연예인 공연이라고 생각했는데 연예인 관련 정보가 빠지게 되어서 마음이 아팠다.
다음 축제 때는 꼭 총학생회와 협업을 해서 더 많은 정보를 제공하게 되었으면 좋겠다.
🫧 개발
1. 개발환경
프론트엔드는 Vue.js, 백엔드는 스프링 부트를 사용해서 개발했다.
(전체 서비스 아키텍쳐 추가)
개발 환경을 맞추기 위해서 Docker를 사용했다.
2. 실시간
어드민의 경우, 주문조회와 예약 관리를 실시간으로 할 수 있도록 개발했다.
주문 조회에서는 입금 내역을, 예약 관리에서는 예약 내역을 실시간으로 확인할 수 있도록
새로운 내역이 들어오면 탭 옆에 빨간 점을 띄워 사용자에게 알려주었다.
이때, 3초마다 조회 API를 호출하는 polling 기법을 사용하였다.
성능 개선을 위해, 조리 중 컴포넌트에는 throttle과 debounce를 적용하였다.
+, - 통해 수량을 변경하면 throttle을 적용하여 수량 변경 API를 호출하였다.
사용자가 + 또는 - 버튼을 빠르게 연속해서 클릭해도 300ms 동안 한 번의 API만 호출함으로써 서버로 보내는 요청의 수를 줄였다.
인풋을 통해 수량을 변경하면 debounce를 적용하여 수량 변경 API를 호출했다.
사용자의 입력이 변화할 때마다 API를 호출하는 것보다 debounce를 적용하여
사용자가 300ms 동안 입력하지 않은 경우에 API를 호출하도록 하였다.
3. 사용자 경험 개선
테이블링 기능을 통해 예약을 했을 때, 예약 내역이 존재하는 지 확인하고 존재한다면 이전 예약을 취소하고 예약을 진행한다.
예약이 완료되면 예약자에게 예약이 완료되었다는 문자도 발송한다.
문자 발송 시, 시간이 조금 걸리기 때문에 로딩 창을 추가하였다.
네트워크가 느린 환경에서 데이터 응답이 느리게 오거나,
데이터가 없을 시에 아무것도 없는 빈화면이 나오면 오류가 생긴 것처럼 보이기 때문에
정보가 없다는 것을 알려주기 위해 아래와 같이 우는 아이콘을 추가했다.
4. 라우터 가드
주문 페이지는 QR 코드를 통해 접속하도록 했다.
url의 형식이 'festino.dev-tino.com/order/부스 UUID/테이블번호' 로 이루어져 있는데
사용자가 없는 부스 아이디나 테이블 번호로 접근하는 경우에 에러 페이지로 리다이렉션한다.
어드민 페이지에서는 3가지의 라우터 가드를 사용하였다.
(1) Auth Guard(인증 가드)
사용자가 페이지에 접근 하기 전에, 권한을 먼저 체크한다.
만약 권한이 없다면 로그인 페이지로 리다이렉션한다.
로그인 페이지는 권한에 상관없이 접근할 수 있다.
개발팀 계정으로만 접근할 수 있는 페이지도 따로 설정해두었는데,
만약 개발팀이 아닌 계정으로 접근하려 한다면 원래 있던 페이지로 리다이렉션한다.
(2) Booth Guard(부스 가드)
부스 정보 조회나 부스 정보 수정 페이지로 접근할 때, 해당 부스가 사용자의 부스인지 확인한다.
사용자의 부스가 아니라면 에러 페이지로 리다이렉션한다.
(3) Mobile Guard(모바일 가드)
메인 페이지에 접근했을 때, 모바일 디바이스로 접근한다면 모바일 메인 페이지로 보낸다.
모바일에서 에러가 발생한다면 모바일 로그인 페이지로 리다이렉션한다.
🫧 개발 진행 중 이슈
1. 어드민 페이지 개발
프론트엔드 팀원은 나 포함 4명이였고, 그 중 한 명은 우리 팀의 팀장님이였다.
팀장님은 회사도 다니고 계시고 여러 일로 바쁘기 때문에 개발은 참여하지 않고 코드 리뷰만 해주실 계획이였다.
어드민 페이지를 개발해야하는데 레이아웃 잡는 것부터 시작해서 권한 문제, 반응형 등등.. 막히는 부분이 많았다.
그래도 만들어보고 싶어서 퍼블리싱만 했는데 많이 부족했다.
레이아웃부터 문제가 터지기 시작했고 반응형 개발을 많이 해보지 않아서 어떻게 해야할 지 갈피가 잡히지 않았다.
결국 팀장님 투입..
내가 느끼기에 가장 큰 차이점들은 다음과 같았다.
(1) Grid 레이아웃
지금까지 개발을 하면서 Grid를 사용한 적은 거의 없었다.
Flex를 사용해왔는데 전체적인 틀을 잡기에는 Grid가 더 알맞아보였다.
내가 개발했던 화면
팀장님이 개발한 화면
화면 크기에 따라 열의 개수를 조절할 수 있고, 정돈된 느낌을 줄 수 있다.
Flex를 사용했을 때보다 반응형을 구현하기 쉽고,
패딩이나 마진 같은 여백을 하나의 열로 설정하기 때문에 개발할 때 신경써야 할 부분이 줄어들었다.
이번 개발을 통해서 Grid 사용법도 익히고 레이아웃의 중요성을 깨달았다.
(2) 재사용하지 않는 것은 컴포넌트로 분리하지 않음
이건 개발하는 사람의 스타일에 따라 달라지는 부분인 것 같다.
졸업작품을 할 때는 코드 가독성을 위해서 정말 자잘하게 모든 것을 컴포넌트로 분리해서 개발을 진행했다.
이번 Festino를 진행하면서, 팀장님 스타일을 따라 재사용하지 않는 것은 따로 컴포넌트로 분리하지 않았다.
컴포넌트로 분리하면서 가장 번거로웠던 부분이 props로 데이터를 주고 받는 것이였는데,
한 파일에 작성하다보니 props를 사용하는 일이 많지 않았다.
공통으로 필요한 데이터는 Pinia로 상태관리 함으로써 기능적으로 로직을 분리할 수 있었다.
(3) 반응형
반응형 개발을 많이 해보지 않아서 갈피가 전혀 잡히지 않았었는데 이번 프로젝트가 많은 도움이 됐다.
피그마에 디자이너분들이 디자인 해 준 것을 참고해서 작업하다보니 px값으로 크기를 고정했다.
당연하게도 반응형이 되지 않았고, 어느 정도까지 반응형이 되도록 해야하는지도 모르겠었다.
tailwind css에서 제공하는 브레이크 포인트를 기준으로 여백과 글씨 크기를 줄일 뿐만 아니라,
가로로 배치되었던 UI들을 세로로 배치하는 방법도 사용하였다.
헤더바의 경우, 모든 메뉴를 표시하기 어렵다고 판단되는 시점에 햄버거 버튼이 나타나도록 했다.
메인 앱은 모바일을 타겟으로 해서 반응형 개발을 하기가 비교적 쉬웠다.
최대 너비를 500px로, 최소 너비를 375px로 정해두고 범위 내에서 반응형을 구현했다.
하지만 어드민 페이지의 경우, 웹 버전과 모바일 버전 두 개가 존재한다.
어드민 페이지에 접속하면 디바이스의 종류를 체크해서 아이폰 또는 안드로이드이면 모바일로 간주해서
모바일 어드민으로 이동하고 아니라면 웹 어드민으로 이동하도록 개발을 했다.
2. 계속되는 기능추가
처음에는 기획 -> 디자인 -> 개발 -> 테스트 -> 배포의 흐름으로 waterfall 방식으로 개발을 진행했다.
학과들과 미팅을 진행하면서 학과 측에서 추가 기능에 대한 요청이 들어와서 많은 기능이 추가되었다.
메인의 주문과 어드민의 테이블 커스텀, 주문 조회, 커스텀 메시지, 주문추가 기능은 예정에 없던 기능이였다.
추가로 어드민의 경우, 웹으로만 진행할 예정이였는데 모바일 버전까지 생겼다.
기본 기능이 완벽하게 개발되지 않은 상태에서 기능이 계속 추가되니 일정이 빠듯해졌다.
디자인이 없는데다 API도 새롭게 만들어져야돼서 생각했던 것보다 항상 시간이 더 소요되었다.
이 때, waterfall 방식의 한계를 느끼고 애자일 방식으로 개발하기 시작했다.
일주일 주기로 디자인 -> 개발 -> 테스트 -> 디자인 수정을 반복했다.
디자인은 우리컨셉에 맞게 간단한 디자인으로만 진행하고, 백엔드와 계속해서 소통하면서 API를 만들어달라고 재촉요청했다.
API까지 연결된 후에 디자이너분들께 이런 식으로 임의로 디자인했는데 부족한 것 같아서 수정해주세요.. 라는 부탁을 드리고
디자인이 나오면 디자인을 수정하면서, 새로 추가된 기능을 개발했다.
3. 보안 문제
어드민페이지에서 자신의 학과만 접근할 수 있도록 설정해두는 작업이 필수였다.
로그인 시, JWT 토큰을 사용해서 사용자를 확인하고
추가로 자신의 학과가 아닌 부스를 수정하려하면 에러페이지로 이동하도록 설정했다.
기능 개발이 완료된 후에 배포했을 때 발생할 수 있는 보안 문제인 CSRF 공격과 Dos/DDos 공격이 생각났다.
먼저 CSRF를 막기 위해 JWT 토큰을 CSRF 토큰처럼 사용했다.
Dos/DDos 공격을 막기 위해서는 요청에 rate limit를 걸어두었다.
🫧 홍보
1. SNS(에브리타임, 인스타그램)
축제 기간 일주일전부터 에브리타임을 이용해서 홍보를 시작했다.
배포된 사이트를 올리기 전, 티저부터 올렸는데 생각보다 반응이 좋았다.
티저를 9/5에 올리고, 배포된 사이트를 9/9에 올리고, 축제 시작 날인 9/11에 한 번 더 게시글을 올렸다.
너무 많이 올리면 오히려 반응이 좋지 않을까봐 게시글 업로드는 자제했다.
인스타그램 계정도 만들어서 홍보를 했다.
2. 포스터
학과 건물, 생활관, 학교 게시판 등 학교 구석구석 포스터를 붙이고 다녔다.
(물론 학교 측에 다 허락 맡았습니다!)
포스터를 보고 바로 웹사이트에 접근할 수 있게끔 QR 코드도 넣었다.
🫧 배포 이후 이슈
1. 주간부스/푸드트럭 정보 발로 뛰어서 수집
주간부스 정보는 각 동아리에게 어드민 계정을 만들어주는 것보다 우리가 업로드하는게 좋겠다고 생각을 해서 직접 업로드를 했다.
각 동아리에게 연락을 해서 정보를 받거나 동아리 인스타그램 계정에 올라온 정보를 업로드했다.
물론 사전에 동아리 측에게 정보 제공에 대한 동의를 받고 진행했다.
푸드트럭 같은 경우는 축제 첫 날, 팀장님과 열심히 돌아다니면서 푸드트럭 사장님들께 동의를 구하고 사진을 찍어서 업로드했다.
푸드트럭이 어느 위치에 설치될지 몰라서 작년에 왔던 위치로 마커를 찍어놨었다.
하지만,, 작년과 다른 위치에 설치되는 바람에 마커 위치를 급하게 수정했다.
다행히 팀원이 코드를 잘 짜뒀기 때문에 수정하는데 어려움은 없었다.
(좌표 위치를 하나하나 찍는게 번거로웠을 뿐..)
또한 어드민페이지를 개발하면서 푸드트럭은 사진만 올릴 생각으로 메뉴를 작성하는 기능을 넣어두지 않았다.
푸드트럭에도 메뉴를 목록으로 보여주는게 더 낫다고 판단이되어서 이 부분도 수정하였다.
야간부스만 메뉴를 넣을 수 있도록 코드가 작성되어 있었는데, 푸드트럭에도 메뉴를 넣을 수 있도록 하였다.
어드민 기능을 사용해서 메뉴를 넣었는데 동작이 잘돼서 뿌듯했다..ㅎㅎ
2. 주문 중복
주문이 3개가 들어가는 문제가 발생했다.
'입금 완료' 버튼을 누르면 주문이 들어가도록 되어있는데,
네트워크가 느린 상황에 API 요청을 처리하는 동안 입금 완료 버튼을 여러 번 누르면 주문이 여러 번 들어가는 문제였다.
입금 완료 버튼을 누르고 요청이 완료되기 전까지 버튼을 다시 누를 수 없도록 코드를 수정해서 문제를 해결했다.
기본적으로 추가했어야하는 로직인데 꼼꼼하게 확인하지 못했던 것 같다.
꼼꼼하지 못한 성격이 문제로 들어나게 되니 반성을 하는 계기가 되었다.
🫧 프로젝트 성과
9/11 ~ 9/13 3일 동안 3천명의 사용자와 8만회의 조회수를 달성했다.
재학생이 7천명인 것을 감안하면 10배가 넘는 조회수를 달성한 것이다!
인스타그램 계정은 8월말부터 9월까지 조회수 7200회와 도달한 계정 1500개의 성과를 이뤘다.
조회수도 중요하지만, 내가 만든 사이트를 누군가 실제로 사용한다는 점이 정말 뿌듯했다.
대학 생활을 하면서 가장 기억에 남고 애정이 가는 프로젝트가 되었다.
🫧 아쉬운 점
1. 리팩토링
급하게 개발을 진행하다보니 코드를 가독성있게 짜지 못한 것 같다.
앱에서 비슷한 레이아웃의 모달들이 많았는데, 하나의 모달로 만들어서 사용했으면 좋았을 것 같다.
또한 코드 컨벤션이 존재했지만 팀원들과 코드 작성 스타일이 많이 달랐다.
우리 팀의 코드 컨벤션은 다음과 같았다.
(1) 네이밍 컨벤션
변수, 함수 이름은 camelCase, 상수는 SCREAMING_SNAKE_CASE로 작성한다.
ex) const isMobile , const ADMIN_CATEGORY
이벤트 처리를 하는 함수인 경우, 어떤 이벤트인지 적는다.
ex) handleClickSubmitButton
(2) 브랜치 이름 컨벤션
브랜치 이름만 보고 어떤 기능을 개발한 브랜치인지 알 수 있도록 '브랜치타입/기능' 형태로 작성한다.
ex) feat/reserve-api
(3) 커밋 컨벤션
커밋을 보고 어떤 것을 개발/변경 했는지 알 수 있도록 '커밋타입:커밋내용' 형태로 작성한다.
ex) feat:connect reservation api
이렇게 컨벤션을 정해두고 개발을 했음에도 코드 스타일이 팀원마다 달랐다.
개발 초기에는 자신이 맡은 부분만 개발을 해서 다른 팀원의 코드를 볼 일이 없었다.
개발을 하다보니 다른 팀원이 작성한 파일을 내가 건드려야되는 경우가 생겼는데,
그 때 코드 스타일이 다르다는 걸 깨달았다.
다음 프로젝트를 진행할 때는 틈틈이 팀원들의 코드를 봐야겠다고 생각했다.
2. 총학이랑 협업
연예인에 관한 정보를 기재하지 못했던게 가장 아쉽다.
총학과 협업해서 연예인 정보까지 기재했더라면 사용자 수가 더 많을 거라고 예상이 된다.
이번 프로젝트를 계기로 내년에 후배들이 꼭 총학과 협업을 진행하면 좋겠다.
3. 예약/주문 시스템을 더 많은 학과가 썼다면
예약과 주문 각각 4개의 학과가 사용을 했다.
예약은 72건, 주문은 1308건이였는데 생각했던 것보다 예약을 많이 사용하지 않은 것 같다.
축제 3일동안 비도 왔고, 날씨도 더워서인지 주점에 사람이 많지 않았던 것 같다.
더 많은 사용자가 있었다면 다양한 피드백을 받을 수 있었을 것이고, 이를 통해 개선할 점을 알 수 있었을 것 같아 아쉽다.
4. 꼼꼼하지 못한 테스트
개발이 끝난 후, E2E 테스트를 진행했다.
각자가 개발한 기능을 맡아서 깃허브 이슈에 시나리오를 작성하고 테스트 결과를 작성하는 방식이였다.
https://github.com/DEV-TINO/Festino/issues/5
반복해서 테스트를 하다보니 오류를 찾는 과정이 꼼꼼하지 못했다.
'저번에 됐으니까 이번에도 되겠지' 하는 마음이 은연 중에 있었던 것 같다.
또한 몇 가지 세부사항이 누락되는 부분도 있었다.
시간이 많아서 각자 맡은 부분 뿐만 아니라 전체적으로 테스트를 해봤더라면 오류 발견이 수월하지 않았을까라는 생각이 든다.
시나리오를 꼼꼼하게 작성하고 직접 사용해보는 테스트 말고도 테스트 코드를 작성해서 테스트하는 연습도 해봐야겠다.
'이것저것' 카테고리의 다른 글
2024 TECHEER 아이디어 해커톤 (1) | 2024.06.02 |
---|