#PostHog #UT #UT시뮬레이션 #kpt회고 #서비스정책서
컨디션: 다리가 아프다.. 내일 병원 가니까 스트레칭 열심히 하고 휴식하자
✅ 서비스 정책서 튜터님 피드백 반영하여 수정
✅ 2차 결과물 QA
✅ UT 시뮬레이션
✅ KPT 회고
오늘은 팀의 1차 KPT 회고를 정리하고, UT 시뮬레이션과 QA 준비를 진행했다.
팀이 같은 정보를 보고, 같은 기준으로 판단하고, 같은 방식으로 실행할 수 있는가?
오늘은 프로젝트를 진행하면서 반복적으로 발생했던 협업 문제를 정리하고, 이를 다음 업무에서 실제로 적용할 수 있는 운영 규칙으로 바꾸는 데 집중했다.
팀원들과 프로젝트 진행 과정에서 잘된 점, 아쉬웠던 점, 다음에 시도할 점을 정리했다.
우리 팀의 Keep에서는 공통적으로 다음과 같은 내용이 나왔다.
업무를 티켓 단위로 나누어 관리한 점
정·부 담당 체계를 활용한 점
회의 내용을 문서화한 점
일정과 진행 상황을 지속적으로 확인한 점
각자의 강점에 따라 역할을 나누어 진행한 점
나 역시 일정 관리, 회의 준비와 회의록 작성, 튜터님과의 커뮤니케이션, 산출물 확인을 맡아 프로젝트가 일정 안에서 진행될 수 있도록 했다.
반면 Problem에서는 여러 팀원이 비슷한 문제를 이야기했다.
이전에 논의한 내용이 다시 논의됨
결정 사항이 여러 문서와 채널에 흩어짐
회의 목적과 아젠다가 명확하지 않음
팀원마다 결정 내용을 다르게 이해하는 경우가 생김
산출물 리뷰와 최종 검수 기준이 명확하지 않음
제출 직전에 수정 사항이 몰림
처음에는 각각 다른 문제처럼 보였다.
하지만 내용을 묶어보니 공통 원인은 크게 세 가지였다.
문제가 다시 발생하지 않으려면 다음 업무부터 무엇을 바꿀지 구체적으로 정해야 했다.
반복 논의 문제
기존에는 회의록을 작성했지만, 최종 결정 사항과 결정 이유를 빠르게 찾기 어려운 경우가 있었다.
그래서 다음 방식을 Try로 정리했다.
회의 목적이 불명확했던 문제
회의 전에 아젠다가 충분히 준비되지 않으면 회의 중에 무엇을 결정해야 하는지부터 다시 맞춰야 했다.
이 과정에서 논의 범위가 넓어지고, 이미 결정한 내용까지 다시 이야기하게 되는 경우가 있었다.
이를 개선하기 위해 회의 전 다음 내용을 작성하기로 했다.
그리고 회의가 끝나기 전에는 결정 사항과 담당자, 마감 일정을 함께 확인하기로 했다.
오늘 정리하면서 회의가 길어지는 원인은 단순히 말이 많아서가 아니라는 점을 알게 됐다.
회의의 목적과 완료 조건이 없으면, 어디까지 이야기해야 끝나는지 판단하기 어렵다.
산출물 검수 문제
이번 프로젝트에서는 각자 맡은 산출물을 작성했지만, 작성 이후 상호 리뷰가 충분히 이루어지지 않았다.
그 결과 제출 직전에 다음과 같은 부분을 다시 확인해야 했다.
또한 산출물마다 작성자뿐 아니라 리뷰 담당자와 최종 검수 기준을 정해야 한다고 정리했다.
UT 시뮬레이션을 진행해야 했던 이유
오늘 UT 시뮬레이션을 진행하는 과정에서는 예상하지 못한 의견 차이도 있었다.
한 팀원은 이미 UT 대본이 준비되어 있으니 각자 알아서 읽고 연습하면 되고, 팀 전체가 함께 시뮬레이션할 필요는 없지 않겠냐는 의견을 주었다.
처음에는 조금 당황스러웠다.
현재 UT 문서는 처음 보는 사람이 바로 전체 진행 흐름을 파악할 수 있을 만큼 충분히 정돈된 상태는 아니었다. 진행 대본, 과업, 관찰지, 질문지가 각각 존재했지만 실제 진행 순서에 따라 한 번 연결해보지 않으면 파악하기 어려운 부분이 있었다.
특히 이번 UT는 일반적인 1인 테스트보다 진행 구조가 복잡했다.
쪽지 발신자와 수신자가 구분됨
두 명의 참여자가 한 조로 진행됨
한 명의 행동이 다른 참여자의 다음 과업으로 연결됨
진행자, 관찰자, 기록자가 동시에 역할을 수행함
인터뷰 대본과 관찰지가 같은 흐름으로 움직여야 함
이 구조에서는 대본을 혼자 읽는 것만으로 충분하지 않다고 판단했다.
내가 시뮬레이션을 통해 확인하고 싶었던 것은 다음과 같았다.
발신자와 수신자의 과업 순서가 자연스러운가
진행자가 어떤 시점에 누구에게 질문해야 하는가
인터뷰 질문과 관찰지의 항목이 서로 맞는가
관찰자가 무엇을 기록해야 하는지 명확한가
진행자마다 안내 방식이 지나치게 달라지지 않는가
실제 UT 시간 안에 모든 순서를 완료할 수 있는가
참가자가 막혔을 때 진행자가 어느 정도까지 개입해야 하는가
시뮬레이션은 그냥 대본을 읽는 연습이 아니고, UT 문서, 역할, 과업, 질문, 관찰 기준이 실제 진행 과정에서 하나의 흐름으로 작동하는지 확인하는 과정이다.
이전과 달라진 나의 대응
이전의 나라면 팀원이 굳이 시뮬레이션을 할 필요가 없다고 이야기했을 때, 갈등을 만들고 싶지 않아 그냥 알겠다고 했을 가능성이 높다.
하지만 오늘은 바로 내 의견을 포기하지 않았다.
그렇다고 상대방의 의견을 강하게 반박하거나 내 방식대로 밀어붙이지도 않았다. 조심스럽게 다른 팀원들에게도 시뮬레이션이 필요한지 의견을 물었다.
그 결과 해당 팀원을 제외한 나머지 팀원들은 모두 시뮬레이션이 필요하다고 이야기했고, 팀 전체가 함께 진행하기로 결정했다.
이 과정에서 잘했다고 생각하는 점은 내 의견을 끝까지 관철한 것이 아니다.
내가 왜 시뮬레이션이 필요하다고 생각하는지 설명했고
다른 팀원들의 의견을 확인했고
개인 간 대립이 아니라 팀의 합의로 결정했고
합의한 내용을 실제 실행으로 연결했다
오늘 경험을 통해 협업에서 중요한 것은 모든 의견에 바로 맞추는 것이 아니라는 점을 배웠다.
제품과 프로젝트 품질에 영향을 주는 일이라면, 필요한 이유를 설명하고 팀이 판단할 수 있도록 의견을 꺼내야 한다.
✅ posthog 셋팅
✅ UT 시뮬레이션 2차
✅ 오픈을 위한 데이터 정리
처음엔 "액션을 만들면 그 이름으로 이벤트가 찍히는 줄" 알았는데 아니었다.
액션 6개를 만들었다 (친구홈 작성, 마이홈 작성, 공유, 상태메시지 수정, 탭 클릭 등).
액션을 만들면서 selector가 불안정하면 경고가 뜨는 걸 여러 번 겪었다.
.font-bold, .relative > .text-center 같은 범용 클래스는 여러 요소를 잡아서 위험 ("Matches 2 elements").
nth-of-type(1) 같은 위치 기반 selector는 순서가 바뀌면 깨진다 → PostHog이 "Fragile selector" 경고를 띄움.
textarea/input은 오토캡처가 못 잡는다 (텍스트가 없어서). → 검색해도 안 나옴.
💡해결책
selector만 두지 말고 Text 조건을 같이 걸어서 정확도를 높였다. 하지만 근본적으로는:
오토캡처 액션보다 개발자가 코드로 심은 커스텀 이벤트가 훨씬 안정적이다. 오토캡처는 버튼 텍스트가 바뀌면 매칭이 끊긴다.
(→ 실제로 다음 날 CTA 버튼 텍스트를 바꾸면서 이 문제가 그대로 벌어졌다.)
개발자가 심은 커스텀 이벤트를 발견했는데, 이름과 실제 동작이 달랐다.
card_write_start: 이름은 '작성 시작'인데, 실제로는 친구 홈 진입 시점에 찍혔다.
card_write_complete: 이름은 'complete'인데, URL이 아직 /u/...인 걸 보고 '보내기 버튼 클릭 시점'임을 확인. (진짜 발송 완료는 /send/complete Pageview)
URL의 변화를 보고 이벤트가 언제 찍히는지 역추적한 게 핵심이었다. 이름만 믿었으면 퍼널 해석이 통째로 틀어졌을 것이다.
card_write_start가 친구 홈과 마이홈 양쪽 다 찍히는 문제를 발견했다. 이대로 퍼널을 만들면 두 경로가 섞여서 KPI가 오염된다.
속성을 직접 뜯어보니:
→ URL로 거르는 것보다 entry_path 속성으로 필터하는 게 정확하고 안정적이었다. 개발자가 의도적으로 심은 값이라 URL 구조가 바뀌어도 안 깨진다.
교훈: 오토캡처 이벤트는 이름이 뭉뚱그려져 있어서, 같은 이벤트라도 어느 화면/경로인지 구분하려면 속성으로 필터해야 한다.
친구 홈 발송 전환 퍼널 (핵심 KPI: 친구 홈 진입 대비 발송률)
배운 것:
퍼널은 "한 번이라도 거치면 통과", 순서만 맞으면 됨. 사용자가 입력창을 여러 번 클릭하고 왔다갔다 해도 1명으로 깔끔하게 집계된다.
"얼마나 헤맸나"는 퍼널이 아니라 세션 리플레이로 본다. 역할이 다르다.
PostHog에서 DB 데이터를 직접 조회하려고 Supabase를 연동했다.
Session pooler를 써야 한다 (IPv4). Direct connection은 IPv6라 PostHog이 연결 못 함.
읽기 전용(readonly) role로 연결하는 게 안전 (PostHog이 실수로 DB 못 건드리게).
연동 후 PostHog SQL에서 supabase.public__profiles 같은 테이블을 쿼리할 수 있음.
주의: 동기화는 실시간이 아니라 주기적이다. 그래서 DB와 PostHog 숫자가 시차로 안 맞을 수 있다.