halang-log
🔥 Nexters

[넥스터즈] 동아리에서 사용할 팀빌딩 서비스 만들기

date
Aug 22, 2023
slug
nexters-moyeomoyeo
author
status
Public
tags
넥스터즈
회고
모여모여
summary
넥스터즈 23기 프론트엔드 파트로 참여하면서 만든 서비스 회고록입니다.
type
Post
thumbnail
Slide 16_9 - 1.png
category
🔥 Nexters
updatedAt
Aug 23, 2023 09:12 AM
언어

개요

넥스터즈 23기 활동을 하면서 동아리에서 사용할 팀빌딩 서비스(모여모여)를 만들었다. 이번 포스팅에서는 개발하면서 겪었던 과정들을 되돌아 보려한다. cf) 서비스 깃헙 레포는 여기다.
 

이걸 왜 만드나요?

기존 팀빌딩 방식은 아래와 같다.
  1. 모임모임 이라는 동아리 사이트에 만들어보고 싶은 서비스를 올린다.
  1. 투표를 통해 약 10개의 아이디어가 선정되며, 이를 제안한 사람은 PM이 된다.
  1. PM은 첫 세션날 본인이 만들고자 하는 서비스에 대해 발표를 하고 다른 사람들은 참여하고 싶은 아이디어에 투표를 한다. (1지망부터 4지망까지 지원 가능)
  1. 투표 결과를 엑셀로 변환한다. 이 데이터를 토대로 PM은 1지망으로 선택해준 팀원부터 차례대로 뽑는다.
 
기존 넥스터즈에서는 이를 수작업(a.k.a 노가다)으로 진행했다. 좀 더 편하고 개성있는 팀빌딩 서비스를 만들기 위해 모여모여라는 서비스를 만들게 됐다.
모여모여: 모임모임에서 아이디어를 모았으니 모여모여에서는 팀원을 모으자라는 의미
 
요게 바로 넥스터즈의 모임모임 서비스이다
요게 바로 넥스터즈의 모임모임 서비스이다
 

1차 MVP (UT 이전의 모습)

우선 전체적인 UI/UX는 아래와 같았다. UT때는 아직 백엔드는 붙이지 않았고 UI 작업만 끝내둔 상황이였다. 팀빌딩 로직은 더미데이터를 이용해 자동으로 팀에 배치되게 했다.
메인 홈
메인 홈
팀빌딩 만들기 페이지
팀빌딩 만들기 페이지
초대링크로 들어오면 보이는 페이지
초대링크로 들어오면 보이는 페이지
운영진 사이드 페이지
운영진 사이드 페이지
플레이어 사이드 페이지
플레이어 사이드 페이지
 

UT 진행 하고 받은 피드백 정리 & 액션 아이템 도출

UT 후기는 이전에 작성한 이 글을 참고하면 될 것 같다.
정말 많은 피드백이 있었고 두번의 회의 끝에 액션 아이템으로 만들었다. 아래는 이를 정리한 것들이다.
피드백 모음

홈페이지

  • 문구 변경: "개최" -> "준비"
  • 초대 링크 입력창 제거

팀빌딩 생성 페이지

  • "방"이라는 단어 대신, "팀 빌딩"으로 대치
  • (설문 추가되면서)
  • 포지션 입력창 추가
  • 팀 입력창 추가

팀 빌딩 운영진 페이지

  • 초대 링크 공유 버튼 문구 "링크 복사하기"로 변경
  • 직군별 컬럼을 가지는 UI로 변경
    • "팀 이름 | 디자이너 | 프론트 | 백엔드 | iOS | 안드로이드" 형식
  • 임의 배정 후 토스트 표시
  • 임의 배정 후 N지망 대신 별도 문구로 표시
    • “E” (extra) 로 결정
  • 팀별 선택 완료 UI에 반영하기
  • PM도 직군 컬럼에 추가시키기
  • 설문지 링크 복사하기 버튼 추가
    • 처음 진입 시 설문지 관련 모달 표시
  • 사용자 삭제 버튼 추가
    • 설문 중복 제출하는 경우 대비

팀 빌딩 플레이어 페이지

  • 전체적인 UI 개선
    • 선택할 수 있는 사람과 선택된 사람의 영역 구분
    • 팀원 선택 완료 버튼을 오른쪽 하단으로
      • 사용자 경험 개선을 위해
    • 오른쪽 팀 목록 제거
    • 팀 빌딩 완료 버튼 제거
    • 팀원 선택 완료 버튼위에 가이드 문구 추가
      • 선택 전: "N지망 선택 라운드로"
      • 선택 후: "다른 팀 선택 완료 대기중..."
      • 최종 라운드: "팀원 최종 확정하기"
    • 선택할 수 있는 사람이 없으면 문구 표시
      • ex) 선택할 수 있는 지원자가 없습니다.
  • 라운드 표시 롤체 UI처럼 개선
    • 상단에 다른 팀 선택 여부 표시
  • 팀원 해제하려는 경우 얼럿 표시
  • 팀 빌딩 완료시 롤체처럼 승리 UI 보여주기

기타

  • 라운드에 대한 정리
    • 연장전? 구성 조율? 조율? 임의? 잉여? ⇒ “팀 구성 조정” 으로 결정

(New) 팀 빌딩 설문 페이지

  • 팀 빌딩 제목
  • 이름 입력창
  • 링크 입력창 (notion, github, behance …)
  • 포지션 선택창(dropdown)
  • 1지망 ~ 4지망 선택창(dropdown)
  • 제출 버튼
  • (제출 후) 제출 완료되었습니다 문구
 
거의 모든게 바뀌었다. 또한 기존에는 회원들의 수요조사(1지망 ~ 4지망)를 할 때 구글 폼을 이용했다. 하지만 이렇게 할 경우 클라이언트에서 먼저 데이터를 갖고 있게 된다. 그래서 백엔드 팀원분들과 API 관련 회의를 할 때 애매했던 부분들이 있었다. (ex. 유저 id는 어떡하지?)
 
또한 구글폼을 이용할 경우 해당 폼에 대한 가이드가 필요해보였다. (이름, 포지션을 어떤 식으로 작성해주세요 등등) 이런 방식은 팀원 모두가 원하지 않아서 설문 폼도 직접 만들기로 했다.
 

2차 MVP (UT 이후의 모습)

메인 홈
메인 홈
초대 링크로 들어오면 보이는 페이지
초대 링크로 들어오면 보이는 페이지
팀빌딩 만들기 페이지
팀빌딩 만들기 페이지
운영진 사이드 페이지
운영진 사이드 페이지
플레이어 사이드 페이지
플레이어 사이드 페이지
리스트 펼쳤을 때
리스트 펼쳤을 때
라운드 시작할 때 보이는 모달
라운드 시작할 때 보이는 모달
개선된 서비스를 보고 같이 UT를 했던 팀원들도 많이 놀랬었다. 완전히 다른 서비스라고 칭찬해줘서 많이 뿌듯했다 ㅎㅎ 위에 작성해둔 피드백 이외에서 세세하게 변경된 것들이 있다. bgm이나 효과음도 추가했는데 확실히 좀 더 게임과 같은 모습이였으며 몰입감(?)을 주는듯 했다.
 

좋았던 점

  • 꼼꼼하게 했던 코드리뷰
notion image
이번에 라쿤과 같이 프론트엔드 개발을 진행했는데, 정말 너무너무 감사하게도 라쿤이 코드 리뷰를 꼼꼼하게 해줬었다. 개선해야 할 방향들과 놓치고 있었던 부분 등 여러 코멘트들을 받았는데 정말 유익한 시간이었다. 덕분에 구조, 설계 등 코드를 여러 방면에서 생각할 수 있는 시간이었다.
  • 새로운 css 라이브러리 사용(panda css)
이번 프로젝트에서 PandaCSS라는 라이브러리를 처음 도입했다. Zero Runtime 이며 Typescript도 지원해준다. 공식문서에서는 panda css를 서버-퍼스트 시대의 CSS-in-JS의 도전을 해결하기 위한 새로운 CSS-in-JS 엔진이라고 명시하고 있다.
const theme = { tokens: { colors: { primary: { value: '#0FEE0F' }, secondary: { value: '#EE0F0F' } ... }
위 처럼 theme에 토큰을 custom할 수 있다. 또한 아래와 같이 recipe를 정해줄 수 있어 공통 컴포넌트를 만드는데 유용했다.
import { cva } from '../styled-system/css' const button = cva({ base: { display: 'flex' }, variants: { visual: { solid: { bg: 'red.200', color: 'white' }, outline: { borderWidth: '1px', borderColor: 'red.200' } }, ... } })
이미 만들어진 recipe를 사용할 수도 있으며 여러 pattern(vstack, stack, container, center …) 들을 제공해주어 아주 유용하게 사용했었다. 축약어로도 쓸 수 있어서 (ex. background → bg) 간결하게 작성할 수도 있다. 특히 가장 마음에 들었던 것 중 하나는 중첩된(?) 속성들을 _접두사만 붙여서 아주 간단하게 쓸 수 있다는 거였다. (ex. _hover)
처음에는 JSX 코드가 너무 길어져서 가독성이 많이 떨어진다고 생각했는데, 축약어와 pattern을 적절히 잘 사용하면 괜찮았던것 같다. 그리고 확실히 inline style이 개발 시간을 많이 단축해주는것 같다.. (진짜 편하긴 함)
 
하지만 한가지, 동적 스타일링을 할 땐 주의해주어야 한다. panda는 정적으로 스타일링을 분석하기 때문에 동적으로 변하는 값은 제대로 인식하지 못한다. 실제 프로젝트를 진행하면서도 아래와 같이 코드를 짜면 색상 적용이 안됐었다.
const choiceColors: Record<Choice, Token> = { FIRST_ROUND: 'colors.red.20', SECOND_ROUND: 'colors.green.10', THIRD_ROUND: 'colors.yellow.10', FORTH_ROU: 'colors.red.10', }; export const Card = ({ name, position, choice, link, selected = false, onClick, }: CardProps) => { return ( <button className={hstack({ ... <span className={center({ background: choiceColors[choice], // 동적으로 bg가 바뀌어야 함 ... > ... </button> ); };
이를 해결하려면 공식문서에 나와있는 방법들과, cva를 사용하는 방법이 있다. 나는 가독성을 위해 아래 코드처럼 cva로 분리하여 만드는 방법을 택했다.
 
const choiceRecipe = cva({ base: { ... }, variants: { choice: { FIRST_ROUND: { background: 'purple.40' }, SECOND_ROUND: { background: 'purple.50' }, THIRD_ROUND: { background: 'purple.60' }, FORTH_ROUND: { background: 'purple.70' }, }, }, }); export const Card = ({ name, position, choice, link, selected = false, onClick, }: CardProps) => { return ( <button className={hstack({ ... <span className={choiceRecipe({ choice })}> ... </button> ); };

아쉬웠던 점

  • 넥스터즈 내부에서만 사용가능
아무래도 넥스터즈 동아리를 타겟팅으로 만든 서비스다보니 좀 더 범용적으로 사용할 수는 없다. 기본적으로 폼의 양식이 정해져있다는 것과 이에 따라 팀빌딩 루틴이 fix되어 있다는게 조금은 아쉬운것 같다. 그래도 개발 기간이 비교적 짧았다는 것과 (UT 이후 다시 만들어서 1달 정도..?) 애초에 우리 동아리를 위한 서비스였다는걸 생각하면 괜찮은것 같기도 하다. ㅎ.ㅎ
 
  • SSE
사실 요건 아쉬웠다기 보다 고민이 많이 됐던 부분인데 일종의 기술 부채일수도 있을 것 같다. 기능 중 서버에서 클라이언트로 단방향 데이터를 전송해야 하는게 있어서(팀원 조정, 라운드 변경 등) SSE(Server Sent Event)를 이용했다. 하지만 문제는 간혹가다 이 이벤트를 제대로 수신하지 못한다는 것이다. 등록해둔 이벤트 리스너를 삭제하고 다시 등록하는 사이에 이벤트 수신이 될때가 그 예다. useEffect에 리스너들을 등록해두고 return 함수를 이용해 이를 remove 하는데 handler에서 데이터를 직접 조작하는게 어려움이 있었다. 왜냐하면 클로저 때문에 해당 useEffect dependency에 이를 무조건 추가해줘야 했는데 이렇게 될 경우 아까 말했던, 이벤트 리스너의 공백 기간이 빈번해지기 때문이다. 그래서 refetch를 호출하는 방법으로 바꿨으며, 불가피하게 이벤트 리스너를 받지 못할 경우를 대비해 10초마다 polling으로 fetch하는 것을 추가했다. 좀 더 우아한 방식이 있다면 리팩토링을 해봐야겠다.

끝으로

감격의 눈물ㅜㅜ
감격의 눈물ㅜㅜ
정말 정말 정말 생각하지 못했었는데 1등상을 받았다… 이번 기수 팀 대부분 출시도 하고 홍보도 많이 해서 3등상만 받아도 잘했다고 생각했는데 예상하지 못한 1등상을 받았다. 그만큼 우리 서비스가 그래도 멋있었다는 뜻이겠지..! 많이 뿌듯했고 기뻤다. 팀원들 모두 열정 넘치고 능력자라 많이 배우고 행복한 두달을 보냈던것 같다. 진짜 우리팀 너무 최고야!!!!🫶 일정이 좀 타이트해서 팀원들이랑 따로 놀러가지 못했었는데 상금도 받았으니 회식도 하고 뒷풀이도 재밌게 해야겠다. ㅎㅎ
그리고 최종발표날 다음 기수 CEO선거도 진행했다. CEO 후보에 올라서 앞에 나가 공약(?)도 말하고 나름의 포부를 밝혔다ㅋㅋㅋㅋ 많은 분들이 응원해주셔서 정말 감사하게도 CEO에 당선됐다. 내년에 진행할 24기 넥스터즈를 위해 열심히 노력해야겠다. (이번 기수 운영진분들 정말 최고였다…🥹❤️) 아자아자!!