Skip to content

Conversation

@oaoong
Copy link
Collaborator

@oaoong oaoong commented Dec 13, 2025

🔗 관련 이슈

#119

✨ 변경사항

  • 리뷰 홈 레이아웃 추가(리뷰 작성 확인 후 상세사항 적용)
  • 변경된 리뷰 API 명세 적용

🎯 리뷰 포인트

📝 추가 정보

@oaoong oaoong self-assigned this Dec 13, 2025
@oaoong oaoong added the ✨ Feature 기능 개발 label Dec 13, 2025
@vercel
Copy link

vercel bot commented Dec 13, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
moyeoit Ready Ready Preview, Comment Dec 13, 2025 4:07pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 13, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#119

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @oaoong, 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

  • 새로운 후기 탐색 페이지 추가: 사용자들이 후기를 찾아보고 필터링할 수 있는 전용 페이지(/review/explore)가 추가되었습니다. 이 페이지는 기존의 임시 페이지를 대체합니다.
  • 동적 필터링 및 정렬 기능 구현: 새로운 후기 탐색 페이지에는 카테고리, 결과(합격/불합격/대기), 인기순 또는 최신순으로 후기를 필터링하고 정렬하는 기능이 포함되어 있으며, 데스크톱과 모바일 환경에 최적화된 반응형 UI를 제공합니다.
  • 후기 생성 API 구조 리팩토링: 기본 후기 생성 요청(BasicReviewCreateRequest)의 구조가 백엔드 API의 새로운 사양에 맞춰 업데이트되었습니다. 질문/답변 필드와 최상위 후기 속성들이 변경되었습니다.
  • 새로운 후기 검색 API 통합: 후기 탐색 페이지를 지원하기 위해 새로운 API 엔드포인트(/api/v1/review/search)와 이에 상응하는 클라이언트 측 훅(useSearchReviews)이 통합되었습니다.
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.

@oaoong oaoong merged commit 19ba437 into develop Dec 13, 2025
6 of 7 checks passed
Copy link

@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은 리뷰 홈 레이아웃을 추가하고 관련 API 연동을 구현한 것으로 보입니다. 새로운 Explore 컴포넌트가 추가되었고, 리뷰 작성 로직도 새로운 API 명세에 맞게 수정되었습니다. 전반적으로 기능 구현이 잘 이루어졌지만, 몇 가지 개선점을 제안합니다. 필터링 로직의 잠재적인 버그, 컴포넌트의 key prop 사용, 타입 정의의 일관성 및 정확성, 그리고 사용자 경험(UX) 개선에 관한 피드백을 포함했습니다. 자세한 내용은 각 파일의 주석을 확인해주세요.

Comment on lines +48 to +51
const mappedResult =
resultArray.length === 0 || resultArray.includes('all')
? undefined
: resultArray[0]

Choose a reason for hiding this comment

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

high

MultiDropDown 컴포넌트는 여러 값을 선택할 수 있도록 구현되어 있고, handleResultChange 함수에서도 여러 값을 콤마로 연결하여 result 상태를 업데이트합니다. 하지만 mappedResult에서는 resultArray[0]으로 첫 번째 값만 사용하고 있어, 사용자가 여러 필터를 선택하더라도 첫 번째 선택만 적용됩니다. 이는 사용자의 의도와 다르게 동작할 수 있는 버그입니다.
API가 여러 result 값을 지원하지 않는다면, MultiDropDown 대신 단일 선택이 가능한 드롭다운 컴포넌트를 사용하는 것을 고려해보세요. 만약 여러 값을 콤마로 구분하여 지원한다면, mappedResult 로직을 resultArray.join(',')과 같이 수정해야 합니다.

