Skip to content

[Feature](WO-138): 특정 문제 상세 조회 API 연동#51

Open
soooheeee wants to merge 5 commits intodevfrom
feature/WO-138-problem-detail-api
Open

[Feature](WO-138): 특정 문제 상세 조회 API 연동#51
soooheeee wants to merge 5 commits intodevfrom
feature/WO-138-problem-detail-api

Conversation

@soooheeee
Copy link
Copy Markdown
Contributor

@soooheeee soooheeee commented Apr 2, 2026

Motivation

  • 사용자가 특정 문제의 정보를 상세하게 조회할 수 있도록 하고자 함.
  • 상태관리 로직을 리팩토링 하고자 함.

Problem Solving

  • 특정 문제 상세 조회 API 연동 및 타입 추가 (021d549)
  • 문제 상세 조회바 컴포넌트 추가 및 데이터 바인딩 (739662a)
  • 문제 상세 조회 기능 추가 및 상태 관리 구조 리팩토링 (a721fe8)
특정 문제 상세 조회 페이지
image

To Reviewer

image

이 문제에 대한 총 제출, 이 문제에 대한 찾은 총 반례 이 문구가 애매한 거 같아서 다른 좋은 문구가 있을까요?

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 59fe3d8c-788f-4721-9bad-016c4d9dcce0

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

이 PR은 문제 상세 정보 조회 기능을 추가합니다. getProblemDetail API 함수와 ProblemDetail 타입을 신규 추가하고, 문제 정보를 표시하는 ProblemInfoBar 컴포넌트를 생성합니다. CounterExamplePage는 상태 관리를 useState에서 useReducer로 리팩토링하고, 라우트 파라미터 기반 네비게이션을 쿼리 스트링 기반으로 변경하며, 페이지 레이아웃에 ProblemInfoBar 헤더를 추가합니다.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes


리뷰 피드백 및 개선 제안

1. 상태 관리 리팩토링 시 검토 포인트

현황:
CounterExamplePage에서 useState 기반 다중 상태 관리를 useReducer로 통합하셨습니다.

개선 사항:
✅ 상태 로직의 응집도가 높아졌습니다. 관련 상태 전환이 counterExampleReducer에 집중되어 있어 복잡한 상태 머신을 관리하기 용이합니다.

추가 검토 권장사항:

  • counterExampleReducer.ts의 각 액션 핸들러에서 상태 불변성이 제대로 유지되고 있는지 확인하세요. (예: failedCases 배열 초기화 시 새 배열 참조 사용)
  • 참고: React useReducer 공식 문서 - 상태 업데이트의 불변성 패턴

2. 네비게이션 방식 변경 검토

변경 사항:
useParamsuseSearchParams로 변경되었습니다.

고려사항:

  • 쿼리 스트링 방식은 북마크와 공유에 유리하지만, 페이지 새로고침 시 getProblemDetail 재요청이 발생합니다.
  • 로딩 상태 (isLoadingDetail)가 올바르게 처리되고 있으므로 UX 관점에서는 안전합니다.
  • 향후 필요시 React Router의 loader 패턴 검토를 권장합니다.

3. ProblemInfoBar 컴포넌트 설계

현황:
ProblemDetail 데이터를 받아 네 가지 정보(문제번호, 플랫폼, 총 제출, 찾은 반례)를 표시합니다.

제안:

  • totalSubmissionsfoundSubmissions의 null/undefined 처리에서 기본값 0을 사용하고 있는데, 이는 실제 데이터와의 구분이 어려울 수 있습니다. 필요시 "정보 없음" 같은 명시적 상태 표시를 검토해보세요.
  • 스타일링에서 foundSubmissions만 빨간 텍스트를 사용 중입니다. 컬러 팔레트 일관성 검증을 권장합니다.

4. 타입 안정성 확인

ProblemDetail 인터페이스가 명확하게 정의되어 있고, API 응답 타입과 컴포넌트 props 타입이 일치합니다.

권장:


전반적으로 상태 관리 개선과 새로운 기능 추가가 체계적으로 구현되었습니다. 위 사항들을 검토한 후 병합하시면 될 것 같습니다! 🚀

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경사항의 핵심을 명확하게 반영하고 있으며, API 연동이라는 주요 목표를 잘 전달합니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/WO-138-problem-detail-api

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/apis/problems/problems.type.ts (1)

29-36: P4: ProblemDetail 인터페이스가 기존 Problem 인터페이스와 동일합니다.

현재 ProblemDetailProblem 인터페이스의 필드가 완전히 동일합니다. 이는 코드 중복으로 이어질 수 있으며, 추후 필드 변경 시 두 곳을 모두 수정해야 하는 유지보수 부담이 생깁니다.

개선 방법:

  • API 응답이 동일하다면 Problem 타입을 재사용하거나, 타입 별칭(type alias)을 활용할 수 있습니다.
  • 만약 향후 필드가 달라질 가능성이 있다면 현재 구조를 유지해도 무방합니다.
♻️ 타입 재사용 예시
-export interface ProblemDetail {
-  problemId: number;
-  problemNo: number;
-  title: string;
-  platform: string;
-  totalSubmissions: number;
-  foundSubmissions: number;
-}
+// Problem과 동일한 구조라면 재사용
+export type ProblemDetail = Problem;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/apis/problems/problems.type.ts` around lines 29 - 36, ProblemDetail
duplicates the fields of the existing Problem interface; update the code to
reuse the existing type instead of duplicating it by replacing the separate
ProblemDetail declaration with a type alias or direct reference to Problem
(e.g., make ProblemDetail = Problem or remove ProblemDetail and use Problem
where referenced). Locate the ProblemDetail and Problem symbols in
src/apis/problems/problems.type.ts and adjust exports/usages accordingly so only
the canonical Problem type is maintained and referenced throughout the codebase.
src/pages/CounterExamplePage.tsx (1)

89-94: P4: 로딩/에러 상태 UI를 별도 컴포넌트로 분리하면 재사용성이 높아집니다.

현재 인라인으로 작성된 로딩/에러 UI를 공통 컴포넌트로 분리하면 다른 페이지에서도 일관된 UI를 제공할 수 있습니다. 당장은 필수가 아니지만, 프로젝트가 커지면 고려해보세요.

// 예시: 공통 로딩 컴포넌트
<LoadingSpinner message="로딩 중..." />
<ErrorMessage message="문제를 찾을 수 없습니다." />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/CounterExamplePage.tsx` around lines 89 - 94, Extract the inline
loading/error UI in CounterExamplePage (the conditional blocks that check
isLoadingDetail and detail) into reusable presentational components (e.g.,
LoadingSpinner and ErrorMessage), replace the early returns with those
components, and pass the display text as props (message) so other pages can
reuse them; ensure the new components encapsulate the common wrapper classes
("flex h-[400px] items-center justify-center") and any i18n text, and update
imports and JSX in the isLoadingDetail and !detail branches to use
LoadingSpinner and ErrorMessage respectively.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/CounterExamplePage.tsx`:
- Line 36: The call to getProblemDetail(Number(currentProblemId)) can pass NaN
when currentProblemId is not numeric; update the component to validate and
coerce currentProblemId before calling getProblemDetail: parse/convert
currentProblemId (e.g., parseInt or Number), check isNaN on the result, and if
invalid handle it (early return, show an error/toast, or redirect) instead of
calling getProblemDetail with NaN; change the line that creates data (the site
using getProblemDetail and currentProblemId) to only call getProblemDetail with
a verified numeric id and include appropriate user-facing or logging handling
when validation fails.
- Around line 21-22: The page is reading a non-existent query param via
useSearchParams().get('id') so currentProblemId is always null; replace this
with path param usage by importing and calling useParams() and reading
problemPlatform and problemNo (or compute an id from them) instead of
useSearchParams, updating references to currentProblemId where used (look for
useSearchParams, currentProblemId, problemPlatform, problemNo in this file) so
the API call gating logic uses the actual route params.

---

Nitpick comments:
In `@src/apis/problems/problems.type.ts`:
- Around line 29-36: ProblemDetail duplicates the fields of the existing Problem
interface; update the code to reuse the existing type instead of duplicating it
by replacing the separate ProblemDetail declaration with a type alias or direct
reference to Problem (e.g., make ProblemDetail = Problem or remove ProblemDetail
and use Problem where referenced). Locate the ProblemDetail and Problem symbols
in src/apis/problems/problems.type.ts and adjust exports/usages accordingly so
only the canonical Problem type is maintained and referenced throughout the
codebase.

In `@src/pages/CounterExamplePage.tsx`:
- Around line 89-94: Extract the inline loading/error UI in CounterExamplePage
(the conditional blocks that check isLoadingDetail and detail) into reusable
presentational components (e.g., LoadingSpinner and ErrorMessage), replace the
early returns with those components, and pass the display text as props
(message) so other pages can reuse them; ensure the new components encapsulate
the common wrapper classes ("flex h-[400px] items-center justify-center") and
any i18n text, and update imports and JSX in the isLoadingDetail and !detail
branches to use LoadingSpinner and ErrorMessage respectively.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 06ed3944-1e5e-42fd-a40a-697895c2e475

📥 Commits

Reviewing files that changed from the base of the PR and between 5b69941 and a721fe8.

📒 Files selected for processing (5)
  • src/apis/problems/problems.ts
  • src/apis/problems/problems.type.ts
  • src/components/problem/ProblemInfoBar.tsx
  • src/pages/CounterExamplePage.tsx
  • src/types/counterExampleReducer.ts

@soooheeee soooheeee requested review from Jsplix and juiuj April 3, 2026 09:21
@soooheeee soooheeee self-assigned this Apr 3, 2026
@soooheeee soooheeee added the enhancement New feature or request label Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant