Skip to content

Feature: 온보딩 페이지 퍼널 패턴 적용, api 연동(로그인 처리 완료)#14

Merged
Monixc merged 31 commits into
developfrom
feature/api-onboarding-home
Aug 9, 2025
Merged

Feature: 온보딩 페이지 퍼널 패턴 적용, api 연동(로그인 처리 완료)#14
Monixc merged 31 commits into
developfrom
feature/api-onboarding-home

Conversation

@Monixc

@Monixc Monixc commented Aug 8, 2025

Copy link
Copy Markdown
Contributor

📌 PR 종류 (PR Type)

  • 🐛 버그 수정 (Bugfix)
  • ✨ 기능 추가 (Feature)
  • 🎨 UI 스타일 변경 (Style) - CSS, 클래스명, 레이아웃 등 UI 변경
  • ♻️ 코드 리팩토링 (Refactor) - 기능 변화 없이 코드 구조 개선
  • 📦 패키지/빌드 관련 변경 (Build) - 설정 파일 수정, 의존성 추가 등
  • 🧱 테스트 코드 추가/수정 (Test)
  • 📝 문서 수정 (Docs)
  • 🚧 WIP (작업 중 PR)
  • 기타 (Other):

📝 요약 (Summary)

ex) 게시글 리스트 UI 개선 및 반응형 대응

온보딩 페이지 퍼널 적용, api 연동


🔍 상세 내용 (Describe your changes)

ex)

  • 게시글 카드형 UI로 변경
  • 화면 너비에 따라 그리드 컬럼 개수 조절
  • 사용하지 않는 컴포넌트 삭제

  1. 온보딩 퍼널 패턴 구현
  • toss/@use-funnel 적용
  • 뒤로가기 기능 구현
  1. 위치 정보 수집 기능
  • geolocation api를 활용한 사용자 위치 수집
  • Nominatim Reverse Geocoding으로 좌표 -> 주소 변환
  • 한국어 주소 포맷팅(도로명 주소 기반: 시, 구, 로/길 순서로 표시)
  • 위치 정보 수집용 컴포넌트 구현
  1. api 연동 및 데이터 관리
  • Recct query를 활용한 서버 상태 관리
  • 기능별 api 모듈 분리
  • 타입 안정성을 위한 타입스크립트 인터페이스 정의
  1. 데이터 흐름
  • github oatuh 로그인 -> sessionId 획득
  • 상태코드가 200 단일로, 로그인/회원가입 구분은 response 데이터 구조로 파악

📸 스크린샷 (필수)

image

✅ 확인 사항 (CheckList)

  • 브라우저에서 정상 동작 확인
  • 기존 기능에 영향 없음
  • 반응형 UI 대응 확인
  • 코드 컨벤션에 맞게 작성됨 (eslint, prettier 등)
  • 테스트 코드 추가/수정 또는 테스트 통과 확인

💬 기타 참고사항 (Optional)

ex) 이 부분 로직이 좀 복잡해서 한번 더 확인 부탁드립니다 🙏

  • 로딩 상태에 대한 처리가 미흡합니다...skeleton or 스피너 or 점프하는 점 세개로 loading, error 컴포넌트 처리할 예정

Monixc added 23 commits August 7, 2025 21:06
@github-actions github-actions Bot added ⚙️chore 기타 잡무 ✨feature 기능 개발 🎨style 스타일 변경 🐞bugfix 버그 수정 🔄refactor 코드 리팩토링 labels Aug 8, 2025

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Summary of Changes

Hello @Monixc, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

I've focused on building out the core onboarding experience for new users, integrating it deeply with our backend API. This involved creating a guided, multi-step process for profile creation, enhancing our data fetching strategy with React Query, and introducing location-based features. The changes also include significant refactoring of our API service layer and type definitions to ensure a robust and scalable foundation for future development.

Highlights

  • New Onboarding Funnel: I've implemented a comprehensive multi-step onboarding flow using the @use-funnel/react-router-dom library, allowing users to smoothly navigate through profile setup, technical interests, and additional information steps with proper state management and back navigation.
  • API Integration and Query Hooks Refactor: I've refactored our API integration by creating a dedicated lib/api directory with separate modules for authentication, developers, posts, and tags. This improves code organization and maintainability. All data fetching now leverages @tanstack/react-query with new custom hooks (useAuth, useLocationQuery, useTags) for efficient state management and caching.
  • Location Information Collection: A new feature has been added to collect user location information during onboarding, including reverse geocoding to display a human-readable address. This is crucial for connecting users with nearby developers.
  • Dependency Updates and Type Standardization: I've updated the project's dependency management, adding @use-funnel/react-router-dom and react-hot-toast for enhanced UI/UX. Additionally, type definitions across the application have been standardized and organized into .types.ts files for improved clarity and consistency.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

이번 PR은 온보딩 퍼널 도입, API 연동 및 관련 타입 정의, 다수의 컴포넌트 리팩토링 등 많은 변경 사항을 포함하고 있습니다. 전반적으로 React Query를 활용한 데이터 페칭 로직 개선과 API 모듈화 등 코드 구조가 잘 개선되었습니다. 몇 가지 개선점을 제안합니다. useLocationQuery 훅의 타임아웃 설정이 사용자 경험에 영향을 줄 수 있어 조정을 제안하며, 온보딩 마지막 단계에서 데이터 불일치 및 예외 처리 관련 피드백을 추가했습니다. 또한, 프로젝트의 안정성을 위해 추가된 기능들에 대한 테스트 코드를 작성하는 것을 고려해보시는 것이 좋겠습니다.[^1]

interestIds: data.interests,
...(data.email && { email: data.email }),
...(data.instagram && { instagram: data.instagram }),
...(data.linkedin && { linkedIn: data.linkedin }),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

SignUpRequest 타입에서는 linkedIn으로 정의된 속성이 OnboardingData 타입과 다른 컴포넌트에서는 linkedin으로 사용되고 있어 불일치가 발생합니다. 이로 인해 혼란과 잠재적인 버그가 발생할 수 있습니다. 현재 코드에서는 linkedIn으로 변환해주고 있지만, 프로젝트 전반에 걸쳐 속성명을 linkedIn으로 통일하여 일관성을 유지하는 것이 유지보수에 더 좋습니다. OnboardingData 타입과 OnboardingStep3 컴포넌트의 상태 변수명도 linkedIn으로 변경하는 것을 고려해보세요.

Comment on lines +33 to +34
timeout: 300000,
maximumAge: 300000,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

getCurrentPositiontimeoutmaximumAge 값이 300000ms(5분)으로 설정되어 있습니다. 이 값은 너무 길어서 사용자 경험에 좋지 않은 영향을 줄 수 있습니다. 타임아웃이 너무 길면 사용자가 오래 기다려야 할 수 있고, maximumAge가 길면 오래된 위치 정보가 사용될 수 있습니다. 항상 새로운 위치 정보를 가져오도록 timeout을 30초 정도로 줄이고 maximumAge를 0으로 설정하는 것을 권장합니다.

Suggested change
timeout: 300000,
maximumAge: 300000,
timeout: 30000,
maximumAge: 0,

