AI 역문서 · 1D1S-client@ad5edf9 · 1D1S-server-v2@f69a4eb 기준 · 코드에서 거꾸로 만든 초안입니다. 근거 링크로 확인하세요.
관련 소스 파일
이 페이지는 로그인한 사용자가 마이페이지에서 자신의 프로필, 참여 챌린지, 일지, 활동 통계와 성장 관련 수치를 확인하는 흐름을 설명합니다. 클라이언트의 마이페이지 라우트와 챌린지·일지 하위 라우트가 서버의 회원 API와 어떻게 연결되는지, 서버가 반환하는 MyPageDto 응답의 구조와 페이지네이션 방식을 코드 기준으로 정리합니다.
주요 대상은 다음과 같습니다.
/mypage에서 마이페이지 화면을 여는 흐름/mypage/challenge에서 참여 챌린지 목록으로 이동하는 흐름/mypage/diary에서 자신의 일지 목록으로 이동하는 흐름StatUnit으로 정의된 통계 집계 단위반대로 이 원문에는 친구 목록이나 친구 요청 API, 성장 전용 컨트롤러·서비스, 레벨·XP·배지 엔티티, 클라이언트의 실제 데이터 요청 훅 구현이 포함되어 있지 않습니다. 따라서 해당 기능의 구체적인 호출 함수와 화면 동작은 확인 필요 사항으로 남깁니다.
관련 내용은 1.3 시스템 아키텍처, 2.1 챌린지 탐색과 참여, 2.3 일지 작성과 조회, 3.2 API와 응답 구조, 3.3 도메인 데이터 모델, 3.6 스트릭과 보상, 4.1 클라이언트 화면 구조와 함께 보아야 합니다.
출처: 1D1S-client/src/app/mypage/page.tsx:1-10, 1D1S-client/src/app/mypage/challenge/page.tsx:1-5, 1D1S-client/src/app/mypage/diary/page.tsx:1-5, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:61-97
클라이언트에는 마이페이지의 진입점과 두 개의 하위 화면 라우트가 있습니다.
| 라우트 파일 | 연결 컴포넌트 | 코드에서 확인되는 역할 |
|---|---|---|
src/app/mypage/page.tsx | MyPageScreen | 마이페이지 화면을 반환합니다. |
src/app/mypage/challenge/page.tsx | MyChallengeListScreen | 사용자의 챌린지 목록 화면을 반환합니다. |
src/app/mypage/diary/page.tsx | MyDiaryListScreen | 사용자의 일지 목록 화면을 반환합니다. |
MyPage는 별도의 데이터 변환이나 API 호출을 직접 구현하지 않고 MyPageScreen을 반환합니다. 따라서 마이페이지 데이터 조회 로직은 해당 화면 컴포넌트 또는 그 하위 계층에 있을 가능성이 있지만, 제공된 원문만으로는 실제 훅·API 클라이언트 이름을 확인할 수 없습니다.
마이페이지 하위 화면도 동일한 구조입니다. MyChallengeListPage는 MyChallengeListScreen을, MyDiaryListPage는 MyDiaryListScreen을 반환합니다. 이 라우트 파일만으로는 하위 화면이 회원의 challengeList·diaryList 데이터를 재사용하는지, 별도의 챌린지·일지 API를 호출하는지 확정할 수 없습니다.
서버의 MemberController는 /member를 공통 경로로 사용합니다. 컨트롤러는 MemberService, MemberDeleteService, MemberRepository를 주입받으며, 마이페이지 조회에서는 MemberService.getMyPage를 호출합니다.
getMyPage는 현재 로그인한 회원 식별자를 CurrentUserContext.getCurrentMemberId()에서 얻고, 요청의 page와 size로 PageRequest를 만든 뒤 서비스에 전달합니다. 성공 응답은 ApiResponse.success로 감쌉니다.
출처: 1D1S-client/src/app/mypage/page.tsx:1-10, 1D1S-client/src/app/mypage/challenge/page.tsx:1-5, 1D1S-client/src/app/mypage/diary/page.tsx:1-5, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:28-35, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:91-97
마이페이지 성공 예시는 memberId, nickname, profileUrl, email, provider, streak, challengeList, diaryList, pageInfo로 구성됩니다. 실제 반환 타입은 컨트롤러 선언의 MyPageDto입니다.
| 영역 | 필드 | 설명 |
|---|---|---|
| 회원 | memberId | 회원 식별자입니다. |
| 회원 | nickname | 닉네임입니다. |
| 회원 | profileUrl | 프로필 이미지 URL입니다. |
| 회원 | email | 이메일입니다. |
| 회원 | provider | 소셜 로그인 제공자 예시입니다. |
| 활동 집계 | todayGoalCount | 오늘 목표 수 예시입니다. |
| 활동 집계 | currentStreak | 현재 스트릭입니다. |
| 활동 집계 | totalDiaryCount | 전체 일지 수입니다. |
| 활동 집계 | totalGoalCount | 전체 목표 수입니다. |
| 활동 집계 | currentMonthDiaryCount | 현재 월 일지 수입니다. |
| 활동 집계 | currentMonthGoalCount | 현재 월 목표 수입니다. |
| 활동 집계 | maxStreak | 최대 스트릭입니다. |
| 활동 집계 | longestGoalStreak | 목표별 연속 기록 예시입니다. |
| 챌린지 집계 | totalChallengeCount | 전체 챌린지 수입니다. |
| 챌린지 집계 | completedFiniteChallengeCount | 종료형 챌린지 완료 수입니다. |
streak.calendar에는 날짜별 기록도 포함됩니다. 각 항목은 date, count, frozen 필드로 표현되며, 예시에서는 frozen: true인 날짜가 있습니다. 이 자료는 마이페이지에서 활동 캘린더를 구성할 수 있는 응답 필드를 보여주지만, 실제 클라이언트 캘린더 컴포넌트 이름은 제공되지 않았습니다.
challengeList의 항목에는 challengeId, title, category, startDate, endDate, maxParticipantCnt, challengeType, participantCnt, likeInfo가 포함됩니다. likeInfo는 likedByMe와 likeCnt로 구성됩니다.
diaryList의 항목에는 id, title, content, isPublic, likeInfo가 포함됩니다. 응답 예시의 pageInfo는 다음 페이지 처리에 필요한 정보를 제공합니다.
pageInfo 필드 | 의미 |
|---|---|
page | 현재 페이지 번호입니다. 예시는 0입니다. |
size | 페이지 크기입니다. |
totalElements | 전체 원소 수입니다. |
totalPages | 전체 페이지 수입니다. |
hasNextPage | 다음 페이지 존재 여부입니다. |
친구 정보는 MyPageDto 예시의 최상위 필드나 streak·challengeList·diaryList 안에서 확인되지 않습니다. 따라서 이 원문만으로는 친구가 마이페이지 응답에 포함되는지 판단할 수 없습니다.
출처: 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:61-97, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberApiExamples.java:20-83
마이페이지 조회의 서버 처리 흐름은 다음과 같습니다.
/mypage 경로에 진입합니다.src/app/mypage/page.tsx의 MyPage가 MyPageScreen을 반환합니다.MyPageScreen의 실제 호출 코드는 제공되지 않았으므로, 클라이언트가 어떤 API 함수나 훅을 사용하는지는 확인 필요입니다.MemberController.getMyPage가 요청을 처리합니다.@RequestParam의 page 기본값 0, size 기본값 10을 사용해 PageRequest.of(page, size)를 만듭니다.CurrentUserContext.getCurrentMemberId()로 로그인한 회원의 memberId를 얻습니다.memberService.getMyPage(memberId, pageable)를 호출합니다.ApiResponse.success(Message.GET_MYPAGE, ...)로 감싸져 클라이언트에 반환됩니다.챌린지와 일지 하위 화면의 라우트 흐름은 다음과 같이 확인됩니다.
이 도식에서 챌린지 데이터와 일지 데이터를 실제로 공급하는 API는 원문에 제시되지 않았습니다. 마이페이지 응답의 challengeList·diaryList를 사용하는지, 별도 도메인 API를 사용하는지 확인이 필요합니다.
출처: 1D1S-client/src/app/mypage/page.tsx:1-10, 1D1S-client/src/app/mypage/challenge/page.tsx:1-5, 1D1S-client/src/app/mypage/diary/page.tsx:1-5, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:91-97
회원과 마이페이지에 직접 연결되는 엔드포인트는 다음과 같습니다.
| 메서드 | 경로 | 인증·입력 | 성공 처리 |
|---|---|---|---|
GET | /member/my-page | 로그인 회원, page, size | MyPageDto와 활동·챌린지·일지 정보 반환 |
GET | /member/side-bar | 로그인 회원 | SideBarDto 반환 |
PATCH | /member/nickname | NicknameRequest | 닉네임 변경 |
PATCH | /member/profile-image | ProfileImageRequest | 프로필 이미지 변경 |
PATCH | /member/phone-number | PhoneNumberRequest | 휴대폰 번호 변경 |
GET | /member/profile/:memberId | memberId, page, size | 다른 회원의 MyPageDto 반환 |
GET | /member/nickname/check | nickname | 닉네임 사용 가능 여부 반환 |
GET /member/my-page는 page와 size를 쿼리 파라미터로 받으며 기본값은 각각 0, 10입니다. 성공 메시지는 예시에서 “마이페이지 조회 성공했습니다.”로 표시됩니다.
프로필 편집 API는 마이페이지 조회와 별개의 작업입니다. 닉네임 변경은 NicknameRequest의 nickname을 받아 memberService.editNickname을 호출합니다. 프로필 이미지 변경은 ProfileImageRequest의 objectKey를 받아 memberService.editProfileImage를 호출합니다. 컨트롤러 설명에는 프로필 이미지를 먼저 /image/presigned-url API로 업로드한 뒤 발급된 키를 objectKey에 담는 흐름이 기재되어 있습니다. 다만 해당 이미지 API의 구현은 이 원문에 없습니다.
휴대폰 번호 변경은 PhoneNumberRequest를 검증한 뒤 memberService.editPhoneNumber를 호출합니다. 컨트롤러 설명상 하이픈 유무와 관계없이 숫자만으로 정규화해 저장합니다.
GET /member/profile/:memberId는 다른 회원 프로필을 조회합니다. 예시 응답은 자신의 마이페이지와 유사하게 streak, challengeList, diaryList, pageInfo를 포함하지만, 비공개 프로필 접근 시 USER-005, 삭제 처리된 회원에 대해서는 USER-006 오류가 사용됩니다.
출처: 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:37-59, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:61-97, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:99-130, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:132-249, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:251-297
서버에는 통계 집계 단위를 나타내는 StatUnit enum이 정의되어 있습니다. 값은 DAY, WEEK, MONTH, YEAR입니다.
StatUnit 값 | 코드 설명 |
|---|---|
DAY | 일 단위 |
WEEK | 주 단위이며 월요일 시작, KST 기준입니다. |
MONTH | 월 단위 |
YEAR | 연 단위 |
StatUnit의 주석에는 엔드포인트별 허용 값이 서비스에서 검증된다고 적혀 있습니다. 그러나 제공된 자료에는 이 enum을 받는 통계 컨트롤러, 통계 서비스, 요청 DTO, 응답 DTO가 없습니다. 따라서 실제 통계 API 경로와 마이페이지의 통계 화면이 DAY·WEEK·MONTH·YEAR 중 어떤 값을 언제 사용하는지는 확인할 수 없습니다.
마이페이지 응답 예시에는 통계에 가까운 집계 필드가 이미 포함되어 있습니다. 예를 들어 currentStreak, totalDiaryCount, totalGoalCount, currentMonthDiaryCount, currentMonthGoalCount, maxStreak, calendar가 있습니다. 이 필드들은 마이페이지 한 번의 응답으로 표시할 수 있는 활동 요약 데이터로 확인됩니다. 반면 레벨, XP, 배지, 성장 단계 필드는 MEMBER_03 또는 MEMBER_19 예시에 없습니다.
따라서 코드 기준으로 확정할 수 있는 범위는 다음과 같습니다.
streak 객체 아래에 표현됩니다.calendar 배열로 전달됩니다.StatUnit에 정의되어 있습니다.성장 도메인의 실제 연결을 문서화하려면 성장 컨트롤러, API DTO, 서비스, 관련 클라이언트 화면 또는 훅의 추가 원문이 필요합니다.
출처: 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/statistics/StatUnit.java:3-16, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberApiExamples.java:28-51
마이페이지 진입 전 인증 상태는 src/app/mypage/page.tsx 자체가 아니라 애플리케이션 미들웨어에서 처리된다고 해당 파일의 주석에 기록되어 있습니다. 파일의 컴포넌트 본문은 MyPageScreen을 반환할 뿐이며, 클라이언트 useEffect 기반 인증 가드는 포함하지 않습니다. 실제 미들웨어 구현은 제공되지 않았으므로 리다이렉트 조건과 쿠키 이름은 이 페이지에서 확정하지 않습니다.
회원 마이페이지 API의 주요 오류는 다음과 같습니다.
| HTTP 상태 | 코드 | 상황 |
|---|---|---|
401 | AUTH-001 | 인증되지 않은 접근입니다. |
404 | USER-003 | 회원을 찾을 수 없습니다. |
403 | USER-005 | 다른 회원의 비공개 프로필에 접근했습니다. |
404 | USER-006 | 삭제 처리된 회원입니다. |
400 | 400 | 휴대폰 번호 형식이 올바르지 않습니다. |
GET /member/my-page에는 401과 404 응답이 Swagger 예시로 정의되어 있습니다. 다른 회원 프로필 조회에는 인증 실패, 비공개 프로필, 회원 없음 또는 삭제 처리 상태가 별도로 문서화되어 있습니다.
회원 정보 수정은 성공 시 데이터 객체가 아니라 메시지 응답을 반환하는 형태로 선언되어 있습니다. 예를 들어 닉네임 변경은 Message.UPDATE_NICKNAME, 프로필 이미지는 Message.UPDATE_PROFILE_IMAGE, 휴대폰 번호는 Message.UPDATE_PHONE_NUMBER를 사용합니다. 따라서 수정 직후 화면의 프로필·닉네임을 최신 값으로 갱신하는 방법이 클라이언트 캐시 재조회인지, 로컬 상태 갱신인지 여부는 제공된 코드만으로 판단할 수 없습니다.
출처: 1D1S-client/src/app/mypage/page.tsx:4-9, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:74-89, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:261-287, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberApiExamples.java:85-93, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberApiExamples.java:251-269
다음 항목은 제공된 코드만으로는 연결 관계를 확정할 수 없으므로 추가 확인이 필요합니다.
MyPageScreen이 GET /member/my-page를 호출하는 실제 함수, 훅 또는 API 모듈의 이름은 무엇입니까?MyChallengeListScreen과 MyDiaryListScreen은 마이페이지 응답의 challengeList·diaryList를 사용합니까? 아니면 챌린지·일지 도메인의 별도 목록 API를 호출합니까?StatUnit을 사용하는 통계 엔드포인트의 경로와 HTTP 메서드, 요청 필드, 응답 DTO는 무엇입니까?streak.calendar의 frozen 값이 어떤 정책으로 계산되는지, 그리고 longestGoalStreak의 배열 구조가 어떤 DTO 필드 타입인지 확인할 수 있습니까?ApiResponse의 실제 JSON 래퍼 구조와 클라이언트에서 사용하는 페이지네이션 타입은 무엇입니까?GET /member/my-page를 재호출하는지, React Query 캐시를 갱신하는지, 화면 상태를 직접 바꾸는지 확인이 필요합니다./image/presigned-url의 실제 구현과 objectKey의 저장·검증 규칙은 3.4 이미지 업로드에서 추가 확인해야 합니다.출처: 1D1S-client/src/app/mypage/page.tsx:1-10, 1D1S-client/src/app/mypage/challenge/page.tsx:1-5, 1D1S-client/src/app/mypage/diary/page.tsx:1-5, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/statistics/StatUnit.java:5-16, 1D1S-server-v2/src/main/java/com/odos/odos_server_v2/domain/member/controller/MemberController.java:61-97