Skip to content

✨ [Feat] 마이페이지 「나의 스터디」·「나의 활동 ・프로젝트」 목적지 연결 (#1228) - #1272

Merged
JEONG-J merged 2 commits into
developfrom
feat/1228
Aug 30, 2026
Merged

✨ [Feat] 마이페이지 「나의 스터디」·「나의 활동 ・프로젝트」 목적지 연결 (#1228)#1272
JEONG-J merged 2 commits into
developfrom
feat/1228

Conversation

@JEONG-J

@JEONG-J JEONG-J commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

🔗 관련 이슈

Closes #1228

✨ PR 유형

  • 새로운 기능 추가 (MP-F10 · MP-F11 목적지 연결)
  • 버그 수정 (죽은 탭 · 렌더되지 않던 카운트 · pop 복귀 스피너)
  • 접근성 개선 (Dynamic Type · VoiceOver)

📷 스크린샷 or 영상(UI 변경 시)

시뮬레이터 기준 확인 완료. 화면 캡처는 리뷰 시 코멘트로 첨부합니다.

  • 마이페이지 「나의 스터디」 탭 → 활동 탭 스터디 섹션 착지
  • 마이페이지 「나의 활동 ・프로젝트」 탭 → 활동 이력 목록(빈 상태 포함)
  • 「나의 활동 ・프로젝트」 행 우측 카운트 표시 (기존에는 미표시)

🛠️ 작업내용

MP-F10 — 「나의 스터디」 → 활동 탭 스터디 섹션

스터디 화면의 정본 소유자는 Activity 탭입니다. MyPage 가 Activity 를 직접 참조하면 Feature ↔ Feature
의존이 생기므로, 이미 명함에서 쓰고 있는 규약(BusinessCardEntryRootTabView 번역)을 그대로 따랐습니다.

  • ActivityEntry(신규, Activity 모듈 소유) — "스터디로 가고 싶다"만 표현하는 중립 요청.
    모드별로 .studyActivity(챌린저) / .studyManage(운영진) 중 어디인지는 Activity 모듈이 정합니다.
  • MyPageFeatureViewonOpenStudy 콜백만 올리고, App 셸 RootTabView.enterActivityStudy(pathStore:)
    ① Activity 탭 스택을 루트로 리셋 → ② 탭 전환 → ③ .study 요청 발행 순으로 번역합니다.
  • 탭만 바꾸면 두 군데가 어긋납니다. PathStore 가 탭별 스택을 보존하므로 이전에 보던 상세 화면이 복원되고,
    ActivityView 가 마지막에 고른 섹션을 들고 있어 기본값인 출석 화면이 뜹니다. 위 ①·③이 각각을 막습니다.
  • ActivityView.task(id: pendingEntry) 로 요청을 소비합니다. 요청이 도착할 때 그 탭이 이미 살아 있을 수도,
    아직 만들어지지 않았을 수도 있는데 .task(id:) 는 등장·값 변경 양쪽에서 돌아 두 경우를 함께 덮습니다.
    (.onChange 만 쓰면 후자에서 요청이 등록 전에 지나갑니다.)

MP-F11 — 「나의 활동 ・프로젝트」 → 활동 이력 목록

  • MyActivityLogsView(신규) — 기존 ActiveLogs 컴포넌트를 읽기 전용으로 재사용합니다.
    onAddTapnil 이면 추가 버튼을 그리지 않으므로 별도 분기 없이 그대로 씁니다.
    (기록 추가는 지금도 「명함 편집」이 소유합니다.)
  • 목록에 싣는 값은 행 우측 카운트가 세는 것과 같은 Profile.activityLogs() 스냅샷입니다.
    같은 파생을 쓰므로 "카운트와 목록 개수 일치"가 구조적으로 보장됩니다.
  • 빈 상태는 ContentUnavailableView.

함께 고친 것

셋 다 이번 연결 작업이 드러낸 문제라 같은 PR에 담았습니다.

  • 렌더되지 않던 카운트 — 「나의 활동 ・프로젝트」 행에 value 인자가 아예 없어 카운트가 표시되지 않았습니다.
  • 죽은 탭MyPageListRowaction == nil 이면 탭 제스처를 달지 않으면서 chevron 은 계속 그려서,
    목적지 없는 행이 "활성 외관인데 눌러도 무반응"이 됐습니다. 공용 행에서 chevron 도 함께 감추게 고쳤고,
    같은 경로를 쓰던 기존 「명함 편집」 행도 함께 낫습니다.
  • pop 복귀 스피너fetchProfile 이 재조회마다 .loading 으로 밀어, 상세에서 돌아올 때마다 행이 스피너로
    되돌아갔습니다. loadBusinessCard 와 같은 stale-while-revalidate 정책으로 맞췄습니다
    (첫 진입·실패 후 재시도만 로딩을 그림).

접근성

  • MyPageListRow / ActiveLogRow: 고정 높이 → 최소 높이 + 세로 패딩으로 Dynamic Type 대응 (🎨 Design: 명함 화면 다크 모드 · Dynamic Type 미대응 #1234 에서 잡은 패턴).
  • 두 행 모두 .accessibilityElement(children: .ignore) + 레이블 합성으로 한 줄 = 한 요소가 되게 했습니다.
    아이콘 타일·chevron 은 옆 글자를 그림으로 옮긴 장식이라 따로 읽히면 한 줄을 네 번 스와이프하게 됩니다.
    (선례: DiscoveredPeerRow)

테스트

  • ActivityEntryTests — 스터디 요청이 모드별로 올바른 섹션으로 해석되는지 (모드를 잘못 보면 빈 화면으로 떨어짐).
  • RootTabStudyEntryTests — Activity 탭 스택만 리셋하고 마이페이지 스택은 보존하는지.
  • MyPageViewModelTests — 재조회 중에도 pending 이 다시 켜지지 않는지 (기존 실패-경로 테스트 의도는 그대로 유지).

📋 추후 진행 상황

이번 범위 밖이라 남긴 것들입니다.

항목 사유
「프로젝트」 축 서버·도메인·DTO 어디에도 프로젝트 엔티티가 0건입니다. 그릴 값이 없어 목록은 활동 이력만 담고, 섹션 헤더도 「활동 이력」으로 뒀습니다. 서버에 엔티티가 생기면 같은 화면에 축을 추가하는 형태로 확장 가능합니다.
스터디 상세 목적지 「나의 스터디」가 특정 스터디 상세로 바로 가야 하는지, 지금처럼 스터디 섹션 목록으로 가는 게 맞는지 기획 확정이 없습니다. 현재는 목록 착지.
studyCount 스코프 (#1222) 카운트가 GET /api/v1/study-groups/managed(운영 스코프)에서 와서 일반 챌린저는 항상 0입니다. 이번 PR 범위 밖이며, 그래서 F10 쪽은 카운트-목록 일치를 검증할 수 없습니다.
glassEffect 배지 (#1236) ActiveLogRow 의 역할 배지 Glass 처리는 해당 이슈 소관이라 손대지 않았습니다.
시안 node-id MP-F10·F11 은 코드 주석에만 존재하는 ID로, 기획 레포(specs/·plans/)에도 대응 문서가 없습니다. 활동 이력 화면의 헤더 문구·빈 상태 카피는 기존 컴포넌트 톤에 맞춰 잠정 확정했으므로 디자인팀 확인이 필요합니다.

📌 리뷰 포인트

  1. 모듈 경계 — MyPage → Activity 를 App 셸이 중개하는 구조가 명함 규약과 어긋나지 않는지.
    ActivityFeatureView.initpendingEntry: 를 받는 public API 변경이라 호출부는 RootTabView 하나입니다.
  2. MyPageListRow chevron 규칙 변경 — 공용 행이라 「명함 편집」·「받은 명함」 행에도 영향이 갑니다.
    목적지 없는 행에서 chevron 이 사라지는 게 의도대로인지 봐주세요.
  3. fetchProfile stale-while-revalidate — 재조회 중 옛 프로필을 그대로 보여주는 게 맞는지.
    .loading 대신 인플라이트 플래그로 중복 호출을 막았습니다.
  4. 활동 이력 헤더·빈 상태 카피 — 디자인 확정 전 잠정값입니다.

✅ Checklist

PR이 다음 요구 사항을 충족하는지 확인해주세요!!!

- 「나의 스터디」 → Activity 탭 스터디 섹션. MyPage 가 Activity 를 직접 알지 않도록
  중립 요청 `ActivityEntry` 를 올리고 App 셸(`RootTabView`)이 번역한다(명함 `BusinessCardEntry` 와 같은 규약)
- 탭 전환 시 Activity 탭에 남아 있던 스택을 루트로 되돌리고, 마지막에 고른 섹션이
  아니라 요청받은 스터디 섹션으로 착지하도록 `ActivityView` 가 요청을 소비
- 「나의 활동 ・프로젝트」 → 활동 이력 목록(`MyActivityLogsView`). 기존 `ActiveLogs` 를
  읽기 전용으로 재사용하고, 행 우측 카운트와 같은 `Profile.activityLogs()` 스냅샷을 실어
  숫자와 목록이 어긋나지 않게 한다
- 카운트가 렌더되지 않던 「나의 활동 ・프로젝트」 행에 `value` 연결
- `MyPageListRow`: `action` 이 없으면 chevron 도 감춘다 — 목적지 없는 행이 활성 외관인 채
  무반응으로 남던 죽은 탭 제거(기존 「명함 편집」 행에도 적용)
- `MyPageListRow`·`ActiveLogRow`: 고정 높이를 최소 높이로 바꿔 Dynamic Type 대응,
  VoiceOver 는 행 단위로 묶어 한 줄을 여러 번 스와이프하지 않도록 레이블 합성
- `fetchProfile` 을 stale-while-revalidate 로 바꿔 pop 복귀 재조회마다 행이
  스피너로 되돌아가던 문제 제거
@JEONG-J JEONG-J added the ✨ Feature 새로운 기능을 추가합니다. label Aug 29, 2026
@JEONG-J JEONG-J self-assigned this Aug 29, 2026
# Conflicts:
#	UMCApp/Features/Activity/Presentation/Sources/ActivityFeatureView.swift
#	UMCApp/Features/Activity/Presentation/Sources/Views/ActivityView.swift
#	UMCApp/UMCApp/Sources/RootTab/RootTabView.swift
@JEONG-J
JEONG-J merged commit bd0d21a into develop Aug 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능을 추가합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Feature: 마이페이지 「나의 스터디」·「나의 활동・프로젝트」 목적지 연결 (MP-F10·F11)

1 participant