Skip to content

[Deploy] 스프린트3 배포 #90

Merged
LeeWxx merged 69 commits into
prodfrom
dev
Apr 28, 2026
Merged

[Deploy] 스프린트3 배포 #90
LeeWxx merged 69 commits into
prodfrom
dev

Conversation

@LeeWxx
Copy link
Copy Markdown
Collaborator

@LeeWxx LeeWxx commented Apr 28, 2026

이슈 번호

#MM-1234

작업내용

  • 변경한 주요 내용 목록

리뷰어에게 전할 말

스크린샷 (선택사항)

hin6150 and others added 30 commits March 1, 2026 11:09
이용약관 → 닉네임 → 연애상태 → 홈으로 플로우 축소.
제거된 단계(MBTI, 커플 연동 등)는 deprecated 처리하여 코드 보존.
연애상태 선택 후 즉시 회원가입 API 호출 및 홈 이동.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
홈 화면에서 애착유형 배너, 애착유형 카드, MBTI 필수 입력 모달 제거.
채팅 메시지 리스트에서 애착유형 미완료 시스템 메시지 및 CTA 제거.
/mbti, /partner-mbti 페이지 및 required-profile-flow는 마이페이지 연동
여부 확인 전까지 deprecated 처리로 보존.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 온보딩 커플 전용 페이지 삭제 (my-code, partner-code, anniversary)
- partner-code-sheet.tsx 삭제 (미사용 dead code)
- __root.tsx에서 coupleFlowRoutes 및 관련 라우팅 로직 제거
- onboarding-context에서 partnerCode 필드 및 updatePartnerCode 제거
- profile/index.ts에서 PartnerCodeSheet export 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- required-profile-flow.ts 파일 삭제 (deprecated)
- calculateDDay 함수 제거 (D-day UI 완전 제거)
- UserInfo에서 startLoveDate 필드 제거
- analytics 상수에서 MYPAGE_COUPLE, OPEN_COUPLE_MANAGE 제거
- mbti/page.tsx onBack dead code 단순화
- chat-entry-card.tsx getChatEntryFlowStart 인라인화 및 dead else 분기 제거
- 기념일(anniversary) 관련 파일 및 훅 삭제
- 온보딩 컨텍스트/네비게이션에서 MBTI 관련 코드 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- personalityFlowSearchSchema: flow/chatId 라우트 검색 파라미터 스키마
- FlowProgressBar / FlowStepDots: 플로우 진행 상태 표시 컴포넌트
- useMemberUpdateMutation: 멤버 정보 업데이트 공통 훅

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- my-attachment-select: 내 애착유형 선택 페이지
- my-result-preview: 내 성향 완성 결과 미리보기 페이지
- partner-attachment-select: 상대 성향 선택 페이지 (모르겠어요 모달·flow별 버튼 분기 포함)
- partner-result-preview: 상대 성향 결과 미리보기 페이지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- attachment-test: flow/chatId 검색 파라미터 전달
- partner-mbti: personalityFlowSearchSchema로 전환, partner-attachment-select로 이동
- mbti-form: navCenter/contentTopSlot 슬롯 추가
- header-bar: DetailHeaderBar center 슬롯 지원
- attachment/index.ts: AttachmentTypeCards export 추가
- ATTACHMENT_OPTIONS 상수 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- isFromChat boolean → from: 'home' | 'chat' | 'my-page' prop으로 리팩토링
- from='my-page': "마이페이지로 가기", from='chat': "상담하러 가기", 그 외: "홈으로 가기"
- "홈으로 이동하기" → "홈으로 가기" 카피 통일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MemberData에 partnerLoveTypeCategory 필드 추가
- UpdateMemberRequestDto에 otherLoveTypeCategory 필드 추가
- UserInfo에 partnerLoveTypeCategory 추가 및 _fetchUserInfo 매핑
- 내 성향 배지: {MBTI} {애착유형} 형태로 변경 (예: "INFP 불안형")
- loveTypeCategory 미입력 시 배지 미표출 ("미입력" 제거)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AttachmentTestBanner: 카피 "아직 채우지 않은 성향 카드가 {N}건 있어요!"로 변경, onClick/count props 추가
- AttachmentTypeCards: isPartnerUnknown=true 시 AI 분석 예정 툴팁 표출, 카드 클릭 시 툴팁 해제
- 홈 화면: 미완성 성향 카드 수 계산 후 배너 조건부 렌더링, partnerLoveTypeCategory 기반 분기 로직 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PersonalityFlowLoadingPage: note 로티 + "성향 프로필 생성중..." 표시 후 1.5초 뒤 플로우 이동
- chat-entry-card: 새 대화 시작 후 /mbti 직접 이동 → /personality-flow-loading 경유로 변경
- 홈 배너 클릭도 /personality-flow-loading 경유로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- key-message-banner 컴포넌트 추가 (icon, subtitle, title, onClick)
- bell-notification-icon 컴포넌트 추가 (amber 벨 + 빨간 알림 dot)
- attachment-test-banner 제거 후 key-message-banner로 대체
- 홈 상담 카드 하단 여백(mb-4) 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 선택 state 추가 후 즉시 저장 → 버튼 클릭 시 저장으로 변경
- key-message-banner 상단 배치
- 건너뛰기 버튼 제거 → 프로필 완성! 버튼으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- selectable-button 컴포넌트 추가 (selected, onClick, children, className)
- mbti-form, relationship-status-form, partner-attachment-select에 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fixed-bottom 컴포넌트 추가 (mt-auto + safe-bottom 패딩 표준화)
- my-result-preview, partner-result-preview에 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- flow 단계별 navigate 헬퍼 함수 추가 (personality-flow.ts)
- mbti, partner-mbti 페이지에 헬퍼 적용으로 분기 로직 중앙화

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- my-attachment-select, partner-attachment-select, relationship-status에 useMemberUpdateMutation 훅 적용
- flow 네비게이션 헬퍼 및 fixed-bottom 컴포넌트 통합 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- createPortal로 document.body에 렌더링하여 motion.div transform 계층 탈출
- bridge.setModalOpen 호출 추가로 native 상태바 영역까지 오버레이 커버
- useIsFrozenRoute 적용으로 FrozenScreen에서 가이드가 잠깐 노출되는 버그 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 옵션 클릭 시 즉시 저장 → 선택 state 설정으로 변경
- 건너뛰기 버튼 제거 → 프로필 완성! 버튼으로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- POST /members/onboarding: personalityType, otherPersonalityType 제거
- PATCH /members: otherPersonalityType 제거, loveTypeCategory 추가
- GET /members: partnerLoveTypeCategory 응답 필드 추가 (UNKNOWN enum 포함)
- GET /members/partner: memberState, avoidanceRate, anxietyRate, nickname, isStartLoveDateUpdated 제거
- POST /members/partners: 상대 프로필 최초 등록 API 추가
- PATCH /members/partners: 상대 프로필 수정 API 추가
- GET /love-types/result: MBTI + 애착유형 상세 결과 조회 API 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- POST/PATCH /members/partners 연동:
  useUpsertPartnerProfileMutation (POST→PATCH fallback),
  useUpdatePartnerProfileMutation 훅 신규 추가