Comment on lines +50 to +71
if (
!data.nickname ||
!data.age ||
!data.experience ||
!data.bio ||
!data.location ||
!data.position ||
!data.techStack ||
!data.interests
) {
console.error("온보딩 데이터가 불완전합니다:", {
nickname: data.nickname,
age: data.age,
experience: data.experience,
bio: data.bio,
location: data.location,
position: data.position,
techStack: data.techStack,
interests: data.interests,
});
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

온보딩 데이터가 불완전할 경우, 콘솔에만 에러를 기록하고 사용자에게는 아무런 피드백을 주지 않아 사용자가 페이지에 갇히게 될 수 있습니다. 사용자에게 알림을 표시하고 온보딩 첫 단계로 돌려보내는 등 명확한 피드백을 제공하는 것이 좋습니다.

      if (
        !data.nickname ||
        !data.age ||
        !data.experience ||
        !data.bio ||
        !data.location ||
        !data.position ||
        !data.techStack ||
        !data.interests
      ) {
        console.error("온보딩 데이터가 불완전합니다:", {
          nickname: data.nickname,
          age: data.age,
          experience: data.experience,
          bio: data.bio,
          location: data.location,
          position: data.position,
          techStack: data.techStack,
          interests: data.interests,
        });
        alert("입력 정보가 완전하지 않습니다. 온보딩을 다시 시작합니다.");
        navigate("/onboarding", { replace: true });
        return;
      }

@Monixc Monixc changed the title Feature/api onboarding home Feature: 온보딩 페이지 퍼널 패턴 적용, api 연동(로그인 처리 완료) Aug 8, 2025
@Monixc Monixc requested review from ksy90101 and woo-dev-log August 8, 2025 03:41
@Monixc

Monixc commented Aug 8, 2025

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

온보딩 페이지에 퍼널 패턴을 적용하고, 전반적인 API 연동을 React Query를 사용하여 리팩토링한 점이 인상적입니다. 코드 구조가 모듈화되고 상태 관리가 개선되어 유지보수성이 크게 향상되었습니다. 몇 가지 개선점을 제안드렸으니 확인 부탁드립니다. 특히, 게시글 생성 시 위치 정보가 하드코딩된 부분과 온보딩 마지막 단계의 예외 처리 로직은 반드시 수정이 필요해 보입니다.

Comment thread src/lib/api/posts.ts
Comment on lines +52 to +56
location: {
lng: 127.0,
lat: 37.5,
},
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

게시글 생성 시 위치 정보가 서울 시청 좌표로 하드코딩되어 있습니다. 실제 사용자 위치 정보를 받아서 사용하도록 수정해야 합니다. createPost 함수의 인자로 위치 정보를 받을 수 있도록 시그니처를 변경하고, 호출하는 부분에서도 실제 위치 값을 전달해야 합니다.

Comment on lines +50 to +71
if (
!data.nickname ||
!data.age ||
!data.experience ||
!data.bio ||
!data.location ||
!data.position ||
!data.techStack ||
!data.interests
) {
console.error("온보딩 데이터가 불완전합니다:", {
nickname: data.nickname,
age: data.age,
experience: data.experience,
bio: data.bio,
location: data.location,
position: data.position,
techStack: data.techStack,
interests: data.interests,
});
return;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

온보딩 마지막 단계에서 회원가입 요청 시 필요한 데이터가 누락되었을 경우, 콘솔 에러만 출력하고 아무런 처리를 하지 않아 사용자가 아무런 피드백 없이 멈춘 화면에 있게 됩니다. 사용자에게 오류가 발생했음을 알리고, 로그인 페이지로 이동시키는 등의 예외 처리가 필요합니다.

      if (
        !data.nickname ||
        !data.age ||
        !data.experience ||
        !data.bio ||
        !data.location ||
        !data.position ||
        !data.techStack ||
        !data.interests
      ) {
        console.error("온보딩 데이터가 불완전합니다:", {
          nickname: data.nickname,
          age: data.age,
          experience: data.experience,
          bio: data.bio,
          location: data.location,
          position: data.position,
          techStack: data.techStack,
          interests: data.interests,
        });
        alert("온보딩 정보가 올바르지 않습니다. 다시 시도해주세요.");
        navigate("/login", { replace: true });
        return;
      }

Comment on lines +31 to 33
} else {
console.log(" 예상치 못한 응답:", result);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

로그인 처리 중 예상치 못한 API 응답을 받았을 때 console.log로 처리하고 있습니다. 이는 잠재적인 오류를 놓치게 할 수 있습니다. console.error를 사용하여 에러로 기록하고, 사용자에게 오류가 발생했음을 알리는 것이 더 안전한 방법입니다.

        console.error("예상치 못한 로그인 응답:", result);
        // 사용자에게 에러 토스트 메시지를 보여주는 로직 추가를 고려해보세요.
        navigate("/login", { replace: true });

Comment on lines +10 to +87
type ProfileSetup = {
nickname?: string;
age?: number;
experience?: number;
bio?: string;
location?: {
lng: number;
lat: number;
};
};

type TechInterests = {
nickname: string;
age: number;
experience: number;
bio: string;
location: {
lng: number;
lat: number;
};
position?: number;
techStack?: number[];
interests?: number[];
};

type AdditionalInfo = {
nickname: string;
age: number;
experience: number;
bio: string;
location: {
lng: number;
lat: number;
};
position: number;
techStack: number[];
interests: number[];
linkedin?: string;
email?: string;
instagram?: string;
blog?: string;
};

type Complete = {
nickname: string;
age: number;
experience: number;
bio: string;
location: {
lng: number;
lat: number;
};
position: number;
techStack: number[];
interests: number[];
linkedin?: string;
email?: string;
instagram?: string;
blog?: string;
};

export interface OnboardingData {
nickname?: string;
age?: number;
experience?: number;
bio?: string;
location?: {
lng: number;
lat: number;
};
position?: number;
techStack?: number[];
interests?: number[];
linkedin?: string;
email?: string;
instagram?: string;
blog?: string;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

온보딩 각 단계의 컨텍스트 타입(ProfileSetup, TechInterests 등)이 다소 느슨하게 정의되어 있습니다. 예를 들어, TechInterests 단계에서는 ProfileSetup에서 입력받은 값들이 반드시 존재해야 하지만, 타입상으로는 여전히 optional로 되어 있습니다. 타입스크립트의 Required 유틸리티 타입과 타입 교차(&)를 사용하면 각 단계에서 사용 가능한 컨텍스트를 더 명확하고 안전하게 타이핑할 수 있습니다. 이는 '최대한 타입은 좁혀서 사용한다'는 프로젝트 스타일 가이드에도 부합합니다.1

예시:

type ProfileSetupData = { /* ... */ };
type TechInterestsData = { /* ... */ };

type TechInterestsContext = Required<ProfileSetupData> & TechInterestsData;

Style Guide References

Footnotes

  1. 타입스크립트 타입을 최대한 좁혀서 사용하면 코드의 안정성과 가독성을 높일 수 있습니다. (link)

@Monixc Monixc merged commit c0ccd8a into develop Aug 9, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞bugfix 버그 수정 ⚙️chore 기타 잡무 ✨feature 기능 개발 🔄refactor 코드 리팩토링 🎨style 스타일 변경

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant