이번에도 프로필 잠금 기능을 추가하는 에픽에 단독 구현을 맡았다.
간단한 작업이라 1d안에 끝이났고 큰 이슈도 없었지만, 그 와중에 또 배운 것 투성이였어서 우당탕탕 시리즈로 추가해보았다.
이전에 구현되어있던 비정규 카드의 unlock-profile 기능과 이번 에픽의 기능이 같은 플로우로 기획되어 비교적 쉽게 작업을 마칠 수 있었던 것 같다. 이건 잘 차려놓은 밥상에 숟가락만 얹은 전형적인 케이스. 숟가락도 가지런히 안놓고 삐뚫게 놔서 다른 누가 보고 눈살을 찌푸릴까봐 걱정되긴 하지만.. 이번에는 비교적 에픽 작업 시간이 널널했어서 작업을 하면서도 더 나은 방식은 없을지 고민하고 기존 코드도 더 나은 방향으로(내 기준이지만…) 수정하기도 했다.
항상 작업 시간이 널널할 순 없기때문에, 작업하면서 내 눈에 거슬리는 부분이 있다면 마감 기한을 지킬 수 있는 선 안에서 조금이라도 더 나은 코드를 작성하려고 노력하자.
이번에도 매튜가 먼저 이런 내용들 정리해서 공유해달라고 하셨는데,
사실 작업 자체가 간단했었고 영향범위가 좁아서 이런 시나리오에 대해 작성할 생각도 안했던 것 같다. (자만 금지 제발…)
막상 적고보니 미리 안챙겼으면 테스트를 꼼꼼히 진행 못했을 것 같고, 테스트 과정에서 놓치는 부분이 무조건 생겼을 것 같다.
아래와 같이 작성해두고나니 마음도 편안하고 든든하면서 배포 후에도 내가 무엇을 먼저 파악하면 될지 정리가 돼서 너무 후련했다.
롤백하는 상황도 안벌어지면 좋겠지만.. 필요한 상황이 닥친다면 당황해서 허둥거릴수도 있는데 미리 작성해두니 틀리면 바로 참고할 수 있는 오답지를 손에 쥔 느낌.
[롤백 시나리오]
argocd 롤백(오토싱크 해제) > revert-1.13.66 브랜치 생성하여 base/enfpy/receive-up-lock 브랜치 revert > 해당 브랜치 main 머지하여 재배포 > argocd 오토싱크 on
[테스트 시나리오]
- 기존 여성 유저
- 기존 받은 업 리스트 잠겨있지 않음 확인
- 기존 남성 유저
- 기존 받은 업 리스트 잠겨있지 않음 확인
- 신규 남성 유저(계정 생성)
- 받은 업 리스트 잠겨있음 확인
- 기존 받은 업 리스트 잠겨있지 않음 확인(세팅 가능하다면...)
- 잠겨있는 업 아이템 프로필 열기
- 프로필 열림 상태 확인
- 친구신청 후 신청 상태 확인
[테스트 전 준비]
- 신규 남성 유저 계정 생성
- 신규 남성 유저 계정을 기존 여성유저 두명에게 비정규추천 카드로 추가
- 잠금되기 전 생성된 업 추가
- 잠금 후 생성된 업 추가
위와 같이 작성해두고 보니, 배포 전 미리 준비해야할 테스트를 위한 to-do 리스트도 떠올랐다.
잠금 기능 배포 전
1. 기존 여성 A, B에게 신규남성을 비정규 카드로 추천
2. 기존 여성 A만 신규 남성에게 업 전송
잠금 기능 배포
1. 기존 여성 B도 신규 남성에게 업 전송
예상 결과
- 기존 여성 A가 보낸 업은 잠금되어있지 않음
- 기존 여성 B가 보낸 업은 잠금되어있음
위 내용대로 작성해서 이 시나리오대로 배포 전 미리 환경 세팅이 가능할지 함께 에픽을 진행한 백엔드 개발자분께 문의를 드렸다.
위 테스트 환경을 배포 전 미리 구축해두지 않았더라면, 일반 테스트로는 하기 힘든 케이스에 대해서 제대로 확인하지 못하고 넘어갈 수도 있었다. 엣지케이스까지 미리 대응해서 확인하고나니 이번 배포에서는 또 어떤 예상치못한 이슈가 발생할지에 대한 불안감을 많이 덜어낼 수 있었다.
아무리 간단한 에픽이라도, 반드시 배포 시나리오 & 테스트 시나리오 & 롤백 시나리오 세가지는 필수로 작성하자!!!
기존 로직에 추가적인 수정이 이루어지면서, useCallback에서 호출하는 새로운 함수를 생성하였고, 이 새로운 함수는 useCallback이 아닌 일반 이벤트 함수로 생성하니 해당 함수는 계속해서 re-render 될 것이라는 린트 경고를 확인했다.
그래서 나는 단순히, 린트 경고를 없애기 위해 새로 생성한 함수도 useCallback으로 감싸버렸는데, 제리가 PR봐주시면서 이거 왜 useCallback으로 감쌌는지 물어보셨고, 린트 경고를 없애려고요.. 라고 대답하는 내 자신이 너무 구렸다. 사실 그 때는 귀찮아서 그냥 useCallback으로 감싸고 넘어간건 아니고 린트 경고를 없애야한다는 생각에 단순히 그렇게 했는데, 이 린트 경고가 발생한 근본적인 원인은 무엇인지를 파고들었어야 했다는걸 뒤늦게 깨달았다.
항상 회고 액션 아이템으로 나오는 것이지만 수행하기에도 가장 어려운 것 중 하나가 내가 무엇을 목적으로 이 코드를 작성하고 있는지 생각하면서 작업할 것.. 이걸 항상 생각하면서 개발을 하기란 정말 어려운 것 같다.
그치만 어렵다고 계속 포기하고 구린 코드를 작성하고 구린 이유를 입으로 뱉어낼 것이냐???? 절대 안된다😱
잠시라도 막히는 부분이 생긴다면, 내가 이 코드를 작성하고 있는 목적을 항상 생각하자. 왜 해야 하는지? 무엇을 위한 것인지? 임팩트가 무엇인지?
이번 에픽의 주 내용은 신규 유저를 대상으로 상대방의 프로필을 조회하는 기능이 유료로 전환되어 프로필이 잠금되도록 변경하는 작업이었고, 이를 위해 상대 유저의 A
라는 프라퍼티가 true일 경우 프로필이 잠금해제된 상태, false일 경우 프로필이 잠금된 상태라는 조건이 추가되었다.
나는 이것을 A
라는 프라퍼티가 true일때만 잠금이 해제된 상태이고, undefined이거나 false일 경우에는 잠금된 상태이므로 유저가 해당 기능을 유료로 돈을 지불해야하는 것이기 때문에 “유료를 무료로 제공하는 것은 안된다”라는 판단을 내려 default값을 false로 설정하였다.
isFree = !!A
이런 식으로 A
라는 프라퍼티가 true일 때에만 프로필 조회를 무료로 할 수 있도록 조건을 추가하였는데,
보통은 기능 배포 시 서버가 먼저 배포를 하고 이어서 프론트 배포를 진행했는데 오늘은 서버쪽에 추가적인 작업이 필요해 프론트에서 먼저 나가도 되는 상황이었다. 그러나 이럴 경우, A
라는 프라퍼티가 추가된 서버의 코드가 배포되기 전에 프론트의 코드가 먼저 서비스에 적용되면 A
라는 프라퍼티를 모든 유저가 갖고 있지 않기 때문에, isFree = !!A
라는 조건식에 의하여 프로필 조회를 무료로 이용 가능한 유저들에게까지 모든 상대방의 프로필이 유료로 전환되는 일이 벌어진다.
사실 이 조건을 만들 때에 내가 고려했던 부분은 “유료 서비스를 무료로 제공하면 안된다”는 나름의 판단을 가지고 했던 것인데, 더 많은 상황에 대한 고려가 필요했던 것 같다.
이후에 이 값의 조건을 isFree = A !== false
라는 조건으로 변경하여 A
라는 프라퍼티의 값이 명확하게 false일 경우에만 유료, false 외에 true이든 undefined이든 null값이든 무슨 값이 오든 그 때에는 무료가 오도록 코드를 수정했다.
그리고 얻은 인사이트
새로운 property가 추가되어 서비스상의 변화가 생긴다면?
→ 여기서 이해가 안되는 부분은…?
화면 View에는 “프로필 잠금”버튼으로 노출되어야 하는 B 아이템이 애초에 그려져 있지 않았음
새로운 RatingUp을 받고나서 새로고침을 했고, 새로고침해서 패칭해온 데이터는 isUnlockProfile
값이 처음부터 true였을 것이고, View에도 새로 그려진 아이템이었는데 왜 “프로필 잠금”텍스트가 노출되지 않았을까?
isUnlockProfile
데이터를 저장하는 변수가 const로 선언되어있어서 state/props의 값이 변하지 않아서 발생한 이슈인가? 하고 생각을 했는데 사실 props로 넘어온 데이터의 property 단 하나의 value만 바껴도 리액트에서는 해당 데이터에 새로운 주소값을 할당한다고 하니 이건 원인이 아닌 것 같다. 🤔
이 두가지에 대해서 테스트 & 서치해볼 것!