Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ Fix ] 온보딩 완료 후 이탈한 선배 대비 SENIOR_PENDING 추가 반영 #357

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from

Conversation

se0jinYoon
Copy link
Collaborator

@se0jinYoon se0jinYoon commented Nov 13, 2024

#️⃣ Related Issue

Closes #350

✅ Done Task

  • 온보딩 완료 후 프로필 등록 하지 않은 선배 SENIOR_PENDING role 추가
  • 선배 온보딩에서 프로필 등록으로 넘어갈 때 location.state로 전달하던 seniorId, nickname 로직 변경
  • 선배 프로필 뷰 (Preview 컴포넌트) 로직 수정 (seniorId 조건부 전달)
  • 온보딩 + 프로필 등록 완료 선배 -> SENIOR role으로 변경

☀️ PR Point

  • 온보딩 QA를 하다가 [선배]의 경우 온보딩 완료 후 프로필 등록을 완료하지 않고 이탈한 유저가 재접속했을 경우, 바로 약속 리스트 페이지로 이동하는 문제를 발견했습니다.
  • 따라서 온보딩 후 이탈한 선배의 경우를 핸들링 할 필요를 느껴 서버에 요청하여 SENIOR_PENDING이라는 role을 추가하였습니다.
  • role에 대한 분기가 하나 더 늘어나서, role을 사용하는 여기저기 부분적으로 수정된 부분이 많은데, 굵직하게 변경된 부분만 PR에 작성해둘게요!

[선배] 온보딩 완료 / 프로필 등록 안 함 -> SENIOR_PENDING
[선배] 온보딩 완료 / 프로필 등록 완 -> SENIOR

전체적인 플로우

  1. 온보딩 완료 / 프로필 등록 안 한 선배가 페이지를 이탈 한 후 선약에 재접속하면 프로필 등록 페이지로 라우팅 시켜주어야 합니다.
  2. 선배 프로필 등록 플로우에는 선배가 온보딩에서 작성한 닉네임이 필요합니다. (뷰에서 사용되기 때문)
  3. 기존에는 온보딩 -> 프로필 등록 플로우에서 �사용자가 이탈하지 않고 이동한다고 가정하고 구현되었기 때문에 온보딩 -> 프로필 등록으로 이동할 때 location.state를 이용해서 닉네임을 사용했어요.
  4. 하지만 이탈을 한 후 재접을 하는 경우라면 Location.state를 받아올 수 없겠죠?
  5. 따라서 선배 온보딩의 마지막 단계인 문자인증 api가 성공할 경우, outletContext에 저장된 닉네임 데이터를 localStorage에 저장하는 로직을 추가했어요.
// Step번호입력.tsx

  // SENIOR_PENDING - 프로필 등록 이동
  // JUNIOR - 온보딩 다음 단계로 이동
  const handleClickLink = () => {
    if (pathname.includes('senior')) {
      joinMutate.mutate(contextData, {
        onSuccess: () => {
          // ✅✅✅✅ 요 부분!!! ✅✅✅✅✅
          setSeniorNickname(contextData.nickname);
          navigate('/seniorProfile');
        },
        onError: (err) => {
          console.log(err);
        },
      });
    } else navigate('/juniorOnboarding/4');
  };
  1. 선배 프로필 등록 페이지에서는 로컬스토리지에 저장된 Nickname을 가져와서 사용하도록 했어요.
  2. 프로필 등록이 완료되면 localStorage에 있는 nickname이 제거되고, localStorage의 role이 SENIOR_PENDING에서 SENIOR로 변경되도록 했어요.
// seniorProfile > index.tsx > Preview

// 선배 프로필 등록
  const mutation = useSeniorProfileHook();
  const handleRegisterClick = () => {
    mutation.mutate(
      {
        catchphrase,
        career,
        award,
        story,
        preferredTimeList: deleteProfileField(preferredTimeList),
      },
      {
        onSuccess: () => {
          setStep && setStep((prev) => prev + 1);
          // 온보딩 + 프로필 등록 완료
         // ✅✅✅✅ 여기!!!!! ✅✅✅✅
          // 선배 role SENIOR_PENDING -> SENIOR로 변경
          // 선배 닉네임 local storage에서 제거
          setRole('SENIOR');
          localStorage.removeItem('seniorNickname');
        },
      }
    );
  };

To. 진이) Preview 컴포넌트 로직 변경

  1. Preview 컴포넌트가 프로필 등록 직전뷰에서도 쓰이고 [후배] '둘러보기' 탭에서 선배 카드를 클릭할 경우 프로필을 불러올 때도 쓰이는 중이에요.
  2. 그러다보니 [선배] 프로필 등록 직전뷰에서도 필요없는 api([후배] '둘러보기' 탭에서 선배 프로필을 보여주기 위한 api들)을 쏘고있더라구요.
  3. 그래서 [선배] 프로필 등록 직전뷰에 필요없는 seniorId를 넘기고 있길래 해당 부분 제거해주었어요.
  4. 또한, [후배] '둘러보기' 탭에서 선배 프로필을 보여주기 위한 경우일 때만 해당 api를 쏘기 위해 관련 쿼리들에 isJuniorRequest 를 추가해두었어요
// index.tsx
  // 선배 카드 정보 조회 (온보딩 정보)
  const {
    data: cardData,
    error: cardDataError,
    isLoading: isCardDataLoading,
  } = useSeniorCardQuery(seniorId, variant === 'secondary');
  // 선배 상세 프로필 조회 (프로필 정보)
  const {
    data: profileData,
    error: profileDataError,
    isLoading: isProfileDataLoading,
  } = useGetSeniorProfileQuery(seniorId, variant === 'secondary');
  // 선배 선호 시간대 조회
  const {
    data: secondaryPreferredTimeList,
    isError: secondTimeListError,
    isLoading: isSecondTimeListLoading,
  } = useSeniorTimeQuery(+seniorId, variant === 'secondary');

이해가 안 되시는 부분은 댓 남겨주시면 자세히 설명드릴게요 !!!!

💎 추가적인 부분

  • 현재 해결해야하는 부분이 하나 남아있는데요

  • [선배] 온보딩 완료 / 프로필 등록 미완 후 이탈하고 나서 나~중에 재접했을 때 토큰이 만료된 사람을 핸들링해야하는데요.

  • 저희가 토큰이 만료된 걸 판별하는 경우는 authClient 를 사용해서 api를 쐈을 때 서버에서 40076 에러를 던져주었을 때입니다.

  • 하지만, 프로필 등록이 미완된 선배가 재접했을 경우, 프로필 등록 페이지로 라우팅되게 되고, AuthClient를 사용해서 api를 쏘게되는 시점은 선배가 열심히 프로필 등록은 완료 한 후에 '프로필 등록하기' 버튼을 눌렀을 경우에요 (혹은 다른 선배들 예시 프로필을 눌러봤을 경우)

  • 따라서 . .만료된 토큰인지 확인하는 api가 필요하여 서버에 요청해두었고, 해당 부분은 다음주 월요일에 따로 이슈파서 작업하겠습니다~

📸 Screenshot

  • 문자인증 완료하고 회원가입시 (온보딩 완료 / 프로필 등록X) SENIOR_PENDING과 닉네임을 로컬에 저장
1.mp4
  • 온보딩만 완료하고 이탈 후 재접시 프로필 등록 페이지로 이동
2024-11-14.12.58.03.mov
  • 프로필 등록 완료하면 SENIOR로 변경, Nickname 제거
2024-11-13.11.45.46.mov

@se0jinYoon se0jinYoon added 🛠 Fix 기존의 버그 수정 서진 labels Nov 13, 2024
@se0jinYoon se0jinYoon self-assigned this Nov 13, 2024
Copy link
Member

@j-nary j-nary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 울엄마 짱짱! 여러 이슈 발견하고 고쳐주어서 감사함니당
리뷰 몇개만 확인해주시와요 >_<

Comment on lines 28 to 30
useEffect(() => {
if (!seniorId || !nickname) navigate('/');
}, [seniorId, nickname, navigate]);
if (!nickname) navigate('/');
}, [nickname]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 제 PR에도 이 부분 적용했었는데 제 PR 먼저 머지하고 컨플릭잡을 때 언니 파일 우선으로 해서 머지하면 좋을 것 같앙요!!

