Festino
축제 가이드 Festino 제작기
다양한 축제와 이벤트 정보를 한번에 보여주는 웹을 만들자 라는 목표로 시작하게 되었다
이전부터 함께 프로젝트를 진행했었던 개발 소모임에서 주도적으로 주최가 되었으며,
팀장님과 프론트엔드 3명, 백엔드 5명, 디자이너 3명으로 진행되었다
나로선 디자이너하고 함께 진행한 지금까지 중 가장 큰 프로젝트였다
2024년 6월부터 기획해서 학교 축제기간인 9월 11일까지 약 두달 반 동안 열심히 참여했다
프로젝트 진행 방식
해당 프로젝트는 처음에는 waterfall 방법론을 이용하여 진행했다
처음에는 무리없이 진행되는가 싶었지만 속도에 취약한 waterfall 방법론의 특성 상 중간에 학과 학생회들의 요구사항들을 모두 받아들일 수 없었다
따라서 미팅 이후로는 agile 방법론을 이용해 사용자의 요구사항에 맞추어 웹을 수정하였다
개발팀과 디자인팀이 서로의 진행상황을 확인하기 위해서 매주 일요일 3시에 정기 회의를 진행했으며,
개발 중 발생하는 이슈들은 보통 해당 회의 시간에 다루었다
프로젝트 기획
레퍼런스
첫 회의 때 다같이 모여서 한 일은 축제 웹사이트 레퍼런스를 찾는 일이었다
축제 웹사이트 특성 상 학교 축제가 진행되는 기간 동안만 웹이 열려있는 경우가 많아서 사실 여기서부터 난관이었던 것 같다
결국 현재 열려있는 사이트들 보다는 축제 웹사이트를 운영했던 인스타 계정을 위주로 찾아보았고 해당 레퍼런스들을 참고하여 Festino의 기능들을 확정했다
기능 정의
처음에는 총학생회와의 협업을 염두에 두고 프로젝트를 진행했다
따라서 총학생회를 설득하기 위해서 기능이 정의가 되고 디자인이 빠르게 나와야 했다
기능을 정의하는 과정에서 팀원들간의 의견을 조율하는 과정이 필요했고 금방 정리가 되는 기능들도 있었지만 시간이 걸린 기능들도 있었다
특히 이후에 추가된 기능인 주문 기능에 대해서 이야기를 할 때는 서로가 생각하고 있는 바도 다르고, 중요하게 생각하는 것 들도 달라서 정리하는데 시간이 가장 오래 걸린 기능이다
(화면 레이아웃에 뭐가 더 중요하게 보여야 하는지... 라던가...)
와이어프레임 제작
사실 기능 정의보다 더 큰 문제는 와이어프레임 제작이었다
디자인 팀에게 개발 팀이 생각하고 있는 웹의 대략적인 구조를 전달하기 위해서 와이어프레임을 제작했어야 했는데, 이때 사용했던 Figma라는 툴이 생각보다 다루기 어려웠다
또한 어떤 방식으로 요소를 배치해야 사용자가 어렵지 않게 웹을 사용할 수 있을 지 생각하는 과정과 다른 타 축제 사이트와 다르게 Festino라는 웹 만의 정체성을 부여하기 위해서 시간을 많이 소모했다
(와이어프레임을 만들다보니 특정 축제 웹 사이트와 점점 유사해지는 것 같은 느낌이 들어서...)
해당 과정을 회의시간에 모여서 하다보니 회의 시간이 정말 길어졌다
결과적으로 사용자들에게 보여질 Main 페이지와 운영진들이 사용하게 될 Admin 페이지를 나눠서 기능 정의를 하고 해당 기능을 토대로 와이어 프레임을 만들어 디자인 팀에게 잘 전달되었다
프로젝트 개발
이번 프로젝트에서도 동일하게 vue.js를 사용했지만 앞선 프로젝트들과 다르게 composition API를 사용했다
이전보다 프로젝트 규모가 커져서인지 option API와 다르게 data, mounted, methods 등의 영역이 나누어져 있지 않아서 오히려 가독성이 좋아졌다는 느낌을 받았다
이외에 사용한 라이브러리와 프레임워크들은 상태 관리 라이브러리로는 pinia를 사용했고 css 프레임워크인 tailwind를 사용해서 보다 쉽게 반응형 페이지를 구현했다
백엔드는 스프링을 사용했고, 디자인은 대부분 Figma를 통해 진행되었다
디자인을 Figma를 통해 확인할 수 있다보니 개발자 입장에서 디자인 진행상황을 바로 확인할 수 있어 편리했다
그리고 버전관리를 위해서 당연하게도 Git과 Github를 사용했다 Festino Github 바로가기
Convention
본격적인 개발에 앞서 여러 명이서 하는 협업이기 때문에 개발 중에 지켜야 할 컨벤션들이 많았다
1. 네이밍 컨벤션
변수, 함수 이름은 camelCase, 상수는 SCREAMING_SNAKE_CASE로 작성한다
이때 이벤트 처리를 하는 함수인 경우, 어떤 이벤트인지 적는다 (handleClick...)
2. 브랜치 컨벤션
브랜치 명을 작성할 때는 브랜치의 목적을 빠르게 식별 할 수 있도록 접두사를 사용한다
(기능 개발은 feat, 버그 수정은 fix, 레이아웃 수정은 style...)
브랜치 이름에는 소문자를 사용하고, 단어 사이는 하이픈으로 구분하며 브랜치가 수행하는 작업을 명확하게 반영하는 이름을 사용한다
3. 커밋 컨벤션
커밋을 작성할 때는 가장 앞에 commit type을 작성한다
브랜치와 다르게 태그: 제목 형태로 작성한다 (feat: 새로운 기능 추가, fix: 버그 수정...)
API 설계
개발을 시작하면서 가장 먼저 한 API 설계
위에서 기능 정의를 잘 해둬서 금방 마칠 수 있을 거라고 생각했는데 API 자체가 많다보니 생각보다 오래걸렸다
그리고 당시에는 완벽하게 했다고 생각했는데 개발 도중에 생각지도 못한 필드가 빠져있거나 기능이 추가, 삭제되면서 API가 바뀌거나 추가되는 경우도 매우 많았다
개발 중 이슈
총학생회와의 협업 불발
다른 팀 구성원들은 어떻게 생각했는지 모르겠지만 사실 나는 당연하게 협업이 성사될 거라고 생각했다
결과적으로는 총학생회와의 협업은 불발되었고 팀 내에서 해야할 일들이 좀 늘어났다
우리 학교는 기존에 축제 웹사이트를 개발 한 사례가 없었고, 웹 내의 기능들도 많은데다가 큰 동아리도 아닌 소모임으로 이루어진 팀에서 협업 제안을 했던 것이기 때문에 총학생회 측에서는 너무 큰 부담이라 거절 의사를 밝혔다
물론 협업이 틀어지게 되면서 동아리와 학생회 부스 섭외등을 직접 해야해서 일이 좀 많아지긴 했지만 큰 문제는 아니라고 생각했다
문제는 웹에서 연예인 관련 정보를 제공하는 과정에서 발생했다
총학생회 측 사정으로 인해서 총학생회에 관련된 정보를 웹에 개시할 수 없게 됬는데 관련 정보를 개발 막바지에 알게된 것
해당 사안으로 인해서 마지막까지 너무 많은 수정사항이 나와서 생각보다 개발이 더 늦게 마무리 된 것 같다
계속해서 바뀌는 기능
주문과 예약 기능을 사용하는 학생회의 의견들을 수렴하면서 기능들이 너무 단시간에 바뀌거나 사라졌다
이 과정에서 agile 방식으로 바뀌면서 어떻게든 개발이 완료 된 느낌이다
사실 웹을 만드는 건 크게 문제가 되지 않았는데 급하게 개발을 하다보니 디자인을 프론트에서 직접 하는 경우가 많았다
(커스텀 테이블이라던가,,, 커스텀 메세지라던가,,, 어드민 모바일 예약이라던가,,,,,,)
이 과정에서 시간을 생각보다 많이 소비해서 개발에 지장이 가지 않았나 하는 아쉬움이 든다
어드민 페이지 개발
각 학과 학생회장과의 회의 전에 MVP가 나와야 하는 상황이었는데 프론트에서 어드민 페이지를 그만큼 만들지 못 한 상황이었다
'개발을 안했다'는 아니지만 회의 전 코드 리뷰를 받는 상황에서 반응형도 전혀 적응이 되어있지 않고 API도 연결이 되어있지 않고...
결국 팀장님께서 어드민 페이지의 대부분을 개발하셨는데 확실히 코드 자체가 많이 달랐다
주로 Flex를 사용했던 내 코드와 다르게 Grid를 사용해서 확실히 반응형을 구현하기 쉬워보인다는 느낌을 받았다
<div> 태그로만 가득한 내 코드와 다르게 시멘틱 태그를 많이 사용했다는 점도 차이점이었다
그리고 가장 큰 차이점은 역시 코드 자체가 정돈되어있다는 느낌을 많이 받았다
계속 사용되는 함수들은 util에 정리되어있고, popup 또한 한 페이지에 정리되어 있었다
<template>
<ModalBackground v-if="isModalOpen">
<BoothPopup v-if="modalType === 'boothPopup'" />
<ReservePopup v-if="modalType === 'reservePopup'" />
</ModalBackground>
</template>
이후 모바일 어드민 페이지를 제작할 때 모바일 팝업도 비슷한 방식으로 만들었는데 확실히 한번 코드를 정리해 놓고 나니 이후에 팝업을 제작할 때 확실히 제작 시간이 줄어들었다는 것을 느낄 수 있었다
Github가 너무 어려워요
생각보다 많았던 이슈인데 제대로 pull을 받고 개발을 하지 않아 다른 팀원의 코드 중 일부가 날아가는 경우가 있었다
이번 개발 할 때는 그런 일이 있을 때마다 이전 커밋을 참고해서 지워진 코드를 직접 채웠다...
이외에도 브랜치 이동을 안하고 메인 브랜치에 그대로 푸시를 해버린다던가... 하는 자잘한 실수들이 많았어서 확실히 Git과 Github에 대한 숙련도가 모자라다고 느껴졌다
해당 이슈들이 몇번 있고 나서는 개발 시작 전에는 반드시 pull을 받고, commit 전에는 branch를 확인하는 버릇이 생겼다
(실수를 한번 하고 난 뒤부터는 늘 commit 전에 긴장해서 오히려 실수를 안했던 것 같다)
최종 기능 확정
기획 단계에서 어느정도 기능들이 확정 되고 개발을 했지만 최종 기능들은 처음 기획단계의 기능들과 많이 달라졌다
7월 말 MVP를 뽑아 각 학과 회장들과의 미팅을 진행했고 이 과정에서 커스텀 메세지, 테이블 번호 수정 기능 등 큰 기능이 추가되었다
이후에도 각 학과 학생회를 통해서 전달받은 요구사항을 수렴하여 주문 시 메모 추가 기능, 서비스 메뉴 추가 기능 등 많은 기능들이 바뀌거나 추가되었다
(이때부터는 agile 방식으로 개발하게 된다)
최종 확정된 기능들은 아래와 같다
메인 페이지
메인 페이지는 따로 PC를 위한 레아이웃은 구현되어 있지 않아서 최대 너비를 500px로 제한했다
따라서 PC에서 봐도 모바일 환경처럼 보이도록 구현되어 있다
1. 타임테이블
Main 웹에 들어가면 가장 먼저 보이는 페이지 (왼쪽)
축제 3일간의 동아리 공연 정보를 시간별로 제공하고 중요 공지사항을 전달하는 페이지이다
그 날의 공연 시간이 끝나면 타임테이블에 gray scale을 주어서 공연이 끝났음을 표시했다
2. 부스 정보 제공
학과에서 진행하는 주점과 동아리에서 주관하는 주간부스, 푸드트럭 정보들을 모아놓은 페이지
지도는 버튼을 눌러서도 확대가 가능하지만 핀치 줌도 구현되어 있으며, 각 부스 관련 마커를 클릭하면 해당 부스에 대한 간단한 정보를 제공한다
또한 상세보기 페이지에서 부스의 상세 정보와 운영여부, 주점의 메뉴 정보, 해당 학과 또는 동아리의 인스타로 바로 넘어갈 수 있다
3. 테이블링 시스템
해당 테이블링 시스템이 다른 축제 웹사이트와 가장 차별화 된 점이라고 생각한다
원하는 학과를 눌러 예약을 할 수 있고, 예약 조회를 통해 현재 자신이 몇번 째 대기 손님인지 확인 할 수 있다
사용자 경험 개선을 위해서 버튼을 누를 수 없는 경우(학과를 선택하지 않았거나, 정보를 제대로 입력하지 않은 경우) 버튼들을 gray scale로 만들어 누를 수 없음을 표시했고, 특정 작업 처리를 위해 로딩이 필요한 경우 preloader를 추가했다
주문 페이지
주점에서 음식을 주문할 수 있는 페이지
메인 페이지에서는 따로 접근할 수 없고 각 학과에 테이블마다 접근 할 수 있는 QR을 제공했다
메뉴를 하나도 담지 않거나 정보가 제대로 입력되지 않은 경우 버튼들이 gray scale로 비활성화된다
처음 기획에는 없었지만 쿠폰 확인이 쉽도록 이후에 메모 기능을 추가했다
(백엔드를 한번도 경험해본 적이 없어서... 필드 하나 추가는 쉬울 줄 알았던 그 기능...)
어드민 페이지
1. 부스 페이지
어드민 페이지는 로그인을 해야만 사용할 수 있는 페이지이다
만약 특정 학과 아이디를 이용해서 로그인하면 부스 리스트에 해당 학과가 하이라이트 되어 가장 위에 위치한다
예약기능과 부스, 주문 오픈 기능은 부스 리스트 페이지에서 on, off가 가능하며,
바로가기 버튼을 누르면 부스 정보를 수정할 수 있다
부스 이미지와 메뉴정보들은 drag and drop을 이용해서 메뉴 순서를 변경할 수 있다
(drag and drop이 drag 이벤트로 생각보다 쉽게 구현되서 놀랐다)
커스텀 테이블 기능은 주문 기능을 이용할 때 테이블 번호 체계를 다르게 쓰는 학과를 위해서 추가적으로 제작했던 기능이다
2. 예약 관리 페이지
메인의 테이블링 기능을 통해 받은 예약을 확인할 수 있는 페이지이다
운영진 측에서 예약을 입장, 취소 상태로 바꿀 수 있고, 이미 입장되거나 취소 된 예약을 복구할 수도 있다
예약을 지속적으로 확인하기 위해 polling 기법을 사용해서 3초에 한번 씩 예약 목록을 새로 불러온다
또 예약의 상태가 바뀌거나 문자를 전송할 때 로딩 시간이 길어 preloader를 추가했다
예약의 상태가 바뀌면 Gabia의 문자서비스를 이용해서 지정된 문구를 전송하는데,
이후 학생회 측의 요구에 따라 문자 커스텀 기능을 제작했다
3. 주문 조회 페이지
주문 페이지를 통해 주문하면 이를 확인할 수 있는 페이지이다
주문을 받게 되면 입금 확인하고 조리되는 내용을 체크하고 조리 완료를 체크하는 것 까지 해당 페이지에서 관리한다
통계 페이지에서 축제 기간동안 판매된 메뉴 수량을 확인할 수 있다
해당 페이지에서도 실시간으로 주문의 상태가 변경되어야 하는데 이를 위해서 polling을 사용, 3초마다 api를 호출했다
또한 조리 현황을 +, - 버튼으로 변경할 때 throttle을 통해 300ms동안 한번의 API만 호출되도록 했으며,
직접 숫자를 입력하는 경우 300ms동안 동작이 없으면 API를 호출하도록 debounce를 사용했다
4. 어드민 모바일
처음부터 어드민 모바일 페이지를 기획하지는 않았지만... 소통의 오류로 인해서 만들어진 페이지이다
어드민의 기능 중 부스 정보 수정과 예약 관리 기능을 사용할 수 있다
내가 개발한 페이지라서 한마디를 더 얹자면 예약 관리 부분에 버튼이 두개 씩 들어가야 하는데 모바일이기 때문에 버튼을 둘 공간이 모자라서 시간을 많이 쏟았던 기억이 난다 (디자인 팀한테 부탁할걸...)
사이트 주소에 /mobile 을 추가해서도 해당 페이지에 접속할 수 있지만, 기본적으로 어드민 페이지에 접속하면 디바이스의 종류를 체크해서 아이폰 또는 안드로이드인 경우 모바일 어드민으로 이동하도록 해두었다
테스트
테스트는 축제 2주 전인 8월 27일 부터 진행됐다
각자 개발을 담당한 파트를 맡아서 Github Issue에 시나리오를 작성하고 댓글에 매일 테스트를 하고 오류를 찾는 방식으로 E2E 테스트를 진행했다
해당 과정에서 기종 별 UI 문제가 있거나 오류가 생기는지 확인하고, 만약 오류가 있다면 해당 오류를 최대한 빨리 수정했다
프로젝트 홍보
축제는 개발자들이 직접 발로 뛰어서 했다
오프라인에서는 포스터를 제작하여 붙였고, 온라인에서는 에브리타임과 인스타그램에 게시글을 올렸다
에브리타임에는 축제 기간 일주일 전인 9월 5일 첫 티저 글을 작성했고, 웹사이트 오픈 당일인 9월 9일날 두번째 게시글을 작성했다
(게시글 도배는... 오히려 반감을 부른다는 사례를 봤기 때문에... 이 정도만 작성했다)
프로젝트 성과
한국공학대학교 축제기간인 9/11 ~ 13 단 3일간 3천명의 사용자와 8만회의 조회수를 달성했다
내가 참여한 프로젝트에 조회수가 8만회라니...
태어나서 처음 보는 수치에 너무 놀랐고 많은 시간을 투자한 해당 프로젝트가 성공적으로 마무리 되서 상당히 뿌듯했다