스토리 홈

인터뷰

피드

뉴스

조회수 1012

옛날 얘기

내가 7~8살이던 시절에는 부모님이 사주신 닌텐도 고전 게임기를 즐겼고(89년도) 마리오, 동키콩 등의 초기 버젼의 게임들을 밤 늦게까지 했다. 당시 교육 분위기가 그랬는지 부모님이 개방적이었는지 모르겠지만 내가 게임기를 사달라고 하지도 않았는데 부모님은 게임기(패밀리)와 수백가지 게임이 들어있는 게임팩을 선물해주셨고 아마도 맞벌이로 저녁 늦게 귀가하셔서 그런지 나는 하고 싶은 만큼 게임을 했었다. 외동이라 형제 자매와 싸울 일도 없었고.당시에는 울트라맨 피규어나 후레시맨 합체로봇, 부메랑이라는 만화에서 나온 건전지 자동차, 레고가 유행했고 부모님은 내가 갖고 싶은 것을 잘 사주셨다. 게임을 하거나 조립식 장난감을 가지고 혼자 의성어를 내면서 놀기도 했다. 조립하는 것을 좋아해서 레고나 건담 피규어나 미니 자동차, 과자 상자에 들어있는 조악한 조립식 장난감을 열심히 조립해서 혼자 전쟁놀이를 했던 건데 어머니는 혼자 노는게 짠했다고 하신다.초등학교 2학년 때까지는 연탄 보일러를 떼는 대방동 골목길 주택에 살았다. 겨울이면 아침마다 아버지가 보일러 연탄을 바꿔놓고 출근하셨다. 어머니는 동네에서 피아노 학원을 운영하셨다. 나는 하교해서 어머니 학원에 가서 피아노를 배우거나 동네 쌀집, 통닭집, 미용실에 가서 놀거나, 친구네 집에서 페르시아의 왕자 같은 게임을 하거나 했다. 줄로 감아서 던져서 돌리는 팽이와 딱지를 가지고 놀거나 구슬 치기도 했다.초등학교 3학년 때 서초동으로 이사왔는데 그 때는 별 생각 없이 따라왔지만 나름 좋은 학군을 따라 적당한 시기에 전학을 온 것이었고 어머니는 자식의 학군을 위해 한 동안 꽤 먼 길을 출퇴근 하시다가 학원을 정리하셨다. 그 무렵 집에 컴퓨터가 놓였다. 486 컴퓨터였을 것 같은데 워크래프트를 했던 기억이 난다. 서이초등학교에 다녔는데 혼자 축구공이나 장난감 석궁, 부메랑 같은 것을 가지고 가서 아이들이 있으면 같이 공을 차고 없으면 혼자 벽에 공을 차면서 놀다가 석양을 보면서 귀가하곤 했다. 평발이라서 오래 뛰면 발이 아팠는데 아파서 못 걸을 때까지 뛰어다녔다.슈퍼패미컴이라는 게임기를 가진 친구네 집이 또래들의 아지트가 되어 매일 그 집에서 모였다. 마리오카트나 드래곤볼 같은 콘솔 게임을 하다가 컴퓨터로 멀티플레이 탱크 게임을 하다가 삼국지를 하다가 대전 격투 게임을 지칠 때까지 했다. 초등학교 때의 여가는 축구와 게임이 전부였던 것 같다.초등학교 5~6학년 때는 방과후 특별활동으로 MS-DOS와 GW-BASIC 등의 프로그래밍을 배웠다. 94~95년도 인 것 같은데 당시엔 5.25인치 플로피 디스크를 이용했다. MS가 뭔지도 DOS가 뭔지도 몰랐고 사실 프로그래밍을 제대로 배웠던 기억은 없고 선생님 몰래 고인돌 같은 게임을 했다. MS가 마이크로소프트라는 회사였고 DOS를 앞세워 당시 OS 시장에서 IBM과 애플 등과 전쟁을 치르던 중이라는 것도 20년 가까이 지나서 알았다.중학교 때는 오락실도 열심히 갔다. 철권과 킹오브파이터, 1942, 매탈슬러그를 했다. 가스렌지에 불꽃을 일으키는 장치를 오락실 기기 동전 넣는 곳에서 누르면 동전을 넣지 않아도 플레이할 수 있었는데 몰래 하다가 걸려서 혼난 적도 있다. 겁이 많아서 나쁜 짓은 별로 안 했던 것 같은데 게임은 너무 하고 싶어서 그랬나보다. 독서실 간다고 하고 오락실을 갔던 적도 많은데 한 번은 아버지에게 걸렸는데 크게 혼내지 않으셨던 게 기억이 난다.컴보이라는 휴대용 게임기를 항상 휴대하고 다니면서 다 깬 게임을 또 하고 또 하고 했다. 재미있어서라기 보다는 부모님이나 친구들과 함께 있는게 아닐 때 혼자 시간을 보낼 수 있는 방법이 마땅치 않았다. 만화책 대여방, 비디오 대여방에서 만화책과 비디오를 대여해서 보곤 했다. 당시에 3.5인치 디스크 5장~10장에 달하는 RPG게임이나 연애 시뮬레이션 게임이 유행했고 인터넷 시대 이전에 PC통신의 시기가 있었는데 나는 당시 유행하던 커뮤니티나 채팅 보다는 게임이 재미있어서 PC통신은 자료실 정도만 이용했던 것 같다. 중학교 2학년 무렵 플레이스테이션을 가진 친구네 집을 매일 들러서 늦게까지 놀다가 귀가하곤 했다. 철권이나 파이널판타지7을 플레이했다.중3 때 스타크래프트가 출시되었고 PC방이 유행하기 시작했다. 지금과 같은 PC방 분위기가 아니라 사무실 같은 곳에 컴퓨터만 많이 갖다놓은 느낌이었는데 시간 당 2천 원인가 3천 원인가 중학생에게 비싼 가격이어서 느긋하게 게임하지 못하고 한 두 시간 바짝 하고 헤어지곤 했다. 난 중 2~3때 항상 의기소침해 있었고 학교에 가기 싫었고 부모님과는 말도 잘 안 했었는데 어머니는 그 때 속상했다고 하신다.고1 때는 써클 활동으로 '전산반'에 가입했는데 3차에 걸친 면접과 10:1에 달하는 경쟁율이었다. 100명 정도가 지원을 해서 10명 정도를 뽑았다. 실력을 본다기 보다는 이 써클에 얼마나 들어오고 싶은지 열정을 보여야 가입을 할 수 있다는 게 전통이었는데 지금도 전산반 선후배 동기들과 친하게 지내는 것을 보면 그런 전략이 먹히긴 했던 것 같다. 그 전에는 축구나 게임 말고는 뭔가 열심히 했던 것이 없던 것 같은데 이 써클은 일단 가입부터 빡세고 선배들이 무서워서 열심히 활동을 하게 됐다.방과후에 매일 남아서 축제나 체육대회 준비를 하거나 프로그래밍, 3D 모델링, 에니메이션 툴 등을 배웠고 선배들을 만나면 복도가 울리도록 크게 인사를 해야 했다. 나는 그게 싫지가 않았는데 어느 정도의 규율과, 축제라는 목표와, 프로그래밍/그래픽 툴 공부라는 성장과, 매일 모이고 크게 인사를 하면서 느끼는 소속감이 좋았던 것 같다. 그리고 반 친구들보다도 써클 친구들과 동고동락을 하게 되다보니 더 친하게 지냈다.나는 MAX로 3D 에니메이션을 만들었는데 아주 어설픈 실력이었겠지만 내가 혼자서 어떤 결과물을 만들어냈다는 것에 뿌듯했었다. 데스크탑 컴퓨터를 부품별로 사서 직접 조립했었고 친구네 집 컴퓨터가 고장났다고 하면 출장 수리를 해주고 짜장면을 얻어먹기도 했다. PC용 건반 게임인 비트매니아가 유행했고 오락실에서 펌프나 이지투디제이 같은 게임을 잘하는 친구가 멋있어 보였다. 2학년 방학 때는 학교 전산실을 쓸 수 있었는데 전산반 친구들과 거의 매일 스타크래프트를 하면서 친목을 다졌다.고등학교 2학년 여름방학부터 공부를 하기로 마음먹어서 원래 반에서 10~15등 하던 등수가 3학년 부터는 전교 2~3등까지 올랐다. 그 시기에 메가스터디의 인터넷 강의가 생겼는데 학원에 가지 않고 인터넷 강의를 2배속으로 들으면서 공부했고 나에게 잘 맞았다. 공부를 한참 하던 시기에 반에서 나에 대해 뒷담화를 하는 친구가 있었는데 뭔가 이 상황을 정리하지 않으면 공부에 집중할 수 없을 것 같았고 내가 선택한 방법은 한 번 주먹다짐으로 결판을 내는 것이었다.중학교 때 자존감이 낮기도 하고 외소하고 겁도 많았던 시기에 나를 괴롭히던 친구들이 있었고 고등학교 와서는 친구들과 잘 지내고 성적이 오르면서 자존감이 높아져 있었는데 이 히스토리를 알고 있고 아니꼽게 보던 친구가 비아냥 거리는 소리가 간간히 들렸고 한 동안 참고 피하다가 어느 날 내가 날을 잡아서 시비를 걸고 치고 받았다. 내가 겁이 많은 성격인 건 여전했고 싸움을 해봤던 사람도 아니었지만 이 상황을 어떤 식으로든 해결을 해야한다는 생각이 강하게 들었다나는 그 시기를 내 삶에서 용기를 내어 뭔가를 깬 최초의 시기라고 생각하는데 자연스러운 상태라면 내가 절대 하지 않았을 법한 일을 행하기로 선택을 했고, 그 결과 그 친구는 뒷말을 하지 않았고 나는 내가 할 일에 집중할 수 있었다. 화가 나서 싸운 게 아니라 문제를 해결하기 위해 나름의 해결책을 실행했다. 부연하자면 내가 그 친구를 때려서 겁을 주거나 한 건 아니고 덩치가 나보다 컸기 때문에 내가 많이 맞았는데, 나에 대해 '건드리면 성가시다' 정도로만 인지시켜도 충분했다. 고2 담임선생님은 서울 안에 대학을 못 갈것이라고 했는데 내신과 수능이 엄청 올라서 연세대 공대에 02학번으로 입학했다.자존감이 올라 있었기 때문에 대학교 1~2학년 때 굉장히 많은 친구들을 사귀었고 동아리 활동을 했고 수백권의 책을 읽었고 연애를 했고 여러 공모전에 도전해 수상도 했다. 대학 때는 공강 때마다 당구 대신 레인보우식스라는 FPS를 친구들과 자주 했고 클래식 기타 동아리 활동도 했다. 동아리 연주회나 여름 MT에 가고 조인트 동문회를 하고, 주량 모르고 선배가 주는 술을 받아 마시다가 필름이 끊기는 등 성인이 되어 해볼 수 있는 것들을 최초로 경험했다. 아직도 생각나는 당시의 경험들은 내가 그래도 풍성한 대학생활을 했구나 하고 안도하게 해준다.2학년을 마치고(2004년) 아버지가 하시던 휴대폰 대리점에 도움이 필요하기도 하고 내가 어깨 수술을 받아 거동도 불편해서 휴학을 하고 대리점에 앉아 책을 많이 읽었다. 대리점 컴퓨터가 전산 업무 빼고는 할 수 없었고 손님이 뜸한 지점이었기 때문에 시간이 많이 남았는데 학교 도서관에서 책을 엄청 빌려와서 하루 종일 읽었다. 줄을 칠 수 없으니 컴퓨터에 책 내용을 요약 타이핑하면서 읽었는데 그 때 내용을 파악하고 정리하는 실력이 늘었던 것 같다.복학하지 않고 그 해 겨울에 병역 특례 회사에 입사해서 22살에 처음 회사 생활을 시작했다. 그 이후로 계속 개발을 했고 외주 개발도 하고 스타트업들의 개발팀장이나 CTO를 맡으면서도 복학을 안 하다가 2010년에 복학해서 2012년에야 졸업했는데 항상 일이 가장 중요했기 때문에, 학교 수업은 교수님들께 양해를 구하고 일주일에 한 두 번 잠깐 씩 가서 발표를 하거나 프로젝트 제출을 해서 딱 졸업을 할 수 있을 정도의 학점을 받았다.집에서 학비 지원을 받기 어렵기도 했고 일을 하는데 졸업장이 얼마나 의미 있을까 싶어 복학을 안 할까도 진지하게 고민했었는데 장학금과 내가 번 돈으로 학비를 낼 수 있었기 때문에, 그리고 결혼을 한다면 고졸 보다는 대졸이어야 허락을 받기 쉬울 거라는 생각에 졸업을 했다. 이제 회사 생활은 그만하고 사업을 해야겠다는 생각에 2013년에 인썸니아 개인사업자를 냈다. 정부지원사업 제출 마감 전날인데 급하게 사업자를 내야 했고, 그 고민을 했던 시간이 새벽 4시였기 때문에 꽤 어울리는 이름이라고 생각했다.
조회수 2893

JANDI CONNECT 개발기

지난 1월 말, 새해를 맞아 잔디에 새로운 기능이 업데이트되었습니다. 바로 잔디 커넥트에 관한 내용인데요, 협업에서 많이 쓰이는 몇 가지 외부 서비스를 잔디와 쉽게 연동해서 더욱 효율적인 업무 커뮤니케이션을 할 수 있게 되었습니다. 많은 고객분들이 이번 업데이트를 기다려주신 만큼, 저희 개발팀 또한 기대에 보답하고자 지난 몇 주의 스프린트 동안 열심히 준비했습니다. 이번 글에서는 커넥트 동작 방식을 설명하고 그 개발 과정에서 저희가 겪은 시행착오를 비롯한 여러 값진 경험들을 공유하고자 합니다.Integration? Webhook!연동: [기계] 기계나 장치 따위에서, 한 부분이 움직이면 다른 부분도 함께 잇따라 움직임.앞서 말한 대로 잔디 커넥트는 여러 웹 서비스들과 잔디를 연동할 수 있는 기능입니다. 서로 다른 웹 서비스를 연동하기 위해선 한 서비스 내에서 특정 이벤트가 발생 했을 때 다른 서비스로 해당 이벤트를 알려주는 연결 고리가 필요합니다. 이때 해당 연결 고리 역할을 위해 대표적으로 사용되는 기법이 웹훅(WebHook) 입니다. 웹훅은 user-defined HTTP callbacks, reverse APIs 등으로 불리는데, 간단히 설명하자면 웹 서비스에서 공개한 API가 아닌 사용자가 직접 지정한 주소(URL)로 특정 이벤트가 발생 시 HTTP Request를 보내주는 기법입니다. 예를 들어,새로운 일정이 등록된 경우(Google Calender)요청한 Pull Request가 Merge된 경우(GitHub)카드에 새로운 코멘트가 작성된 경우(Trello)이러한 이벤트가 발생했을 때 사용자가 매번 이벤트가 발생했는지 확인하지 않아도 서비스가 먼저 알려줄 수 있도록 일종의 알림을 등록하는 것이죠. 잔디 커넥트는 이와 같은 특징을 이용해서 각각의 웹 서비스에서 제공하는 웹훅을 잔디의 메시지 형태로 전달하는 기능입니다.일반적으로 웹훅은 이벤트에 대한 알림을 외부로 전달하는 것을 말합니다. 이 부분에서 중요한 것은 전달 방향인데, 서비스 내부에서 외부로 전달하기 때문에 이를 Outgoing Webhook으로 부르기도 합니다1. 같은 맥락에서 반대로 생각해보면 외부에서 서비스 내부로 특정 데이터를 전달하는 경우이니 Incoming Webhook이 됩니다. 앞서 웹훅을 reverse API라고 했는데 이를 다시 뒤집으니 결국 서비스 내부로 통신하는 제한적인 API와 같은 역할을 합니다. 굳이 용어를 구분한 이유는 API와 달리 접근하려는 서비스의 별도 인증 절차를 거치지 않고도 사용자가 생성한 웹훅의 URL을 인증 토큰으로 사용하며 약속된 Request Body 포맷만 알고 있다면 자유롭게 사용할 수 있기 때문입니다.개념 설명이 다소 길어졌지만, 이번 잔디 커넥트 기능에 대해 용어나 개념이 낯설다는 피드백이 생각보다 많았기 때문에 이번 글을 통해 더 많은 분들이 웹훅을 이해하는 데 도움이 될 수 있으면 좋겠습니다.구현에 앞서서비스를 운영한지 1년 정도 지난 시점에서 저희 내부적으로는 백엔드의 기술 스택 변경 및 각 서비스 분리에 대한 갈증이 있었습니다. 하지만 이미 서비스를 운영 중이기 때문에 안정성이 최우선시 되는 만큼 꽤 부담스러운 숙제로 미뤄둘 수밖에 없었고요. 때마침 커넥트 기능은 숙제를 시험해볼 만한 좋은 기회임에는 분명했지만, 새로운 기술 스택을 바로 서비스에 적용하기엔 오히려 개발 효율이 떨어질 것이라는 판단하에 일단 서비스 분리에만 집중하기로 했습니다.기본적으로 API와 DB를 기존 서버와 분리하고 웹훅 데이터를 저장하기 위한 큐와 해당 데이터를 처리하는 배치 서버 또한 모두 기존 서비스와 분리해서 최대한 결합도를 제거했습니다. 이런 설계 덕분에 추후 사업 전략이나 각 국가의 특성에 맞춰 커넥트 기능을 어렵지 않게 포함하거나 제외할 수 있게 되었습니다. 전반적인 저희 잔디 백엔드 아키텍쳐에 대해서는 아직 한 번도 소개 해드린 적이 없으니 다음에 따로 주제로 선정해 집중적으로 다뤄보도록 하겠습니다.동작 방식잔디 커넥트가 동작하는 방식은 기본적으로 다음과 같습니다.Incoming Webhook URL 생성 - 외부 서비스 웹훅 등록 - 웹훅 수신 - 메시지 작성 연동 대상 서비스마다 조금씩 차이가 있지만, 기본적으로 모두 위와 같은 방식으로 동작하기 때문에 단계마다 나누어 설명하겠습니다.1. Webhook URL 생성Webhook URL은 https://wh.jandi.com/connect-api/webhook/{teamId}/{webhook-token}와 같은 형태로 생성됩니다. hostname을 별도로 설정함으로써 기존 API 서버와의 분리는 물론이고, nginx의 Limiting the Request Rate 설정을 이용해서 호출되는 웹훅 요청 수를 효과적으로 제한할 수 있었습니다. webhook-token은 중복을 피하면서 각 웹훅에 대한 유효성을 검증할 수 있도록 여러 키를 조합한 md5 hash 값을 이용했습니다.이렇게 생성된 URL은 Incoming Webhook 뿐만 아니라 Google Calendar 등의 서비스에 등록하는 콜백 URL로 사용합니다.2. 외부 서비스 웹훅 등록웹훅을 등록하는 방법은 서비스에 따라 API를 이용하거나 수동으로 직접 등록할 수 있습니다. 사용자가 직접 웹훅을 등록하는 방법은 웹훅 URL만 생성해서 전달하면 등록 과정의 추가 처리가 필요 없어서 간단하지만, 서비스마다 등록하는 방법이 조금씩 다르고 다소 복잡하게 느껴지는 문제가 있습니다. 반대로 각 서비스에서 제공하는 API를 이용해 웹훅을 등록하면 사용자의 부담을 많이 줄일 수 있지만, 그만큼 내부적으로 처리해야 할 작업이 많아집니다. 그래서 구현 초기에 꽤 많은 시간을 투자할 수밖에 없었고 그 과정에서 아래와 같은 어려움을 겪었습니다.웹훅 관련 API를 사용하려면 먼저 인증을 받아야 하는데 서비스마다 제공하는 인증 방식이 조금씩 달라서 이를 통합하는 모델을 만들기가 쉽지 않았습니다. 요약하자면 기본적으로 accessToken을 사용하지만, 인증 방식에 따라 부가적으로 필요한 데이터가 서로 조금씩 다른것이죠. 가령, 구글캘린더는 만료 일시와 토큰 갱신을 위한 refreshToken 값을 별도로 갖고 있어야 합니다. 또 한가지 놓치기 쉬운 부분은 인증 폐기(revoked) 관련한 데이터 처리인데 저희가 경험한 바로는 인증이 폐기되었을 때 별도로 웹훅 알림을 주지 않기 때문에 반드시 인증의 유효성을 확인하는 추가 로직이 필요합니다.대부분의 사무실이 그렇듯이 저희 또한 공유기를 이용해 내부 네트워크를 구성하고 있습니다. 게다가 백엔드 파트는 개개인의 로컬 가상 서버에 동일한 환경을 설정해놓고 개발을 하므로2보통 경우엔 외부(public network)에서 들어오는 요청을 받을 수 없습니다. 그렇다고 매번 외부 네트워크에 있는 서버에 배포 후 테스트하기가 어려우니, 저희는 각 로컬 서버마다 고유 포트 번호를 나눠 갖고 WAN이 물린 공유기의 포트 포워딩을 알맞게 설정한 뒤에 네트워크 터널링 유틸리티인 ngrok을 이용해 내부와 연결되는 public 주소를 생성해서 외부 서비스와 문제없이 통신할 수 있었습니다.3. 웹훅 수신웹훅을 통해 들어오는 Request는 일단 정상 응답을 하는 게 좋습니다. 서비스마다 최초 웹훅 등록 시 유효한 URL인지 확인하는 테스트 요청을 하는데 이때 정상 응답을 하지 못하면 아예 등록조차 처리되지 않습니다. 또한, 정상적으로 등록된 이후 특정 이벤트에 해당하는 웹훅 요청에 대한 응답에도 주의할 필요가 있는데, 만약 에러 응답이 반복되면 일정 시간 동안 각 서비스에서 아예 해당 웹훅을 발송하지 않도록 제한이 걸려 더 이상 테스트를 진행할 수 없는 경우도 있었습니다.따라서 일단 웹훅 요청이 들어오면 teamId와 webhook-token 값으로 올바른 웹훅인지 검증한 후 서비스별 큐에 Request header와 body를 포함한 데이터를 전달한 뒤 바로 응답하고, 큐에 쌓인 데이터는 커넥트 종류별로 배치 서버가 돌면서 처리하게 됩니다. SQS를 사용함으로써 늘어나는 데이터에 대한 안정성을 확보하고 각각의 배치 서버를 독립적으로 분리해서 구현함으로써 자연스레 확장성(scalability)도 보장할 수 있게 되었습니다.4. 메시지 작성웹훅 데이터를 잔디의 메시지로 변환하는 역할은 배치 서버가 담당합니다. 서비스별로 데이터 포맷이 다르므로 해당 데이터를 파싱 및 처리하는 Worker 또한 각각 구현했습니다. 사실 커넥트 기능에서 가장 핵심적인 역할을 하는 부분인 만큼 가장 많은 공수가 드는 작업이였던 것 같습니다.서비스마다 정해놓은 웹훅 이벤트와 잔디 커넥트에서 제공하고자 하는 알림이 서로 완전히 일치하지 않아서 이를 서로 연결하는 작업연동 서비스의 문서가 잘 정리되어 있지 않아서 일일이 필요한 동작을 취하고 그에 따라 들어오는 데이터를 정리하는 작업잔디 계정 언어에 따라 메시지 L10N3을 적용하는 작업커넥트 메시지를 전달하기 위해 기존 멤버와 다른 커넥트 봇을 구현하는 작업등 요약하기 어려울 정도로 크고 작은 이슈들이 많았습니다. 그 내용이 너무 다양해서 모두 상세히 기록하긴 어렵지만, 개중에 도움이 될만한 내용을 추려서 아래 따로 정리했으니 관심 있으신 분들은 참고하시면 좋을 것 같습니다.서비스별 집중 탐구커넥트 구현 일정을 최대한 앞당기기 위해 저희는 개발자들끼리 각각의 커넥트 종류 별로 전담해서 작업하는 전략을 취했습니다. 제가 대표로 글을 작성하기는 하지만 보다 정확하고 구체적인 정보를 전달하는 것이 좋겠다는 생각에 개발을 담당하신 분들과의 짧은 인터뷰 형식을 빌려 공유하겠습니다.- Google CalendarQ. 기술적으로 난이도가 높았던 작업을 소개해달라.전반적으로 어려운 작업이 있었다기보단, 캘린더 특성상 세세하게 처리할 부분들이 많아 설계와 구현이 어쩔 수 없이 복잡해졌다. 가장 골치 아팠던 작업은 일정 알림을 타임존(Time Zone)에 따라 각각 알맞은 시간에 전달하는 작업인데, “잔디 계정의 타임존”, “구글 캘린더의 타임존”, “개별 일정의 타임존” 이렇게 3가지를 모두 고려해서 경우마다 기준이 되는 타임존을 결정하는게 엄청 까다로웠다. 심지어 구현 후 테스트를 하는 과정에서도 출력된 시간이 올바로 표시된 것인지조차 헷갈려서 디버깅하는데 한참 고생할 수 밖에 없었다.웹훅을 등록하고 관리하는 부분도 꽤 복잡했는데, 구글 답게(?) 웹훅에도 만료 기간이 존재한다는 것이 포인트다. 때문에 만료되기 전에 반드시 재등록 및 과거 웹훅 삭제 작업을 하는데, 효과적으로 처리하기 위해 “웹훅을 받을 때마다 만료 기간을 확인”, “등록된 일정이 많지 않아 웹훅을 받지 못하는 경우도 있으니 별도의 배치서버가 하루 단위로 확인” 이렇게 두 가지 로직을 넣어서 자동으로 웹훅을 유지하도록 구현했다.또한, 다른 연동 서비스와 달리 구글은 웹훅 콜백으로 들어오는 요청에 해당 이벤트에 대한 데이터를 직접 담아주지 않기 때문에 key를 가지고 한 번 더 API 호출을 통해 필요한 데이터를 가져와야 한다는 점도 주의해야 한다. 요청해야 할 API 문서는 비교적 잘 정리된 편이지만, 같은 요청에 대해서도 인자를 어떻게 보내는지에 따라 그 응답이 제각각이기 때문에 응답 값에 대해 무조건 신뢰하고 처리해서는 안 된다. 당연히 존재할 것으로 생각한 필드 값에 빈 배열이 들어와서 일정 관련된 데이터를 일부 날리고 나서야 깨달았다.. -_-Q. 가장 처리해야 할 이슈가 많았다고 알고 있는데, 그중에서도 기억에 남는 이슈가 있을 것 같다.너무 많은 이슈를 동시에 처리하다 보니 특별히 기억에 남는 이슈는 없다. 다만 아직도 왜 그랬는지 확실한 이유는 알 수 없지만, 언젠가 한 번 구글에서 웹훅을 아예 전달해주지 않았던 경우가 있었다. 과도한 요청으로 limit이 걸린 것도 아니었는데, 갑자기 웹훅이 안들어오니깐 우리로서는 어떻게 풀어볼 방법이 없었다. 그러다 나중에 확인해보니 대략 12시간쯤 지나고 나서 그동안 밀려있던 웹훅 데이터가 한 번에 밀려서 들어와 있더라. 다행히 그 이후로 지금까지 한 번도 재현되지 않는걸 보니, 혹 동일한 증상을 겪는다면 당황하지 말고 기다려 보시라.반복 일정을 다루는 것도 꽤 골치 아픈 이슈인데, 왜냐하면 일정이 있을 때 마다 웹훅 알림을 주지 않고 처음 등록된 시점에서 한 번만 정보를 알려주기 때문에 등록된 시점 이후의 일정은 내부적으로 계속 등록해줘야 한다. 기본적으로 구글 캘린더는 RFC-55454 표준을 따르지만, 실제 전달되는 데이터 중 일부는 표준과 조금 다른 부분이 있었다. 특히 반복 일정(recurrence) 관련 데이터 포맷이 조금 다르므로 캘린더 데이터를 파싱하기 위해 만약 외부 library를 사용한다면 별도의 예외처리가 필요하다. 더욱 더 까다로운 건 사실 등록된 반복 일정이 수정되거나 삭제되는 경우인데, 이때 “특정 일정만 삭제”, “지금 시점 이후의 일정 모두 수정” 등 워낙 케이스도 많고 각각을 테스트 하는 것도 쉽지 않기 때문에 작업 시간이 꽤 오래 걸렸다. (심지어 아직 확인하지 못한 드문 케이스에서는 잠재된 버그가 있을 수도…)Q. 그 밖의 도움이 될만한 노하우나 꿀팁이 있다면?구글 캘린더 API는 Webhook 보단 Push Notification 키워드를 많이 사용한다. 푸시 노티라는 게 좀 다른 카테고리에서 많이 쓰이는 용어이기도 하다 보니 코드 리뷰 등의 커뮤니케이션을 할 때 혼동이 좀 있었던 것 같다.물론 서비스 요구사항마다 다르겠지만, 잔디 같은 경우엔 요구사항에 맞춰 계속 설계를 변경 및 개선하다 보니 결과적으로 너무 복잡해져 효율이 떨어지는 코드를 작성할 수밖에 없었다. 처음부터 연동을 생각하기보다는 아예 캘린더 자체 기능을 베이스로 설계하고 데이터만 구글에서 가져온다 생각했다면 개발 생산성이 더욱 좋았을 것 같다.- TrelloQ. 기능을 구현하면서 느낀 아쉬웠던 점과 좋았던 점을 짚어달라.트렐로 공식 API 문서가 더 명확했다면 좀 더 개발이 수월했을 것이다. 문서가 RESTful하게 end-point path는 간결하게 잘 정돈되어 있지만, 각 요청 parameter에 대한 설명이나 response 데이터 등이 명확하게 정리되지 않아서 적합한 API를 찾거나 불명확함을 걷어내기 위한 테스트를 하다 보니 전반적으로 시간이 길어지고 비효율적이었던것 같다.그에 반해 트렐로에서 웹훅 이벤트를 발생시키기 위한 유저 액션들이 비교적 간단하고, 그에 따른 콜백 리퀘스트 또한 누락 없이 빠르게 잘 들어와서 그나마 쉽게 테스트를 할 수 있었다.Q. 기능 구현을 위해선 반드시 알아야 할 웹훅 이벤트 종류 및 데이터에 대한 문서는 정리가 전혀 안 되어있다고 하던데 정말인가?그렇다. 처음엔 좀 당황했지만, 그래도 방법이 없으니 일일이 경우마다 테스트해보면서 직접 정리를 하려고 했다. 하지만 각 웹훅마다 큰 구분만 있고 세세한 데이터는 너무 다양해서 깔끔하게 정리하기가 어려워 따로 공유를 위한 문서를 만들지는 못했다. 예를 들자면 트렐로에서 updateCard 라는 action type의 웹훅 데이터를 보내주는데, 그 데이터만 보고 “Card Archive”, “Description 수정/삭제”, “Due date 등록/수정”, “카드 이동” 등의 여러 가지 서로 다른 이벤트를 구분해야 한다. 근데 그 구분하는 방법이 특정 flag가 있는 게 아니라서 각 data를 모아놓고 역으로 분리하다 보니 코드를 깔끔하게 작성하기가 어려움은 물론, 추후 트렐로 측 데이터의 변동이 있을 때의 품질을 보장할 수 없는 리스크를 안고 구현할 수밖에 없었다.Q. 그 밖의 도움이 될만한 노하우나 꿀팁이 있다면?만약 트렐로와 어떤 형태로든 연동하려고 한다면, 설계 전에 모든 API에 대해 꼼꼼히 살펴보고 웹훅 이벤트 또한 직접 테스트해서 일단 전체적으로 리스트업을 정리하는 게 보다 생산성에 도움이 될 것이다. 트렐로를 잘 알고 있더라도 서비스 내부에서 “보드”, “리스트”, “카드”가 어떤 상관관계를 가지는지 미리 정리해보는 것도 좋다.사소하지만 좀 특이했던 점은 웹훅을 처음 등록할 때 해당 URL로 확인 요청을 한번 하는데, 이때 요청은 HTTP method가 POST가 아닌 HEAD로 들어온다. 그래서 반드시 동일한 URL의 HEAD 요청에 대해서도 정상 응답을 할 수 있도록 구현해야 한다.마무리잔디 커넥트를 구현하면서 특히 서비스 품질과 개발 속도 간의 밸런스에 대한 고민을 많이 했습니다. 초반에 서비스 종류별로 작업을 분리하고 각각의 방식으로 설계한 뒤 나중에 정리하는 전략이다 보니 공통으로 가져갈 수 있는 DB 모델이나 서비스 로직이 많아서 이를 통합하기 위해 반복 작업을 할 수밖에 없었는데 이 부분이 저희 내부적으로 느낀 가장 아쉬운 부분이 아니었나 생각합니다. 기능 중 많은 부분이 외부 서비스에 의존적이다 보니 생각하지도 못한 크고 작은 이슈들이 발생해서 일정 산출에도 꽤 어려움을 겪었습니다.커넥트 기능을 출시한 이후로 꽤 시간이 지났음에도 불구하고 이슈 백로그(Backlog)를 보니 아직도 개선할 부분이 많이 남아있는 듯 합니다. 그렇지만 이번에 기반이 되는 작업을 최대한 튼튼히 하기 위한 많은 시행착오를 거쳤기에, 추후 연동되는 커넥트 종류를 늘려나가는 시점5에 보다 효과적으로 개발할 수 있을 것이라 기대하면서 이번 글을 마치겠습니다.Slack API 문서 참고 ↩vagrant의 box로 서로의 로컬 개발 환경을 동일하게 유지하고 있습니다. 참고로, 현재 저희 서버 환경은 Local - Dev - Staging - Production으로 구성되어 단계별로 상황에 알맞게 배포하고 있습니다. ↩Localization의 약어. 잔디는 아시아 시장에 최적화된 서비스를 제공하고자 한국어, 일본어, 중국어 간체자(중국), 번체자(대만/홍콩), 영어 총 5가지 언어를 지원합니다. ↩아이캘린더(iCalendar)로 불리는 인터넷 캘린더의 데이터 포맷에 관한 표준. IETF 문서참고 ↩구체적인 시점은 말씀드리기 어렵지만, 더욱 좋은 사용성을 제공하고자 유저분들의 설문조사를 진행하고 있으니 많은 참여 부탁드립니다. ↩#토스랩 #잔디 #JANDI #개발후기 #일지 #인사이트
조회수 4494

자바스크립트 기초 문법 정리 Part 2 - 객체

지난 Part 1 포스팅에 이어 자바스크립트 기초 문법에 대해 정리해보았습니다. 이번 포스팅에서는 여러 객체와 그 객체에서 제공하는 각 메서드에 대해 정리하였습니다. 다루는 객체의 여러 메서드에 대해 정리하였기 때문에 전 포스팅처럼 간략하지는 않지만 이번 포스팅을 저장해 두고 자바스크립트로 개발하면서 필요할 때마다 참고하여 보기에는 좋을 것 같습니다. 다만, 메서드 사용 예의 코드는 넣지 않았으니 예제 부분이 필요하다면 필히 공식 문서를 참고해주세요. 익히는 것 자체도 공식 문서를 통하여 보는 것이 가장 좋지만 혹여 영어에 취약하신 분이라면 이 포스팅을 참고하는 것도 괜찮을 것 같습니다. :)내장 객체브라우저의 자바스크립트 엔진에 내장된 객체. String/Date/Array/Nath/RegExp Object 등이 있음.날짜 객체 DateDate 객체 생성new Date()new Date(milliseconds)new Date(dateString)new Date(year, month, day, hours, minutes, seconds, milliseconds)Date Get 메서드getDate() - 일 정보를 가져옴.getDay() - 요일 정보를 가져옴. 0(일요일)-6(토요일)getFullYear - 연도 정보를 가져옴. (yyyy)getHours() - 시간 정보를 가져옴.getMilliseconds() - 밀리초 정보를 가져옴. 0-999 (1/1000 초의 단위)getMinutes() - 분 정보를 가져옴.getMonth() - 월 정보를 가져옴. 현재 월에서 -1한 값으로 옴.getSeconds() - 초 정보를 가져옴.getTime() - 1970년 1월 1일부터 경과된 시간을 밀리초로 가져옴.Date Set 메서드setDate() - 일 정보를 설정.setFullYear() - 연도 정보를 설정. 원한다면 월과 일 정보도 설정할 수 있다.setHours() - 시간 정보를 설정.setMillseconds() - 밀리초 정보를 설정.setMinutes() - 분 정보를 설정.setSeconds() - 초 정보를 설정.setTime() - 1970년 1월 1일부터 경과된 시간을 밀리초로 설정.기타 Date 메서드now() - 1970년 1월 1일부터 지금까지의 밀리초를 반환.parse() - 날짜 형태의 문자열을 변환하여 1970년 1월 1일부터 입력한 날짜까지의 밀리초를 반환.toString() - Date 객체를 문자열로 변환.toJSON() - Date 객체를 JSON 데이터로 변환.valueOf() - Date 객체를 밀리초로 반환.숫자 객체 NumberNumber 생성var num = 1;      var num2 = new Number(1);Number 객체의 속성MAX_VALUE - 표현 가능한 가장 큰 수.MIN_VALUE - 표현 가능한 가장 작은 수.POSITIVE_INFINITY - 무한대 수 표기.NEGATIVE_INFINITY - 음의 무한대 수 표기.NaN - 숫자가 아닌 경우 표기.Number 객체 메서드toExponential(n) - 자수 표기법으로 소수점 n자리만큼 문자형 데이터로 반환.toFixed(n) - 소수점 n자리만큼 반올림하여 문자형 데이터로 반환.toPrecision(n) - 유효 숫자 n의 개수만큼 반올림하여 문자형 데이터로 반환.toString() - 숫자형 데이터를 문자형 데이터로 반환.valueOf() - 객체의 원래 값을 반환.parseInt(값) - 데이터를 정수로 변환하여 반환.parseFloat(값) - 데이터를 실수로 변환하여 반환.수학 객체 MathMath 메서드 및 상수Math.abs(숫자) - 숫자의 절댓값을 반환.Math.max(숫자1, 숫자2, 숫자3) - 숫자 중 최댓값을 반환.Math.min(숫자1, 숫자2, 숫자3) - 숫자 중 최솟값을 반환.Math.pow(숫자, 제곱값) - 숫자의 거듭제곱한 값을 반환.Math.random() - 0~1 사이의 난수를 반환.Math.round(숫자) - 소수점 첫째 자리에서 반올림하여 정수를 반환.Math.ceil(숫자) - 소수점 첫째 자리에서 무조건 올림에서 정수를 반환.Math.floor(숫자) - 소수점 첫째 자리에서 무조건 내림해서 정수를 반환.Math.sqrt(숫자) - 숫자의 제곱근 값을 반환.Math.PI - 원주율 상수를 반환.배열 객체 ArrayArray 생성var array = new Array();array[0] = 1;array[1] = 2;var array2 = new Array(1, "temp", true);var array3 = [1, true, "문자열도 가능"];Array 객체의 메서드 및 속성join(연결문자) - 배열 객체에 데이터를 연결 문자 기준으로 1개의 문자형 데이터로 반환.reverse() - 배열 객체에 데이터의 순서를 거꾸로 바꾼 후 반환.sort() - 배열 객체에 데이터를 오름차순으로 정렬.slice(index1, index2) - 배열 객체에 데이터 중 원하는 인덱스 구간만큼 잘라서 배열 객체로 가져옴.splice() - 배열 객체에 지정 데이터를 삭제하고 그 구간에 새 데이터를 삽입할 수 있음.concat() - 2개의 배열 객체를 하나로 결합.pop() - 배열에 저장된 데이터 중 마지막 인덱스에 저장된 데이터 삭제.push(new data) - 배열 객체에 마지막 인덱스에 새 데이터를 삽입.shift() - 배열 객체에 저장된 데이터 중 첫 번째 인덱스에 저장된 데이터를 삭제.unshift(new data) - 배열 객체의 가장 앞의 인덱스에 새 데이터를 삽입.length - 배열에 저장된 총 데이터의 개수를 반환.문자 객체 StringString 생성var str = "hello";      var str2 = new String("hi");String 객체 메서드 및 속성charAt(index) - 문자열에서 인덱스 번호에 해당하는 문자 반환.indexOf("찾을 문자") - 문자열에서 왼쪽부터 찾을 문자와 일치하는 문자를 찾아 최초로 일치하는 문자의 인덱스 번호를 반환. 찾는 문자가 없으면 -1 반환.lastIndexOf("찾을 문자") - indexOf와 동일하나 문자열의 오른쪽부터 찾음.match("찾을 문자") - indexOf와 동일하나 찾는 문자가 없으면 null을 반환.replace("바꿀 문자", "새 문자") - 문자열에서 왼쪽부터 바꿀 문자와 일치하는 문자를 찾아 최초로 찾은 문자를 새 문자로 치환.search("찾을 문자") - 문자열 왼쪽부터 찾을 문자와 일치하는 문자를 찾아 최초로 일치하는 인덱스 번호를 반환.slice(a, b) - a개의 문자를 자르고 b번째 이후에 문자를 자른 후 남은 문자를 반환.substring(a, b) - a 인덱스부터 b 인덱스 이전 구간의 문자를 반환.substr(a, 문자 개수) - 문자열에 a 인덱스부터 지정한 문자 개수만큼 문자열을 반환.split("문자") - 지정한 문자를 기준으로 문자 데이터를 나누어 배열에 저장하여 반환.toLowerCase() - 문자열에서 영문 대문자를 모두 소문자로 바꿈.toUpperCase() - 문자열에서 영문 소문자를 모두 대문자로 바꿈.length - 문자열에서 문자의 개수를 반환.concat("새로운 문자") - 문자열에 새로운 문자열을 결합.charCodeAt("찾을 문자") - 찾을 문자의 아스키 코드 값을 반환.fromCharCode(아스키 코드 값) - 아스키 코드 값에 해당하는 문자를 반환.trim() - 문자의 앞 또는 뒤에 공백 문자열을 삭제.브라우저 객체 모델(BOM)브라우저에 내장된 객체. window 객체브라우저 객체의 최상위 객체.window 객체 메서드open("url 경로", "창 이름", "옵션 설정") - 새 창을 열 때 사용.- open() 메서드 옵션 설정: width/height/left/top/location/status/scrollbars/tollbarsalert("메세지") - 경고 창을 띄움.prompt("질의 내용", "기본 답변") - 질의응답 창을 띄움.confirm("질의 내용") - 확인/취소 창을 띄움.- 확인 클릭시 true 반환, 취소 클릭시 false 반환.moveTo(x 위치값, y 위치값) - 창의 위치를 이동시킬 때 사용.resizeTo(너빗값, 높잇값) - 창의 크기를 변경시킬 때 사용.setInterval("스크립트 실행문", 시간 간격) - 일정 간격으로 반복하여 실행문을 실행시킬 때 사용.clearIntervar(참조 변수) - 참조 변수에 참조되어 있는 setInterval() 삭제.setTimeout("스크립트 실행문", 시간 간격) - 일정 간격으로 한 번만 실행문을 실행시킬 때 사용.clearTimeout(참조 변수) - 참조 변수에 참조되어 있던 setTimeout() 삭제.screen 객체사용자의 모니터 정보를 제공하는 객체.screen 객체 속성width/height/availWidth/availHeight/colorDepth(사용자 모니터가 표현 가능한 컬러 bit)location 객체사용자 브라우저의 주소 창에 url에 대한 정보와 새로 고침 기능을 제공하는 객체.location 객체 속성 및 메서드href - 주소 영역에 참조 주소를 설정하거나 URL 반환.hash - URL의 해시값을 반환.hostname - URL의 호스트 이름을 설정하거나 반환.host - URL의 호스트 이름과 포트 번호를 반환.port - URL의 포트 번호를 반환.protocol - URL의 프로토콜을 반환.search - URL의 쿼리를 반환.reload() - 새로 고침.history 객체사용자가 방문한 사이트 중 이전에 방문한 사이트와 다음 방문한 사이트로 다시 돌아갈 수 있는 속성과 메서드를 제공하는 객체.history 메서드 및 속성back() - 이전 방문한 페이지로 이동.forward() - 다음 방문한 페이지로 이동.go(이동 숫자) - 이동 숫자만큼의 페이지로 이동. 음의 값이면 이전 페이지로 이동.length - 방문 기록에 저장된 목록의 개수 반환.navigator 객체현재 방문자가 사용하는 브라우저 정보와 운영체제의 정보를 제공하는 객체.navigator 속성appCodeName - 방문자의 브라우저 코드명을 반환.appName - 방문자의 브라우저 이름 반환.appVersion - 방문자의 브라우저 버전 정보를 반환.language - 방문자의 브라우저 사용 언어를 반환.product - 방문자의 브라우저 사용 엔진 이름을 반환.platform - 방문자의 브라우저를 실행하는 운영체제를 반환.userAgent - 방문자의 브라우저와 운영체제의 종합 정보를 제공.문자 객체 모델(DOM)HTML 문서의 구조.선택자직접 선택자직접 문서에서 요소를 선택함. (id/class/폼 명/요소 명 등)document.getElementById("아이디 명") - 아이디를 이용해 요소를 선택.document.getElmentsByTagName("요소 명") - 요소의 이름을 이용해 요소를 선택.document.formName.inputName - 폼 요소에 name 속성을 이용해 요소를 선택.인접 관계 선택자직접 선택자를 사용해 선택해 온 문서 객체를 기준으로 가까이에 있는 요소를 선택함. (parentNode/childeNodes 등)parentNode - 선택한 요소의 부모 요소를 선택.childNodes - 선택한 요소의 모든 자식 요소를 선택. 선택한 모든 요소가 저장됨.firstChild - 선택한 요소의 첫 번째 자식 요소만 선택.previousSibling - 선택한 요소의 이전에 오는 형제 요소만 선택.nextSibling - 선택한 요소의 다음에 오는 형제 요소만 선택.문서 객체 이벤트 핸들러 적용하기onclick - 선택한 요소를 클릭했을 때 이벤트 발생.onmousevoer - 선택한 요소에 마우스를 올렸을 때 이벤트 발생.onmouseout - 선택한 요소에 마우스가 벗어났을 때 이벤트 발생.submit - 선택한 폼에 전송이 일어났을 떄 이벤트 발생.버튼document.getElementById("btn").onclick = function() {    alert("welcome");}일단은 참고하는 책을 기준으로하여 정리해보았는데 후에 시간이 될 때마다 공식 문서를 참고하여 번역한다는 생각으로 보다 세부적인 사항을 정리해도 좋을 것 같다는 생각이 드네요. 우선적으로는 빠르게 함수와 이벤트에 대해 배우고 객체에 대한 더 자세한 사항을 정리하도록 하겠습니다. 다음 포스팅은 자바스크립트의 함수와 이벤트에 대해 다룰 예정입니다!참고문헌:Do it! 자바스크립트+제이쿼리 입문 - 정인용JavaScript 튜토리얼 문서 (http://www.w3schools.com/js/default.asp)티스토리 블로그와 동시에 포스팅을 진행하고 있습니다.http://madeitwantit.tistory.com#트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유
조회수 1096

나이들면서 더욱 와닿게 될 단상 5가지.

1. 통장에 몇백억 있는 사람이 주는 인사이트와 조 단위가 있는 사람의 인사이트는 다르다. 전자는 성공 방정식에 대해 잘 모르고 있고 후자는 방정식 자체가 있다. (물론 운이 언제나 중요하지만.. 운은 통제할 수 없는 것이고 통제할 수 있는 것은 방정식이 존재한다.) 이 이유는 전자는 성공을 목표로 했기 때문이고 후자는 돈을 넘어선 철학이 있기 때문이다. 무슨 말이냐? 성공의 목표는 언제나 성공밖에 생각할 수 밖에 없기 때문에 막상 사회적으로 성공이라는 자리에 도착했을 때 내가 무엇 때문에 이런 길을 걸어왔나에 대한 멘붕이 온다. 하지만 철학이 있는 사람은 항상 생각한다. 내가 끝까지 가고자 하는 길.. 그리고 매일 매일 그 길에 대한 질문과 반성과 참회. 그렇기 때문에 후자가 성공에 대한 더 뚜렷한 관점과 철학을 가지고 있다.2. 책을 읽는다고 해서 성공하는 건 아니지만 성공하는 사람들을 보면 책을 안 읽는 사람들이 없다라는 말을 굉장히 공감했었다. 근데 이제는 이 말을 한 줄로 요약해서 생각한다. 책을 읽어야지만 아주 아주 큰 성공을 할 수가 있다. 책은 인간이 가장 빠르게 성장해야할 때 활용할 수 있는 최고의 도구다.3. 성공은 다 같은 방식으로 성공하지만 실패는 다 제 각기 이유로 실패한다. 그 이유는 성공이라는 것은 단 하나의 요소로서 만들어지는 것이 아니라 여러가지 요소들이 공통적으로 뒷받침될 때 성공할 수 있는 반면 실패는 한 요소만 실패해도 그 일 자체는 실패하기 때문이다. 가령 타이밍, 마켓핏, 팀, 자본 등 어느 한가지라도 갖추어지지 않으면 실패하는 반면 모든 것을 다 갖쳐야지만 성공할 수 있는 것이다. 그래서 성공은 다 같은 방식으로 성공하지만 실패는 제 각기 다른 이유로 실패한다. 그래서 실패에서 배울점을 찾기보다 제대로 성공한 것을 자기만의 방식으로 습득하여 체화시켜야한다.4. 꿈이라는 것을 가질 수 있는 것이 정말 중요하다. 꿈은 직업이 아니다. 직업을 넘어선 그 무엇인가 가슴 떨리는 것이다. 근데 꿈을 가지는 것은 이제 당연한거고 그 꿈의 "크기"와 "의도"가 중요하다. 크기는 아주 아주 아주 아주 커야된다. 사람들이 말도 안된다고 할 정도로 커야된다. 의도는 내 이익을 위한 것이 아니어야한다. 남들의 이익을 목표로하지만 결국에 그 믿음이 나한테 더 많은 이익으로 돌아올거라는 선한 의도와 용기다.5. why에 대한 질문을 습관화해야된다. 이 why를 끝까지 파고들어가면 내 존재의 이유에 대한 why에 도착하게 된다. 나는 왜 사는가? 나는 왜 존재해야되는가? 이 질문에 회피해서는 안된다. 일단 태어났으니깐 어떻게 살아야되는지가 중요할까? 그렇지 않다. 내가 존재해야만 하는 그 why를 내 스스로 내 가슴으로 정의내려야한다. 내 존재의 이유가 빠지는 순간 그 다음에 따라오는 모든 일련의 사건들은 철학이 없고 신념이 없으며 논리가 부정확하고 매번 의사결정에서 흔들리게 된다. #페오펫 #peopet #아이디어기업 #기업문화 #목표 #비전 #각오 #인사이트 #경험공유
조회수 1583

최진 이야기

최진님은 내가 처음으로 만난 UX 기획자다. 지난 회사에서 새로운 사업 아이디어가 나올 때마다 했던 이야기가 있다.A: “새로운 서비스 개발을 시작합시다!"B: “그럼 기획은 누가 하나요?"A: “적당히 나눠서 해야죠."나에게 기획자라 하면 개발해야 할 것을 완벽하게 정리해서 가져다주는 마법사였다. 하지만 당시 그 일을 해줄 수 있는 사람은 없었고 매번 그 지점에서 갈등이 생기곤 했었다.8퍼센트에 처음 왔을 때 “오. 이 회사에는 기획자가 있네?”라고 생각했었다. 밑도 끝도 없이 일하기 편하겠다는 생각을 했던 것 같다. 당시만 해도 기획자에게 어떤 결과물을 기대해야 하는가? UI와 UX는 어떻게 다른 건가? 기획자와는 어떻게 일하는 것이 좋은가? 등등을 전혀 몰랐었는데 이제 진님을 통해서 하나씩 배워가고 있다. 어떻게 생각해 보면 B2B 플랫폼 개발자에서 B2C 서비스 개발자로 바뀌면서 알아야 할 것들을 배워가는 과정이라고 할 수 있겠다.내가 기획 했으니 너는 들으라. (이효진 대표님 지켜주지 못해 미안해요.)자 그럼 내가 8퍼센트의 최진님을 통해서 알게 된 'UX 기획자의 역할'을 살펴보자. (내가 잘못 알고 있다면 진님 탓이다)사람들을 토론의 장으로 데려온다.기존까지 생각하던 기획자는 모든 것을 고려한 이후에개발자: “더 이상 변경은 없는 거죠? 이대로 개발만 하면 되는 거죠?”기획자: “네!"를 할 수 있는 문서를 건네주는 사람이었다.이렇게 마법같이 한번에 최적의 솔루션을 찾는 일은 일어나지 않는다하지만 이제는 기획자에게 기대하는 바가 달라졌다. 100%를 한 번에 하는 것이 불가능하다는 것을 알고 있고, 혹시나 가능하더라도 효율적이지 않다는 것도 알고 있다. 60%를 빠르게 만들어서 회사 내 구성원들을 토론에 적극적으로 참여시키는 것이 기획자의 역할이라고 생각한다. 아무것도 없는 상태에서 무언가를 만들어내는 것은 어렵다. 당연히 그 상태에서는 생산적인 논의도 되지 않는다. 하지만 다른 사람이 해 놓은 것에 대해서 평가하는 것은 다들 손쉽게 하지 않는가. 기획자가 가져온 초안을 바탕으로 CS팀은 고객이 되어 기능을 검토하고, 그래픽 디자이너는 결과물을 상상하고, 개발자는 다른 모듈과의 연관성, 사용해야 할 라이브러리를 검토한다. 여기서 부터가 적극적인 시작이다.8퍼센트의 연결고리 최진. 직접 그린 그림에서 힙합 매니아임을 알 수 있다좋게 말하면 8퍼센트에서는 최진을 중심으로 일이 돌아간다. 하지만 실제는 그냥 이리저리 치이고 여기저기 불려 다니는 인터럽트 인생이다.답을 찾아 준다.그냥 주는 것이 아니라 찾아 준다는 것이 중요하다. 제품을 만들다 보면 결정해야 할 것들이 너무나도 많다. 버튼의 위치, 폰트의 크기, 안내 문구, 페이지 전환을 할 것인가? 에러 상황은 어떻게 처리할 것인가? 등등. 이런 질문들에 대해 답을 줄 수 있는 사람이 명확한 경우도 있다. 예를 들면 디자인을 할 때 “이런 식의 구현이 가능한가요?”라고 물으면 개발자가 답을 해 줄 수 있다. 하지만 대부분은 고객에게 던지는 질문이다. 이런 질문들에 대한 답을 찾아 주는 것이 기획자의 역할 중 하나라고 생각한다. 그 답은 영업팀에서 가지고 있을 수도 있고, 고객서비스팀에서 가지고 있을 수도 있다. 하지만 우리 모두는 그 질문을 기획자에게 던지고 기획자는 그 질문에 대한 답을 찾아 준다.프로덕트 팀의 피어리뷰 시간에 아기새님이 진님에게 전달한 피드백컨베이어 벨트를 따라 걷는다.요구사항의 정리부터 기획, 디자인, 개발, QA, 릴리즈에 이르기까지 모든 과정을 지켜보는 한 사람이 있다. 기획자다. 이 사람이 제 역할을 하지 않으면 '방과 방 사이' 같은 일이 발생한다. 기획자는 프로젝트를 시작되게 한 고객의 요구사항이 정확히 다시 고객의 손에 전달될 때까지의 과정을 지켜본다. 컨베이어 벨트를 따라 걸으며  방향이 빗나갔을 때에는 바로잡고 놓친 사용자 패스가 있을 때에는 이를 채워 넣는다. 때로는 최초의 가정이 틀렸을 때 빨간 버튼을 눌러 컨베이어 벨트를 멈추는 역할을 한다. 결국 모든 과정이 완료되어 고객에게 제품이 전달되었을 때 기획은 끝이 난다.제품에 대한 책임을 진다.원래 결정하는 자가 책임을 지는 법이다. 제품이 시장에서 좋은 평가를 얻지 못할 때 사람들은 그 책임을 돌릴 곳이 있다. 기획자다.쟤가 그렇게 하라고 했어요. (흥. 난 몰라)물론 8퍼센트는 그 책임을 서로 미루지 않고 다 함께 진다. 하지만 진님은 그 책임을 무겁게 느끼고 있다. 외부에서 쓴소리가 들려올 때 받는 스트레스를 보면 알 수 있다.이 정도가 내가 생각하는 UX 기획자가 하는 일이다. 다른 회사의 UX 기획자가 하는 일과 얼마나 다를지는 모르겠다. 크게 깨닫지 못하고 있었는데 글로 정리하고 보니 UX 기획자는 서비스를 만드는 회사에서 대단히 중요한 사람이다. 새삼 감사한 마음이 든다. 사실 진님은 지금까지 이야기한 UX 기획 외에도 UI 설계도 함께 맡고 있다. 진님이 8퍼센트에서 하는 일을 좀 더 알고 싶다면 진님이 직접 쓰신 글을 읽어 보자.진님은 브런치에 글을 쓴다. 무려 나보다 5배나 많은 구독자를 가지고 계신 인기 작가(질투로 인해 표현이 좀 꼬인 것을 이해해 달라) 이시니 램프의 요정 GENIE의 브런치를 방문해 보시길 바란다. 직접 그린 그림과 함께 글을 쓰시기 때문에 브런치 메인의 웹툰 작가 리스트에서도 종종 찾을 수 있다. 때로는 긴 글 보다 한 장의 그림이 훨씬 더 많은 것들을 전달할 수 있음을 알기에 참 부러운 능력이다. 그러고 보니 진님의 추천으로 나도 개인 블로그에서 브런치로 넘어와서 재미있게 글을 쓰고 있으니 이 자리를 빌려 감사함을 표해야 하겠다. 진님의 구독자 수를 따라잡을 때까지 열심히 해보겠다.청순한(?) 외모도 갖고 있고 일에서는 완벽을 추구하지만 신은 역시 공평하다. 사람이 허술하다.그 누군가는 이렇게 말했다.처음에는 시크한 이미지여서 다가가기 어렵지만 조금만 지나면 이런 허술한 점들을 아주 손쉽게 발견할 수 있어서 사람들을 편하게 해주는 반전 매력이 있다.처음에 진님과 일을 했을 때에는 자신의 기획안에 대한 불안감과 일을 이끌어 나가는 것에 대한 부담감이 느껴졌다. 하지만 최근에는 그런 것들이 점점 느껴지지 않는다. 발전하고 있다는 증거다. 진님은 자신의 위치와 역할에 대해서 끊임없이 고민한다. 그 질문을 내게 던진다면 내가 만나본 유일한 UX 기획자이기에 진님이 UX 기획자로 어디쯤에 있는지 나는 잘 모르겠다고 답해야겠다. 하지만 지금처럼 치열하게 고민하고 노력한다면 내가 만난 최초의 UX 기획자가 최고의 UX 기획자로도 남을 것이라고는 확실히 말해줄 수 있겠다.진님의 인생사진으로 마무리!같이 일하는 동료에 대한 글을 쓰는 것은 쉽지 않다. 특히 조직도(회사 내에서 별 의미는 없지만)에서 상하 관계에 있는 사람에 대한 글을 쓰는 것은 꽤 부담스러운 일이다. 그래도 이 기회를 빌어 동료에 대한 고민을 깊게 해본다.#8퍼센트 #에잇퍼센트 #협업 #기획 #기획자 #UX기획 #팀워크 #팀플레이 #조직문화 #기업문화
조회수 1769

가격과 편의성은 B2B SaaS서비스의 핵심이 아니다.

SaaS 서비스는 기존의 소프트웨어를 서비스로 만드는 것이다. 이건 누구나 다 아는 이야기다. SaaS의 최대 장점은 기존의 소프트웨어 솔루션 대비 저렴한 가격과 편의성이다. 이것도 맞다. 하지만 B2B 시장에서는 틀리다.종종 다른 회사에서 진행하는 B2B SaaS 서비스에 대한 소개 발표를 들을 때가 있다. 회사의 대표 또는 임원이 나와서 이렇게 설명을 한다. "우리 회사의 서비스는 기존 패키지 보다 훨씬 저렴하며 사용하기도 편합니다. 그리고 기존의 패키지 솔루션의 핵심 기능을 모두 담았습니다." 아마 해당 회사의 새로운 SaaS 서비스는 기존 패키지 솔루션의 핵심 기능을 담기 위해 많은 노력을 했을 것이다. 그런데 이런 서비스는 성공하기 힘들다.먼저 알아야 하는것은 B2B 솔루션을 사용하는 구성원의 성향이다. B2B 솔루션 또는 서비스를 사용하는 담당자는 해당 분야의 전문가이다. 이 담당자들은 솔루션을 사용해서 자신의 역할을 더 잘하는 것을 목표로 삼는다. 이들에게 가격과 편의성은 중요한 것이 아니다. 자신의 전문성에 맞는 수준의 솔루션이 필요한 것이다. 해당 분야에 워낙 밝다보니 사용법이 어려워도 크게 문제되지 않는다. 하물며 기능이 어려운걸 좋아하기 까지 한다.이 문제를 해결할 수 있는 방법은 2가지가 있다. 하나는 전문가 그룹을 피해가는 것이다. 타겟을 기존 전문가가 아닌 비 전무가가 있는 그룹으로 하면 된다. 예를 들면 스타트업이나 SMB 시장을 목표로 잡는 것이다. 하지만 SMB 시장에서 SaaS로 돈을 번다는 것은 쉬운 일이 아니다. 북미나 중국처럼 시장의 규모가 크다면 비 전문가 그룹부터 시작하는 것도 좋은 전략이기는 하지만 국내에서는 쉽지 않다.내가 생각하는 가장 좋은 전략은 SaaS만이 제공해 줄수 있는 핵심 기능을 만들거나 기존 솔루션이 제공 못하는 기능을 추가하는 것이다. 많은 기능을 만들라는 것이 아니다. 해당 서비스를 이용해야만 할수 있는 기능이 있어야 한다는 것이다. 이 전략은 기존의 전문가 그룹도 공략할 수 있으며 글로벌 서비스를 할 때도 차별화 전략을 쓸수 있는 장점이 있다. 물론 쉬운일도 아닐뿐더라 서비스 설계에서부터 고민을 해야 하는 문제이다.와탭이 2016년에 어플리케이션 모니터링 서비스를 내 놓을 때도 같은 고민을 하였다. SaaS 서비스는 외부망을 사용하기 때문에 데이터를 수집하는 데 있어서 내부망을 사용하는 소프트웨어 솔루션 대비 불리한 상황에서 서비스를 제공해야 하는 특성이 있다. 이를 해결하기 위해 와탭은 전세계 어느 리전이든 수집 서버를 제공하는 멀티리젼 기능을 추가했고 기존 어플리케이션 모니터링 솔루션에서는 제공하지 못하던 메소드 기반의 분석 기능도 만들었다. 기존의 많은 어플리케이션 모니터링 솔루션을 사용해본 경험을 가진 전문가 집단이 반할 만한 기능을 만들기 위해 설계에서 부터 많은 공을 들였는데 이건 와탭의 첫번째 SaaS 서비스인 서버 모니터링을 서비스 하면서 배운 경험을 살린 것이기도 하다.와탭의 첫번째 서비스인 서버 모니터링은 오픈 소스를 기반으로 만들었고 기존의 솔루션을 SaaS 로 변환하는 것만으로도 모든 고객이 충분히 만족 할거라는 가정에서 시작했다. 하지만 B2B 전문 담당자에게는 우리의 가정이 통하지 않았고 와탭의 서버 모니터링은 절반의 성공을 거둔것으로 만족해야 했다. SMB 시장에는 편하게 사용할 수 있는 모니터링 서비스로 인식되었지만 전문가의 눈높이를 맞추는건 쉽지가 않았던 것이다. 하지만 그 경험은 현재 와탭의 DNA에 고스란히 남아 새로운 서비스에 녹아 들어 더 좋은 서비스를 만드는데 사용되고 있다. 그리고 이제 곧 서버 모니터링을 대체하는 와탭의 인프라스트럭처 모니터링이 오픈 될 예정이다. 와탭의 실시간 데이터 저장 기술이 그대로 반영되어 서버의 모든 프로세스 정보를 모니터링하고 추적할 수 있으며 수집 주기도 5초 단위로 나타나기 때문에 실시간 성을 지닌 서비스이다. 오픈소스로 구현이 불가능하며 기존의 다른 솔루션과도 차별성을 둔 제품이다.    길게 이야기 했는데 마지막으로 정리하겠다. B2B SaaS 서비스를 만든다면 기존 솔루션을 서비스로 전환하겠다는 생각으로 만들지 말아라. 현재나 곧 다가올 미래의 상황에 최적화 된 새로운 방안을 제시하는 서비스를 만들어야 한다. 그렇게 된다면 SaaS 고유의 가격과 편의성은 서비스의 날개가 되어줄 것이다.  #와탭랩스 #와탭 #SaaS #SaaS서비스 #SaaS기업 #B2B #B2BSaaS #인사이트 #경험공유 #조언
조회수 691

부정을 바라보는 관점

"저는 항상 고민이 많습니다. 그래서 이렇게 사연을 보내게 되었습니다. 고민하는 문제들이 타인에겐 작은 문제일지라도 저는 심각하다고 늘 느낍니다. 항상 부정적인데 친구들이 저의 그런 부정적인 문제점을 닮아간다고 해서 저 고민이기도 합니다. 저의 그런 늘 부정적인 면 때문에 사람들과 갈등도 많아지고 제 자신도 너무 힘들답니다. 고치려고 노력하지만 정말 힘들더라고요. 그래서 조언을 조금 듣고 싶어요." - '쬬맹이쿠키'님의 사연종종 우린 '긍정의 힘'에 대해 듣곤 한다. 그래서 다들 긍정 긍정한다. 마치 긍정적이면 작은 기적이 일어날 거라고 믿는 모양이다. 긍정이란 진짜 뭘까? 어떠한 힘든 순간에서도 웃을 수 있는 힘? 다시 일어날 수 있는 힘? 긍정적인 사람은 타고나는 걸까? 아니면 상황에 따라 변하는 걸까?나도 오래전부터 비슷한 경험을 했다. 나는 분명 철 없이 해맑고 긍정적인 사람이었는데 어느 순간 주변 사람으로부터 왜 이렇게 부정적이냐며 핀잔을 받았다. 그리고 나 자신에 대해 혼란이 가기 시작했다. 왜 이렇게 많은 것들에게 대해 호의적이지 않고 비판적인지, YES가 아닌 'NO를 먼저 말하고 생각하게 되었는지 꽤나 오랜 시간 동안 고민하고 돌이켜보니 상황에 따라 내가 겪어온 환경에 따라 변할 수 있다는 것을 알게 되었다. 닥친 환경이 얼마나 사람을 많이 변화시키지를 사람들은 모른다. 어떤 트라우마들이 쌓이고 쌓여 두려움을 안겨주었는지 이해하지 못하는 것 같다. 무엇보다도 '부정적'인 면모가 얼마나 살아가면서 우리에게 필요한지를 모르는 사람도 꽤 많다고 느낀다. 어떤 책들은 마치 긍정적이면 이 세상 모든 것을 해낼 수 있을 것처럼, 어떤 어려움도 다 헤쳐나갈 수도 있을 것 마냥 긍정을 우리에게 요구한다. 그렇다고 '부정적'인 사람을 마냥 옹호하는 것은 아니다. 다만 '부정'이 단지 나쁜 의미가 아니라는 걸 말해보고 싶다. 개인적으로 나는 부정적이기에 현재의 내가 있다고 생각한다. 마냥 철 없이 긍정적이던 그때의 나보다 현재 부정적인, 비판적인 내가 나는 더 좋다. 우리는 비판하고, 부정적인 사고를 가져야 성장을 한다. 되러 현재에 만족하며 살아가자는 긍정적인 사고는 성장을 멈춘다고 생각한다. 사실 부정과 긍정은 정말 밀접한 관계가 있다는 걸 느낀다. 마냥 긍정도 마냥 부정도 결국 우리에 인생에 있어 아무 도움이 되지 않는다는 것이다. 내가 생각하는 부정은 '현실 직시'와도 같다. 내가 부족한 점이 있다면 그걸 인지하고 더 좋아지도록 노력하는 것도 일종의 부정에서 비롯된다고 생각한다. 물론 나의 부족한 점을 포용하고 긍정적으로 받아들이고 살아갈 수도 있다. 그냥 현재 나에게 만족해하며 살아갈 수 있다. 본인이 그렇게 사는 것이 행복하다면 말이다. 하지만 나의 부족한 점을 채우고 조금 더 나은 결과를 원한다면 현재를 부정해야 한다. 현재에 만족하고 안주하지 않고 현재, 현실을 인정할 줄 알아야 우리는 앞으로 나아갈 수 있다고 생각한다. 개인적으로 나는 그렇게 생각하고 늘 그래 왔다.잘될 거야!라고 무작정 긍정적으로 믿고 멈춘다면 그 이상으로 원하는 바로 나아가기가 힘들다. 그저 믿는 긍정은 부정보다도 못하는 생각이 든다. 이런 친구들이 있다. 무슨 말만 하면 부정적으로 대답하는 친구들. 가끔 정말 분위기를 망치기도 하고 그런 사람들과는 함께 하기가 거부감이 들 때가 많다. (나도 그런 사람 중 한 사람 아닐까 싶다) 하지만 그런 친구들의 이야기를 잘 곱씹어보면 정말 현실 직시를 하는 이야기를 해줄 때가 많다. 물론 매번 그러면 정말 짜증 나고 함께 하기 힘들다고 생각하게 되지만.. 개인적인 경험이지만 나를 포함해 주변 부정적인 사람들을 보면 보통 겁이 많다. 그리고 부정적인 경험에서 오는 불안감도 큰 것 같다. 이런 일이 있었는데.. 또 이러면 어쩌지?경험, 트라우마에서 오는 일종의 방어가 아닐까 싶다. 그렇다고 부정 자체를 마냥 옹호하고 싶지는 않다. 더군다나 주변 사람들을 너무 힘들게 할 만큼 부정적인 영향을 끼친다면 더더욱 말이다. 부정적인 사고는 가지되, 부정을 긍정으로 그리고 긍정을 부정으로 오고 가며 사고하는 방식을 배우면 좋겠다. 예를 들어 앞으로 나가기 위한 부정 말이다. 그리고 부정함을 완화시키기 위해서 조금씩, 앞으로의 좋은 경험을 쌓을 필요가 있지 않을까 싶다. 내게 부정적인 이미지로 고민으로 다가왔던 것들을 하나하나씩 긍정적인 경험으로 쌓도록 노력한다면 조금은 완화가 되곤 한다. 물론 사람마다 각각 다른 방법과 정도가 다르겠지만 말이다.  '부정' 자체를 너무 부정하지 말자 (부정에도 긍정만큼의 힘이 있다.) 부정을 통해 긍정을 얻도록 노력해보자 (부정을 긍정으로 완화시키는 노력을 조금씩 해보자) 전문가에게 도움을 받는 것도 꼭 한번 고려해보자 (감기에 걸려서 병원에 가듯이, 마음이 아플 때도 병원에 가는 것은 당연한 것이다.) 부정적인 본인을 너무 미워하지 말자. 나의 부정적인 면도 이해하고 감싸주면 변화가 올 수 있다.끝으로 부정적인 나의 곁에서 나의 존재 자체를 받아주고 나를 응원해주는 그리고 변화하도록, 노력하도록 도와주는 주변인들에게 진심으로 고맙다는 말과 미안하다는 말을 한 번씩 해보는 건 어떨까? 주변인들에 대한 감사와 미안함으로부터 부정에서 긍정으로의 작은 변화가 시작될 수 있다.안녕하세요. 스푼 라디오입니다.'쬬맹이쿠키' 님, 본인의 부정적인 면을 먼저 안아주고 이해해주셨으면 좋겠습니다. 먼저 왜 이렇게 무엇이 나를 부정적으로 만들었는지에 대한 생각과 시간이 먼저 필요하지 않을까란 생각과 함께, 부정적인 면도 충분히 노력을 통해 개선될 수 있고, 부정도 꼭 필요한 감정중 하나라는 것도 알아주셨으면 좋겠습니다. 얼마든지 노력 또는 환경에 의해 개선될 수 있는 부분이라고 생각합니다. 혼자 고민 많이 되셨을 텐데, 사연을 이렇게 보내주셔서 감사합니다. 끝으로 쬬맹이 쿠키님께 따뜻한 겨울맞이 하시길 바라며 스푼에서 직접 제작한 스푼 굿즈 Made in Spoon '담요' 그리고 '머그컵'을 보내드리도록 하겠습니다.누구에게나 사연은 있다.당신의 사연, 고민을 함께 나누는 공간 스푼 라디오입니다.사연에 채택되신 스푼 유저 '쬬맹이쿠키'님께 스푼 라디오 공식 굿즈를 선물로 보내드립니다.여러분의 이야기를 듣고 싶습니다. 스푼 라디오에 사연을 보내주세요.사연에 채택되신 분들께 소정의 선물을 보내드립니다.자세한 사항은 [email protected]으로 문의 바랍니다.
조회수 1724

지표가 중요하지.

스타트업이 챙겨야 할 지표는 정말 많다. 모든 지표를 챙겨야 할 필요는 없지만 사람들의 입에 오르내릴 정도의 지표라면 특정 상황 별로 필요에 대해 어느정도 인정받았다는 뜻일거다. 그러므로 내 분야에 필요한 지표가 무엇인지 체크해 둘 필요가 있다.  지표는 투자를 받을 때 엄청 중요한 요소로 동작한다. 숫자로 표현되지 않는 미래는 왠만한 비전이 아니면 상대방을 설득하기 힘들다. 지표는 다른 사람들에게 현재 상황을 객관화해서 보여주는 가장 좋은 방법이다. 하지만 중요한 것은 다른 사람에게 보여주기 위한 지표가 아니라 내가 사용해서 도움이 되는 지표를 찾아내야 한다.실제로 사업을 하면서 중심이 되는 지표를 선정하는 일은 매우 중요한데, 지표를 잘 선정해야 사업 방향을 제대로 잡아 갈 수 있기 때문이다. 예를 들어 와탭의 경우 서비스 초기에는 모니터링의 확장성에 집중했기 때문에 모니터링 하는 서버의 대수를 핵심 지표로 삼았다. 그래서 모니터링 분야의 특성상 일별 사용자나 월별 사용자가 아닌 일별 모니터링 대수와 월별 모니터링 대수 지표를 사용했다. 스타트업에서 사용하는 지표는 정말 많은데, 아래와 같은 지표들을 사용한다. 모르는 지표가 있다면 의미 정도만 체크해 두었으면 한다.  Bookings계약서에 찍힌 금액Revenue받은 돈ARR(annual recurring revenue)매년 꾸준히 들어오는 돈ARR per customer고객 1명 당 매년 꾸준히 들어오는 돈  MRR(monthly recurring revenue)월별 꾸준히 들어오는 돈Gross Profit쓰고 남은 모든 돈 TCV(total contract value)계약상 받을 모든 돈ACV(annual contract value)12개월 동안 받을 수 있는 모든 돈 LTV(life time vlaue)관계가 있는 동안 받을 수 있는 돈 GMV(gross merchandise value)시장에서 거래되는모든 돈CAC(customer acquistion cost)고객 유치하는데 쓴 돈 DAU(daily active user)하루동안 한번이상 방문하는 사람 MAU(monthly active user)한달동안 한번이상 방문한 사람 CMGR(compounded monthly growth rate)기간 동안 매월 성장한 비율Churn떠나간 사람의 총 수Gross churn줄어든 돈의 비율 Net churn기존 고객 전체에서 줄어든 돈의 비율 Gross burn월별 쓰는 돈 + 추가로 쓴 현금Net burn월별 쓰는 돈위에 있는 개념들은 하나씩 살펴 보고 좋은 지표들은 채택해서 검증해 나가면 좋은 지표들이다. 와탭은 가입자 / 서버수 / Revenue / Burn / Gross Profit / Churn 등의 지표를 관리하고 있는데, 이 지표들을 만드는데 약 50개 정도의 항목을 수집하고 있다.  참고자료http://a16z.com/2015/08/21/16-metrics/#와탭랩스 #와탭 #SaaS #SaaS서비스 #SaaS기업 #문제해결 #데이터분석 #트래킹 #인사이트
조회수 894

나의 창업 이야기(1)

2014년 6월 처음으로 스타트업이라는 말을 알게 된다. ( 사업이라는 단어는 알고 있었다. )알게 된 계기는 간단했다. 당시 '초소형 파력발전기'를 만드는 팀에 소속된 것이다.팀에 들어간 것도 카톡 방에 "사업 관심 있는 사람"라고 물어본 친구가 있었고, 그 물음에 나도 모르게나 관심 있어장난 반 진담 반으로 아무 생각 없이 대답한 게 지금까지 오게 된다.창업가들은 사업을 하게 된 멋진 계기가 존재하지만 나는 그냥 메신저 톡 하나에 무심코 뱉은 말로 시작된 어찌 보면 좀 어이없는(?) 케이스라고 말할 수 있다. 그렇게 팀 엑시스오션을 시작하게 된다.그 당시 생각해보면 정말 스타트업이라는 단어도 모르는 무지 그 자체였다. 그렇다고 솔직히 알려고 하지 않았다. 그냥 무언가를 만든다는 게 즐거웠고 팀 동료들과 함께하는 게 마냥 좋았던 거 같다. 지금까지 틀에 박힌 교육과 경험을 해온 나였지만 엑시스오션에 들어온 계기로 인생은 180도 달라지게 된다.실제 사이즈 모델 제작과 파력 발전량 테스트 파도의 상하운동과 바다의 깊이에 따른 속도차를 이용한 자가발전 에너지를 활용한 바다정보 관측하는 해상부이를 만들고자 하였다. 어렵게 말했지만 바다를 떠다니면서 스스로 에너지 만들고 바다의 데이터를 측정하는 장치라고 생각하면 된다.미니어처도 만들어보았다 헤헤6개월 만에 첫 창업(?)이라고 하기도 뭐한 프로젝트가 기술적 한계에 부딪혀서 정리가 됐지만, 지금도 그 당시 팀 리더 형과는 거의 매주 꼭 보는 사이다.  2014년 첫 창업 이야기 위에 적힌 게 전부다. 생략된 내용이 꽤 많긴 하지만, 군복무를 끝내고 현대자동차에 들어가기 위해 준비하던 나에게 어이없는 창업 생태계에 발 디딤은 그렇게 시작됐다.창업을 하며 느낀점 중 가장 중요한 건 바로 경험의 중요성이다. 해보는 것 겪어보는 것은 정말 중요하다. 생각의 깊이는 결국 경험의 깊이다.많은 사람들은 굉장히 의존적이다. 어떤 일을 하기 전에 질문을 하고 조언을 구하고 확인을 받고 싶어 한다.이게 맞는 건지? 이건 괜찮은 건지?특히나 창업 생태계 내에서는 더더욱 그런 것 같다. 안 해본 경우가 많고 체크할 사항이 어떤 일보다도 더 많다.그래서 그런가 내가 풀어야 할 문제를 남에게 질문하는 경우가 굉장히 많다.물론 멘토들이나 미리 경험해본 사람의 이야기를 들어보는 건 굉장히 중요하다. 하지만 그건 단순히 참고사항일 뿐이다. 그렇다면 어떻게 해야 될까? 그냥 하는 거다. 정말 부딪혀보는 거밖에 없다. 내가 풀어야 할 문제는 결국 내가 부딪혀보고 경험하는 것으로 내 안에 고스란히 녹으며 해결되는 경우가 많다.시작을 한 이후에 문제가 생기고 그 해결책을 찾는 과정에서 전문가를 만나고 조언을 구하는 건 정말 좋다. 하지만 해보지도 않고 앞으로 경험할 일들을 논하는 건 정말 어리석은 일인 것 같다. 현대 창업주 고 정주영 회장님의 꼰대 아닌 꼰대 같은 말 "해보기나 해봤어?"하고 싶으면 하는 거다. 가즈아!( 단! 창업 전에 스타트업과 관련된 기본적인 소양과 지식은 필수다. 창업 관련 서적이나 글들을 읽어서 조심해야 할 부분들은 미리 체크하고 부딪히는 걸 추천한다. ) #태그솔루션 #TAGSOLUTION #제품소개 #인사이트
조회수 1215

아토큐브 is Real Startup!

권한과 책임“책임과 자유, 상호 존중이 중요한 기업입니다. 호칭부터 영어 이름이나 –님이라고 서로를 부릅니다. 수평적 호칭으로 바꾸니 수직적인 관계에서 발생할 수 있는 문제가 사라져 건설적인 토론을 할 수 있더라고요. 아토큐브는 휴가나 반차도 결제받지 않고 본인 업무에 책임만 질 수 있다면 자유롭게 쉴 수 있어요. 출퇴근은 오전 10시부터 오후 5시까지예요. 솔직히 5시에 퇴근하는 분은 없어요. 다들 일이 남으면 집을 안 가세요. 팀원들은 보통 10시, 공동창업자들은 새벽 1시까지 일을 하세요.”자유로운 기업 문화팀원들에게 대표의 눈치를 정말 보지 않느냐고 물으니 약속한 듯이 “전혀 안 본다”고 이구동성으로 답했습니다. (팀원들끼리 자유롭게 말하라며 한 대표는 사무실로 복귀해 팀원 인터뷰는 대표 없이 진행됐습니다.) 안사대부 개발자는 “몇 개월을 팀원들과 함께 제품 개발에 빠져 있다 보면 어느 새 제 사업처럼 느껴진다”고 했습니다.팀원들의 인터뷰에 비춰 볼 때 그는 팀원들에게 업무를 ‘강요’하기보다 ‘주체적’으로 일할 수 있는 환경을 마련하는 것 같았습니다. 실제로 한 대표의 최근 고민은 팀원들이 업무시간에 최대한 집중할 수 있는 환경을 마련해 제 시간에 기꺼이 퇴근할 수 있는 시스템을 만드는 거랍니다.팀 빌딩의 기본“저희 팀원 모두가 각자 전문 역량을 갖추면서도 영업도 언제든 할 수 있을 만큼 외향적이고 회사 제품에 대한 열정이 가득합니다. 함께 할 팀원을 찾을 때 능력도 중요하지만, 기본적이지만 아무나 지닐 수 없는 인성, 매너, 상호존중을 많이 봤어요.”누군가에게는 뜬구름 잡는 이야기인 것 같지만 실제로 그런 조건의 인재를 찾기 위해 저는 장시간 인터뷰를 통해 팀원을 뽑았습니다.문제해결능력“단순한 스킬보다는 문제 해결 능력을 지닌 분을 원합니다. 스타트업에는 하루에도 수십 번씩 다양한 이슈들이 발생하는데, 이런 문제들을 다 해결해야 하잖아요. 벽에 막혔을 때 포기하거나 방법을 못 찾으시는 분이 있지만 적극적으로 문제를 해결하는 분이 있습니다. 그런 분들을 원합니다. 스타트업은 끊임없이 문제를 찾아 해결하는 과정이라고 생각합니다. 이런 역량을 지닌 분인지 알기 위해서는 오랜 시간 인터뷰가 필요해요. 서윤호 pm을 뽑을 때도 네 시간씩 세 번 만났습니다. 저는 상호면접이라고 표현합니다. 상대방도 저나 회사에 대한 궁금한 점을 물어보고 저도 그분에 대해 물어보고요.”#아토큐브 #기업문화 #조직문화 #사내문화 #팀워크 #스타트업 #필요능력 #자유 #팀빌딩 #자율 #문제해결 #권한 #책임
조회수 872

스푼 재무팀  Ellie를 만나보세요!

스푼을 만드는 사람들 11번째 이야기엉뚱하고 솔직한 매력이 넘치는, 재무팀 엘리를 소개합니다!재무팀 Ellie를 표현하는 단어 4가지 1. 두더지2. 빵순이3. 단발머리4. 엘리자베스 여왕알고 보니 별명 부자 엘리, 나를 한마디로 표현한다면?사이다 - 저는 솔직함이 매력입니다. 저의 솔직함엔 '악' 이 없어요 하하! (기분 나쁘지 않게, 하지만 팩트만 쏙쏙 말하는 엘리, 사이다 인정합니다)두더지 잡기 게임'Ellie' 당신이 궁금합니다.Q. 이 구역 최강 빵순이셨다고요?"네, 저 빵 되게 좋아해요. 건강상 몇 년 전부터 줄이긴 했지만 사실 매일 빵을 먹었을 정도로 빵을 좋아해요. 모든 빵을 좋아하긴 하는데, 앙버터가 진짜 맛있는 거 같아요. 추가로, 저는 '고기'를 좋아해요. 고기를 많이 먹어서 그런가? 그래서 제가 건강해요 (웃음)"Q. 엘리자베스 여왕 feat. 커피 값 내는 여자"제가 언젠가부터 갑자기 엘리자베스 여왕이 됐더라고요? 저는 여왕 싫은데.. 전 공주 하고 싶은데.. 왕자는 어디 있죠? 얼마 전에 준이랑, 써니랑 몇 분 다 같이 커피를 마시러 갔을 때 제가 커피값을 냈는데, 갑자기 그 후로 제가 엘리 + 자베스 여왕이 되었더라고요. 부끄러워라"Q. 별명중에 '두더지'가 있던데.."제가 키가 작은 편인데요. 다른 멤버분들이 말씀하실 때, 잘 안 들리거나 궁금하면 제가 의자에서 살짝 일어나서 위를 빼꼼 쳐다보는데요. 그 모습이 두더지 잡기 게임 같다고 그 후로 두더지라는 별명이 생겼어요."당신의 회사생활이 궁금합니다Q. 재무팀에선 어떤 일을 하시나요?"저는 재무회계 관련된 모든 업무를 담당하고 있는데요.1. 급여와 복지비 지급2. BJ 환전 지급3. 법인 카드 관리 및 세금 신고하고 납부 4. 매출 입금 확인 등의 업무를 담당하고 있습니다!"Q. 엘리가 스푼에게 바라는 점은?"저는 현재 딱히 바라는 건 없고요. 회사가 많이 성장하면서 이미 많이 다양한 것들을 제공해주시고 있기도 하고. 반반 차(2시간 off) 제도도 생기고 만족스러워요. 희망사항이 있다면, 회사 내 동아리가 생기면 좋겠다고 생각해요. 그리고 예전에 저희 Jun 이 리드해주셨던 6시 30분, 퇴근 30분 전에 하던 거 있잖아요. 그거 다시 생겼으면 좋겠어요!"*일일 미션: 각 한 사람씩 주어진 다양한 주제를 가지고 정리 및 요약하여, 퇴근 30분 전 모여서 함께 지식과 의견을 나누는 미션.Q. 어떤 사람과 근무하고 싶으세요?인성이 바른 사람이요. 근데, 인성이 바르다는 걸 판단하는 게 참 어렵더라고요. 물론 일도 잘했으면 좋겠지만! 일은 사실 가르치면 돼요. 현재 스푼 멤버들처럼 바른 인성을 가지신 분들이면 좋겠어요.Q. 동료들에게 하고 싶은 말이 있다면?"파이팅..? 우리 모두 부자 됩시다. 아 그리고 특히 제 또래분들께 하고 싶은 말이 있어요. 모두 건강합시다. 건강 챙기셔야 해요. 이제 저희 나이면..(중략)"Q. 스푼에서 근무하면 좋은 점은?"젊은 사람들하고 일할 수 있다는 게 가장 큰 장점이라고 생각해요. (본인도 젊으심). 젊은 분들은 생각도 더 열려있고, 아이디어도 많고 많은 면에서 잘하는 게 많은 것 같아요. 우리 때(?)는 본인이 하고 싶은 이야기를 잘 못하는 문화였는데.. 요즘은 그렇지 않은 회사가 많아지는 추세이다 보니, 스푼도 그중에 한 곳이고요. 그리고 저랑 비슷한 또래분들이 많아서 좋습니다."당신의 사생활이 궁금합니다Q. 엘리의 스트레스 푸는 방법은?"저는 스트레스를 받아도 잘 표현을 안 하는 편이에요. 스트레스를 안 받는 체질이기도 하고요. 가끔씩 스트레스를 받을 때는.. 맛있는 거 먹고 사람들과 이야기하고 술 마시면 괜찮아지더라고요."Q. 여행 마니아라고 들었습니다"최근 1년 정도 3-4번 정도 다녀온 것 같아요. 혼자 여행하는 것도 좋아하고, 가족들이랑 친구들과 가는 여행도 굉장히 좋아하는데요. 보통 대부분 일본과 대만에 가서 쉬다가 와요! 관광하고, 쉬고, 먹고 다 그런 거죠 뭐!"(나중에 여행 같이 가요. 엘리랑 가면 재밌을 거 같아요)Q. 퇴근하고 다양한 활동을 하시던데.."저 요즘 퇴근하고 요가도 하고 영어학원도 다니는데요. 회사 건물이 영어학원인데 사실 여기 안 다니고 반대편 경쟁사 업체에서 공부하고 있어요. 이 건물 학원을 안 다니는 이유요? 퇴근하고 같은 건물에 있으면, 퇴근하고 같은 건물에 있으면, 퇴근 안한 기분도 들고, 잠깐의 산책도 할겸 다른 건물에서 퇴근 후 삶을 만끽하고 싶어서요 하하"Q. 15년 차 경력과 경험의 팁을 알고 싶어요"먼저, 저는 다른 직무를 해보고 싶단 생각을 20대 때 잠깐 했던 것 같긴 한데.. 그 후에는 없었던 것 같아요. 원래 어릴 때부터 주판도 배우고, 속셈학원도 열심히 다녀서 그런지 대학 때 전공도 이쪽으로 공부를 했었어요. 그래서 앞으로도 쭉 이쪽으로 하고 싶단 생각이 들고 50대까지 쭉쭉 일하는 게 꿈이고요.재무회계 쪽으로 진로를 결정하는 분에게 해드리고 싶은 나름의 팁이 있다면, 당연한 말이겠지만(?) 정말 꼼꼼하셔야 하고, 성실하셔야 한다고 생각해요. 특히 숫자에 관심이 많으시면 조금 더 쉬우실 것 같다고도 생각이 들고요. 아무래도 제가 공부했을 때랑 많이 변했겠지만, 이런 부분은 필수라고 생각해요. 자격증 공부를 미리미리 해두시면 좋지 않을까 싶어요."팀원들이 엘리를 한마디로 표현한다면?Jun 曰: 마이쿤 탄산가스 - "톡톡 튀는데.. 가끔은 빵 하고 터질까 봐 두려워요"(오늘도 말하는데 입 아프다니까, 엘리가 저한테 "입은 안 아프시잖아요"라고 그랬음)
조회수 1042

모르면 난리 나는 인스톨 이후 지표들

우리가 마케팅 임원이라고 생각해 보도록 하죠. 팀원들이 이번 캠페인의 성과를 보고하러 왔습니다. 팀원들에게 단 하나의 질문만 할 수 있다면 무엇을 물어 보시겠습니까? 저라면 이 글에서 소개할 다섯 가지 데이터 중 하나를 선택해 질문할 것입니다.앱 인스톨 이후(Post-Install)에 인게이지먼트로 인해 얼마나 긍적적인 성과가 나타나는지를 확인할 수 있는 다섯 가지 주요 지표를 소개합니다. 이 중에는 앱 서비스의 OMTM(One Metric That Matters)으로 관리해야 할 지표도 있을 것입니다. 1. N-day Retention특정 날짜까지의 리텐션을 의미합니다. 대부분의 분석 툴이 30 Day 리텐션까지 데이터를 제공하지만, 각 앱마다 유저에게 제공하는 서비스가 다르기 때문에 앱 고유의 N-day 리텐션을 정해놓고 관리해야 합니다.게임 앱은 주로 30D 외에도 1D, 7D 리텐션을 관리합니다. 1D 리텐션이 40%를 넘는다면 유저들의 반응이 상당히 좋은 것으로 생각해도 됩니다. 7D 리텐션은 보다 복합적입니다. 만약 7D 리텐션이 15% 이하라면, 게임의 난이도가 높다거나 흥미를 유발하는 요소가 부족한 것일 수 있습니다. 출석이나 레벨 업 보상을 늘려서 게임을 보다 쉽고 재미있게 진행할 수 있도록 하는 것도 좋습니다.이커머스는 앱의 성격이 오픈마켓인지 아닌지에 따라서 리텐션이 크게 달라집니다. 오픈마켓 성격이 강하다면 3D 이후의 리텐션이 크게 떨어집니다. 그렇지 않고 컨텐츠나 스타일링 제안이 성공적으로 추가된 서비스라면 30D 리텐션이 15~20%에 이르기도 합니다. 2. DAU앱의 방문수(세션)가 앱을 사용하는 ‘횟수’라면, DAU(Daily Active Users)는 하루에 앱을 사용하는 ‘사람 수’를 말합니다. 큰 의미가 없어 보이는 ‘싱거운 지표’라고 생각할 수도 있지만 결코 무시해서는 안되는 지표가 DAU입니다.예를 들어 하루에 앱이 100번 실행되었다고 가정해 보겠습니다. 1명이 100번 실행한 것과, 100명이 각각 1번씩 실행한 것 중 어떤 경우가 조금 더 바람직할까요? 당연히 후자입니다. 비용을 지불하는 것은 ‘횟수’가 아니라 ‘사람’이기 때문이죠! 유저를 더 모으기 위해 마케팅을 하는 것도 결국 같은 이야기일 것입니다.또한 DAU는 다양한 파생 지표의 모수가 되기도 합니다. 유저 한명이 하루에 몇 번 앱을 실행하는지는 ‘DAU당 방문수(세션)’로, 몇 개의 페이지를 조회하는지는 ‘DAU당 페이지뷰’로 확인할 수 있습니다. 그리고 나중에 소개할 ARPDAU도 그 중 하나입니다. 3. MAUMAU(Monthly Active Users)는 한 달 동안 앱을 사용한 순수(Unique) 유저수를 말합니다. 장기적인 관점에서 앱의 외형 성장과 밀접한 관계가 있는 지표입니다. 실제로 앱의 금전적인 가치를 평가할 때 MAU, 그리고 MAU당 매출액 등의 수치를 중요하게 참고하니까요.만약 4월 MAU가 1만명이라고 가정해 보겠습니다. 이 1만명은 한달 동안 우리 앱에 비용을 지불할 가능성이 있는 유저 풀이 됩니다. 특히 월 단위 구독(Subscription) 중심의 컨텐츠 서비스나 게임이라면, MAU 증가가 곧바로 매출 증가로 이어지므로 가장 중요하게 관리하게 되는 지표입니다. 이런 경우라면 UA(User Acquisition) 캠페인의 궁극적인 목적도 MAU 성장이 될 것입니다.MAU를 높이기 위해서 대규모 UA를 준비하고 있다면 UA 이전의 Stickiness(고착성) 수치를 UA 이후의 수치와 비교할 필요가 있습니다. Stickiness는 사용자들이 앱을 얼마만큼 자주 사용하는지를 확인할 수 있는 효율적인 지표입니다. [DAU / MAU * 100] 공식으로 계산하면 됩니다. 평균 이상의 게임이라면 20%를 상회하는 Stickiness가 나온다고 알려져 있습니다. UA를 통해 MAU가 늘었으나 Stickiness가 눈에 띄게 줄었다면 완벽하게 성공적인 캠페인은 아니었다고 판단할 수 있을 것입니다. 4. ARPDAU드디어 매출액 관련 지표가 나왔습니다. ARPDAU는 Average Revenue Per Daily Active Users의 약자로, 1일간 앱에서 발생한 매출액을 1일간 앱을 실행한 유저 숫자로 나눈 금액을 의미합니다. 공식으로 표현하면 [1일간 매출액 / DAU] 입니다. 오늘 앱에서 발생한 매출이 1백만원이고 DAU가 50명이라면, 공식에 따라 ARPDAU는 2만원이 됩니다.특히 게임 앱은 신규 유저가 많이 유입되면 ARPDAU가 요동치는 경향이 있는데, 유저의 유입이 크게 늘면 ARPDAU가 일시적으로 하락하는 경우가 많습니다. 그래서 유입된 유저 숫자에 따른 적정 ARPDAU 하락폭을 발견하는 것이 중요합니다. 유저의 유입에 비해 ARPDAU가 지나치게 하락하는 시점을 파악하고, 그 이후 ARPDAU가 정상 수준으로 회복되는지를 추적 관찰해야 하기 때문입니다.유저들의 대다수는 30일 안에 앱을 떠날 것이고, 경쟁 서비스가 있기 때문에 우리가 UA로 확보할 수 있는 유저의 숫자도 한계가 있습니다. 따라서 신규 유입이 정체된 상황에서 ARPDAU가 하락하고 있다면 위험한 신호로 받아들여야 합니다. 5. LTVLifetime Value를 줄여서 LTV로 부릅니다. 과거에는 주로 CLV(Customer Lifetime Value)라고 사용 했었지요. 경영학에서 말하는 ‘고객생애가치’가 바로 LTV입니다. 고객이 자신의 전 생애에 걸쳐 우리 서비스에 지출한(또는 지출할 것으로 예상되는) 총 비용이라고 할 수 있습니다. 그래서 LTV를 통해 우리는 매우 단순하고 당연한 결론에 이르게 됩니다. ‘비용보다 LTV가 크면 성공이다’라는 결론 말입니다.자연스럽게 앱 마케팅의 LTV가 궁금해 지는군요. LTV 계산을 위해서는 ‘고객의 생애’가 언제 끝나는지를 알아야 하는데, 유저가 앱을 완전히 떠나버린 – 다시 말해 앱으로 돌아올 가능성이 전혀 없는 – 시점을 알 수는 없다는 것이 문제가 됩니다. 그래서 보다 ‘현실적인’ 방법으로 LTV를 계산해야만 하지요.첫번째 ‘현실적인’ 방법은 평균사용일수와 ARPDAU를 곱해서 Actual LTV를 계산한 다음 적절한 예측모델을 적용해 미래의 LTV를 추정하는 것입니다. 특정 코호트의 30일 리텐션이 아래 표와 같다고 가정해 보겠습니다.코호트1D2D3D4D5D6D7D...30DA 매체 유입 유저50%40%30%20%20%15%10%...5%이 코호트의 1개월 평균 사용일수는 아래 수식으로 계산할 수 있습니다. 0 Day의 리텐션을 1(100%)로 놓고 다음날부터의 리텐션을 모두 더해 나가면 됩니다.(1 + 0.5 + 0.4 + 0.3 + 0.2 + 0.2 + 0.15 + 0.1 + … + 0.5) = 평균 사용일수이렇게 구한 30일 평균 사용일수에 30일 평균 ARPDAU를 곱하면 30일간의 Actual LTV가 됩니다. 30일 평균 ARPDAU는 아래 공식으로 계산하면 됩니다.30일간의 ARPDAU 합계 / 30 = 30일 평균 ARPDAU이렇게 계산된 Actual LTV를 적절한 예측모델에 입력해서 미래 특정 일자의 LTV를 예측해볼 수 있습니다. 앱의 특성에 따라 다양한 예측모델을 적용할 수 있겠지만, 중요한 것은 일반적인 리텐션 그래프는 아래 그림과 같이 감소하는 지수함수(Exponential Function, y = ax^b)의 형태를 가지므로 거듭제곱을 활용한 예측모델이 결정계수(R제곱)가 높을 것입니다.두번째 ‘현실적인’ 방법은 누적 ARPU에 예측모델을 적용하는 것입니다. 예측모델의 신뢰도를 높이려면 특정 코호트의 ARPU를 적어도 30일 이상 측정한 데이터가 있는 것이 좋습니다. 아래 그림은 누적 ARPU 차트의 일반적인 형태입니다. 여러분 앱의 누적 ARPU 역시 매우 높은 확률로 아래 그림과 유사한 곡선을 그리게 될 것입니다. 전형적인 로그함수(Logarithm) 그래프죠. 그래서 누적 ARPU에 적합한 예측모델은 로그함수를 기반으로 하는 것이 좋습니다.Source: https://gameanalytics.com/기본적으로는 예측된 LTV와 마케팅 예산을 비교해 봄으로써 비용의 적정성을 파악할 수 있습니다. 그리고 유저의 인구통계정보(성별, 연령, 회원등급 등)별 코호트를 비교해보면 타겟 고객이 누구인지도 알 수 있겠지요. 경우에 따라서는 지역별 코호트를 비교함으로써 잠재시장을 파악할 수도 있을 것입니다.

기업문화 엿볼 때, 더팀스

로그인

/