🐛 지원 대학 수정 모달에서 정원 외 필드가 채워지지 않던 문제 수정 - #620
Conversation
수정 모달을 열 때 검색 목록(search/text) 응답의 값으로 폼을 채웠는데,
그 응답에는 정원(studentCapacity) 외 필드가 애초에 포함되어 있지
않아 나머지 항목은 값이 있어도 항상 비어 보였다.
GET /admin/univ-apply-infos/{id} 단건 조회 API(백엔드 #817)를
호출해 상세 정보를 받아온 뒤 폼을 채우도록 수정했다.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EwpgqdNTrn8dGDr7g7WnYg
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Walkthrough선택한 대학 지원 정보의 상세 조회 API를 추가했습니다. 수정 모달은 조회 상태에 따라 로딩, 오류 또는 전체 수정 폼을 표시합니다. 상세 데이터 ID가 변경될 때만 수정 폼과 추가 정보 JSON을 초기화합니다. Estimated code review effort: 3 (Moderate) | ~20 minutes
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: af1b715527
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| detailsForAccommodation: detail.detailsForAccommodation, | ||
| }); | ||
| setEditExtraInfoText(detail.extraInfo ? JSON.stringify(detail.extraInfo, null, 2) : ""); | ||
| }, [editDetailQuery.data?.id]); |
There was a problem hiding this comment.
Refresh cached details when reopening the same record
After an administrator saves a record and reopens it, React Query immediately returns the cached pre-update detail and then refetches it because the detail query was neither updated nor invalidated on mutation success. The effect runs for the cached value when the modal reopens, but the network response has the same id, so this dependency suppresses the second run and leaves the form showing stale values; saving again can silently overwrite the previous update. Update/remove the detail cache after mutation or key form initialization to each modal session while still protecting active edits from focus refetches.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/admin/src/components/features/univ-apply-infos/tabs/UnivApplyInfoManageTab.tsx`:
- Around line 107-127: 수정 성공 처리에서 검색 쿼리뿐 아니라 상세 쿼리도 무효화하도록 업데이트하세요. 수정 대상인
`["univ-apply-infos", "detail", editingId]`를 `invalidateQueries`에 포함해 재조회 시 최신
데이터를 사용하고, `editDetailQuery.data?.id`가 동일해도 최신 값으로 폼이 갱신되도록 하세요. 동일 항목을 수정한 뒤 다시
열었을 때 최신 값이 표시되는 검증도 추가하세요.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1d93cf0e-541e-4c8e-8008-ab0bb36813bb
📒 Files selected for processing (2)
apps/admin/src/components/features/univ-apply-infos/tabs/UnivApplyInfoManageTab.tsxapps/admin/src/lib/api/admin.ts
| const editDetailQuery = useQuery({ | ||
| queryKey: ["univ-apply-infos", "detail", editingId], | ||
| queryFn: () => adminApi.getUnivApplyInfo(editingId as number), | ||
| enabled: editingId !== undefined, | ||
| }); | ||
|
|
||
| // biome-ignore lint/correctness/useExhaustiveDependencies: 조회된 상세 정보의 id가 바뀔 때만 폼을 채워야 하며, 리페치로 데이터 참조가 바뀌어도 수정 중인 값을 덮어쓰면 안 됨 | ||
| useEffect(() => { | ||
| if (!editDetailQuery.data) return; | ||
| const detail = editDetailQuery.data; | ||
| setEditForm({ | ||
| studentCapacity: detail.studentCapacity, | ||
| semesterAvailableForDispatch: detail.semesterAvailableForDispatch, | ||
| semesterRequirement: detail.semesterRequirement, | ||
| detailsForLanguage: detail.detailsForLanguage, | ||
| gpaRequirement: detail.gpaRequirement, | ||
| gpaRequirementCriteria: detail.gpaRequirementCriteria, | ||
| detailsForAccommodation: detail.detailsForAccommodation, | ||
| }); | ||
| setEditExtraInfoText(detail.extraInfo ? JSON.stringify(detail.extraInfo, null, 2) : ""); | ||
| }, [editDetailQuery.data?.id]); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE='apps/admin/src/components/features/univ-apply-infos/tabs/UnivApplyInfoManageTab.tsx'
ast-grep outline "$FILE" --items all
rg -n -C 8 'editDetailQuery|updateMutation|invalidateQueries|setEditModal' "$FILE"Repository: solid-connection/solid-connect-web
Length of output: 8823
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE='apps/admin/src/types/admin.ts'
# Locate adminApi definition even if filename differs.
ast-grep outline apps/admin/src --items all 2>/dev/null | rg -n 'adminApi|getUnivApplyInfo|updateUnivApplyInfo' || true
# Print relevant sections from candidate files.
fd -t f 'admin.*\.(ts|tsx)$' apps/admin/src | while read -r f; do
echo "===== $f ====="
rg -n -C 6 'getUnivApplyInfo|updateUnivApplyInfo|univ-apply-infos|queryKey' "$f" || true
done
# Print exact relevant source ranges from the tab.
sed -n '1,230p' "$FILE" 2>/dev/null || true
sed -n '129,143p' apps/admin/src/components/features/univ-apply-infos/tabs/UnivApplyInfoManageTab.tsxRepository: solid-connection/solid-connect-web
Length of output: 4003
수정 성공 후 상세 쿼리도 무효화하세요.
수정 성공 후 ["univ-apply-infos", "search"]만 invalidateQueries합니다. 같은 항목을 다시 열면 이전 상세 캐시가 폼에 적용될 수 있고, 동일한 detail.id 재조회는 useEffect를 다시 실행하지 않아 최신 값이 표시되지 않습니다.
수정 예시
- onSuccess: async () => {
- await queryClient.invalidateQueries({
- queryKey: ["univ-apply-infos", "search"],
- });
+ onSuccess: async (_response, { id }) => {
+ await Promise.all([
+ queryClient.invalidateQueries({
+ queryKey: ["univ-apply-infos", "search"],
+ }),
+ queryClient.invalidateQueries({
+ queryKey: ["univ-apply-infos", "detail", id],
+ }),
+ ]);
setEditModal({ open: false });
toast.success("지원 대학 정보를 수정했습니다.");
},동일 항목을 수정한 뒤 다시 열어 최신 값이 표시되는 검증도 추가하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@apps/admin/src/components/features/univ-apply-infos/tabs/UnivApplyInfoManageTab.tsx`
around lines 107 - 127, 수정 성공 처리에서 검색 쿼리뿐 아니라 상세 쿼리도 무효화하도록 업데이트하세요. 수정 대상인
`["univ-apply-infos", "detail", editingId]`를 `invalidateQueries`에 포함해 재조회 시 최신
데이터를 사용하고, `editDetailQuery.data?.id`가 동일해도 최신 값으로 폼이 갱신되도록 하세요. 동일 항목을 수정한 뒤 다시
열었을 때 최신 값이 표시되는 검증도 추가하세요.
요약
GET /univ-apply-infos/search/text) 응답 데이터로 폼을 채웠는데, 이 응답에는 목록용 미리보기 필드만 있고 정원 외 상세 필드는 애초에 포함되어 있지 않았음GET /admin/univ-apply-infos/{id}단건 조회 API를 호출해 상세 정보를 받아온 뒤 폼을 채우도록 수정의존성
GET /admin/univ-apply-infos/{id}) 배포 이후 정상 동작. 아직 배포 전이라면 상세 조회가 404로 실패하고 모달에 에러 메시지가 표시됨테스트 플랜
pnpm --filter admin typecheck,lint:check통과 (커밋 시 CI parity 훅으로 확인)pnpm --filter admin build성공 (push 시 CI parity 훅으로 확인)Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
https://claude.ai/code/session_01EwpgqdNTrn8dGDr7g7WnYg