Conversation
Feat(#109) : 홈 및 인증(Auth) 화면 API 연동
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
feat: 원본 자료 조회 팝업 api 추가
* feat: 자료 업로드 isOwn을 실제 로그인 memberId 기준으로 계산 - POST /api/auth/reissue 응답에 이미 오고 있던 userId(=memberId)를 그동안 프론트에서 버리고 있었음 - authApi.reissue/useAuthStore/http_client의 401 재발급 흐름에 memberId를 담아 저장하도록 반영 - upload_api_mapper의 isOwn을 항상 false였던 것에서 uploaderMemberId ↔ 내 memberId 비교로 교체 (mock 인증 상태에선 memberId를 알 수 없어 여전히 false - 실 로그인 후에만 정확하게 동작) * fix: 지식 구조 3D 그래프에서 단일 클러스터가 화면 중심을 벗어나던 문제 수정 카메라는 항상 원점(0,0,0)을 바라보는데, 클러스터가 하나뿐인 경우(현재 실 API는 항상 단일 클러스터만 줌)에도 원점에서 CLUSTER_ANCHOR_RADIUS(26)만큼 떨어진 곳에 앵커를 배치하고 있었음. 그 결과 전체 노드 뭉치가 화면 중심을 벗어나 보이고, 중요도가 높아 원점 쪽으로 당겨진 노드 하나만 화면 중앙에 고립된 것처럼 보였음 (실사용 중 스크린샷으로 발견). 클러스터가 하나뿐이면 원점에 바로 앵커링하도록 수정.
카메라는 항상 원점(0,0,0)을 바라보는데, 클러스터가 하나뿐인 경우(현재 실 API는 항상 단일 클러스터만 줌)에도 원점에서 CLUSTER_ANCHOR_RADIUS(26)만큼 떨어진 곳에 앵커를 배치하고 있었음. 그 결과 전체 노드 뭉치가 화면 중심을 벗어나 보이고, 중요도가 높아 원점 쪽으로 당겨진 노드 하나만 화면 중앙에 고립된 것처럼 보였음 (실사용 중 스크린샷으로 발견). 클러스터가 하나뿐이면 원점에 바로 앵커링하도록 수정.
- 전체 스터디(studyId 없음) 선택 시 내부적으로 null로 처리되어 쿼리가 완전히 비활성화(enabled: false)되는 문제 해결" -m "- 백엔드 명세서 요구사항에 맞추어 전체 선택 시 studyId 파라미터로 -1을 전달하도록 파싱 로직 개선
- [StudyPage] 스터디 조회 오류 시 무조건 홈으로 리디렉션하던 로직 수정 - [StudyPage] 403(권한 없음), 404(찾을 수 없음) 에러일 때만 홈으로 이동하고, 일반적인 네트워크/서버 오류 시에는 재시도(refetch) 버튼이 포함된 EmptyState 렌더링 - [useMyStudies] 동시 요청(Race Condition) 시 오래된 응답이 최신 목록을 덮어쓰는 문제 해결 - [useMyStudies] useRef와 AbortController를 도입하여 이전 요청을 안전하게 취소하고 가장 마지막 요청만 상태에 반영하도록 수정
Feat(#109) : 홈 및 인증(Auth) 화면 API 연동 (삭제 기능 추가)
Feat(#130) : 홈 화면 '전체 스터디' 팀 활동 조회 비활성화 버그 수정
- /api/home/materials, /questions, /answers, /reports API 통신 로직 추가 - 기존 하드코딩된 더미 데이터(Mock) 완전 제거 - 응답 데이터 스펙(Swagger)에 맞춰 프론트엔드 모델 매핑 로직 신규 작성
- ProfileMenu 컴포넌트 신규 구현 및 드롭다운 연동 - 공통 레이아웃(AppLayout) 우측 상단에 프로필 메뉴 UI 배치 - 로그아웃 클릭 시 스토어 초기화 및 /login 페이지 리다이렉트 처리 - 프로필 메뉴가 페이지 콘텐츠와 겹치지 않도록 flex 컨테이너 구조 개선
- 스터디 상세 페이지 헤더에 '설정' 버튼 및 StudySettingsModal UI 신규 구현 - 스터디 기본 정보(이름, 시작일, 설명) 수정 API 연동 - 상호 검토 리뷰어 인원 수(1~10명) 변경 API 연동 - 새로운 팀원 초대 링크 발급 및 클립보드 복사 연동 - 스터디 종료 처리 API 연동 및 상태 즉각 갱신(종료 시 읽기 전용 상태 전환 유지) - React Hook Form 및 Zod를 활용한 설정 폼 입력값 검증 처리
- POST /api/study/{studyId}/invitation API의 응답 데이터가 객체가 아닌 단일 문자열(String) 토큰으로 반환되는 백엔드 스펙에 맞추어 `studyApi.getInvitationToken` 리턴 타입 수정
- 설정 모달에서 토큰 할당 시 `res.token`이 아닌 `res` 자체를 상태에 저장하도록 수정하여 화면에 링크가 정상 노출되도록 픽스
- Zod 검증 에러 할당 로직에서 발생하던 TS 인덱싱 에러(any 유추) 방지를 위한 명시적 형변환(String) 추가
- useMaterialTodos, useQuestionTodos, useReportTodos의 useState/useEffect/AbortController 수동 관리 로직을 useQuery로 전환 - homeApi.getAnswers 추가 및 AnswerInfo, AnswerDetailRes 타입 정의 - homeApi 전체 함수에 signal 파라미터를 추가하여 TanStack Query 요청 취소를 Axios까지 연동 - homeApi.MaterialInfo 타입을 실제 Swagger 응답 필드(studyMaterialId, dataTitle, uploaderName)에 맞게 수정 - 읽음 처리 상태를 Zustand(useHomeTodoStore)로 분리, markAsRead 식별자를 to에서 id로 변경하여 질문/답글 중복 읽음 버그 수정 - rawDate 필드 추가 후 원시 타임스탬프 기반 정렬로 연도 경계 정렬 버그 수정 - API에 상태 필드가 없어 항상 비어있던 '재업로드 필요' 필터 탭 제거
- useMyTodo의 queryFn에 homeApi.getMyTodos를 직접 전달 시 signal 타입 불일치 에러 수정 (({ signal }) => homeApi.getMyTodos(signal))
- MaterialDetailModal에서 삭제된 '재업로드 필요' 필터 탭 참조 제거
Feat(#133) : 홈 내 할 일(Todo) 상세 모달 실제 API 연동
- UpdateStudyReq 스펙에 맞게 optional인 description 폼 필드 값이 없을 경우 빈 문자열('')로 전달하도록 수정하여 빌드 에러(TS2345) 해결
- studyApi.getStudyDetail 응답 타입 및 공통 Study 모델에 startDate, members 필드 추가 - Header 공통 컴포넌트가 children을 받아 커스텀 메타데이터를 렌더링할 수 있도록 확장 - StudyPage의 헤더에 진행 상태 뱃지, 현재 주차, 시작일, 멤버 프로필(Avatar 겹침 UI) 적용 - ReviewPage에서 하드코딩된 mockStudies 대신 실제 API(useStudyDetail) 연동 - 사용이 완료된 하드코딩된 mockStudies 데이터 전체 삭제
- CodeRabbit 리뷰 피드백 반영 - useStudyDetail의 isLoading 및 error 상태를 페이지 전체의 isLoading과 errorMessage 렌더링에 통합 반영 - studyData가 성공적으로 로드되고 isActive === true임이 확인되기 전까지 effectiveIsReadOnly를 true로 강제하여, 종료된 스터디 또는 로딩 중일 때 부적절한 검토 액션 및 제출(handleSubmit) 차단
- StudySettingsModal이 기존 시작일, 설명, 리뷰어 수 데이터를 받아 폼 기본값으로 초기화하도록 수정 (의도치 않은 덮어쓰기 방지) - getStudyDetail 응답 스키마에 startDate, description, reviewerCount 필드 추가 - navigator.clipboard.writeText 복사 실패 시 에러 토스트를 표시하도록 try/catch 예외 처리 추가 - closeStudyMutation의 onSuccess에서 invalidateQueries를 Promise.all로 반환하여 캐시 갱신 완료를 보장
Feat(#136) : 우측 상단 프로필 메뉴 및 로그아웃 기능 연동
Feat(#138) : 스터디 설정(초대/수정/종료) 기능 연동 및 종료 모드 처리
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
|
@copilot resolve the merge conflicts in this pull request |
|
@mint0326 I can’t apply these changes because the pull request’s branch is the repository’s default branch, which I’m not allowed to push to directly. You can ask me to create a new pull request with the requested changes instead and I'll open a separate PR on a new branch. |
|
@copilot resolve the merge conflicts in this pull request |
|
@mint0326 I can’t apply these changes because the pull request’s branch is the repository’s default branch, which I’m not allowed to push to directly. You can ask me to create a new pull request with the requested changes instead and I'll open a separate PR on a new branch. |
There was a problem hiding this comment.
Pull request overview
인증/스터디/홈/질문/리포트/주간기록 등 여러 도메인에서 mock 기반 동작을 실제 API + TanStack Query 기반으로 전환하고, 스터디 설정/종료 요약, 질문 이미지 처리, 프로필 메뉴 등 UI 기능을 확장한 변경입니다.
Changes:
- axios
httpClient에 401 자동 재발급(동시 요청 단일화 포함) 로직을 추가하고useAuthStore에memberId를 도입 - 스터디 화면(질문/주간기록/주간리포트)과 홈 투두(질문/답글/자료/리포트), 팀 활동을 실제 API/쿼리 기반으로 전환하며 관련 mapper·hooks·테스트 추가
- UI 공통 컴포넌트(Modal/Header/Layout) 확장 및 프로필 메뉴/스터디 설정 메뉴/원본자료 팝업 등 신규 UI 추가, 일부 mock/문서/예시 env 정리
Reviewed changes
Copilot reviewed 84 out of 84 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared/ui/ProfileMenu.tsx | 프로필 드롭다운(로그아웃) UI 추가 |
| src/shared/ui/Modal.tsx | overlay/title/body 클래스 커스터마이즈 옵션 추가 |
| src/shared/ui/Layout.tsx | 레이아웃 상단에 ProfileMenu 배치 |
| src/shared/ui/index.ts | ProfileMenu export 추가 |
| src/shared/ui/Header.tsx | Header에 children 슬롯 추가 |
| src/shared/types/stology.ts | Study/Question 타입 확장(멤버/이미지 등) |
| src/shared/stores/useAuthStore.ts | memberId 도입 및 토큰 기반 login/reissue 반영 |
| src/shared/stores/useAuthStore.test.ts | memberId/reissue 케이스 테스트 보강 |
| src/shared/mocks/weeklyRecords.ts | 주간기록 mock 제거 |
| src/shared/mocks/studies.ts | 스터디 mock 정리(탭 중심) |
| src/shared/hooks/useMyStudies.ts | 내 스터디 조회를 React Query 기반으로 전환 |
| src/shared/hooks/useMyStudies.test.ts | useMyStudies 테스트 신규 추가 |
| src/shared/api/weekly_reports.ts | 주간 리포트 API 클라이언트 신규 추가 |
| src/shared/api/weekly_records.ts | 주간 기록 API 클라이언트 신규 추가 |
| src/shared/api/study.ts | 스터디 업데이트/종료/초대 토큰 등 API 확장 |
| src/shared/api/questions.ts | 질문/답글 API 및 multipart 폼 전송 추가 |
| src/shared/api/questions.test.ts | 질문/답글 mutation API 테스트 신규 |
| src/shared/api/http_client.ts | 401 재발급/재시도 인터셉터 및 단일화 추가 |
| src/shared/api/http_client.test.ts | 재발급 동작/동시성 테스트 신규 |
| src/shared/api/home.ts | 홈 API 스키마/AbortSignal 지원 및 answers 추가 |
| src/shared/api/auth.ts | ReissueRes 필드 순서 정리(userId/accessToken) |
| src/pages/study/upload/model/upload_api_mapper.ts | memberId 기반 isOwn 계산 추가 |
| src/pages/study/upload/model/upload_api_mapper.test.ts | upload mapper 테스트 신규 |
| src/pages/study/upload/MaterialUploadPage.tsx | 업로드/빈상태/종료 스터디 UI 문구 및 구조 변경 |
| src/pages/study/upload/MaterialUploadPage.test.tsx | 업로드 페이지 테스트 갱신 |
| src/pages/study/upload/MaterialUploadForm.tsx | zod 기반 검증/레이아웃 조정 및 UX 개선 |
| src/pages/study/upload/hooks/useUploadedMaterials.ts | memberId를 쿼리키에 포함해 isOwn 반영 |
| src/pages/study/StudyPage.tsx | 스터디 상세 에러 처리/종료 요약/설정 메뉴/탭별 실제 데이터 연결 |
| src/pages/study/reports/WeeklyReportTeamStats.tsx | 팀 통계 헤더 UI 정리 |
| src/pages/study/reports/WeeklyReportPage.tsx | mock 리포트 제거 및 전달된 report만 표시 |
| src/pages/study/reports/WeeklyReportPage.test.tsx | report 주입 형태로 테스트 수정 |
| src/pages/study/reports/model/weekly_report_api_mapper.ts | 리포트 API → 화면 모델 mapper 신규 |
| src/pages/study/reports/model/weekly_report_api_mapper.test.ts | 리포트 mapper 테스트 신규 |
| src/pages/study/reports/hooks/useWeeklyReport.ts | 주간 리포트 query hook 신규 |
| src/pages/study/records/WeeklyRecordsPage.tsx | mock 기록 제거 및 API 기반 props/연동 방식 변경 |
| src/pages/study/records/WeeklyRecordsPage.test.tsx | 주간 기록 페이지 빈 상태 테스트 신규 |
| src/pages/study/records/WeeklyRecordItem.tsx | 개념 펼침 시 원본자료 API 조회/재시도 UI 추가 |
| src/pages/study/records/model/weekly_records_api_mapper.ts | 기록 API → 화면 모델 mapper 신규 |
| src/pages/study/records/model/weekly_records_api_mapper.test.ts | 기록 mapper 테스트 신규 |
| src/pages/study/records/hooks/useWeeklyRecords.ts | 주간 기록 query hook 신규 |
| src/pages/study/records/hooks/useWeeklyRecordMaterials.ts | 노드별 원본자료 query hook 신규 |
| src/pages/study/questions/QuestionsPage.tsx | mock 제거, 서버 데이터/상세 로딩/이미지 토큰 처리/삭제 로딩 등 반영 |
| src/pages/study/questions/QuestionsPage.test.tsx | 초기 데이터 주입 및 비동기 동작에 맞게 테스트 갱신 |
| src/pages/study/questions/QuestionFormModal.tsx | submit 비동기/로딩 처리 및 닫기 차단 |
| src/pages/study/questions/QuestionDetailPanel.tsx | 답글 이미지 첨부/로딩, 인라인 이미지 렌더링 추가 |
| src/pages/study/questions/model/question_mutation_content.ts | 이미지 토큰 strip/build 유틸 신규 |
| src/pages/study/questions/model/question_mutation_content.test.ts | 토큰 유틸 테스트 신규 |
| src/pages/study/questions/model/question_api_mapper.ts | 질문 API → 화면 모델 mapper 신규 |
| src/pages/study/questions/model/question_api_mapper.test.ts | 질문 mapper 테스트 신규 |
| src/pages/study/questions/hooks/useQuestions.ts | 질문 목록/상세 query hooks 및 queryKey 정의 |
| src/pages/study/questions/hooks/useQuestionMutations.ts | 질문/답글 mutation + invalidate/toast 처리 |
| src/pages/study/knowledge/KnowledgeGraphPage.tsx | 그래프 설명 텍스트 제거(렌더 구조 변경) |
| src/pages/study/knowledge/KnowledgeGraphPage.test.tsx | 원본자료 팝업 플로우에 맞게 테스트 갱신 |
| src/pages/study/knowledge/hooks/useKnowledgeNodeMaterials.ts | 노드 원본자료를 weekly_records API로 조회하도록 변경 |
| src/pages/study/knowledge/engine/graph_layout.ts | 단일 클러스터일 때 원점 앵커링 처리 |
| src/pages/study/knowledge/engine/graph_layout.test.ts | 단일 클러스터 centroid 테스트 추가 |
| src/pages/study/knowledge/components/SourceMaterialsModal.tsx | 원본 자료 목록 모달 신규 추가 |
| src/pages/study/knowledge/components/KnowledgeNodeInspector.tsx | 원본자료 팝업 버튼/목록 UI 개선 및 모달 연동 |
| src/pages/study/hooks/useStudySettings.ts | 스터디 설정(수정/검토인원/종료/초대) 훅 신규 |
| src/pages/study/components/StudySettingsMenu.tsx | 스터디 설정 메뉴/모달 UI 신규 추가 |
| src/pages/study/components/StudySettingsMenu.test.tsx | 설정 메뉴 및 종료 요약 테스트 신규 |
| src/pages/study/components/StudyEndedSummary.tsx | 스터디 종료 요약 화면 신규 |
| src/pages/review/ReviewPage.tsx | 스터디 종료 여부를 실 API 기반으로 판단하도록 변경 |
| src/pages/review/ReviewPage.test.tsx | 숫자형 studyId 기반으로 테스트 갱신 |
| src/pages/login/LoginPage.tsx | 로그인 UI 개편 및 테스트 로그인 버튼 추가 |
| src/pages/login/LoginPage.test.tsx | 로고/문구 노출 테스트 추가 |
| src/pages/login/components/InviteNoticeCard.tsx | 초대 안내 카드 제거 |
| src/pages/invite/hooks/useInvite.ts | Study 타입 변경에 맞춰 isNew/members 채움 |
| src/pages/home/store/useHomeTodoStore.ts | 홈 투두 읽음 상태 zustand store 추가 |
| src/pages/home/hooks/useTeamActivity.ts | 팀 활동 무한스크롤을 API 기반으로 전환 및 표시 문구 개선 |
| src/pages/home/hooks/useReportTodos.ts | 리포트 투두를 API 기반으로 전환 |
| src/pages/home/hooks/useQuestionTodos.ts | 질문/답글 투두를 API + 읽음 store 기반으로 전환 |
| src/pages/home/hooks/useMyTodo.ts | myTodos API 호출에 AbortSignal 전달 |
| src/pages/home/hooks/useMaterialTodos.ts | 자료 투두를 API 기반으로 전환 및 상태명 정리 |
| src/pages/home/HomePage.tsx | active 스터디만 노출하고 각 상세 모달에 activeStudyIds 전달 |
| src/pages/home/HomePage.test.tsx | QueryClientProvider 적용 및 모달 오픈 테스트로 변경 |
| src/pages/home/components/TeamActivityPanel.tsx | 팀 활동 패널 안내 문구 제거 및 레이아웃 미세조정 |
| src/pages/home/components/ReportDetailModal.tsx | 리포트 상세 모달을 activeStudyIds 기반 데이터로 전환 |
| src/pages/home/components/QuestionDetailModal.tsx | 질문 상세 모달을 activeStudyIds 기반 데이터로 전환 |
| src/pages/home/components/MaterialDetailModal.tsx | 자료 상세 모달을 activeStudyIds 기반 데이터로 전환 |
| src/pages/home/components/CreateStudyModal.tsx | 생성 후 myStudies invalidate 및 문구/필드 안내 정리 |
| docs/onboarding/domain/study.md | 원본 자료 팝업 플로우 문서 반영 |
| .env.example | 예시 env 제거 |
Suppressed comments (2)
src/shared/api/http_client.test.ts:21
- afterEach에서도
memberId가 초기화되지 않아 테스트 간 상태가 남을 수 있습니다. 다른 필드들과 같이memberId: null로 리셋해 주세요.
src/shared/ui/ProfileMenu.tsx:46 - 드롭다운 컨테이너가
role="menu"가 아니라서 내부role="menuitem"이 의미를 잃습니다. 최소한 메뉴 컨테이너에role="menu"/id를 부여해 주세요.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const numericStudyId = studyId && studyId !== 'all' ? Number(studyId) : -1; | ||
|
|
||
| const { data, isLoading, error, hasNextPage, fetchNextPage, isFetchingNextPage } = | ||
| useInfiniteQuery({ | ||
| queryKey: ['teamActivity', numericStudyId], |
| const handleActionClick = (item: QuestionTodoItem) => { | ||
| function handleActionClick(item: QuestionTodoItem) { | ||
| // 1. 해당 알림을 읽음 처리 | ||
| markAsRead(item.to); |
| const TEST_TOKEN = | ||
| 'eyJhbGciOiJIUzM4NCJ9.eyJzdWIiOiI0OTc2OTIyODY0Iiwicm9sZSI6IiIsInNvY2lhbF90eXBlIjoiS0FLQU8iLCJpYXQiOjE3ODY2MjEwMDIsImV4cCI6MTgxODE1NzAwMn0.cHbtGFGa_oumeu8cKtZtnvBwdAUpmOZEQJC0Gs7WBExHTxgkjmIkRsgj7Mbxgkjl'; |
| aria-label="프로필 메뉴 열기" | ||
| aria-expanded={isOpen} | ||
| aria-haspopup="true" | ||
| > |
| import { Navigate, useNavigate, useParams, useSearchParams } from 'react-router-dom'; | ||
|
|
||
| import { useEffect, useMemo, useState } from 'react'; | ||
| import { useQueryClient } from '@tanstack/react-query'; | ||
| import { isAxiosError } from 'axios'; |
| useAuthStore.setState({ | ||
| accessToken: 'expired-token', | ||
| isAuthenticated: true, | ||
| isInitialized: true, | ||
| }); |
📌 관련 이슈
🏷️ PR 타입
📝 작업 내용
📸 스크린샷
✅ 체크리스트
dev브랜치를 현재 작업 브랜치에 반영했습니다.🔀 Merge 규칙
dev로 병합할 때는 Squash and merge를 사용합니다.dev에서main으로 병합할 때는 Create a merge commit을 사용합니다.dev반영을 확인한 후 Merge합니다.📎 기타 참고사항