className={`grid ${isDesktop ? 'grid-cols-3 gap-6' : 'grid-cols-1 gap-4'}`}
>
{bestReviewsData.content.map((review) => (
<BestReviewCard key={review.title} review={review} />

Choose a reason for hiding this comment

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

high

map 함수 내에서 key prop으로 review.title을 사용하고 있습니다. 제목은 고유하지 않을 수 있으므로, 중복될 경우 React의 리스트 렌더링 시 예기치 않은 동작이나 성능 저하가 발생할 수 있습니다. review 객체에 고유 ID인 reviewId가 있으므로 이를 key로 사용하는 것이 가장 좋습니다. reviewId가 없는 경우를 대비한 fallback 처리도 함께 추가하는 것을 권장합니다.

Suggested change
<BestReviewCard key={review.title} review={review} />
<BestReviewCard key={review.reviewId ?? `${review.clubName}-${review.title}`} review={review} />

<div className="flex flex-col gap-4">
{reviewsData.content.map((review) => (
<ReviewListItem
key={`${review.title}-${review.clubName}`}

Choose a reason for hiding this comment

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

high

map 함수 내에서 key prop으로 review.titlereview.clubName의 조합을 사용하고 있습니다. 이는 단순히 title만 사용하는 것보다 낫지만, 여전히 고유성을 100% 보장하지는 않습니다. review 객체에 고유 ID인 reviewId가 있으므로 key={review.reviewId}와 같이 사용하는 것이 가장 안정적입니다. reviewId가 없는 경우를 대비한 fallback을 함께 사용하는 것이 좋습니다.

Suggested change
key={`${review.title}-${review.clubName}`}
key={review.reviewId ?? `${review.title}-${review.clubName}`}

export default function Page() {
return <ConstructionPage />
return (
<Suspense fallback={null}>

Choose a reason for hiding this comment

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

medium

Suspensefallback prop에 null을 전달하면 컴포넌트가 로드되는 동안 사용자에게 아무것도 표시되지 않아 페이지가 멈춘 것처럼 보일 수 있습니다. 로딩 스켈레톤 UI나 간단한 로딩 스피너를 fallback으로 제공하여 사용자 경험을 개선하는 것이 좋습니다.

Comment on lines +273 to +282
review: {
reviewId?: number
clubName: string
jobName: string
title: string
answerSummaries: { answerSummary: string }[]
rate: number
likeCount: number
commentCount: number
}

Choose a reason for hiding this comment

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

medium

BestReviewCard 컴포넌트의 review prop 타입을 인라인으로 정의하고 있습니다. 이 타입은 features/review/types.ts에 정의된 ReviewSearchItem 타입과 거의 동일합니다. 코드 중복을 줄이고 타입 일관성을 유지하기 위해 ReviewSearchItem 타입을 직접 import하여 사용하는 것을 권장합니다.

import { type ReviewSearchItem } from '@/features/review/types'

function BestReviewCard({ review }: { review: ReviewSearchItem }) {
  // ...
}

또한, 현재 answerSummaries의 인라인 타입이 API 응답 타입(ReviewAnswerSummary[])과 일치하지 않습니다. questionTitleSummary 필드가 누락되어 있어 타입 안정성이 떨어집니다.

Comment on lines +335 to +346
review: {
reviewId?: number
clubName: string
jobName: string
generation: number
title: string
answerSummaries: { answerSummary: string }[]
rate: number
likeCount: number
commentCount: number
category?: string
}

Choose a reason for hiding this comment

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

medium

ReviewListItem 컴포넌트의 review prop 타입을 인라인으로 정의하고 있습니다. 이 타입은 features/review/types.ts에 정의된 ReviewSearchItem 타입과 거의 동일합니다. 코드 중복을 줄이고 타입 일관성을 유지하기 위해 ReviewSearchItem 타입을 직접 import하여 사용하는 것을 권장합니다.

import { type ReviewSearchItem } from '@/features/review/types'

function ReviewListItem({ review }: { review: ReviewSearchItem }) {
  // ...
}

또한, 현재 answerSummaries의 인라인 타입이 API 응답 타입(ReviewAnswerSummary[])과 일치하지 않습니다. questionTitleSummary 필드가 누락되어 있어 타입 안정성이 떨어집니다.

Comment on lines +46 to +63
export interface ReviewAnswerRequest {
/**
* 노출 순서
*/
sequence: number
/**
* 질문 ID
*/
question_id: number
/**
* 질문 타입
*/
question_type: QuestionType
/**
* 답변 값 (객관식 또는 주관식)
*/
value: ReviewAnswerValue
}

Choose a reason for hiding this comment

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

medium

ReviewAnswerRequest 인터페이스의 속성명으로 question_id, question_type과 같이 snake_case가 사용되었습니다. 프로젝트의 다른 타입 정의(예: BasicReviewCreateRequestclubId, jobId)에서는 camelCase를 사용하고 있으므로, 코드 스타일의 일관성을 위해 camelCase(questionId, questionType)로 통일하는 것을 고려해보세요. 만약 백엔드 API가 snake_case를 요구한다면, API 요청을 보내기 직전에 camelCase를 snake_case로 변환하는 어댑터나 함수를 사용하는 것이 프론트엔드 코드베이스의 일관성을 유지하는 데 도움이 됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant