MVP를 빠르고 효과적으로 개발하기: 우리는 협업해요

민정(Joanne)
당근 테크 블로그
10 min readAug 22, 2024

안녕하세요. 저는 당근 LocalMaps UGC 팀에서 서버 개발을 하고 있는 조앤(Joanne)이라고 해요. 저희 팀은 얼마 전까지 지역사업실 UGC(User Generated Contents) TF로서 MVP 스펙 개발에 몰입해 있었는데요. 이 글에서는 저희가 TF일 당시 어떻게 빠르고 효과적으로 기능을 구현할 수 있었는지 그 방법을 소개해보려고 해요. 단기간에 새로운 기능을 도입하기 위해 어떤 협업 방식을 갖춰야 할지 궁금하신 분들에게 도움이 되었으면 해요.

UGC TF의 배경과 목표

먼저 UGC(User Generated Contents)는 후기와 같이 사용자가 자발적으로 생산하는 콘텐츠를 의미해요. 저희는 사용자들이 더 많은 UGC를 생산하도록 동기부여하는 데에 집중하기 위해 UGC TF를 결성했어요. 즉, 사용자에게 UGC를 생산해야 하는 이유를 만들어 줌으로써 UGC 생산을 효과적으로 늘리려고 했죠.

개발자의 경우 클라이언트 2명, 서버 4명으로 구성된 저희 TF는 최근 MVP 개발을 완료했어요. 최소 비용으로 사용자 반응을 빠르게 확인하여 가설을 검증하려 했기에 일정을 타이트하게 가져갔죠. 저희 팀은 약 한 달간의 일정 내로 여러 기능을 구현해야 했는데요. 그 중 대표적인 것은 피드백 루프였어요.

다시 말해, 생산해 낸 콘텐츠에 피드백을 제공함으로써 사용자에게 자기 효능감을 주는 것을 중심으로 MVP 스펙을 구성했죠. 대표적인 요구사항으로는 내가 참여한 장소와 기여 내역을 확인할 수 있는 프로필 페이지, 내가 생성한 콘텐츠의 조회수가 일정 수준 도달 시 이를 전달해 주는 성과 알림 등이 있어요.

단기간에 여러 기능을 구현해야 하는 요구사항이 주어졌을 때, 어떻게 일하는 것이 가장 좋은 방법이라고 생각하시나요? 혼자서 하나를 담당해 빠르게 구현하는 것이 가장 좋은 방법일까요?

혼자 하면 빨리 가고, 함께 하면 멀리 간다.

잘 알려져 있는 유명한 문구죠. 저도 이 문구를 오랫동안 믿어 왔어요. 하지만 이번 UGC TF에서 협업하는 과정에서 이 문장이 틀렸다는 걸 깨달았죠. 함께 하는 것은 멀리 갈 뿐만 아니라 사실 결국 더 빨리 갈 수 있는 방법이었어요. 멀리 가면서도 빠르게 갈 수 있었던, 저희 TF의 협업 방식을 본격적으로 이야기해 볼게요.

1. Tech Spec을 작성하고 함께 리뷰해요.

기능 구현을 위해 바로 코드부터 짜시나요? 그 이전에 테크 스펙을 작성하고 팀원들과 공유하는 과정이 필요해요. 테크 스펙은 기술적인 세부 사항을 기록한 문서예요. 테크 스펙은 요약 및 배경, 목표와 목표가 아닌 것, 계획, 임팩트 측정, 고려사항 및 마일스톤, 질의응답 등의 주요 요소로 구성돼 있어요.

이해를 돕고자 UGC TF의 요구사항 중 하나인 성과 알림을 예시로 들어볼게요. UGC TF는 유저에게 긍정적인 피드백 루프를 제공하기 위해 성과 알림을 발송하기로 했어요. 아래는 성과 알림 구현을 위한 요구사항 중 일부예요.

  • 특정 유저가 작성한 후기의 조회수가 N회에 도달하면 알림을 발송해요.
  • 같은 횟수로 이미 발송된 적이 있다면 중복으로 발송하지 않아요.
  • 유효한 후기가 아닐 경우 발송하지 않아요.

이를 바탕으로 Tech Spec의 핵심이 되는 부분인 목표와 계획 파트를 작성한다면, 다음과 같이 작성할 수 있어요.

목표와 목표가 아닌 것

목표:

  • 사용자가 작성한 후기의 조회수가 특정 기준(N회)에 도달했을 때 성과 알림을 발송해요.
  • 중복 알림 발송을 방지하여 사용자 경험을 해치지 않도록 해요.
  • 유효한 후기에 대해서만 알림을 발송하여 알림의 품질을 유지해요.

목표가 아닌 것:

  • 모든 종류의 사용자 활동에 대한 알림을 구현하는 것은 이번 프로젝트의 목표가 아니에요.
  • 사용자가 알림 기준(N회)을 직접 설정하는 기능은 이번 단계에서 구현하지 않아요.

계획

