워크로그 개발기

Sep 10, 2018 • typescript razzle after.js


이 글은 2018년 9월 10일에 야놀자 기술 블로그에 게시된 글을 백업한 것 입니다.

저는 야놀자 CX 서비스실의 API 파트에서 백엔드(90%)와 웹 프론트엔드(10%) 프로그래머로 일하는 송요창입니다.

개정된 근로기준법에 따라 2018년 7월 1일부터 300인 이상 규모 기업인 경우 주 40시간(최대 52시간) 근로합니다. 이에 따라 야놀자에서도 업무 집중도 향상과 함께 업무 시간을 명시하는 방안이 논의되었습니다. 이런 배경 속에서 만들어진 워크로그 개발 경험을 이야기하겠습니다.

개인의 업무 시간 작성

근로 시간이 기존 대비 단축되면서 각 개인의 업무 시간을 기록하고 기준 근로 시간을 초과하였을 때 이를 소진하도록 하는 방향이 결정되었지만 어떤 도구를 사용할지가 문제였습니다. Timing, TMetric, 출퇴근 기록기 알밤 등 다양한 도구를 사용해서 각자 기록을 시작했습니다.

1차 시도 - Workflow + Alfred 활용

그러던 중에 캘린더를 이용해서 출/퇴근 기록을 남기고 슬랙(Slack)으로 메시지를 발송하는 방법을 CX 서비스실 강미경 님이 공유합니다.

미경님은 개발자같은 기획자

캘린더와 - 유료인 경우 - 슬랙 모두에 기록이 남는 장점이 있습니다. 사용하기 쉽습니다.

iOS 앱인 Workflow를 이용해서 캘린더에 이벤트를 등록하고 슬랙으로 메시지를 전송.

데스크톱이나 노트북은 Alfred의 Workflows 기능으로 해결할 수 있었습니다.

Alfred 워크플로우 공유

Workflow + Alfred로 워크로그를 기록하는 단점

개인적으로 편리했지만 CX 서비스실 내부로 전파하여 사용하기에는 문제가 있었습니다.

  • 안드로이드 휴대전화를 사용하는 경우 Workflow를 사용할 수 없습니다.
  • 아이폰을 쓰더라도 유료로 판매되는 Workflow를 사지 않으면 쓸 수 없습니다.
  • Alfred를 쓰더라도 Power Pack을 구매한 사용자만 Workflows를 적용할 수 있습니다.

돈이 필요한 Alred

2차 시도 - 슬랙봇 활용

위에서 언급된 문제를 해결하고 구성원 누구나 추가 앱 설치 없이 손쉽게 접근할 수 있는 슬랙봇에 주목합니다. 캘린더가 아니라 데이터베이스를 활용해서 개발하면 어떨지 논의했습니다.

늦은 저녁(대략 23시부터 03시)에 Firebase 실시간 데이터베이스(Realtime Database)와 Firebase 클라우드 함수(Functions)를 활용해서 단순한 슬랙봇을 만들었습니다.

슬랙을 실행한 뒤 슬래시 커맨드(slash command)로 /wl 출근을 입력하면 출근 로그가 추가되고 완료 메시지를 수신합니다.

뿌듯해하며 사용법 공유

슬랙의 3초 이내 응답 요구

단순한 기능이었지만 슬랙봇을 활용해서 워크로그를 작성하는 동료가 조금 늘었을 때 치명적인 문제가 발생했습니다.

슬랙의 슬래시 커맨드는 3초 이내로 응답할 때 완료 메시지를 노출합니다. 3초를 초과하면 아래 메시지를 노출합니다.

버그리포트

Firebase 클라우드 함수로 작성한 코드에 문제가 있었습니다. 단순한 로그 데이터와 사용자 요청에 대한 기록을 모두 완수한 후에 응답을 보내도록 했습니다. 이 부분에서 응답 지연이 발생합니다.

기록은 된다고 변명해봤지만, 사용자가 기록 여부를 알 수 없으니 재시도하는 횟수가 늘어났습니다. 중복된 데이터를 삭제 요청하는 사용자가 늘었습니다. 이런 불편을 겪고 초기 사용자가 이탈했습니다.

이탈하는 사용자

위 문제를 제외하고도 다수 사용자의 특정 기간 내 로그를 모두 살펴보기에 슬랙봇은 그다지 좋은 도구가 아니었습니다.

제가 잘 못 쓴 것이지 슬랙봇에게는 죄가 없습니다.