@@ -43,7 +44,7 @@ const SeniorProfilePage = () => {
case 5:
return <TimeSelect profile={profile} setProfile={setProfile} setStep={setStep} />;
case 6:
return <PreView setStep={setStep} profile={profile} seniorId={seniorId} />;
return <PreView setStep={setStep} profile={profile} seniorId="" />;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

온보딩을 거치고 나면 온보딩에서 입력했던 정보들이 서버에 저장이 되잖아요?
그 정보들은 seniorId를 통해 얻어올 수 있구요!
해당 정보들은 SeniorCard에서 쓰이게 됩니다.
그래서 SeniorCard를 PreView에서 불러오려면 seniorId를 넘겨주어야합니다!
선배 프로필 등록 에서의 SeniorCard 는 온보딩 과정 거친 후에 로컬 스토리지로 넘겨받은 seniorId가 필요할 것 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 오케이 확인이요!

Copy link
Collaborator

@lydiacho lydiacho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굵직한 버그 잡느라 고생하셨습니다!!

제가 드리고 싶은 의견 정리해보자면,

1️⃣ SENIOR_PENDING role이 과연 필요할까?

카톡에서 언급드렸던 부분인데, 만료확인API가 추가될 예정이라면 SENIOR_PENDING role이 불필요하지 않나 싶은 생각이 들었어요.
SENIOR_PENDING이 추가됨에 따라 role 데이터의 역할이 조금 흐려진다는 점이 살짝 아쉬웠고,

무엇보다도 요번 PR에서 모든 SENIOR 값을 SENIOR_PEDING으로 바꿔주셨는데요!
사실 서버에서 응답으로 보내준 role을 저장하는 시점은 온보딩이 완료되어 join API를 쏘는 시점이고, 그 전까지 state로 들고다니는 role은 유저가 최초에 회원가입 버튼을 누르면서 후배로 시작하기를 눌렀냐 선배로 시작하기를 눌렸냐에 따라 달라지는 데이터예요. 근데 이 친구들이 SENIOR_PENDING으로 네이밍되기에는 의미가 살짝 안맞지 않나 라는 생각이 들었습니다!
(SENIOR_PENDING 이라는 값은, 온보딩이 완료되었지만 프로필등록은 완료되지 않았다는 의미로 서버에서 내려주는 데이터니까 온보딩 중에 사용되기엔 부적합하다는 생각)

현재 플로우가

온보딩 후 로컬에 SENIOR_PENDING이라고 저장 -> 이탈 후 재접속하여 자동로그인 시 프로필 등록으로 이동 -> 만료확인 API를 쏴서 토큰 확인, 만료 시 앞단으로 튕기기

이렇게 되는건데
만료확인 API를 사용하면 아래와 같이 불필요한 리다이렉트를 간소화할 수 있지 않을까요?

자동로그인 시 무조건 최초로 만료확인 API 호출 -> 응답으로 isPending true가 내려온 유저는 프로필등록을 마치지 않았다는 의미로, 프로필 등록 페이지로 이동 / 만료된 토큰일 경우 바로 튕기기

이렇게 하면 굳이 만료된 사람이 프로필등록 페이지를 불필요하게 거칠 필요도 없어지고,
또 SENIOR_PENDING이라는 찝찝한 role도 구분해줄 필요가 사라져요

여기서 포인트는 자동로그인될 때 만료토큰API를 무조건 쏴주는건데요, 어차피 프로필등록으로 갈 사람이든, 정상 자동로그인되어 메인페이지로 이동할 사람이든 만료토큰 체크는 필요하니까, 프로필등록 페이지에 한해서 이를 실행하지말고 그냥 HomePage 컴포넌트에서 바로 처리해줘도 될 것 같아요


2️⃣ 닉네임도 localStorage로 관리하지 않고 API응답으로 대체해도 되지 않을까?

현재 온보딩 -> 프로필등록 으로 넘어갈 때 state로 넘겨주던 닉네임이,
중간에 이탈하고 프로필등록으로 진입할 경우엔 state로 전달받지 못하는 문제 때문에 localStorage에 저장했다가 삭제하는 방식으로 해결해주셨는데요!

이부분도 만료확인 API로 충분히 대체할 수 있을 것 같아요
프로필등록 최초 진입 시 어차피 토큰 담아서 API 쏘는거니까 서버가 응답으로 닉네임 보내주면 그걸 넣어주면 쫌 더 깔끔하지 않을까유?


결론!

만료확인API를 확용해서 SENIOR_PENDING 관리도 간소화, 닉네임 관리도 간소화할 수 있을 것 같다!

API를 활용할 수 있는 상황에서 로컬스토리지를 활용해서 처리하는 것은 최대한 지양하는게 좋을 것 같아욥

그런데 2번은 어렵지 않을 것 같아서 반영되면 좋을 것 같구,
1번 같은 경우엔 두분 다 바쁜 상황에서 리소스 들여서 role 추가하신 부분이니까 만약 바쁘시다면 패스하거나 후순위로 미뤄도 될 것 같습니당 !

// 선배 role SENIOR_PENDING -> SENIOR로 변경
// 선배 닉네임 local storage에서 제거
setRole('SENIOR');
localStorage.removeItem('seniorNickname');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3) localStorage removeItem 함수도 utils storage에 함께 분리시켜주면 좋을 것 같아요/!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🛠 Fix 기존의 버그 수정 size/m 서진
Projects
Status: 🚨 Queued
Development

Successfully merging this pull request may close these issues.

[ Fix ] 선배 온보딩 중 이탈한 유저 방지 SENIOR_ROLE 추가
3 participants