Skip to content

refactor: Gathering 타입 정의 및 지역 상수 추가 #51

Merged
RookieAND merged 3 commits intofeature/ui-bug-fixesfrom
refactor/gathering-types-and-constants
Jan 30, 2026
Merged

refactor: Gathering 타입 정의 및 지역 상수 추가 #51
RookieAND merged 3 commits intofeature/ui-bug-fixesfrom
refactor/gathering-types-and-constants

Conversation

@RookieAND
Copy link
Copy Markdown
Collaborator

🎯 PR 제목

Gathering 타입 정의 및 지역 상수 추가

📑 작업 상세 내역

  1. OpinionForm 타입 필드 required 변경
  • distanceRange, dislikedFoods, preferredMenus 필드를 optional에서 required로 변경
  • 폼 제출 시 필수 입력 검증을 타입 레벨에서 보장
  1. MeetingContext 타입 deprecated 표시
  • @deprecated JSDoc 태그 추가
  • 향후 API 응답 타입으로 대체 예정임을 명시
  1. 지역 옵션 상수 정의
  • src/constants/gathering/opinion/region.ts 생성
  • 서울 지하철역 기반 지역 옵션 배열 추가
  • DistanceStep에서 사용할 region 값 중앙 관리

🙏 리뷰 요청 사항

  • OpinionForm 타입의 required 변경이 기존 코드에 breaking change를 발생시키지 않는지 확인 부탁드립니다.
  • 지역 옵션 상수의 값이 실제 서비스에서 사용하는 지역명과 일치하는지 검토 부탁드립니다.

RookieAND and others added 2 commits January 30, 2026 03:05
Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>
Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>
@RookieAND RookieAND self-assigned this Jan 29, 2026
@github-actions github-actions bot added the 🔨 Refactor 코드 리팩토링 및 구조 개선 label Jan 29, 2026
@github-actions github-actions bot requested a review from youngminss January 29, 2026 18:09
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @RookieAND, 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!

이 PR은 모임 관련 데이터 모델의 견고성을 높이고, 향후 API 변경에 대비하며, 지역 선택 기능을 위한 기반 데이터를 마련합니다. 사용자 입력 폼의 필수 필드를 명확히 하여 데이터 무결성을 강화하고, 레거시 타입의 사용을 줄여 코드의 유지보수성을 개선합니다.

Highlights

  • OpinionForm 타입 필드 필수화: distanceRange, dislikedFoods, preferredMenus 필드가 선택 사항에서 필수로 변경되어 폼 제출 시 유효성 검사가 타입 수준에서 보장됩니다.
  • MeetingContext 타입 Deprecated 처리: MeetingContext 인터페이스에 @deprecated JSDoc 태그가 추가되어 향후 API 응답 타입으로 대체될 예정임을 명시합니다.
  • 지역 옵션 상수 추가: src/constants/gathering/opinion/region.ts 파일이 새로 추가되어 서울 지하철역 기반의 지역 옵션(홍대입구역, 강남역)을 상수로 관리합니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

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.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

이번 PR은 OpinionForm 타입의 필드를 필수로 변경하고, MeetingContext 타입을 deprecated 처리하며, 지역 옵션 상수를 추가하는 리팩터링을 포함합니다. 코드 리뷰 결과, 타입 정의와 관련된 두 가지 개선점을 발견했습니다. src/constants/gathering/opinion/region.ts 파일에서 as const 사용 시 발생하는 타입 오류를 수정하고 스타일 가이드에 따라 interface 대신 type을 사용하도록 제안했습니다. 또한 src/types/gathering/index.ts 파일에서도 OpinionFormtype으로 변경하여 코드 일관성을 높이도록 제안했습니다.

Comment on lines +1 to +17
import type { Region } from "#/types/gathering";

export interface RegionOption {
id: NonNullable<Region>;
label: string;
}

export const REGION_OPTIONS: RegionOption[] = [
{
id: "HONGDAE",
label: "홍대입구역",
},
{
id: "GANGNAM",
label: "강남역",
},
] as const;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

현재 코드에는 as const로 생성된 readonly 타입을 변경 가능한 배열 타입(RegionOption[])에 할당하려고 하여 타입 에러가 발생합니다. 또한, 스타일 가이드(규칙 4. TypeScript Rules, 196행, 224행)에서는 interface보다 type 사용을 권장하며, 상수 객체에 as const를 사용하도록 하고 있습니다.

이 상수는 타입 추론을 활용하여 더 간결하고 타입-안전하게 정의할 수 있습니다. RegionOption 인터페이스를 제거하고 as const를 통해 TypeScript가 타입을 직접 추론하도록 하는 것을 제안합니다. 이렇게 하면 불필요한 타입 정의와 import 구문을 제거하고, 스타일 가이드에 더 잘 부합하는 코드가 됩니다.

export const REGION_OPTIONS = [
	{
		id: "HONGDAE",
		label: "홍대입구역",
	},
	{
		id: "GANGNAM",
		label: "강남역",
	},
] as const;
References
  1. 스타일 가이드에서는 Props 정의에 interface보다 type을 선호한다고 명시되어 있습니다. 비록 Props가 아니더라도 일관성을 위해 type을 사용하는 것이 좋습니다. (link)
  2. 스타일 가이드에서는 상수 객체에 as const를 사용하여 타입 안정성을 높일 것을 권장합니다. 타입 추론을 활용하면 더 간결한 코드를 작성할 수 있습니다. (link)

Comment on lines 25 to 33
export interface OpinionForm {
distanceRange?: DistanceRange;
distanceRange: DistanceRange;
dislikedFoods: FoodCategory[];
preferredMenus: {
first?: FoodCategory;
second?: FoodCategory;
third?: FoodCategory;
first: FoodCategory;
second: FoodCategory;
third: FoodCategory;
};
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

스타일 가이드(규칙 4. TypeScript Rules, 196행)에서는 interface보다 type 사용을 권장하고 있습니다. OpinionFormtype으로 변경하여 프로젝트 전반의 코드 스타일 일관성을 유지하는 것을 제안합니다.

Suggested change
export interface OpinionForm {
distanceRange?: DistanceRange;
distanceRange: DistanceRange;
dislikedFoods: FoodCategory[];
preferredMenus: {
first?: FoodCategory;
second?: FoodCategory;
third?: FoodCategory;
first: FoodCategory;
second: FoodCategory;
third: FoodCategory;
};
}
export type OpinionForm = {
distanceRange: DistanceRange;
dislikedFoods: FoodCategory[];
preferredMenus: {
first: FoodCategory;
second: FoodCategory;
third: FoodCategory;
};
};
References
  1. 스타일 가이드에서는 Props 정의에 interface보다 type을 선호한다고 명시되어 있습니다. 일관성을 위해 다른 타입 정의에도 이 규칙을 적용하는 것이 좋습니다. (link)

@RookieAND RookieAND added the ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 label Jan 29, 2026
@@ -0,0 +1,17 @@
import type { Region } from "#/types/gathering";

export interface RegionOption {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

추후 enum 상수로 치환할 예정이지만, 우선 작업의 단계적 접근을 위해 임시 조치

* @deprecated This interface will be removed in the next PR.
* Use GetGatheringResponse from #/apis/gathering instead.
*/
export interface MeetingContext {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Mock API 구현을 위해 임시로 정의했던 Interface 에 대해서 Deprecated 라벨 부착

Copy link
Copy Markdown
Member

@youngminss youngminss left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

이 부분은 현재 운영에 merge 할 때 conflict 날수 있음 !

* feat: gathering queryKey/queryOption에 capacity 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result API queryKey, queryOption 생성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant API queryKey, queryOption 생성

- participantKeys factory 추가
- participantOptions factory 추가 (create mutation)
- participant/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result queryOption에 select 추가

- response.data 자동 추출하도록 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: OpinionForm 을 중복으로 Export 하던 문제 수정

* fix: accessKey 를 앞 순위로 두어 무효화 전략 용이하게 구조 수정

* fix: mutationOptions 를 사용하여 옵션을 생성하도록 구조 개선

* fix: queryOptions 를 생성하는 팩토리 함수에서는 별도 옵션을 넣지 않도록 수정

* feat: 의견 수렴 페이지에 쓰일 Query Hooks 생성 (#53)

* feat: gathering domain hooks 추가

- useGetGathering: 모임 조회 hook
- useGetGatheringCapacity: 모임 참여자 현황 조회 hook
- Domain별로 hooks 구조화 (폴더별 분리 제거)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant domain hooks 추가

- useCreateParticipant: 모임 참여 mutation hook
- participant를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result domain hooks 추가

- useGetRecommendResult: 추천 결과 조회 hook
- recommend-result를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: hooks index 파일 업데이트

- gathering, participant, recommend-result domain별 export
- Domain 기반 hooks 구조 완성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useGetGatheringCapacity에 10초 refetch 추가

- refetchInterval: 1000 * 10 설정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useQuery Hook 기반의 함수 내 select 옵션 일괄 추가하여 데이터 정제

* feat: 의견 수렴 페이지 전체 API 연동 및 서버 Prefetch 적용 (#54)

* refactor: IntroStep scheduledDate prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep API 기반 region prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStepFooter onSubmit prop 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: CompleteView 텍스트 인라인 처리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: SubmissionBottomSheet props명 변경 (maxCount, currentCount)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 createParticipant 제출 로직 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지 API 연동 및 타입 수정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: queryOption에 select 추가하여 response.data 자동 추출

- gathering detail, capacity에 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지에 서버 프리페치 적용

- page.tsx를 서버 컴포넌트로 변경
- OpinionView.tsx로 클라이언트 로직 분리
- HydrationBoundary로 gathering 데이터 prefetch
- 무한 렌더링 문제 해결

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: useCreateParticipant Hook 을 Import 하는 경로를 올바르게 수정'

* feat: PendingView, CompleteView에 HydrationBoundary 및 API 연동 추가

- pending/page.tsx, complete/page.tsx를 서버 컴포넌트로 변경
- PendingView.tsx, CompleteView.tsx 클라이언트 컴포넌트 분리
- useGetGatheringCapacity hook으로 실시간 참여자 현황 조회
- HydrationBoundary로 capacity 데이터 prefetch
- 하드코딩된 maxCount, currentCount 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: ResultView에 HydrationBoundary 및 API 연동 추가

- result/page.tsx를 서버 컴포넌트로 변경
- ResultView.tsx 클라이언트 컴포넌트 분리
- useGetRecommendResult, useGetGatheringCapacity hook으로 데이터 조회
- HydrationBoundary로 capacity, recommend-result 데이터 prefetch
- MOCK_RECOMMENDATION_RESULT 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 식당 페이지 이동 과정에서 Cursor Pointer 스타일 적용

* feat: distanceRange를 실제 거리 값으로 변환하는 로직 추가

- DISTANCE_RANGE_VALUES 상수 추가 (각 범위를 km 값으로 매핑)
  - RANGE_500M: 0.5km
  - RANGE_1KM: 1km
  - ANY: null
- useOpinionForm에서 하드코딩된 0.5 제거
- distanceRange를 DISTANCE_RANGE_VALUES로 변환하여 API 전송
- CreateParticipantRequest의 distance 타입을 number | null로 변경

리뷰 가이드:
- PR 6에서 DISTANCE_RANGE enum 구조로 더욱 개선 예정
- 현재는 기본적인 매핑 로직만 추가하여 하드코딩 제거

* refactor: Zod 기반 런타임 검증 추가 및 Controller 패턴에서 useController 패턴으로 마이그레이션 (#55)

* feat: Opinion Form에 Zod schema 및 validation 추가

- opinionFormSchema 정의 (distanceRange, dislikedFoods, preferredMenus)
- preferredMenus에 대한 복잡한 검증 로직 (superRefine)
- distanceRangeToKm 헬퍼 함수 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 zodResolver 적용 및 distance 변환 수정

- zodResolver 추가로 런타임 검증 활성화
- distanceRange → distance 변환 로직 수정 (하드코딩 제거)
- useDislikeStep, usePreferenceStep export 제거 (미사용)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStep을 useController 기반 RankChip 패턴으로 리팩토링

- RankChip 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 RankChip으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- RankSection을 RankChip 사용하도록 수정
- PreferenceStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DislikeStep을 useController 기반 DislikedFoodButton 패턴으로 리팩토링

- DislikedFoodButton 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 DislikedFoodButton으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- DislikeStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 컴포넌트 분리 및 개선

- DistanceSelector 컴포넌트 분리 (선택 UI 담당)
- 선택 해제 기능 제거 (다른 거리 선택으로만 변경 가능)
- REGION_OPTIONS 접근 방식 수정 (.value → .id)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionView를 form 태그로 감싸고 onSubmit으로 제출 처리

- form 태그 추가 및 onSubmit 이벤트 핸들러로 변경
- 엔터 키로 제출 가능하도록 개선

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: PreferredMenu 타입 추가 및 OpinionForm에 적용

- PreferredMenu 타입을 Partial<Record<RankKey, FoodCategory>>로 정의
- OpinionForm의 preferredMenus 필드에 PreferredMenu 타입 적용
- 타입 안정성 강화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: preferredMenus 내 Zod Schema 옵션을 간소화 하여 복잡도 감소

* chore: prettier 포맷에 맞지 않았던 코드 수정

* feat: zod 및 @hookform/resolvers 라이브러리 설치

* refactor: Opinion Form 컴포넌트 구조 개선 및 상수 리팩토링 (#56)

* feat: DislikeStep 및 PreferenceStep용 custom hooks 추가

- useDislikeStep: 단일 선택 로직 및 검증
- usePreferenceStep: rank별 선택, 중복 체크, 검증 로직
- hooks/gathering/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 개선 및 DistanceSelector 분리

- DistanceSelector를 별도 파일로 분리
- useWatch compute로 validation 간소화
- Chip 그룹 로직을 컴포넌트로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionForm 타입을 OpinionFormSchema로 마이그레이션

- Zod inferred type 사용으로 타입 안정성 강화
- PreferredMenu를 Partial 타입으로 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: VoteSummarySection을 ResultView에 통합

- VoteSummarySection 컴포넌트 제거
- votes 렌더링 로직을 ResultView로 이동
- VoteList 분리로 관심사 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: FoodCard를 FoodCategoryCarousel에 inline 통합

- FoodCard 타입 개선
- 상수 import 경로 변경
- CompleteView 공백 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: restaurantCard를 pageComponents/gathering으로 이동

- src/components/restaurantCard → src/pageComponents/gathering/restaurantCard
- 도메인별 컴포넌트 구조 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: Enum 구조를 일관되게 재설계

- DISTANCE_RANGE, DISTANCE_RANGE_LABEL enum 추가
- FOOD_CATEGORY_LABEL enum 추가
- REGION, REGION_LABEL enum 추가
- Single Source of Truth 패턴 적용
- 모든 enum은 UPPER_CASE 네이밍 사용

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: recommend-result 폴더명을 recommendResult로 변경

- kebab-case → camelCase 통일
- src/apis/recommend-result → src/apis/recommendResult
- src/hooks/apis/recommend-result → src/hooks/apis/recommendResult

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: RegionChip 컴포넌트 분리 및 useController 적용

- RegionChip: 단일 Chip 렌더링, useController 패턴
- RegionStep: REGION_OPTIONS map하여 RegionChip 사용
- 선택 로직을 컴포넌트 내부로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 병합 충돌 과정에서 발생한 Typescript 이슈 수정

* chore: prettier 포맷에 맞지 않았던 코드 수정

* fix: 이미 제거되었던 Hook 이 작업 이력에 남았던 문제 수정

* feat: 공덕역 항목을 Region 상수에 추가

* fix: Document 제거

* fix: gathering domain 내 타입 정의 모듈의 위치를 수정

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 코드 베이스 상 수정이 필요한 부분 반영

* fix: es-toolkit 을 활용하여 일부 로직 구문 최적화 수행

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 더 이상 사용하지 않는 Type 모듈 제거

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>
@RookieAND RookieAND merged commit 30821f8 into feature/ui-bug-fixes Jan 30, 2026
6 checks passed
RookieAND added a commit that referenced this pull request Jan 30, 2026
* fix: Button 컴포넌트에 기본 type="button" 속성 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: VoteSummarySection 의견 일치율을 자연수로 표시

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: DislikeStep 단일 선택만 허용하도록 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* chore: next.config.ts 외부 이미지 호스트 허용 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: Chip 컴포넌트의 type 속성 기본 값을 button 으로 지정

* refactor: Gathering 타입 정의 및 지역 상수 추가     (#51)

* refactor: gathering 폼 타입 필드 required 변경 및 MeetingContext deprecated 표시

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 지역 옵션 상수 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: API Query 인프라 구축 및 TanStack Query 팩토리 패턴 적용  (#52)

* feat: gathering queryKey/queryOption에 capacity 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result API queryKey, queryOption 생성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant API queryKey, queryOption 생성

- participantKeys factory 추가
- participantOptions factory 추가 (create mutation)
- participant/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result queryOption에 select 추가

- response.data 자동 추출하도록 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: OpinionForm 을 중복으로 Export 하던 문제 수정

* fix: accessKey 를 앞 순위로 두어 무효화 전략 용이하게 구조 수정

* fix: mutationOptions 를 사용하여 옵션을 생성하도록 구조 개선

* fix: queryOptions 를 생성하는 팩토리 함수에서는 별도 옵션을 넣지 않도록 수정

* feat: 의견 수렴 페이지에 쓰일 Query Hooks 생성 (#53)

* feat: gathering domain hooks 추가

- useGetGathering: 모임 조회 hook
- useGetGatheringCapacity: 모임 참여자 현황 조회 hook
- Domain별로 hooks 구조화 (폴더별 분리 제거)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant domain hooks 추가

- useCreateParticipant: 모임 참여 mutation hook
- participant를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result domain hooks 추가

- useGetRecommendResult: 추천 결과 조회 hook
- recommend-result를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: hooks index 파일 업데이트

- gathering, participant, recommend-result domain별 export
- Domain 기반 hooks 구조 완성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useGetGatheringCapacity에 10초 refetch 추가

- refetchInterval: 1000 * 10 설정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useQuery Hook 기반의 함수 내 select 옵션 일괄 추가하여 데이터 정제

* feat: 의견 수렴 페이지 전체 API 연동 및 서버 Prefetch 적용 (#54)

* refactor: IntroStep scheduledDate prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep API 기반 region prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStepFooter onSubmit prop 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: CompleteView 텍스트 인라인 처리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: SubmissionBottomSheet props명 변경 (maxCount, currentCount)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 createParticipant 제출 로직 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지 API 연동 및 타입 수정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: queryOption에 select 추가하여 response.data 자동 추출

- gathering detail, capacity에 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지에 서버 프리페치 적용

- page.tsx를 서버 컴포넌트로 변경
- OpinionView.tsx로 클라이언트 로직 분리
- HydrationBoundary로 gathering 데이터 prefetch
- 무한 렌더링 문제 해결

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: useCreateParticipant Hook 을 Import 하는 경로를 올바르게 수정'

* feat: PendingView, CompleteView에 HydrationBoundary 및 API 연동 추가

- pending/page.tsx, complete/page.tsx를 서버 컴포넌트로 변경
- PendingView.tsx, CompleteView.tsx 클라이언트 컴포넌트 분리
- useGetGatheringCapacity hook으로 실시간 참여자 현황 조회
- HydrationBoundary로 capacity 데이터 prefetch
- 하드코딩된 maxCount, currentCount 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: ResultView에 HydrationBoundary 및 API 연동 추가

- result/page.tsx를 서버 컴포넌트로 변경
- ResultView.tsx 클라이언트 컴포넌트 분리
- useGetRecommendResult, useGetGatheringCapacity hook으로 데이터 조회
- HydrationBoundary로 capacity, recommend-result 데이터 prefetch
- MOCK_RECOMMENDATION_RESULT 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 식당 페이지 이동 과정에서 Cursor Pointer 스타일 적용

* feat: distanceRange를 실제 거리 값으로 변환하는 로직 추가

- DISTANCE_RANGE_VALUES 상수 추가 (각 범위를 km 값으로 매핑)
  - RANGE_500M: 0.5km
  - RANGE_1KM: 1km
  - ANY: null
- useOpinionForm에서 하드코딩된 0.5 제거
- distanceRange를 DISTANCE_RANGE_VALUES로 변환하여 API 전송
- CreateParticipantRequest의 distance 타입을 number | null로 변경

리뷰 가이드:
- PR 6에서 DISTANCE_RANGE enum 구조로 더욱 개선 예정
- 현재는 기본적인 매핑 로직만 추가하여 하드코딩 제거

* refactor: Zod 기반 런타임 검증 추가 및 Controller 패턴에서 useController 패턴으로 마이그레이션 (#55)

* feat: Opinion Form에 Zod schema 및 validation 추가

- opinionFormSchema 정의 (distanceRange, dislikedFoods, preferredMenus)
- preferredMenus에 대한 복잡한 검증 로직 (superRefine)
- distanceRangeToKm 헬퍼 함수 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 zodResolver 적용 및 distance 변환 수정

- zodResolver 추가로 런타임 검증 활성화
- distanceRange → distance 변환 로직 수정 (하드코딩 제거)
- useDislikeStep, usePreferenceStep export 제거 (미사용)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStep을 useController 기반 RankChip 패턴으로 리팩토링

- RankChip 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 RankChip으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- RankSection을 RankChip 사용하도록 수정
- PreferenceStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DislikeStep을 useController 기반 DislikedFoodButton 패턴으로 리팩토링

- DislikedFoodButton 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 DislikedFoodButton으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- DislikeStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 컴포넌트 분리 및 개선

- DistanceSelector 컴포넌트 분리 (선택 UI 담당)
- 선택 해제 기능 제거 (다른 거리 선택으로만 변경 가능)
- REGION_OPTIONS 접근 방식 수정 (.value → .id)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionView를 form 태그로 감싸고 onSubmit으로 제출 처리

- form 태그 추가 및 onSubmit 이벤트 핸들러로 변경
- 엔터 키로 제출 가능하도록 개선

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: PreferredMenu 타입 추가 및 OpinionForm에 적용

- PreferredMenu 타입을 Partial<Record<RankKey, FoodCategory>>로 정의
- OpinionForm의 preferredMenus 필드에 PreferredMenu 타입 적용
- 타입 안정성 강화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: preferredMenus 내 Zod Schema 옵션을 간소화 하여 복잡도 감소

* chore: prettier 포맷에 맞지 않았던 코드 수정

* feat: zod 및 @hookform/resolvers 라이브러리 설치

* refactor: Opinion Form 컴포넌트 구조 개선 및 상수 리팩토링 (#56)

* feat: DislikeStep 및 PreferenceStep용 custom hooks 추가

- useDislikeStep: 단일 선택 로직 및 검증
- usePreferenceStep: rank별 선택, 중복 체크, 검증 로직
- hooks/gathering/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 개선 및 DistanceSelector 분리

- DistanceSelector를 별도 파일로 분리
- useWatch compute로 validation 간소화
- Chip 그룹 로직을 컴포넌트로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionForm 타입을 OpinionFormSchema로 마이그레이션

- Zod inferred type 사용으로 타입 안정성 강화
- PreferredMenu를 Partial 타입으로 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: VoteSummarySection을 ResultView에 통합

- VoteSummarySection 컴포넌트 제거
- votes 렌더링 로직을 ResultView로 이동
- VoteList 분리로 관심사 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: FoodCard를 FoodCategoryCarousel에 inline 통합

- FoodCard 타입 개선
- 상수 import 경로 변경
- CompleteView 공백 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: restaurantCard를 pageComponents/gathering으로 이동

- src/components/restaurantCard → src/pageComponents/gathering/restaurantCard
- 도메인별 컴포넌트 구조 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: Enum 구조를 일관되게 재설계

- DISTANCE_RANGE, DISTANCE_RANGE_LABEL enum 추가
- FOOD_CATEGORY_LABEL enum 추가
- REGION, REGION_LABEL enum 추가
- Single Source of Truth 패턴 적용
- 모든 enum은 UPPER_CASE 네이밍 사용

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: recommend-result 폴더명을 recommendResult로 변경

- kebab-case → camelCase 통일
- src/apis/recommend-result → src/apis/recommendResult
- src/hooks/apis/recommend-result → src/hooks/apis/recommendResult

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: RegionChip 컴포넌트 분리 및 useController 적용

- RegionChip: 단일 Chip 렌더링, useController 패턴
- RegionStep: REGION_OPTIONS map하여 RegionChip 사용
- 선택 로직을 컴포넌트 내부로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 병합 충돌 과정에서 발생한 Typescript 이슈 수정

* chore: prettier 포맷에 맞지 않았던 코드 수정

* fix: 이미 제거되었던 Hook 이 작업 이력에 남았던 문제 수정

* feat: 공덕역 항목을 Region 상수에 추가

* fix: Document 제거

* fix: gathering domain 내 타입 정의 모듈의 위치를 수정

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 코드 베이스 상 수정이 필요한 부분 반영

* fix: es-toolkit 을 활용하여 일부 로직 구문 최적화 수행

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 더 이상 사용하지 않는 Type 모듈 제거

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>
@youngminss youngminss removed the ☑️ Need Review 작업이 완료되어 리뷰를 기다리고 있는 PR 입니다 label Feb 6, 2026
RookieAND added a commit that referenced this pull request Feb 16, 2026
* fix: Button 컴포넌트에 기본 type="button" 속성 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: VoteSummarySection 의견 일치율을 자연수로 표시

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: DislikeStep 단일 선택만 허용하도록 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* chore: next.config.ts 외부 이미지 호스트 허용 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: Chip 컴포넌트의 type 속성 기본 값을 button 으로 지정

* refactor: Gathering 타입 정의 및 지역 상수 추가     (#51)

* refactor: gathering 폼 타입 필드 required 변경 및 MeetingContext deprecated 표시

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 지역 옵션 상수 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: API Query 인프라 구축 및 TanStack Query 팩토리 패턴 적용  (#52)

* feat: gathering queryKey/queryOption에 capacity 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result API queryKey, queryOption 생성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant API queryKey, queryOption 생성

- participantKeys factory 추가
- participantOptions factory 추가 (create mutation)
- participant/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result queryOption에 select 추가

- response.data 자동 추출하도록 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: OpinionForm 을 중복으로 Export 하던 문제 수정

* fix: accessKey 를 앞 순위로 두어 무효화 전략 용이하게 구조 수정

* fix: mutationOptions 를 사용하여 옵션을 생성하도록 구조 개선

* fix: queryOptions 를 생성하는 팩토리 함수에서는 별도 옵션을 넣지 않도록 수정

* feat: 의견 수렴 페이지에 쓰일 Query Hooks 생성 (#53)

* feat: gathering domain hooks 추가

- useGetGathering: 모임 조회 hook
- useGetGatheringCapacity: 모임 참여자 현황 조회 hook
- Domain별로 hooks 구조화 (폴더별 분리 제거)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: participant domain hooks 추가

- useCreateParticipant: 모임 참여 mutation hook
- participant를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: recommend-result domain hooks 추가

- useGetRecommendResult: 추천 결과 조회 hook
- recommend-result를 독립 domain으로 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: hooks index 파일 업데이트

- gathering, participant, recommend-result domain별 export
- Domain 기반 hooks 구조 완성

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useGetGatheringCapacity에 10초 refetch 추가

- refetchInterval: 1000 * 10 설정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useQuery Hook 기반의 함수 내 select 옵션 일괄 추가하여 데이터 정제

* feat: 의견 수렴 페이지 전체 API 연동 및 서버 Prefetch 적용 (#54)

* refactor: IntroStep scheduledDate prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep API 기반 region prop 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStepFooter onSubmit prop 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: CompleteView 텍스트 인라인 처리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: SubmissionBottomSheet props명 변경 (maxCount, currentCount)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 createParticipant 제출 로직 연동

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지 API 연동 및 타입 수정

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: queryOption에 select 추가하여 response.data 자동 추출

- gathering detail, capacity에 select 추가
- 클라이언트 코드에서 .data 접근 불필요

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 의견 수렴 페이지에 서버 프리페치 적용

- page.tsx를 서버 컴포넌트로 변경
- OpinionView.tsx로 클라이언트 로직 분리
- HydrationBoundary로 gathering 데이터 prefetch
- 무한 렌더링 문제 해결

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: useCreateParticipant Hook 을 Import 하는 경로를 올바르게 수정'

* feat: PendingView, CompleteView에 HydrationBoundary 및 API 연동 추가

- pending/page.tsx, complete/page.tsx를 서버 컴포넌트로 변경
- PendingView.tsx, CompleteView.tsx 클라이언트 컴포넌트 분리
- useGetGatheringCapacity hook으로 실시간 참여자 현황 조회
- HydrationBoundary로 capacity 데이터 prefetch
- 하드코딩된 maxCount, currentCount 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: ResultView에 HydrationBoundary 및 API 연동 추가

- result/page.tsx를 서버 컴포넌트로 변경
- ResultView.tsx 클라이언트 컴포넌트 분리
- useGetRecommendResult, useGetGatheringCapacity hook으로 데이터 조회
- HydrationBoundary로 capacity, recommend-result 데이터 prefetch
- MOCK_RECOMMENDATION_RESULT 제거

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: 식당 페이지 이동 과정에서 Cursor Pointer 스타일 적용

* feat: distanceRange를 실제 거리 값으로 변환하는 로직 추가

- DISTANCE_RANGE_VALUES 상수 추가 (각 범위를 km 값으로 매핑)
  - RANGE_500M: 0.5km
  - RANGE_1KM: 1km
  - ANY: null
- useOpinionForm에서 하드코딩된 0.5 제거
- distanceRange를 DISTANCE_RANGE_VALUES로 변환하여 API 전송
- CreateParticipantRequest의 distance 타입을 number | null로 변경

리뷰 가이드:
- PR 6에서 DISTANCE_RANGE enum 구조로 더욱 개선 예정
- 현재는 기본적인 매핑 로직만 추가하여 하드코딩 제거

* refactor: Zod 기반 런타임 검증 추가 및 Controller 패턴에서 useController 패턴으로 마이그레이션 (#55)

* feat: Opinion Form에 Zod schema 및 validation 추가

- opinionFormSchema 정의 (distanceRange, dislikedFoods, preferredMenus)
- preferredMenus에 대한 복잡한 검증 로직 (superRefine)
- distanceRangeToKm 헬퍼 함수 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: useOpinionForm에 zodResolver 적용 및 distance 변환 수정

- zodResolver 추가로 런타임 검증 활성화
- distanceRange → distance 변환 로직 수정 (하드코딩 제거)
- useDislikeStep, usePreferenceStep export 제거 (미사용)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: PreferenceStep을 useController 기반 RankChip 패턴으로 리팩토링

- RankChip 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 RankChip으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- RankSection을 RankChip 사용하도록 수정
- PreferenceStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DislikeStep을 useController 기반 DislikedFoodButton 패턴으로 리팩토링

- DislikedFoodButton 컴포넌트 생성 (useController로 자체 상태 관리)
- Controller 제거, 비즈니스 로직을 DislikedFoodButton으로 이동
- 선택 해제 기능 제거 (다른 항목 선택으로만 변경 가능)
- DislikeStep을 선언적 컴포넌트로 단순화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 컴포넌트 분리 및 개선

- DistanceSelector 컴포넌트 분리 (선택 UI 담당)
- 선택 해제 기능 제거 (다른 거리 선택으로만 변경 가능)
- REGION_OPTIONS 접근 방식 수정 (.value → .id)

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionView를 form 태그로 감싸고 onSubmit으로 제출 처리

- form 태그 추가 및 onSubmit 이벤트 핸들러로 변경
- 엔터 키로 제출 가능하도록 개선

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* feat: PreferredMenu 타입 추가 및 OpinionForm에 적용

- PreferredMenu 타입을 Partial<Record<RankKey, FoodCategory>>로 정의
- OpinionForm의 preferredMenus 필드에 PreferredMenu 타입 적용
- 타입 안정성 강화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: preferredMenus 내 Zod Schema 옵션을 간소화 하여 복잡도 감소

* chore: prettier 포맷에 맞지 않았던 코드 수정

* feat: zod 및 @hookform/resolvers 라이브러리 설치

* refactor: Opinion Form 컴포넌트 구조 개선 및 상수 리팩토링 (#56)

* feat: DislikeStep 및 PreferenceStep용 custom hooks 추가

- useDislikeStep: 단일 선택 로직 및 검증
- usePreferenceStep: rank별 선택, 중복 체크, 검증 로직
- hooks/gathering/index.ts에 export 추가

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: DistanceStep 개선 및 DistanceSelector 분리

- DistanceSelector를 별도 파일로 분리
- useWatch compute로 validation 간소화
- Chip 그룹 로직을 컴포넌트로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: OpinionForm 타입을 OpinionFormSchema로 마이그레이션

- Zod inferred type 사용으로 타입 안정성 강화
- PreferredMenu를 Partial 타입으로 변경

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: VoteSummarySection을 ResultView에 통합

- VoteSummarySection 컴포넌트 제거
- votes 렌더링 로직을 ResultView로 이동
- VoteList 분리로 관심사 분리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: FoodCard를 FoodCategoryCarousel에 inline 통합

- FoodCard 타입 개선
- 상수 import 경로 변경
- CompleteView 공백 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: restaurantCard를 pageComponents/gathering으로 이동

- src/components/restaurantCard → src/pageComponents/gathering/restaurantCard
- 도메인별 컴포넌트 구조 정리

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: Enum 구조를 일관되게 재설계

- DISTANCE_RANGE, DISTANCE_RANGE_LABEL enum 추가
- FOOD_CATEGORY_LABEL enum 추가
- REGION, REGION_LABEL enum 추가
- Single Source of Truth 패턴 적용
- 모든 enum은 UPPER_CASE 네이밍 사용

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: recommend-result 폴더명을 recommendResult로 변경

- kebab-case → camelCase 통일
- src/apis/recommend-result → src/apis/recommendResult
- src/hooks/apis/recommend-result → src/hooks/apis/recommendResult

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* refactor: RegionChip 컴포넌트 분리 및 useController 적용

- RegionChip: 단일 Chip 렌더링, useController 패턴
- RegionStep: REGION_OPTIONS map하여 RegionChip 사용
- 선택 로직을 컴포넌트 내부로 캡슐화

Co-Authored-By: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 병합 충돌 과정에서 발생한 Typescript 이슈 수정

* chore: prettier 포맷에 맞지 않았던 코드 수정

* fix: 이미 제거되었던 Hook 이 작업 이력에 남았던 문제 수정

* feat: 공덕역 항목을 Region 상수에 추가

* fix: Document 제거

* fix: gathering domain 내 타입 정의 모듈의 위치를 수정

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 코드 베이스 상 수정이 필요한 부분 반영

* fix: es-toolkit 을 활용하여 일부 로직 구문 최적화 수행

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

* fix: 더 이상 사용하지 않는 Type 모듈 제거

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>

---------

Co-authored-by: Claude (us.anthropic.claude-sonnet-4-5-20250929-v1:0) <noreply@anthropic.com>
github-actions bot pushed a commit that referenced this pull request Feb 16, 2026
## 1.0.0-beta.1 (2026-02-16)

### Features

* [#70](#70) ([#72](#72)) ([b676e0e](b676e0e))
* [QA] 모임 생성 완료, 결과페이지 페이지 UI 개선 ([#66](#66)) ([f10225d](f10225d))
* [QA] 서비스 전체 배경색 및 Layout Root 그림자 효과 적용 ([#59](#59)) ([384b56f](384b56f))
* api client 모듈 생성 ([#37](#37)) ([a37b0a9](a37b0a9)), closes [#38](#38) [#39](#39) [#40](#40) [#41](#41)
* Button 컴포넌트 추가 ([#11](#11)) ([83b7607](83b7607))
* Chip Component 추가 ([#9](#9)) ([e9d8b8f](e9d8b8f))
* Color theme 초기화 ([#2](#2)) ([97f1dcc](97f1dcc))
* DotsLoader 컴포넌트 추가  ([#48](#48)) ([cfe4582](cfe4582)), closes [#49](#49)
* GA4 이벤트 트래킹 통합 ([#70](#70)) ([0c1b9fa](0c1b9fa))
* GTM(Google Tag Manager) 통합을 위한 Analytics 컴포넌트 추가 ([#57](#57)) ([87a6ded](87a6ded))
* IconBase 컴포넌트 및 아이콘 컴포넌트들 구축 ([#13](#13)) ([8557b75](8557b75)), closes [#FFCD00](https://github.com/Nexters/yogieat/issues/FFCD00) [#FFAD00](https://github.com/Nexters/yogieat/issues/FFAD00) [#15](#15) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c)
* InputField 컴포넌트 추가 ([#16](#16)) ([99b8aa2](99b8aa2))
* Landing / Opinion Form 페이지 분리 ([#61](#61)) ([0f11e71](0f11e71))
* Layout 컴포넌트 추가 ([#10](#10)) ([9efce6f](9efce6f))
* Semantic Color Token 추가 ([#19](#19)) ([fcaedaf](fcaedaf))
* Spacing utility 클래스 초기화 ([#8](#8)) ([2e38d7a](2e38d7a))
* Tag 컴포넌트 추가 ([#20](#20)) ([f69dd05](f69dd05))
* Toast 컴포넌트 추가 ([#21](#21)) ([76e84b0](76e84b0))
* 모임 생성 퍼널 Step 1 (인원 선택) 구현 ([#23](#23)) ([7fc01a1](7fc01a1)), closes [#24](#24) [#1f2933](https://github.com/Nexters/yogieat/issues/1f2933) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c) [#25](#25) [#26](#26) [#27](#27) [#28](#28) [#29](#29) [#30](#30) [#31](#31) [#32](#32) [#34](#34)
* 프로젝트 기초 세팅 진행 ([aa0ec20](aa0ec20))
* 프로젝트 폴더 구조 반영 ([e54962d](e54962d))

### Bug Fixes

* 1순위를 1개라도 선택했다면 바로 CTA 가 활성화 되도록 수정 ([#60](#60)) ([e5758b4](e5758b4))
* 1차 MVP 배포 이전 최종 QA 항목 반영 ([#58](#58)) ([6574231](6574231))
* Button/Chip type 속성 추가 및 의견 수렴 UX 개선 ([#50](#50)) ([7e86e4a](7e86e4a)), closes [#51](#51) [#52](#52) [#53](#53) [#54](#54) [#55](#55) [#56](#56)
* cat 에서 echo 로 env.production 파일을 생성하도록 수정 ([f15307d](f15307d))
* CI/CD health check 타이밍 개선 및 수동 배포 기능 추가 ([54fd2b8](54fd2b8))
* Docker build-args로 환경 변수 전달 방식 변경 ([#77](#77)) ([e5fa0b9](e5fa0b9))
* Docker 이미지 강제 pull 및 컨테이너 재생성 ([#79](#79)) ([c253ec1](c253ec1))
* Health check 전략 개선 및 curl 기반으로 변경 ([765d3da](765d3da))
* nginx http2 deprecated 경고 해결 ([2fd9c75](2fd9c75))
* PendingView 내에서 ShareButton 을 렌더링 하지 않도록 수정 ([7bc3e12](7bc3e12))
* 결과 페이지 맛집 이미지 기본 placeholder, 공유하기 toast 미노출 ([#68](#68)) ([3c80844](3c80844))
* 동시 배포 방지를 위한 concurrency 설정 추가 ([e9bfd52](e9bfd52))
* 모임 생성 퍼널 필드 상태 초기화 버그 수정 ([#64](#64)) ([3934066](3934066)), closes [#65](#65)
* 모임 생성 폼 필드명 변경 (meetingDate → scheduledDate, location → region) ([#35](#35)) ([e90beed](e90beed))
* 배포 워크플로우에 GA4 환경 변수 추가 ([#73](#73)) ([835ae1f](835ae1f))
* 의견 수렴 페이지 내 UI 수정 및 인터렉션 개선 ([#36](#36)) ([a74f7da](a74f7da))
* 의견 수합 Form Capacity 폴링 제거 및 ErrorCode 타입 시스템 추가 ([#67](#67)) ([d55dba1](d55dba1))
* 인원 수 선택 Grid 및 의견 수렴 QA 수정 사항 반영 ([f01626e](f01626e))
* 테스트 용으로 추가했던 페이지 제거 및 icons 폴더 추가 ([4116025](4116025))

### Code Refactoring

* Button 컴포넌트 스펙을 Figma 명세에 맞춰 수정 ([#14](#14)) ([2e27f17](2e27f17))

### Build System

* Docker 빌드 시 NEXT_PUBLIC 환경변수 주입 프로세스 추가 ([#47](#47)) ([88ba163](88ba163))

### Documentation

* 프로젝트 개발 가이드 문서 추가 ([#84](#84)) ([4313145](4313145))
github-actions bot pushed a commit that referenced this pull request Feb 16, 2026
## 1.0.0 (2026-02-16)

### Features

* [#70](#70) ([#72](#72)) ([b676e0e](b676e0e))
* [QA] 모임 생성 완료, 결과페이지 페이지 UI 개선 ([#66](#66)) ([f10225d](f10225d))
* [QA] 서비스 전체 배경색 및 Layout Root 그림자 효과 적용 ([#59](#59)) ([384b56f](384b56f))
* analytics 개선 및 네이버 서치 어드바이저 등록 ([#88](#88)) ([4372aa5](4372aa5))
* api client 모듈 생성 ([#37](#37)) ([a37b0a9](a37b0a9)), closes [#38](#38) [#39](#39) [#40](#40) [#41](#41)
* Button 컴포넌트 추가 ([#11](#11)) ([83b7607](83b7607))
* Chip Component 추가 ([#9](#9)) ([e9d8b8f](e9d8b8f))
* Color theme 초기화 ([#2](#2)) ([97f1dcc](97f1dcc))
* DotsLoader 컴포넌트 추가  ([#48](#48)) ([cfe4582](cfe4582)), closes [#49](#49)
* GA4 이벤트 트래킹 통합 ([#70](#70)) ([0c1b9fa](0c1b9fa))
* GTM(Google Tag Manager) 통합을 위한 Analytics 컴포넌트 추가 ([#57](#57)) ([87a6ded](87a6ded))
* IconBase 컴포넌트 및 아이콘 컴포넌트들 구축 ([#13](#13)) ([8557b75](8557b75)), closes [#FFCD00](https://github.com/Nexters/yogieat/issues/FFCD00) [#FFAD00](https://github.com/Nexters/yogieat/issues/FFAD00) [#15](#15) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c)
* InputField 컴포넌트 추가 ([#16](#16)) ([99b8aa2](99b8aa2))
* Landing / Opinion Form 페이지 분리 ([#61](#61)) ([0f11e71](0f11e71))
* Layout 컴포넌트 추가 ([#10](#10)) ([9efce6f](9efce6f))
* Semantic Color Token 추가 ([#19](#19)) ([fcaedaf](fcaedaf))
* Spacing utility 클래스 초기화 ([#8](#8)) ([2e38d7a](2e38d7a))
* Tag 컴포넌트 추가 ([#20](#20)) ([f69dd05](f69dd05))
* Toast 컴포넌트 추가 ([#21](#21)) ([76e84b0](76e84b0))
* 모임 생성 완료 페이지 UI 리뉴얼 ([#89](#89)) ([17a3fc1](17a3fc1))
* 모임 생성 퍼널 Step 1 (인원 선택) 구현 ([#23](#23)) ([7fc01a1](7fc01a1)), closes [#24](#24) [#1f2933](https://github.com/Nexters/yogieat/issues/1f2933) [#ff5a3c](https://github.com/Nexters/yogieat/issues/ff5a3c) [#25](#25) [#26](#26) [#27](#27) [#28](#28) [#29](#29) [#30](#30) [#31](#31) [#32](#32) [#34](#34)
* 프로젝트 기초 세팅 진행 ([aa0ec20](aa0ec20))
* 프로젝트 폴더 구조 반영 ([e54962d](e54962d))

### Bug Fixes

* 1순위를 1개라도 선택했다면 바로 CTA 가 활성화 되도록 수정 ([#60](#60)) ([e5758b4](e5758b4))
* 1차 MVP 배포 이전 최종 QA 항목 반영 ([#58](#58)) ([6574231](6574231))
* Button/Chip type 속성 추가 및 의견 수렴 UX 개선 ([#50](#50)) ([7e86e4a](7e86e4a)), closes [#51](#51) [#52](#52) [#53](#53) [#54](#54) [#55](#55) [#56](#56)
* cat 에서 echo 로 env.production 파일을 생성하도록 수정 ([f15307d](f15307d))
* CI/CD health check 타이밍 개선 및 수동 배포 기능 추가 ([54fd2b8](54fd2b8))
* Docker build-args로 환경 변수 전달 방식 변경 ([#77](#77)) ([e5fa0b9](e5fa0b9))
* Docker 이미지 강제 pull 및 컨테이너 재생성 ([#79](#79)) ([c253ec1](c253ec1))
* Health check 전략 개선 및 curl 기반으로 변경 ([765d3da](765d3da))
* nginx http2 deprecated 경고 해결 ([2fd9c75](2fd9c75))
* PendingView 내에서 ShareButton 을 렌더링 하지 않도록 수정 ([7bc3e12](7bc3e12))
* 결과 페이지 맛집 이미지 기본 placeholder, 공유하기 toast 미노출 ([#68](#68)) ([3c80844](3c80844))
* 동시 배포 방지를 위한 concurrency 설정 추가 ([e9bfd52](e9bfd52))
* 모임 생성 퍼널 필드 상태 초기화 버그 수정 ([#64](#64)) ([3934066](3934066)), closes [#65](#65)
* 모임 생성 폼 필드명 변경 (meetingDate → scheduledDate, location → region) ([#35](#35)) ([e90beed](e90beed))
* 배포 워크플로우에 GA4 환경 변수 추가 ([#73](#73)) ([835ae1f](835ae1f))
* 의견 수렴 페이지 내 UI 수정 및 인터렉션 개선 ([#36](#36)) ([a74f7da](a74f7da))
* 의견 수합 Form Capacity 폴링 제거 및 ErrorCode 타입 시스템 추가 ([#67](#67)) ([d55dba1](d55dba1))
* 인원 수 선택 Grid 및 의견 수렴 QA 수정 사항 반영 ([f01626e](f01626e))
* 테스트 용으로 추가했던 페이지 제거 및 icons 폴더 추가 ([4116025](4116025))

### Code Refactoring

* Button 컴포넌트 스펙을 Figma 명세에 맞춰 수정 ([#14](#14)) ([2e27f17](2e27f17))

### Build System

* Docker 빌드 시 NEXT_PUBLIC 환경변수 주입 프로세스 추가 ([#47](#47)) ([88ba163](88ba163))

### Documentation

* 프로젝트 개발 가이드 문서 추가 ([#84](#84)) ([4313145](4313145))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 Refactor 코드 리팩토링 및 구조 개선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants