Skip to content

[Fix] #87: 어드민 qa#93

Merged
JIN921 merged 3 commits intodevelopfrom
fix#87/어드민-qa
Apr 29, 2026

Hidden character warning

The head ref may contain hidden characters: "fix#87/\uc5b4\ub4dc\ubbfc-qa"
Merged

[Fix] #87: 어드민 qa#93
JIN921 merged 3 commits intodevelopfrom
fix#87/어드민-qa

Conversation

@JIN921
Copy link
Copy Markdown
Collaborator

@JIN921 JIN921 commented Apr 29, 2026

✅ PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

📌 관련 이슈번호


✅ Key Changes

  • 세션 단일 타입/ 반복 타입 설정
  • 세션 출석 포함된 경우 삭제 경고 추가
  • LNB 메뉴얼 제거 및 동아리 정보 섹션 높이 설정

📸 스크린샷 or 실행영상


🎸 기타 사항 or 추가 코멘트

Summary by CodeRabbit

릴리스 노트

  • 버그 수정

    • 일회성 세션 날짜 처리 개선으로 상태 계산 안정성 향상
    • 세션 삭제 시 관련 출석 데이터 처리 로직 개선
    • 에러 처리 로직 강화로 강제 확인 기능 확대
  • 개선 사항

    • 관리자 영역 네비게이션 항목 정리
    • 레이아웃 스타일 조정
    • 세션 편집 모달 타겟 처리 최적화

@JIN921 JIN921 requested review from dalzzy, nabbang6 and woneeeee April 29, 2026 14:42
@JIN921 JIN921 self-assigned this Apr 29, 2026
@JIN921 JIN921 added the 🐞 BugFix Something isn't working label Apr 29, 2026
@JIN921 JIN921 linked an issue Apr 29, 2026 that may be closed by this pull request
3 tasks
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

Warning

Rate limit exceeded

@JIN921 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 49 minutes and 43 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4006c0c7-8822-4b6f-a2f0-d58279755167

📥 Commits

Reviewing files that changed from the base of the PR and between 0feafaf and d7f440c.

📒 Files selected for processing (1)
  • src/components/admin/schedule/session/SessionTabContent.tsx
📝 Walkthrough

Walkthrough

관리자 페이지의 단일 세션에 대해 그룹 관련 필드들을 nullable로 처리하고, UI 컴포넌트들이 null 값을 안전하게 처리하도록 개선했습니다. 세션 삭제 시 force-required 에러 처리를 추가하고, 그룹 래퍼와 단일 세션을 구분하여 처리합니다.

Changes

Cohort / File(s) Summary
타입 정의 및 상수
src/types/admin/session.d.ts, src/constants/admin/schedule.constants.ts
AdminSessionGroupgroupId, recurrenceType, recurrenceDescription, endDate를 nullable로 변경하여 단일 세션 지원. 세션 삭제 force-required 에러 코드(20306) 추가 및 업데이트/삭제 코드를 집계하는 SESSION_FORCE_REQUIRED_CODES 상수 추가.
UI 컴포넌트 - 레이아웃 및 행 렌더링
src/components/admin/layout/LNB.tsx, src/components/admin/layout/LNBClubInfo.tsx, src/components/admin/schedule/session/SessionGroupRow.tsx, src/components/admin/schedule/session/SessionTable.tsx
LNB에서 "운영진 매뉴얼" 네비게이션 항목 제거. LNBClubInfo 높이를 명시적으로 수정. SessionGroupRowSessionTable에서 단일 세션(null recurrenceType)의 날짜 처리 및 key 생성을 개선하여 null 안전성 강화.
UI 컴포넌트 - 편집 및 훅
src/components/admin/schedule/session/SessionTabContent.tsx, src/hooks/admin/useSessionMutations.tsx, src/hooks/queries/admin/useAdminScheduleQueries.ts
SessionTabContenthandleOpenEdit에서 단일 세션 래퍼를 감지하여 직접 세션으로 리다이렉트. useSessionMutations에서 force-confirm 다이얼로그에 title 추가 및 삭제 작업의 메시지 업데이트. useAdminScheduleQueries에서 SESSION_FORCE_REQUIRED_CODES 목록으로 다중 코드 체크 지원.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • dalzzy
  • woneeeee
  • nabbang6

Poem

🐰 단일 세션이여, 이제 null을 두려워 말라
그룹의 속박을 벗고 자유로워졌으니
안전한 렌더링, 명확한 삭제
날짜의 혼동은 옛날이여, 안녕!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive 제목이 이슈 번호만 포함하고 변경 사항의 주요 내용을 명확하게 설명하지 않아 모호합니다. PR 제목을 더 구체적으로 수정하세요. 예: '[Fix] #87: 어드민 세션 UI 및 삭제 경고 추가' 같이 주요 변경 사항을 명시하세요.
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed PR 설명이 템플릿 구조를 따르고 이슈 번호와 주요 변경 사항을 포함하고 있으나, 스크린샷은 제공되지 않았습니다.
Linked Issues check ✅ Passed PR의 코드 변경 사항들이 이슈 #87의 모든 요구사항을 충족합니다: 단일 세션 UI 수정, 날짜 검증, null 데이터 방어 처리가 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 코드 변경 사항이 이슈 #87의 범위 내에 있으며, 요구되지 않은 변경이 없습니다.

✏️ 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 fix#87/어드민-qa

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
Review rate limit: 0/1 reviews remaining, refill in 49 minutes and 43 seconds.

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

@github-actions
Copy link
Copy Markdown

🤖 Claude 테스트 제안

모델: claude-sonnet-4-6 | 토큰: 0 입력 / 0 출력

변경된 컴포넌트에 대해 Claude가 생성한 테스트 코드입니다. 검토 후 적합한 부분만 사용하세요.

src/components/admin/attendance/AttendanceCard.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/attendance/AttendancePageContent.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/attendance/AttendanceSessionCard.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/layout/Header.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/layout/LNB.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


이 코멘트는 Claude API를 통해 자동 생성되었습니다. 반드시 검토 후 사용하세요.

@github-actions
Copy link
Copy Markdown

PR 테스트 결과

Jest: 통과

🎉 모든 테스트를 통과했습니다!

@github-actions
Copy link
Copy Markdown

PR 검증 결과

TypeScript: 통과
ESLint: 통과
Prettier: 실패
Build: 통과

⚠️ 일부 검증에 실패했습니다. 확인 후 수정해주세요.

@github-actions
Copy link
Copy Markdown

구현한 기능 Preview: https://weeth-k7ye6gcg7-weethsite-4975s-projects.vercel.app

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 (3)
src/components/admin/layout/LNB.tsx (1)

57-66: 주석 처리된 moveNavItems 블록은 완전 삭제를 권장합니다.

Line 57~66은 현재 사용되지 않는 죽은 코드라, 남겨두면 이후 유지보수 시 혼선을 유발합니다. 이번 PR 범위에서 제거하는 편이 깔끔합니다.

정리 제안 diff
-  // const moveNavItems = [
-  //   {
-  //     id: 'manual',
-  //     icon: AdminFileoutIcon,
-  //     label: '운영진 매뉴얼',
-  //     path: 'https://weeth-develop-2.s3.ap-northeast-2.amazonaws.com/Weeth_%E1%84%80%E1%85%AA%E1%86%AB%E1%84%85%E1%85%B5%E1%84%8C%E1%85%A1_%E1%84%86%E1%85%A6%E1%84%82%E1%85%B2%E1%84%8B%E1%85%A5%E1%86%AF_v3.pdf',
-  //     external: true,
-  //     openInWindow: true,
-  //   },
-  // ];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/admin/layout/LNB.tsx` around lines 57 - 66, Remove the dead,
commented-out moveNavItems block from src/components/admin/layout/LNB.tsx:
locate the commented const moveNavItems declaration and its object entries (id:
'manual', icon: AdminFileoutIcon, label, path, external, openInWindow) and
delete the entire commented section so no unused/commented navigation config
remains in the file.
src/components/admin/schedule/session/SessionTable.tsx (1)

72-72: index 기반 key fallback은 가능하면 피하는 편이 안전합니다.

groupId와 첫 세션 id가 모두 없을 때 index를 쓰면 목록 재정렬 시 row 상태가 섞일 수 있습니다. 도메인 값 기반 fallback으로 바꾸는 것을 권장합니다.

예시 수정안
-              key={group.groupId ?? `single-${group.sessions[0]?.id ?? index}`}
+              key={
+                group.groupId ??
+                `single-${group.sessions[0]?.id ?? `${group.startDate}-${group.endDate ?? group.startDate}-${group.title}`}`
+              }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/admin/schedule/session/SessionTable.tsx` at line 72, The key
prop in SessionTable.tsx currently falls back to the unstable loop index
(key={group.groupId ?? `single-${group.sessions[0]?.id ?? index}`}); replace
this index-based fallback with a stable domain-derived identifier (for example
concatenate available stable fields such as the first session's id, start time,
roomId or a persistent group UUID) so keys remain stable across reorders; update
the key expression to use group.groupId if present, otherwise build a
deterministic string from group.sessions[0]?.id + group.sessions[0]?.startsAt
(or another stable session property) or a stored groupId generated when the
group is created.
src/components/admin/layout/LNBClubInfo.tsx (1)

22-23: AvatarImage alt는 항상 string으로 내려가게 방어 로직 추가 권장

alt={club?.name}club 또는 club.nameundefined일 수 있어, 접근성/린트 규칙에 따라 문제가 될 여지가 있습니다.
최소한 alt가 undefined로 떨어지지 않도록 club?.name ?? '' 또는 기본 라벨을 넣어주세요.

🛠️ Proposed fix
-      <AvatarImage src={club?.profileImageUrl ?? undefined} alt={club?.name} />
+      <AvatarImage
+        src={club?.profileImageUrl ?? undefined}
+        alt={club?.name ?? ''}
+      />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/admin/layout/LNBClubInfo.tsx` around lines 22 - 23, The
AvatarImage alt prop can be undefined; update the usage of AvatarImage so its
alt always receives a string (e.g., change alt={club?.name} to alt={club?.name
?? ''} or a default label). Locate AvatarImage in LNBClubInfo (next to
AvatarFallback) and ensure the defensive fallback prevents undefined values
being passed to the alt prop.
🤖 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/components/admin/layout/LNBClubInfo.tsx`:
- Around line 15-19: The root container in LNBClubInfo.tsx hardcodes height with
h-[142px]; replace this with a design-token class or adjust layout to use
existing spacing tokens. If 142px is required, add a new height token (e.g.,
--height-142) to the design tokens and use its generated Tailwind class in the
className string (the JSX div using cn(...) and the collapsed branch), otherwise
refactor the component layout to compose existing spacing tokens (e.g.,
spacing-700/800 combos) instead of h-[142px] so the className no longer contains
the hardcoded h-[142px].

In `@src/components/admin/schedule/session/SessionTabContent.tsx`:
- Around line 49-57: Prettier formatting failed for this file; run Prettier and
reformat the block around isSingleSessionWrapper/isSessionGroup logic so the
file passes `prettier --check`—ensure consistent spacing, semicolons, and line
breaks around the const isSingleSessionWrapper declaration and the if
(isSingleSessionWrapper) { setEditTarget({ target: target.sessions[0]! });
return; } block (references: isSingleSessionWrapper, isSessionGroup,
setEditTarget, target.sessions) and commit the formatted file.

---

Nitpick comments:
In `@src/components/admin/layout/LNB.tsx`:
- Around line 57-66: Remove the dead, commented-out moveNavItems block from
src/components/admin/layout/LNB.tsx: locate the commented const moveNavItems
declaration and its object entries (id: 'manual', icon: AdminFileoutIcon, label,
path, external, openInWindow) and delete the entire commented section so no
unused/commented navigation config remains in the file.

In `@src/components/admin/layout/LNBClubInfo.tsx`:
- Around line 22-23: The AvatarImage alt prop can be undefined; update the usage
of AvatarImage so its alt always receives a string (e.g., change
alt={club?.name} to alt={club?.name ?? ''} or a default label). Locate
AvatarImage in LNBClubInfo (next to AvatarFallback) and ensure the defensive
fallback prevents undefined values being passed to the alt prop.

In `@src/components/admin/schedule/session/SessionTable.tsx`:
- Line 72: The key prop in SessionTable.tsx currently falls back to the unstable
loop index (key={group.groupId ?? `single-${group.sessions[0]?.id ?? index}`});
replace this index-based fallback with a stable domain-derived identifier (for
example concatenate available stable fields such as the first session's id,
start time, roomId or a persistent group UUID) so keys remain stable across
reorders; update the key expression to use group.groupId if present, otherwise
build a deterministic string from group.sessions[0]?.id +
group.sessions[0]?.startsAt (or another stable session property) or a stored
groupId generated when the group is created.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5a99c435-7814-4020-bcdd-3f1e3923447a

📥 Commits

Reviewing files that changed from the base of the PR and between 5eda075 and 0feafaf.

📒 Files selected for processing (9)
  • src/components/admin/layout/LNB.tsx
  • src/components/admin/layout/LNBClubInfo.tsx
  • src/components/admin/schedule/session/SessionGroupRow.tsx
  • src/components/admin/schedule/session/SessionTabContent.tsx
  • src/components/admin/schedule/session/SessionTable.tsx
  • src/constants/admin/schedule.constants.ts
  • src/hooks/admin/useSessionMutations.tsx
  • src/hooks/queries/admin/useAdminScheduleQueries.ts
  • src/types/admin/session.d.ts

Comment on lines 15 to 19
<div
className={cn(
'border-line bg-container-neutral flex h-30 items-start border-b py-400',
'border-line bg-container-neutral flex h-[142px] items-start border-b py-400',
collapsed ? 'justify-center' : 'flex-col gap-300 px-400',
)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== usages: h-[142px] =="
rg -n "h-\\[142px\\]" -S src || true

echo
echo "== tailwind config candidates =="
fd -t f -i "tailwind.config.*" . | head -n 20

echo
echo "== token-related keys in tailwind config (height/spacing) =="
for f in $(fd -t f -i "tailwind.config.*" . | head -n 5); do
  echo "---- $f ----"
  rg -n "theme\\.extend\\b|height\\b|spacing\\b" "$f" || true
done

Repository: Team-Weeth/weeth-client

Length of output: 321


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Looking for tailwind config in various locations ==="
find . -type f \( -name "*.config.*" -o -name "tailwind*" \) 2>/dev/null | grep -E "(js|ts|json|css)" | head -20

echo
echo "=== Checking package.json for tailwind config reference ==="
cat package.json | jq '.tailwindConfig, .dependencies | select(. != null)' 2>/dev/null || echo "No tailwindConfig in package.json"

echo
echo "=== Looking for CSS files with token/design system definitions ==="
fd -t f -e css | head -20

echo
echo "=== Searching for theme or token definitions ==="
rg "theme\s*[:{]|--.*-\d{2,3}|h-\[" -l --type-list | head -15

echo
echo "=== Checking the specific file for imports and context ==="
head -30 src/components/admin/layout/LNBClubInfo.tsx

Repository: Team-Weeth/weeth-client

Length of output: 3436


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== postcss.config.mjs ==="
cat postcss.config.mjs

echo
echo "=== src/app/globals.css (first 100 lines) ==="
head -100 src/app/globals.css

echo
echo "=== Search for '142' in codebase ==="
rg "142" -n src --type ts --type tsx | head -20

echo
echo "=== Look for design token or theme directories ==="
fd -t d -e "design\|token\|theme" . --exclude node_modules | head -20

Repository: Team-Weeth/weeth-client

Length of output: 3066


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Full src/app/globals.css ==="
wc -l src/app/globals.css

echo
echo "=== Last part of globals.css (lines 100-200+) ==="
tail -n +100 src/app/globals.css | head -150

echo
echo "=== Search for spacing/height token definitions ==="
rg "spacing|space-|gap-|padding|height|h-" src/app/globals.css -A 2 || echo "No spacing/height tokens found"

echo
echo "=== Look at full LNBClubInfo.tsx context ==="
cat -n src/components/admin/layout/LNBClubInfo.tsx

Repository: Team-Weeth/weeth-client

Length of output: 10705


h-[142px] 하드코딩은 디자인 토큰 클래스로 교체 필요

루트 컨테이너 높이를 h-[142px](임의 값)로 고정했는데, 코딩 가이드라인상 Tailwind는 디자인 토큰 클래스를 우선하고 하드코딩을 피하도록 규정하고 있습니다. 현재 디자인 시스템에는 --spacing-800: 40px까지의 spacing 토큰만 정의되어 있으며, 142px에 해당하는 height 토큰이 없습니다.

다음 중 하나를 선택하여 진행해주세요:

  • 142px가 의도된 고정 높이라면, 새 height 토큰(예: --height-142)을 추가한 후 토큰 클래스로 교체
  • 또는 기존 spacing 토큰 조합으로 컴포넌트 레이아웃을 재검토
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/admin/layout/LNBClubInfo.tsx` around lines 15 - 19, The root
container in LNBClubInfo.tsx hardcodes height with h-[142px]; replace this with
a design-token class or adjust layout to use existing spacing tokens. If 142px
is required, add a new height token (e.g., --height-142) to the design tokens
and use its generated Tailwind class in the className string (the JSX div using
cn(...) and the collapsed branch), otherwise refactor the component layout to
compose existing spacing tokens (e.g., spacing-700/800 combos) instead of
h-[142px] so the className no longer contains the hardcoded h-[142px].

Comment thread src/components/admin/schedule/session/SessionTabContent.tsx
@github-actions
Copy link
Copy Markdown

🤖 Claude 테스트 제안

모델: claude-sonnet-4-6 | 토큰: 0 입력 / 0 출력

변경된 컴포넌트에 대해 Claude가 생성한 테스트 코드입니다. 검토 후 적합한 부분만 사용하세요.

src/components/admin/attendance/AttendanceCard.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/attendance/AttendancePageContent.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/attendance/AttendanceSessionCard.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/layout/Header.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


src/components/admin/layout/LNB.tsx

오류: Your credit balance is too low to access the Anthropic API. Please go to Plans & Billing to upgrade or purchase credits.


이 코멘트는 Claude API를 통해 자동 생성되었습니다. 반드시 검토 후 사용하세요.

@github-actions
Copy link
Copy Markdown

PR 테스트 결과

Jest: 통과

🎉 모든 테스트를 통과했습니다!

@github-actions
Copy link
Copy Markdown

구현한 기능 Preview: https://weeth-c2awsqni5-weethsite-4975s-projects.vercel.app

@github-actions
Copy link
Copy Markdown

PR 검증 결과

TypeScript: 통과
ESLint: 통과
Prettier: 통과
Build: 통과

🎉 모든 검증을 통과했습니다!

@JIN921 JIN921 merged commit 6d0415d into develop Apr 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞 BugFix Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: 어드민 qa

1 participant