3차 시도 - 웹페이지 도입

앞서 말한 문제가 대두하기 전 다수의 로그를 살펴보기 위해 웹페이지를 제작 중에 있었습니다. 프로그래밍에는 야놀자 앱 하이브리드에서 다뤄본 React.js 외에 최근 소개받은 razzle, After.js를 사용했습니다(이에 관한 회고는 아래서 짧게 다룹니다).

Firebase 실시간데이터 베이스에 쌓인 로그를 Firebase 클라우드 함수로 제작된 API로 사용자별, 일자별로 불러서 표시하는 정도로 개발 착수.

웹페이지로 조회 기능을 만든 시점과 맞물려 슬랙봇이 무용지물이 되었습니다. 로그인 기능을 제작하고 웹페이지에서 워크로그를 추가할 수 있도록 했습니다. 기록과 조회가 웹페이지로 대체 된 것입니다🎉🎉.

Firebase 인증은 정말 편리합니다.

슬랙봇 안녕

대형 이벤트

이렇게 만들었지만 떠나버린 사용자를 돌아오게 만드는 일은 불가능했습니다. 저를 제외하고 몇몇 분들만 사용하는 소소한 서비스로 사라질 예정이었습니다. 그런데 CX 서비스실 실장이신 하희진 님이 전격적으로 CX 서비스실 전 구성원이 워크로그를 통해 기록을 남겨달라고 요청하셨습니다. DAU가 10배는 급상승했습니다(1~2명에서 20명 이상으로). 많은 트래픽📈이 들어오니 부족한 기능과 어설픈 기록 시스템 등이 문제가 되기 시작합니다.

엎친 데 덮친 격으로 초과 근무 차감이란 주 기능 오픈에 대한 관리자(희진 님)와 사용자의 요구가 커졌습니다.

할 일이 넘쳐난다.

DAU 20의 공포

요구사항을 분석하고 구현하면서 미비한 규칙을 관리자와 자주 논의했습니다. 논의 결과에 따라 메뉴가 생겼다가 사라졌다가를 반복해서 사용자의 혼란이 가중되었습니다. 아직 제작되지 않은 관리자 기능 때문에 데이터베이스를 직접 수정하는 일도 빈번했습니다.

무엇보다 갑자기 새로운 도구를 사용하는 사용자의 질문이 쏟아졌습니다. 주 40시간을 어떻게 측정할지, 초과근무시간의 근거나 법정 휴식시간 발생 요건 등 대부분은 규칙에 관한 질문이었습니다. 30분 안에 같은 질문을 5번 듣고 동일하게 답변하는 헤프닝도 있었습니다.

🤔 어디서 많이 본 모습인데? 바로 IT산업 전체에서 자주 일어나는 일입니다.

점진적 개선

우선 비슷한 질문을 모아 FAQ 페이지를 개설했습니다(우리 PO가 자주 하는 업무라서 배운 풍월이 도움이 되었습니다). 지나치게 사용자 기능을 제한하여 CS가 늘어난 측면이 있어서 규칙이 확정된 부분만 사용자 기능 제한을 풀었습니다.

  • 금주 내의 로그는 언제든 추가 및 수정할 수 있도록 변경했습니다.
  • 누적된 초과시간은 금주 중 언제라도 사용할 수 있도록 변경했습니다.

한 주가 끝나면 잘못된 로그가 있는지 검사한 뒤 로그 수정 후 초과시간 확정하는 일은 하고 있습니다.

배포되는 버전마다 변경사항을 문서에 남기고 전체 사용자에게 공지했습니다.

차감 기능은 자투리 시간과 CX 서비스실 구성원의 배려로 개발하였습니다.

다행히 6월에 태어난 둘째가 새벽 4~5시면 한 번씩 울어서 알람 없이 기상할 수 있었습니다😭.


개인 회고

워크로그를 제작하면서 크게 2가지를 느꼈습니다.

미비한 요구사항 분석은 개발 비용을 상승시킨다

하나의 요구사항은 여러 기능을 필요로 합니다. 자세한 분석 없이 뇌내 망상으로만 개발에 착수했더니 구조를 변경하느라 시간을 많이 소모했습니다.

초과 시간을 예로 들면 우선 차감 메뉴를 만들고 있었습니다. 그런데 차감에 근거가 되는 누적 시간이 없습니다. 그럼 누적을 기록할 수 있는 모델을 제작합니다. 1일 8시간 기준으로 기록하도록 개발합니다. 주 40시간이 넘을 때 초과 시간이 발생하는 규칙이라서 1주일 단위로 마감하는 방식으로 변경합니다.

이렇게 우왕좌왕하며 개발하니 밀고 나가는 힘이 약했습니다. 프로덕트 개발 시 PO가 이 부분을 많이 돌봐줘서 기본 없는 프로그래머가 되었습니다(😭).

개발은 50%. 운영이 나머지 50%다

마이너 버전이라도 개발을 완료하고 배포할 때마다 한고비 넘었다고 생각했습니다. 그렇지만 진짜 서비스가 단단해지는 것은 사용자를 만날 때부터였습니다.

사용자는 관리자보다 인내심이 없습니다. 개선 사항을 슬랙을 통해서 말해주고, 잘못된 기록이 있으면 수정을 요구했습니다. 이상한 규칙이 발견될 때마다 피드백이 왔습니다. 정당한 요구와 피드백이지만 1인 개발자가 감당하기는 벅찬 부분이 있었습니다.

피드백을 정리해서 수정할 부분을 JIRA에 정리하고 작업하기를 반복했습니다. 이 과정을 통해 초기보다 더 다듬을 수 있었습니다.

저는 근무시간 중에만 CS 대응을 했음에도 피곤했습니다. 이런 일을 매일 매시간 겪고 있는 야놀자 PO와 IT 업계 동료들은 정말 대단한 사람입니다. 이 자리를 빌려 다시 한번 존경합니다.

개발 관련 회고(신약💊 임상 결과)

토이 프로젝트이기 때문에 회사에서 사용하는 기술 외에 새로운 기술을 다뤄봤습니다. React.js와 함께 엄청나게 사랑받고 있는 vue.js가 아닌 이유는 개발 시간이 촉박해서 공부할 시간이 없었다고 핑계 대봅니다.

razzle + After.js = 👍

React.js를 사용할 때 주로 Next.js를 사용해왔지만 이번에는 razzle과 After.js를 사용했습니다.

razzle은 create-react-app처럼 React.js 애플리케이션을 제작할 수 있도록 초기 구성을 도와줍니다. React.js 외에도 Vue, Angular, Preact, Elm 등을 지원합니다.

After.js는 Next.js처럼 서버사이드 렌더링을 지원합니다. Next.js와 다르게 React Route 4를 이용해서 라우팅을 지원합니다.

사용해본 소감은 razzle이 아무런 설정도 하지 않도록 도와주고 있어서 편리했습니다. TypeScript 도입도 예시가 있어서 쉽게 적용할 수 있었습니다. 코드 수정 후 웹페이지를 다시 로딩하는 핫 리로드(hot reload)도 잘 작동합니다. After.js는 서버사이드 렌더링 시 getInitialProps 를 사용할 수 있어서 Next.js에 익숙한 저에게 편리했습니다. 무엇보다 Next.js처럼 route를 변경하기 위해서 next-route에 의존하지 않아서 편리했습니다(대신 React Route를 의존합니다).

저처럼 프로젝트 셋업을 어려워하는 초심자에게 유용합니다(검색할 때 사례를 더 많이 찾으려면 Next.js가 더 유리합니다).

배포는 초기에 Aws의 beanstalk을 활용하다가 Zeit가 운영하는 now로 변경했습니다. Node.js나 docker에 익숙하고 커맨드 라인 인터페이스(cli)를 사용하는 데 어려움이 없다면 사용할만 합니다. 리전이 모두 해외라서 응답속도가 빠르진 않습니다.

Zeit는 Next.js 프레임워크를 제작한 회사입니다.


도움 주신 분

  • 🤔 아이디어와 기획에 도움을 주고 사용자가 돼주신 R&D CX 서비스실 강미경 님
  • 🐛 제보에 적극적인 R&D CX 서비스실 노현석 님
  • DAU를 비약적으로 높여주신 R&D CX 서비스실 하희진 님
  • 미약한 사용성과 구린 UI임에도 잘 사용해주고 계신 R&D CX 서비스실 모든 구성원!!
  • 공감의 👀🌽! 눈물 흘리는 역할로 열연해주신 R&D UX/UI팀 김하연 님
  • 이 글을 리뷰해주신 유관종 님, 노현석 님, 구본한 님

무엇보다 이런 프로젝트가 가능하도록 도와준 R&D CX 서비스실 내 API파트 전원에게 🙇‍ 감사합니다.


참고한 자료


Buy me a latteBuy me a latte