Skip to content

[FIX] clubId 가 string이지 못하게 교정 (#158)#159

Merged
aaaaaattt merged 3 commits intodevelopfrom
fix/club-apply-button-path#158
Oct 12, 2025
Merged

[FIX] clubId 가 string이지 못하게 교정 (#158)#159
aaaaaattt merged 3 commits intodevelopfrom
fix/club-apply-button-path#158

Conversation

@ganimjeong
Copy link
Contributor

@ganimjeong ganimjeong commented Oct 12, 2025

#️⃣연관된 이슈

close #158

📝작업 내용

지원하기 버튼을 눌러 이동할 때 경로의 클럽아이디가 언디파인드로 뜨는 문제
-> 클럽 아이디를 스트링으로 받지 못하도록 교정 및 타입을 유니온이 아니게 수정

스크린샷 (선택)

💬리뷰 요구사항(선택)

  • 일단 이렇게 해보고 안되면 타입손대볼게요

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요

Summary by CodeRabbit

  • New Features

    • None
  • Bug Fixes

    • Fixed club detail pages failing to load when IDs were non-numeric.
    • Ensured apply links and sidebar actions behave consistently for all clubs.
  • Refactor

    • Standardized club identifier naming and numeric handling across club detail views for more reliable data fetching and UI behavior.

@ganimjeong ganimjeong requested a review from aaaaaattt October 12, 2025 10:19
@ganimjeong ganimjeong self-assigned this Oct 12, 2025
@ganimjeong ganimjeong added the 🐛 bug 버그 이슈 label Oct 12, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ganimjeong, 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은 클럽 상세 페이지로 이동할 때 clubIdundefined로 잘못 처리되어 발생하는 문제를 해결합니다. clubId의 데이터 타입을 string에서 number로 일관되게 처리하도록 수정하여, 경로 이동 및 데이터 페칭 과정에서 발생할 수 있는 오류를 방지하고 애플리케이션의 안정성을 향상시킵니다.

Highlights

  • 클럽 ID 타입 통일: 클럽 상세 페이지에서 clubIdundefined로 처리되던 문제를 해결하기 위해, clubId의 타입을 string에서 number로 명확히 통일했습니다.
  • 타입 변환 로직 추가: useParams를 통해 받아오는 clubIdstring 타입이므로, 이를 Number() 함수를 사용하여 명시적으로 number 타입으로 변환하는 로직을 추가했습니다.
  • 컴포넌트 Prop 타입 수정: ClubInfoSidebarSection 컴포넌트에서 clubId prop의 타입을 number | string에서 number로 변경하여, 타입 안정성을 강화했습니다.
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.

@coderabbitai
Copy link

coderabbitai bot commented Oct 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Converts route clubId to a numeric clubIdNumber, updates fetch call and effect dependencies to use a number-typed ID, renames ClubDetail.idclubId, aligns mocks/repository lookups to clubId, and updates ClubInfoSidebarSection to receive clubId via the picked ClubDetail props.

Changes

Cohort / File(s) Summary
Page: numeric ID flow
src/pages/user/ClubDetail/Page.tsx
Convert route clubId (string) to clubIdNumber = Number(clubId), use it in guard, effect deps, and call fetchClubDetail(clubIdNumber). Pass club's clubId into sidebar.
API: parameter type narrowed
src/pages/user/ClubDetail/api/clubDetail.ts
fetchClubDetail parameter type changed from string | number to number.
Types: renamed ID field
src/pages/user/ClubDetail/types/clubDetail.ts
ClubDetail type field renamed from id: number to clubId: number.
Component: props adjusted
src/pages/user/ClubDetail/components/ClubInfoSidebarSection/index.tsx
Removed explicit `clubId: number
Mocks / repository: data shape and lookup
src/mocks/repositories/club.ts
Mock ClubDetail entries renamed idclubId; repository lookup and update logic now search by clubId instead of id.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Router as Router
  participant Page as ClubDetail Page
  participant API as fetchClubDetail
  participant Repo as mock repo

  User->>Router: Navigate to /clubs/:clubId (string)
  Router->>Page: Provide param `clubId` (string)
  Note over Page: Convert to number -> `clubIdNumber`
  Page->>Page: Guard on `clubIdNumber`
  Page->>API: fetchClubDetail(clubIdNumber)
  API->>Repo: lookup by `clubId` (mock)
  Repo-->>API: ClubDetail { clubId, ... }
  API-->>Page: Club data
  Page-->>User: Render details + Apply button (uses club.clubId)
  User->>Page: Click "Apply"
  Page->>Router: Navigate to /apply/:clubId (uses numeric clubId)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I hop and tidy IDs with care,
From stringy trails to numbers fair.
Mocks align, the button sings,
No undefined on apply wings.
— A tiny rabbit, ears in the air 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and specifically summarizes the main change by indicating that clubId will no longer be treated as a string, which directly addresses the underlying bug of the apply button path receiving an undefined ID. It concisely conveys the fix scope without extraneous detail. It aligns with the PR changes focusing on type correction and renaming.
Linked Issues Check ✅ Passed The pull request fully implements the objectives of issue #158 by converting clubId to a number, narrowing the type signature, renaming the id field to clubId in types, API, mocks, and components, and updating the data-fetch and props flow to ensure the apply button path receives a defined numeric ID. All coding requirements from the linked issue are met.
Out of Scope Changes Check ✅ Passed All modifications are directly related to correcting the clubId type and ensuring proper ID passage; there are no unrelated or extraneous changes introduced in this pull request.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/club-apply-button-path#158

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.

aaaaaattt
aaaaaattt previously approved these changes Oct 12, 2025
Copy link
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은 clubIdstring으로 다루어지면서 발생하던 문제를 해결하기 위해 타입을 number로 교정하는 변경사항을 담고 있습니다. 전반적으로 좋은 방향의 수정이지만, clubId를 숫자로 변환하는 과정에서 발생할 수 있는 엣지 케이스(edge case)에 대한 처리가 필요해 보입니다. Page.tsx에서 Number() 함수 사용 시 NaN이 될 수 있는 경우와 0을 처리하는 부분에 대한 리뷰 의견을 남겼습니다. 이 부분을 수정하면 코드가 더 안정적으로 동작할 것입니다.

if (!clubId) return;
fetchClubDetail(clubId).then(setClub).catch(console.error);
}, [clubId]);
if (!clubIdNumber) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

현재의 !clubIdNumber 조건은 clubIdundefined이거나 숫자가 아닌 문자열일 때 NaN이 되는 경우를 제대로 처리하지 못합니다 (!NaNfalse). 또한 clubId'0'일 경우 0으로 변환되어 !0true가 되므로, 유효한 ID임에도 불구하고 데이터를 가져오지 못하는 버그가 발생할 수 있습니다.

isNaN을 사용하여 clubIdNumber가 유효한 숫자인지 확인하는 것이 더 안전합니다.

Suggested change
if (!clubIdNumber) return;
if (isNaN(clubIdNumber)) return;

Copy link

@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 (1)
src/pages/user/ClubDetail/Page.tsx (1)

18-18: Prefer explicit validation for numeric conversion.

Number(clubId) silently converts invalid inputs to NaN. While the guard at line 22 catches this, an explicit check improves clarity.

Consider this alternative that validates before conversion:

-  const clubIdNumber = Number(clubId);
+  const clubIdNumber = clubId ? Number(clubId) : NaN;

Or combine with the improved guard:

   const { clubId } = useParams<{ clubId: string }>();
-  const clubIdNumber = Number(clubId);
+  const clubIdNumber = clubId ? Number(clubId) : undefined;
   const [club, setClub] = useState<ClubDetail | null>(null);
 
   useEffect(() => {
-    if (!clubIdNumber) return;
+    if (clubIdNumber === undefined || Number.isNaN(clubIdNumber)) return;
     fetchClubDetail(clubIdNumber).then(setClub).catch(console.error);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b23d73a and f8d14e1.

📒 Files selected for processing (2)
  • src/pages/user/ClubDetail/Page.tsx (1 hunks)
  • src/pages/user/ClubDetail/components/ClubInfoSidebarSection/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/user/ClubDetail/Page.tsx (2)
src/pages/user/ClubDetail/types/clubDetail.ts (1)
  • ClubDetail (3-20)
src/pages/user/ClubDetail/api/clubDetail.ts (1)
  • fetchClubDetail (5-9)
🔇 Additional comments (2)
src/pages/user/ClubDetail/components/ClubInfoSidebarSection/index.tsx (1)

17-17: LGTM! Type narrowing improves type safety.

Narrowing clubId from number | string to number eliminates ambiguity and aligns with the fix objective. The URL construction at line 41 correctly coerces the number to a string in the template literal.

src/pages/user/ClubDetail/Page.tsx (1)

24-24: Effect dependency is correct.

Changing the dependency from [clubId] to [clubIdNumber] is appropriate since the effect now uses clubIdNumber for the fetch call. Primitive number values are compared by value, so the dependency will trigger correctly when the route parameter changes.

if (!clubId) return;
fetchClubDetail(clubId).then(setClub).catch(console.error);
}, [clubId]);
if (!clubIdNumber) return;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard rejects valid club ID 0.

The guard if (!clubIdNumber) is truthy for 0, NaN, null, undefined, and false. While it correctly catches NaN from invalid conversions, it also incorrectly rejects a club ID of 0 if that's a valid identifier in your system.

Apply this diff to check for NaN explicitly:

-    if (!clubIdNumber) return;
+    if (!clubId || Number.isNaN(clubIdNumber)) return;

This way, club ID 0 is accepted while invalid conversions are still caught.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!clubIdNumber) return;
// replace this:
- if (!clubIdNumber) return;
// with this:
if (!clubId || Number.isNaN(clubIdNumber)) return;
🤖 Prompt for AI Agents
In src/pages/user/ClubDetail/Page.tsx around line 22, the guard `if
(!clubIdNumber) return;` wrongly rejects a valid club ID of 0; change the check
to explicitly test for NaN (e.g., use Number.isNaN(clubIdNumber) or
isNaN(clubIdNumber)) so that only invalid numeric conversions are rejected while
allowing 0 to pass; update any related early-return behavior or types
accordingly to ensure downstream code receives a valid numeric ID.

@ganimjeong ganimjeong requested a review from kanghaeun October 12, 2025 10:26
kanghaeun
kanghaeun previously approved these changes Oct 12, 2025
@ganimjeong ganimjeong dismissed stale reviews from kanghaeun and aaaaaattt via 5a147cb October 12, 2025 11:18
Copy link

@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: 0

🧹 Nitpick comments (2)
src/mocks/repositories/club.ts (2)

338-348: Consider renaming parameter for clarity.

The function parameter is named id, but it's used to look up club.clubId. For consistency and clarity, consider renaming the parameter to clubId.

Apply this diff:

-  updateClubDetail: (id: number, updatedData: Partial<ClubDetail>) => {
-    const index = mockClubDetail.findIndex((club) => club.clubId === id);
+  updateClubDetail: (clubId: number, updatedData: Partial<ClubDetail>) => {
+    const index = mockClubDetail.findIndex((club) => club.clubId === clubId);

Similarly, consider updating getClubDetailById:

-  getClubDetailById: (id: number) => {
-    return mockClubDetail.find((club) => club.clubId === id);
+  getClubDetailById: (clubId: number) => {
+    return mockClubDetail.find((club) => club.clubId === clubId);

334-336: Unify identifier property names between Club and ClubDetail: Club uses id but ClubDetail uses clubId; consider aligning these to avoid confusion.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8d14e1 and 5a147cb.

📒 Files selected for processing (5)
  • src/mocks/repositories/club.ts (4 hunks)
  • src/pages/user/ClubDetail/Page.tsx (2 hunks)
  • src/pages/user/ClubDetail/api/clubDetail.ts (1 hunks)
  • src/pages/user/ClubDetail/components/ClubInfoSidebarSection/index.tsx (2 hunks)
  • src/pages/user/ClubDetail/types/clubDetail.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/user/ClubDetail/Page.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/pages/user/ClubDetail/api/clubDetail.ts (1)
src/pages/user/ClubDetail/types/clubDetail.ts (1)
  • ClubDetail (3-20)
src/mocks/repositories/club.ts (1)
src/pages/user/ClubDetail/types/clubDetail.ts (1)
  • ClubDetail (3-20)
🔇 Additional comments (5)
src/mocks/repositories/club.ts (1)

242-242: Mock data updated correctly.

The mock data entries correctly use clubId instead of id, aligning with the ClubDetail type definition.

Also applies to: 271-271, 299-299

src/pages/user/ClubDetail/components/ClubInfoSidebarSection/index.tsx (2)

6-17: Improved type safety using Pick.

Using Pick<ClubDetail, ...> to derive the props ensures that clubId maintains the same type as defined in ClubDetail (number), improving type consistency across the component tree. This change directly addresses the PR objective of ensuring clubId is typed as a number, preventing the undefined path issue.


40-40: Apply button route now correctly uses numeric clubId.

The route construction now uses clubId as a number (via the ClubDetail type), which should resolve the issue where the club ID appeared as undefined in the URL path. The template literal will properly convert the number to a string for the URL.

src/pages/user/ClubDetail/api/clubDetail.ts (1)

5-5: fetchClubDetail parameter narrowing is safe
Verified that src/pages/user/ClubDetail/Page.tsx converts useParams’s clubId to a number before calling fetchClubDetail. No other call sites found.

src/pages/user/ClubDetail/types/clubDetail.ts (1)

4-4: LGTM – no residual ClubDetail.id usages found; all remaining club.id refs are on the separate Club type.

@aaaaaattt aaaaaattt merged commit bbff552 into develop Oct 12, 2025
11 checks passed
@aaaaaattt aaaaaattt deleted the fix/club-apply-button-path#158 branch October 12, 2025 11:54
ganimjeong pushed a commit that referenced this pull request Oct 27, 2025
…ly-button-path#158

[FIX] clubId 가 string이지 못하게 교정 (#158)
ganimjeong pushed a commit that referenced this pull request Oct 27, 2025
…ly-button-path#158

[FIX] clubId 가 string이지 못하게 교정 (#158)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug 버그 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FIX] 지원하기 버튼 경로 언디파인드 문제

3 participants