후기 조회수 집계 시스템 구축:

  • 기존 후기 조회 로직에 카운터 증가 기능을 추가해요.
  • 분산 환경에서의 동시성 문제를 고려하여 원자적 연산을 사용해요.

알림 발송 조건 확인 로직 구현:

  • 조회수가 N회에 도달했는지 확인하는 로직을 구현해요.
  • 중복 발송 방지를 위해 이전 알림 발송 이력을 확인해요.
  • 후기의 유효성을 검증하는 로직을 추가해요.

알림 발송 시스템 구축:

  • 자체 알림 발송 시스템을 활용해 알림을 발송해요.
  • 알림 템플릿을 제작하고, 동적으로 내용을 변경할 수 있도록 구현해요.

테스트 및 모니터링 시스템 구축:

  • 단위 테스트와 통합 테스트를 작성하여 시스템의 안정성을 확보해요.
  • 알림 발송 현황을 모니터링할 수 있는 대시보드를 구축해요.

Trade-Off:

  • FCM vs 자체 알림 시스템: 주어진 기간 내에 FCM을 구현하기에는 러닝커브가 높기 때문에, 모니터링 및 구현이 간단한 자체 알림 시스템을 선택해요.
  • 배치 처리 vs 실시간 처리: 사용자 경험을 위해 실시간 처리 방식도 고려했지만, 시스템 부하를 줄이기 위해 조회수 집계와 알림 발송을 배치 처리하는 방안을 선택해요

목표와 계획은 프로젝트의 방향을 명확히 하고, 구체적인 실행 단계를 제시해 줘요. 또한 Trade-Off 부분에서는 의사 결정 과정과 그 이유를 명시하여 팀원들과의 논의 기반을 마련했어요. 이 과정에서 MVP 대비 오버 엔지니어링이 되는 경우는 없는지, 주어진 상황에서 더 적은 리소스를 쓸 수 있는 방법은 없을지 고민할 수 있어요.

테크 스펙을 혼자서만 작성하고 끝나는 것이 아니라 서버 엔지니어가 모두 모여 리뷰하는 시간을 가져요. 리뷰 시간에는 주로 선택지에 대한 트레이드 오프나 발생 가능한 문제 위주로 피드백하죠. 또한 작성자가 생각하는 것과는 다른 개선책이 떠오른다면 함께 제안하고 의견을 적극적으로 나눠요.

테크 스펙을 작성하고 함께 리뷰하는 과정에서 경험한 장점들을 아래와 같이 정리할 수 있어요.

  • 문서를 작성하며 전체적인 설계를 정리하고 다듬을 수 있어 오히려 구현하는 데에 시간이 덜 들었어요. 직관적이고 빠르게 개발할 수 있어요.
  • 고민되는 부분에 대해 나의 생각뿐만 아니라 동료의 의견을 들을 수 있어요. 이러한 리뷰를 통해 더 나은 방향으로 갈 수 있도록 유연함을 가져요.
  • 문서를 Source Of Truth로 바라보고 개발 직군이 아닌 직군과도 일관되게 소통할 수 있어요. 문서는 주기적으로 업데이트하고 문서의 업데이트를 통해 다시 한번 전체적인 구현에 대해 점검할 수 있어요.
  • 예상치 못한 문제들을 미리 방지하고, 함께하는 구성원들과 프로젝트의 상태 및 방향성에 대해 얼라인할 수 있어요.

2️. 맥락을 긴밀히 공유해요.

앞서 예시로 든 성과알림 외에도 프로필 페이지, 내가 참여한 내역 등 여러 가지 요구사항이 동시에 존재했어요. 담당하는 요구사항에만 집중하다 보면 큰 맥락을 놓치기 쉽고, 전체적인 유저 경험을 고려하기 어려울 수 있어요. 저희 TF는 이런 한계를 보완하고자 페어를 구성했어요. 페어는 맥락 공유를 위해 더욱 긴밀하게 협업하는 관계예요.

저(Joanne)는 제니(Jenny)와 페어였는데요, 페어로서 더 잘 일할 수 있는 방법을 함께 많이 고민했어요. 저희는 맥락 공유가 가장 중요하다고 결론 내렸는데요. 이를 위해 가장 처음 한 것은 둘을 한꺼번에 멘션할 수 있도록 Slack에서 JJ라는 유닛을 결성했어요. 멘션 시에도 함께 멘션되도록 해서 사소한 맥락도 공유할 수 있도록 했죠.

맥락 공유가 가져다주는 긍정적인 효과로는 다음과 같은 것들을 경험할 수 있었어요.

  • PR 리뷰 과정에서 둘 다 전체 맥락을 이해하고 있어 효과적인 피드백을 주고받을 수 있었고 리뷰에 소요되는 시간이 줄었어요.
  • 특정 작업자에 대한 의존도가 줄어들어 프로젝트의 유연성이 향상됐어요.
  • 상황에 따라 유동적으로 업무를 나누고 조정할 수 있었어요. 이는 작업 효율성을 높이고 예상치 못한 상황에도 신속히 대응할 수 있었어요.

결과적으로 페어를 통한 맥락 공유는 단순히 정보를 나누는 것을 넘어 팀의 생산성과 코드 품질, 그리고 프로젝트의 전반적인 건강성을 향상시키는 핵심 요소로 작용했어요.

3. 함께 고민하여 변경에 유연하게 대응해요.

프로젝트를 진행하면서 변경에 유연하게 대응하고 팀원들과 함께 고민하는 문화를 만들어갔어요. 이를 위해 여러 가지 방법과 도구를 활용했어요.

Schema-First 접근 방식을 활용해요.

OpenAPI Spec을 사용함으로써 클라이언트와 서버 개발팀이 API 인터페이스에 대해 함께 논의하고 하나의 소스를 바라보며 병렬 작업을 할 수 있었어요. API 응답에 변경이 필요할 때도 서버에서 일방적으로 수정하는 것이 아니라, OpenAPI Spec을 수정하여 더욱 유연하게 대응할 수 있었어요.

OpenAPI의 사용과 관련해서 더 자세한 내용이 궁금하다면, 커뮤니티실의 하이디가 작성해 주신 아래 글을 참고해 보시면 좋을 것 같아요.

🔗 커뮤니티실 API Design-First 접근방식 정착기

테크 스펙을 기반으로 요구사항 변경에 유연하게 대응해요.

요구사항이 변경될 때는 앞서 작성한 테크 스펙을 기반으로 기존에 설계했던 것과 수정되어야 할 것을 명확히 비교할 수 있어요. 수정된 부분을 엔지니어들과 함께 재검토하면서 직관적이고 유연한 수정이 가능해졌죠.

위에서 이야기했던 성과 알림을 계속 예시로 들어볼게요. 중복 발송 로직이 고도화되기로 수정되었다고 가정해 봅시다. 기존에 작성한 테크 스펙을 기반으로 ASIS와 TOBE를 작성하여 변경된 부분을 명확히 하거나 변경된 부분에 대해서만 리뷰를 받는 등 유연한 변경이 가능해져요.

회고와 개선

프로젝트가 끝날 때엔 회고 시간을 가져 개발 과정에서 놓쳤던 부분들을 다시 짚어보고, 더 나은 방향으로 나아갈 수 있도록 수정하는 cool-down 시간을 가졌어요. 이를 통해 지속적인 개선과 성장이 가능했죠.

회고 시 주의해야 할 점이 하나 있어요. 그건 바로 프로젝트를 모두 마친 후 회고를 진행하면 작업 중에 고민했던 부분을 놓치기 쉽다는 점이에요. 저희 TF에서는 그런 상황을 방지하기 위해 미리 회고 티켓을 따로 만들어뒀어요. 추후에 함께 고민해 볼 만한 것들을 미리 등록해두고, 회고 때 함께 논의했죠.

회고 티켓은 다음과 같은 내용을 담을 수 있어요. ‘패키지 구조를 어떻게 나누어야 할 것인가’에 대한 고민을 예로 들어 볼게요. A라는 Service를 a라는 패키지를 만든 뒤 그 하위에 위치시킬지, 혹은 service라는 상위 패키지 하위에 모두 몰아넣을지 고민해 봤다고 가정해봐요. 그럼 그 당시 고민했던 여러 대안들과 최종적인 선택을 내린 이유 등을 티켓에 함께 작성해두는 거죠.

이러한 방식으로 팀원들과 함께 변화에 대응하고 고민하며, 프로젝트의 품질을 높이고 팀워크를 강화할 수 있었어요.

우리는 왜 협업할까?

혼자 하면 빨리 가고, 함께 하면 멀리 간다.

이 문구를 다시 한번 생각해 봐요.

만약 모든 일을 혼자 했다면, 모든 맥락을 혼자만 알고 있었을 거예요. 이는 특정 사람에 대한 의존도를 높이고 문제를 빠르게 개선하기 어려운 상황을 만들어요. 저희는 먼저 문서를 작성하고, 이에 대해 피드백을 받고, 함께 고민하고, 유연하게 대응할 수 있는 방법들을 사용했어요. 이는 복잡도가 높은 상황에서 더욱 안정적이고 빠르게 갈 수 있도록 큰 도움을 주었어요.

우리가 협업하는 이유는 단순히 일을 나눠서 하기 위함이 아니에요. 지속 가능한 방식으로 팀을 전진시키기 위해 협업하죠. 혼자 일할 때의 장점도 분명히 있지만, 협업을 통해 우리는 서로의 지식과 경험을 공유하고 다양한 관점에서 문제를 바라볼 수 있어요. 이는 개인의 성장뿐만 아니라 팀 전체의 성장으로도 이어지죠. 팀이 더 큰 도전을 성취해 내고 더 큰 목표를 향해 나아갈 수 있도록 해요.

여러분은 어떻게 협업하시나요? 더 멋진 방법이 있다면 함께 공유해 주세요.

이만 글 줄일게요. 읽어주셔서 감사해요.

#programming #working

--

--