- partner-mbti, partner-attachment-select 페이지를 신규 훅으로 교체
  (otherPersonalityType→personalityType, otherLoveTypeCategory→loveTypeCategory)
- GET /love-types/result 쿼리 옵션 추가 (loveTypePersonalityTypeResultQuery)
- app/page.tsx: PartnerMemberData.loveTypeCategory UNKNOWN 타입 가드 추가
- deprecated 온보딩 페이지 3개 삭제
  (onboarding/mbti, onboarding/partner-mbti, onboarding/complete)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- personalityFlowSearchSchema에 from: 'profile' 파라미터 추가
- 마이페이지/프로필에서 성향 편집 진입 시 from: 'profile' 전달
- attachment-select 완료 후 from === 'profile'이면 /my-page/profile로 복귀
- api.ts 인터셉터에서 에러코드 40017(이미 파트너 프로필 등록)은 Sentry/Amplitude 리포팅 제외

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- personality-flow.ts에 usePersonalityFlow hook 통합 (use-personality-flow.ts 제거)
- navigateAfterXxx 함수 제거, flow/from 분기 로직을 hook 내부로 집약
- 각 페이지는 next() / exit() 호출만으로 플로우 진행
- chatId 제거 (chat-entry 플로우에서 실제로 사용되지 않는 dead code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- my/partner-result-preview에서 결과 상세 진입 시 replace + from 파라미터 전달
- navigateExit에 my-result-preview, partner-result-preview 케이스 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
hin6150 and others added 28 commits March 21, 2026 16:23
- NavigateFn 타입을 any → ReturnType<typeof useNavigate>로 강화
- FlowParams.from을 리터럴 유니온 타입으로 정확화
- catch (error: any) → unknown + 타입 assertion 적용
- useUpdatePartnerProfileMutation onSuccess optional로 변경
- useMemberUpdateMutation errorMessage optional + fallback 기본값
- partner-attachment-select: 두 mutation 인스턴스 → 단일 partnerMutation
- SelectableButton 중복 className 제거
- 인라인 gradient style → Tailwind 클래스로 교체

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
replace: true 제거로 history stack 유지 → attachment-test에서 뒤로가기 시 home이 아닌 my-attachment-select로 복귀

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
mbti → my-attachment-select 네비게이션의 replace: true 제거
파트너 플로우와 동일하게 push 방식으로 통일하여 history 유지

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
my-attachment-select 완료 시 router.history.back() 대신
명시적 navigate로 /my-page/profile 이동
(history에 /mbti가 추가되어 back()이 MBTI로 이동하던 문제 해결)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 마이페이지에서 상대 성향 변경 완료 시 토스트 메시지 추가
- 채팅 상단 안내 문구: '연동 후에도 대화 내용은 상대에게 공유되지 않으니 안심하세요!' → '대화 내용은 암호화 되어 안전하게 저장하고 있어요!'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
마이페이지와 동일하게 'INFP 불안형' 형식으로 표시

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
banner와 동일하게 my-personality / partner-personality / full-flow 분기 처리

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
getMissingPersonalityFlow() 추출 후 banner, chat-entry-card에 적용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- banner/채팅하기 단일 플로우(my-personality, partner-personality)에서
  직접 선택 완료 후 결과 페이지를 거쳐 홈으로 이동하도록 수정
- from=profile 플로우에서 mbti→attachment-select 이동 시 replace 적용하여
  완료 후 마이페이지에서 뒤로가기 시 중간 플로우 페이지 노출 버그 수정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- from=profile 플로우에서 attachment-select 완료 시 navigate replace 대신
  history.go(-2)를 사용하여 히스토리 포인터를 profile로 이동
- mbti→attachment-select 이동의 잘못된 replace 제거

히스토리 스택: [..., prev, profile, mbti, attachment-select]
- 완료 후 back: prev (마이페이지→마이페이지 중복 제거)
- attachment-select back: mbti (중간 단계 back 정상화)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- getMissingPersonalityFlow: UNKNOWN을 missing으로 처리하던 로직 제거
- 홈 배너: partnerLoveTypeCategory가 UNKNOWN이면 미완성 카운트에서 제외
- 채팅 버튼: UNKNOWN이면 파트너 성향 완성으로 간주하여 바로 채팅 진입
- partner-attachment-select: 모르겠어요(UNKNOWN) 선택 시 결과 페이지 없이 바로 HOME 이동

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[FIX/MM-190] 애착유형 결과화면 수정
FEAT/MM-188 성향 관련된 flow를 개선 및 간소화합니다.
FEAT/MM-187 사용하지 않는 코드를 제거합니다.
REPLACE 액션이 항상 forward로 판정되어 역방향 애니메이션이 재생되던 문제 수정.
navigate state에 forceDirection을 추가하여 REPLACE 이동 시에도 방향을 명시적으로 지정할 수 있도록 개선.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 업데이트일로부터 7일간 전체 유저 대상 모달 노출
- X 버튼 및 '기대돼요!' 버튼으로 닫기, 이후 재노출 없음
- dismissed 상태를 bridge를 통해 native(SecureStore)에 저장
- 웹 환경 fallback은 localStorage 사용

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FEAT/MM-191 모달 화면 표기되도록 추가 개발 및 애니메이션 수정
[FIX] 결과 화면 UI 및 일부동작 QA
@LeeWxx LeeWxx merged commit 48d5f56 into prod Apr 28, 2026
3 checks passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant update to the personality and attachment type flow, including new UI components for personality renewal, updated API integration for partner profiles, and refactored navigation logic. I have identified a critical issue where the mobile app is configured to use a local URL instead of the production URL, which must be corrected before deployment. Additionally, I have provided feedback on improving the data mapping logic in the chat context, optimizing the message sorting performance, and replacing direct browser history manipulation with router-native methods.

Comment thread apps/mobile/app/index.tsx
Comment on lines 30 to +31
const webviewUrl = process.env.EXPO_PUBLIC_LOCAL_URL
// const webviewUrl = process.env.EXPO_PUBLIC_WEB_VIEW_URL
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

배포(Deploy)용 PR임에도 불구하고 webviewUrl이 로컬 환경 변수인 EXPO_PUBLIC_LOCAL_URL을 참조하도록 설정되어 있습니다. 운영 환경에 배포하기 전 EXPO_PUBLIC_WEB_VIEW_URL을 사용하도록 수정이 필요합니다.

Suggested change
const webviewUrl = process.env.EXPO_PUBLIC_LOCAL_URL
// const webviewUrl = process.env.EXPO_PUBLIC_WEB_VIEW_URL
const webviewUrl = process.env.EXPO_PUBLIC_WEB_VIEW_URL

Comment on lines +144 to +147
const groupedContents =
messageGroups.length === sanitizedIds.length
? messageGroups
: sanitizedIds.map((_, index) => messageGroups[index] ?? messageGroups[messageGroups.length - 1] ?? '')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

sanitizedIdsmessageGroups의 길이가 일치하지 않을 때 마지막 메시지 그룹을 반복하거나 일부를 누락시키는 로직은 사용자에게 중복된 메시지를 보여주거나 정보 손실을 일으킬 수 있습니다. 두 배열의 길이가 항상 같음을 보장할 수 없다면, 데이터 정합성을 위해 매핑 로직을 개선해야 합니다.

Comment on lines +63 to +73
.map((message, arrivalIndex) => ({ message, arrivalIndex }))
.sort((a, b) => {
const aRawTime = a.message.createdAt ? new Date(a.message.createdAt).getTime() : 0
const bRawTime = b.message.createdAt ? new Date(b.message.createdAt).getTime() : 0
const aTime = Number.isFinite(aRawTime) ? aRawTime : 0
const bTime = Number.isFinite(bRawTime) ? bRawTime : 0
if (aTime !== bTime) return aTime - bTime
// createdAt 동률 시 API 수신 순서를 유지한다.
return a.arrivalIndex - b.arrivalIndex
})
.map(({ message }) => message)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

sort 함수 내부에서 매번 new Date() 객체를 생성하여 타임스탬프를 구하는 것은 성능 저하의 원인이 될 수 있습니다. 상단의 map 과정에서 타임스탬프 값을 미리 계산하여 객체에 포함시킨 뒤, 정렬 시에는 해당 값을 참조하도록 개선하는 것이 효율적입니다.

      .map((message, arrivalIndex) => {
        const rawTime = message.createdAt ? new Date(message.createdAt).getTime() : 0
        return { message, arrivalIndex, time: Number.isFinite(rawTime) ? rawTime : 0 }
      })
      .sort((a, b) => {
        if (a.time !== b.time) return a.time - b.time
        return a.arrivalIndex - b.arrivalIndex
      })
      .map(({ message }) => message)


// 현재 히스토리 엔트리 URL을 /로 변경 (라우터에 알리지 않고 브라우저 히스토리만 수정)
// 이렇게 하면 /chat 에서 back 시 / 로 돌아감 (플로우 단계들을 건너뜀)
window.history.replaceState(window.history.state, '', '/')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

window.history.replaceState를 직접 사용하여 브라우저 히스토리를 조작하는 방식은 TanStack Router의 내부 상태 관리와 충돌할 가능성이 있습니다. 라우터에서 제공하는 navigate 함수의 replace 옵션이나 전용 히스토리 API를 사용하여 히스토리 스택을 관리하는 것을 권장합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants