정의
WUMM의 커플 협업 모델은 두 사용자를 하나의 커플 단위로 묶고, 그 위에서 예산·일정·체크리스트·알림을 공유하도록 만드는 구조다. 저장소의 모델, 서비스, 웹 초대 문서가 모두 이 개념을 뒷받침한다.
코드 근거
Couple 모델은 user1Id, user2Id, weddingDate, totalBudget를 보유하며 user2Id 존재 여부로 연동 상태를 판단한다. CoupleService는 커플 생성, 파트너 연결/해제, 기본 예산 카테고리 생성, 실시간 리스너 등록까지 담당한다. 구체 근거는 github-repo-2026-04-11에 정리했다.
사용자 흐름
딥링크 wumm://join?code=...와 docs/wumm-join.html은 파트너 초대 흐름이 앱 외부와도 연결된다는 점을 보여준다. 즉, 협업은 앱 내부 버튼 수준이 아니라 공유 가능한 초대 경험까지 포함한다. 이 흐름은 wumm의 핵심 차별점이며, 실제로 wedding-planning-workspace 전체를 두 사람이 함께 운영하게 만든다.
협업을 강화하는 보조 장치
PushNotificationService는 파트너 알림을 Firestore 문서 생성 방식으로 요청하고, Cloud Functions가 이를 처리하도록 설계되어 있다. 그래서 협업은 단순 데이터 공유가 아니라 “행동이 상대방에게 전달되는 경험”까지 포함한다. 이 구조는 firebase-ios-architecture와 강하게 결합되어 있다.
해석
저장소 안의 마케팅 문서가 “진정한 커플 협업”을 차별화 포인트로 둔 이유가 코드 레벨에서도 확인된다. 협업은 보조 기능이 아니라 제품 중심축이다. 2026-04-23 기준 운영 스냅샷에서도 최근 신규 사용자 대부분이 coupleId와 함께 관찰되어, 제품 메시지와 실제 온보딩 패턴이 어느 정도 맞물린다. 관련 수치는 auth-user-growth에 정리했다.
2026-04-28 데이터 병합 보강
파트너 연동 후 기존 작성 내역이 사라졌다는 문의를 계기로 confirmPartnerLink(userId:) 흐름을 점검했다. 기존 구현은 현재 사용자가 이미 만든 커플 공간과 파트너 코드의 커플 공간이 다를 때 기존 커플 문서를 삭제하고 새 coupleId로 갈아타는 구조였고, 예산·일정·체크리스트·하객·업체·자료·로드맵 데이터는 각 컬렉션의 coupleId 기준으로 조회되기 때문에 oldCoupleId의 데이터가 화면에서 보이지 않을 수 있었다.
최종 수정 방향은 기존 커플 문서를 먼저 삭제하지 않고 budgetCategories, budgetItems, budgets, calendarEvents, checklists, guests, vendors, sharedFiles, milestones의 coupleId를 새 커플 ID로 batch update한 뒤 파트너 연결을 완료하는 방식이다. couples와 users는 병합 대상에서 제외하고, 병합과 linkPartner가 성공한 뒤에만 old couple 문서를 삭제해 더미 커플 문서가 남지 않게 정리한다. 기존 피해 유저 복구는 앱 릴리즈만으로 자동 처리되지 않으므로 scripts/recover-couple-data.js dry-run/backup/apply 스크립트로 별도 마이그레이션해야 한다. 이 작업은 firebase-ios-architecture의 Firestore 컬렉션 설계와 wedding-planning-workspace의 저장형 기능 보존에 직접 연결된다.
PR 106의 최종 커밋은 e5fb21d fix: preserve data during partner linking와 ed180b6 fix: clean up merged couple document이며, CoupleDataMergeScope와 CoupleMergeCleanupPolicy 테스트로 병합 대상 컬렉션과 old/new couple ID cleanup 조건을 고정했다. GitHub Actions iOS CI / Build & Test는 3분 39초로 성공했고, PR은 mergeable 상태다.
2026-04-28 실제 복구에서는 t372b55WV4ps33cLSada의 도메인 데이터 84개를 RKUw1xOVaA6COjHOdLAH로 이동했고, 적용 후 새 커플 ID에는 총 120개 문서가 조회되었다. 이후 재확인에서 budgetCategories 6개, budgets 17개, calendarEvents 1개, vendors 2개, milestones 20개는 모두 recoveredFromCoupleId: t372b55WV4ps33cLSada 태그와 함께 새 커플 ID에 남아 있음이 확인되었다. 예산 항목의 estimatedAmount 합계는 38,415,100원, payments 합계는 4,198,000원이었다.
다만 이 작업은 사전 설명대로 users 문서와 couples.user1Id/user2Id는 수정하지 않았으므로, 1차 적용 직후에는 users/kakao_4869195578.coupleId가 e39znDyWMOlX83ify9Fy를 가리키는 정합성 문제가 남아 있었다. RKUw1xOVaA6COjHOdLAH 커플 문서의 user2Id에는 현유경 카카오 UID가 들어가 있었지만, 앱이 사용자 문서의 coupleId를 기준으로 작업공간을 열면 현유경 카카오 로그인에서는 복구 데이터가 바로 보이지 않을 수 있는 상태였다. 이종환 계정의 users.coupleId는 RKUw1xOVaA6COjHOdLAH로 일치했다.
2026-04-28 추가 수정에서 현유경 카카오 계정의 앱 표시 포인터를 맞추기 위해 users/kakao_4869195578.coupleId를 RKUw1xOVaA6COjHOdLAH로 업데이트했다. 적용 전 현유경 카카오가 가리키던 e39znDyWMOlX83ify9Fy에는 기본성 문서 42개만 있었고, 대상 커플에는 복구된 도메인 문서 120개가 있었다. 적용 후 검증에서 users/kakao_4869195578.coupleId == RKUw1xOVaA6COjHOdLAH, couples/RKUw1xOVaA6COjHOdLAH.user2Id == kakao_4869195578가 모두 참으로 확인되어, 앱이 사용자 문서의 coupleId를 기준으로 작업공간을 열면 현유경 카카오 로그인에서도 복구 데이터가 보일 상태가 되었다. 변경 전 백업은 WUMM 프로젝트의 recovery-backups/kakao-coupleid-pointer-fix-2026-04-28T23-47-29-339Z.json에 저장했다.
웨딩 날짜와 커플 레벨 예산은 도메인 데이터 migration 및 사용자 포인터 수정과 별개로 봐야 한다. RKUw1xOVaA6COjHOdLAH.weddingDate는 2027-05-01T00:00:00.000Z, old couple t372b55WV4ps33cLSada.weddingDate는 2027-05-01T12:00:00.000Z로 둘 다 KST 기준 2027-05-01이지만 timestamp는 다르다. 또한 old couple의 totalBudget: 80000000은 새 커플 문서에는 복사되지 않았고, 새 커플에는 estimatedBudget: 0만 확인된다. 따라서 “작성한 예산 항목”은 보존되었지만, 커플 문서 레벨의 총예산 필드는 새 커플로 보존되지 않았다.
2026-04-29 계정 삭제 후 상태
현유경 사용자가 카카오 계정을 삭제했고 신랑도 계정 삭제 후 재로그인했으나 앱 진입이 되지 않는다는 회신을 받은 뒤, Auth와 Firestore를 읽기 전용으로 재확인했다. 기존 현유경 카카오 UID kakao_4869195578는 Firebase Auth와 Firestore users 문서가 모두 사라진 상태였다. 이종환 기존 UID 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2는 Firebase Auth에는 존재하지만 Firestore users 문서가 없어, 앱 로그인 후 사용자 문서 조회 단계에서 진입 실패가 날 가능성이 높다.
복구해 둔 작업 데이터 자체는 보존되어 있다. RKUw1xOVaA6COjHOdLAH 커플 문서가 남아 있고, 앱 도메인 컬렉션 기준으로 총 121개 문서가 조회된다: budgetCategories 6개, budgets 18개, calendarEvents 1개, checklists 74개, vendors 2개, milestones 20개. 이전 old couple t372b55WV4ps33cLSada는 도메인 문서 0개이며 recoveredInto: RKUw1xOVaA6COjHOdLAH가 기록되어 있다.
현재 RKUw1xOVaA6COjHOdLAH의 멤버십은 user1Id: kakao_4869195578, user2Id: null로 남아 있어, 실제 로그인 가능한 사용자 문서와는 다시 끊어진 상태다. 현유경 이름의 별도 Apple relay 계정과 이메일 계정도 관찰되지만 각각 PieVjNWieGw1PVeyxI5a, lOhDrdMlvgAKzX2hSO03의 새 커플에 연결되어 있고, 복구 데이터가 있는 커플과는 다르다. 따라서 “데이터 보존”과 “현재 로그인 계정의 앱 접근성”은 분리해서 다뤄야 한다. 카카오 재가입이 같은 UID로 재생성되면 복구 커플과 다시 연결할 여지가 있지만, 현 상태에서는 운영자가 명시적으로 사용자 문서/커플 멤버십을 재연결하지 않으면 앱에서 자동으로 복구 데이터가 보인다고 말할 수 없다.
2026-04-30 재생성 카카오 계정 포인터 재연결
현유경 카카오 UID kakao_4869195578가 다시 생성된 뒤 users/kakao_4869195578.coupleId가 새 기본 커플 KB12s5s1BJJqnOLbwlE5를 가리키는 상태가 확인되었다. 해당 user 문서의 createdAt은 2026-04-29T15:04:00.214Z(KST 2026-04-30 00:04:00)로, 2026-04-28 포인터 수정 이후 새로 만들어진 문서였다. 이 새 기본 커플에는 기본성 문서 42개만 있었고, 복구 데이터가 있는 RKUw1xOVaA6COjHOdLAH에는 총 121개 문서가 남아 있었다.
공주님의 명시 요청에 따라 적용 전 백업을 저장한 뒤, 새로 생성된 users/kakao_4869195578 문서의 coupleId를 RKUw1xOVaA6COjHOdLAH로 업데이트하고 partnerCode를 삭제했다. 가드 조건으로 적용 직전 user 문서가 KB12s5s1BJJqnOLbwlE5를 가리키는지, 대상 커플 문서에 kakao_4869195578가 멤버로 들어있는지 확인했다. 백업 파일은 /Volumes/T5 EVO/Projects/WUMM/recovery-backups/kakao-reattach-recreated-user-2026-04-30T04-37-37-188Z.json이다.
적용 후 users/kakao_4869195578.coupleId == RKUw1xOVaA6COjHOdLAH로 확인되었고, updatedAt은 2026-04-30T04:37:42.161Z로 갱신되었다. 이전 새 기본 커플 KB12s5s1BJJqnOLbwlE5의 42개 기본 문서는 삭제하지 않고 남겨두었으며, 앱 표시 기준 포인터만 복구 커플과 일치시켰다. 이 상태에서는 앱이 users/{uid}.coupleId를 기준으로 작업공간을 열 때 현유경 카카오 계정도 복구 데이터가 있는 커플을 보게 된다.
2026-04-30 추가 확인에서 대상 커플의 checklists 74개 중 38개는 old couple t372b55WV4ps33cLSada에서 복구된 문서, 36개는 대상 커플에 원래 있던 문서로 확인되었다. 라벨 기준 33개 항목이 각각 2개씩 존재해 기본 체크리스트 템플릿 중복이 있다. 이는 포인터 재연결 때문에 새로 생긴 것이 아니라, 복구 당시 old couple의 체크리스트와 target couple의 기본 체크리스트가 함께 남은 결과다. 중복 없이 1개만 있는 복구 항목은 스촬/네일, 식중영상, 웨딩 무빙포스터, 혼주 메이크업, 혼주 한복 등이다.
동일 날짜에 현유경 카카오 계정이 현재 앱에서 보게 되는 체크리스트를 CSV/JSON으로 추출했다. 추출 기준은 users/kakao_4869195578.coupleId == RKUw1xOVaA6COjHOdLAH이며, 파일은 WUMM 프로젝트의 recovery-backups/hy-current-checklists-RKUw1xOVaA6COjHOdLAH-2026-04-30T04-49-56-822Z.{json,csv}에 저장했다. CSV는 카테고리/항목 계층, 완료 여부, 우선순위, 담당자, 생성자, 복구 출처, 생성·수정 시각, 마감일, 설명을 함께 담는다.
2026-04-30 저녁 현유경 포인터 재이탈 확인
19:34 KST 사용자 피드백 이후 현유경 상태를 다시 확인했다. Firebase Auth의 kakao_4869195578는 여전히 존재하고, Firestore users/kakao_4869195578 문서도 존재하지만 현재 coupleId가 복구 커플 RKUw1xOVaA6COjHOdLAH가 아니라 새 단독 커플 AlQDq25ovzNUQO5oGJlD로 바뀌어 있었다. 해당 변경 시각은 updatedAt: 2026-04-30T09:50:56.913Z(KST 18:50:56)이며, 같은 시각 couples/AlQDq25ovzNUQO5oGJlD가 user1Id: kakao_4869195578, user2Id: null로 생성되었다. 이 커플에는 기본 문서 42개와 현유경이 이후 추가한 것으로 보이는 업체 디아일 1개가 있어 총 43개 문서가 있었다.
복구 데이터 자체는 사라지지 않았다. RKUw1xOVaA6COjHOdLAH는 여전히 user1Id: 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2, user2Id: kakao_4869195578로 현유경 UID를 멤버로 보유하고 있고, 도메인 문서도 총 121개(budgetCategories 6, budgets 18, calendarEvents 1, checklists 74, vendors 2, milestones 20)가 유지된다. 그러나 이종환 users.coupleId는 RKUw1xOVaA6COjHOdLAH인 반면 현유경 users.coupleId는 AlQDq25ovzNUQO5oGJlD라서, 앱 표시 기준 포인터가 다시 불일치한다. 이는 iOS 26 이상 여부와 직접 연결하기보다 계정/커플 포인터 정합성 문제로 해석해야 한다.
원인 분석상 이번에는 계정이 다시 완전히 삭제/재생성된 패턴이라기보다, 앱의 커플 생성 플로우가 다시 실행된 패턴에 가깝다. users/kakao_4869195578.createdAt은 그대로인데 updatedAt과 새 커플 AlQDq25ovzNUQO5oGJlD.createdAt이 거의 같은 시각이고, CoupleService.createCouple(for:)는 새 couples 문서를 만든 뒤 users/{uid}.coupleId를 그 새 ID로 덮어쓴다. 이 경로는 couples where user1Id/user2Id == uid 역검색으로 기존 복구 커플을 찾아 붙이는 방어 로직이 없으므로, 앱이 커플 없음 상태로 판단한 화면에서 사용자가 시작 버튼을 누르면 수동으로 맞춰둔 포인터가 다시 새 커플로 바뀔 수 있다.
2026-05-01 현유경 이름 신규 아이디 확인
2026-05-01 13:39 KST 기준 Firebase Auth 207명과 Firestore users에서 현유경/유경/기존 이메일·UID 기준으로 다시 조회했다. 현유경으로 확인되는 계정은 3개이며, 직전 확인 이후 새로 추가된 별도 Firebase UID는 보이지 않는다.
가장 최근 생성 계정은 계속 추적 중인 카카오 UID kakao_4869195578이다. Auth 생성 시각은 KST 2026-04-30 00:03:58이고, 최근 토큰 갱신은 KST 2026-05-01 11:22:46이다. Firestore users/kakao_4869195578는 여전히 displayName: 현유경, email: "", coupleId: AlQDq25ovzNUQO5oGJlD 상태이며, Firestore user 문서의 createdAt은 KST 2026-04-30 00:04:00, updatedAt은 KST 2026-04-30 18:50:56이다.
나머지 동명이인/동일인 후보 계정은 Apple private relay UID JcsKXYjUK5gKxw54k5pxHFWEfgJ3와 이메일 계정 WY0lPuhTEyXYXXzkwTVoUF2dmm72다. 두 계정은 각각 PieVjNWieGw1PVeyxI5a, lOhDrdMlvgAKzX2hSO03의 별도 단독 커플을 가리키며, 복구 커플 RKUw1xOVaA6COjHOdLAH와는 앱 표시 기준으로 연결되어 있지 않다.
복구 커플 RKUw1xOVaA6COjHOdLAH에는 여전히 user1Id: 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2, user2Id: kakao_4869195578가 유지되고 도메인 문서 121개가 남아 있다. 따라서 신규 UID가 추가된 문제라기보다, 기존 카카오 UID의 users.coupleId가 복구 커플이 아닌 새 단독 커플 AlQDq25ovzNUQO5oGJlD를 계속 가리키는 정합성 문제로 보는 것이 맞다.
2026-05-01 현유경 카카오 포인터 재연결 적용
마잌킴의 명시 요청에 따라, 적용 전 백업을 남기고 users/kakao_4869195578 문서의 앱 표시 포인터를 복구 커플 RKUw1xOVaA6COjHOdLAH로 다시 맞췄다. 적용 직전 가드로 users/kakao_4869195578.coupleId == AlQDq25ovzNUQO5oGJlD인지, 대상 커플 RKUw1xOVaA6COjHOdLAH가 kakao_4869195578를 멤버로 포함하는지 확인했다.
백업 파일은 /Volumes/T5 EVO/Projects/WUMM/recovery-backups/hy-kakao-reattach-to-recovery-couple-2026-05-01T04-43-49-967Z.json이다. 적용한 변경은 users/kakao_4869195578.coupleId = RKUw1xOVaA6COjHOdLAH, partnerCode 삭제, updatedAt 서버 시각 갱신뿐이다. 새 단독 커플 AlQDq25ovzNUQO5oGJlD와 그 안의 기본 문서 43개는 삭제하지 않았다.
적용 후 검증에서 users/kakao_4869195578.coupleId == RKUw1xOVaA6COjHOdLAH, partnerCode 필드 없음, 대상 커플 user1Id: 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2, user2Id: kakao_4869195578가 확인되었다. 대상 복구 커플의 도메인 문서 수는 총 121개(budgetCategories 6, budgets 18, calendarEvents 1, checklists 74, vendors 2, milestones 20)로 유지된다.
2026-05-02 현유경 카카오 포인터 재이탈 재확인
2026-05-02 00:30 KST 읽기 전용 재확인에서, 현유경 카카오 계정의 앱 표시 포인터가 다시 복구 커플에서 새 단독 커플로 이탈한 상태가 확인되었다. users/kakao_4869195578.coupleId는 RKUw1xOVaA6COjHOdLAH가 아니라 Ao3NT42ZeJ2iEBfZeqMx였고, users.updatedAt은 2026-05-01T06:33:36.822Z다. 해당 새 커플 Ao3NT42ZeJ2iEBfZeqMx는 거의 같은 시각 생성되었으며 user1Id: kakao_4869195578, user2Id: null, totalBudget: 70000000, weddingDate: 2027-05-01T06:33:00.000Z 상태다.
현재 앱 표시 커플 Ao3NT42ZeJ2iEBfZeqMx에는 기본성 문서 총 42개만 있다: budgetCategories 6개, checklists 36개, 나머지 주요 컬렉션 0개. 반면 복구 커플 RKUw1xOVaA6COjHOdLAH에는 여전히 user1Id: 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2, user2Id: kakao_4869195578 멤버십과 총 121개 도메인 문서가 유지된다. 이종환 user 문서도 계속 RKUw1xOVaA6COjHOdLAH를 가리킨다.
따라서 이번 상태도 데이터 삭제가 아니라 users/{uid}.coupleId가 새 단독 커플로 덮어써지며 앱 표시 기준이 다시 어긋난 케이스다. 현유경 카카오 Auth는 존재하고 최근 로그인/토큰 갱신도 있으나, 현재 앱에서는 복구 데이터가 아닌 새 기본 커플 화면을 볼 가능성이 높다. 이는 2026-04-30 저녁의 AlQDq25ovzNUQO5oGJlD 재이탈과 같은 패턴으로, 수동 DB 포인터 수정만으로는 앱 플로우가 다시 새 커플을 만들 때 재발할 수 있음을 보여준다.
추가 코드 대조 결과, 재이탈의 직접 원인은 복구 커플 문서의 스키마 불일치로 좁혀졌다. Couple 모델은 totalBudget, createdAt, updatedAt을 필수 필드로 decode하는데, couples/RKUw1xOVaA6COjHOdLAH에는 totalBudget이 없고 estimatedBudget만 있다. 앱이 fetchCoupleForUser → fetchCouple → snapshot.data(as: Couple.self)로 해당 문서를 읽을 때 필수 키 누락 디코딩 에러가 나며, iOS의 localizedDescription이 “데이터가 유실되었기 때문에 읽을 수 없습니다”류로 표시된다. 이는 도메인 데이터 121개가 삭제되었다는 뜻이 아니라, 커플 문서 하나가 현재 앱 모델의 필수 필드 조건을 만족하지 않아 읽히지 않는다는 뜻이다.
이 에러가 나면 setupCoupleListener는 errorMessage만 설정하고 currentCouple은 nil로 남긴다. ContentView는 currentCouple == nil이면 CoupleSetupView를 보여주고, 사용자가 시작하기를 누르면 CoupleService.createCouple(for:)가 새 커플을 만든 뒤 users/{uid}.coupleId를 새 ID로 덮어쓴다. users.updatedAt과 새 커플 Ao3NT42ZeJ2iEBfZeqMx.createdAt이 거의 같은 시각인 것도 이 흐름과 맞다.
2026-05-02 복구 커플 재연결 및 스키마 보강 적용
마잌킴의 명시 요청에 따라 적용 전 백업을 저장하고 현유경 카카오 계정을 복구 커플로 다시 연결했다. 백업 파일은 /Volumes/T5 EVO/Projects/WUMM/recovery-backups/hy-kakao-reattach-with-couple-schema-fix-2026-05-01T15-38-21-326Z.json이다. 적용 직전 가드로 users/kakao_4869195578.coupleId == Ao3NT42ZeJ2iEBfZeqMx, 대상 커플에 kakao_4869195578 멤버십 존재, 이종환 user 문서가 대상 커플을 가리키는 상태를 확인했다.
적용 내용은 두 가지다. 첫째, users/kakao_4869195578.coupleId를 RKUw1xOVaA6COjHOdLAH로 변경하고 partnerCode를 삭제했다. 둘째, 앱 decode 실패를 막기 위해 couples/RKUw1xOVaA6COjHOdLAH.totalBudget = 80000000을 추가했다. 이 값은 prior old couple t372b55WV4ps33cLSada.totalBudget에서 확인된 원래 복구 대상 커플 예산값이다. 두 문서 모두 updatedAt을 서버 시각으로 갱신했다.
적용 후 검증에서 users/kakao_4869195578.coupleId == RKUw1xOVaA6COjHOdLAH, 대상 커플 user1Id == 3YbZlAJfRcbEEfQ5c1Y0xifKL7v2, user2Id == kakao_4869195578, totalBudget == 80000000이 확인되었다. 복구 커플의 도메인 문서 수는 총 121개로 유지된다. 새 단독 커플 Ao3NT42ZeJ2iEBfZeqMx와 그 안의 기본성 문서 42개는 삭제하지 않았다.
2026-05-02 파트너 코드 입력 경로별 영향 분석
A와 B가 모두 가입 후 각각 커플을 만들고 데이터를 입력한 뒤 B가 A의 파트너 코드를 입력하는 경우, 앱 안의 진입 경로에 따라 결과가 갈린다. 홈 화면 PartnerCodeCard의 코드 입력 버튼은 CoupleViewModel.joinCouple(userId:partnerCode:)를 호출하고, 이 함수는 A의 partnerCode로 A 사용자와 A의 coupleId를 찾은 뒤 CoupleService.linkPartner(coupleId: A_coupleId, partnerId: B_uid)만 실행한다. 이 경로에는 PR 106에서 추가한 mergeCoupleData(from:to:) 호출이 없다.
따라서 홈 카드 경로에서 B가 코드를 입력하면 couples/{A_coupleId}.user2Id = B_uid, users/{B_uid}.coupleId = A_coupleId, users/{B_uid}.partnerCode 삭제가 일어나고, 이후 setupCoupleListener와 MainTabView의 리스너들이 A의 커플 ID 기준으로 예산·일정·체크리스트·하객·업체·로드맵을 다시 듣는다. B가 기존 B 커플 ID에 작성해 둔 도메인 문서는 삭제되지는 않지만, coupleId가 B_oldCoupleId 그대로라 앱 표시 기준에서는 orphan처럼 보이지 않게 될 수 있다.
반면 더보기/설정의 파트너 연결 확인 경로는 verifyPartnerCode 후 confirmPartnerLink(userId:)를 호출한다. 현재 로컬 브랜치와 병합된 PR #106 기준으로 이 함수는 B의 기존 커플 ID와 A의 커플 ID가 다르면 먼저 mergeCoupleData(from: B_oldCoupleId, to: A_coupleId)를 실행하고, 그 뒤 linkPartner 및 old couple shell cleanup을 수행한다. 이 경로에서는 B의 기존 도메인 데이터가 A 커플 ID로 재귀속되어 두 사람이 같이 볼 수 있다. 다만 양쪽에 기본 체크리스트·예산 카테고리가 이미 있으면 중복은 남을 수 있으며, 현재 병합 로직은 dedupe하지 않는다.
제품 관점의 위험은 PR 106이 병합되었더라도 가장 눈에 띄는 홈 카드 입력 경로가 아직 joinCouple 직접 호출이라는 점이다. A/B 둘 다 데이터를 입력한 뒤 B가 홈 카드에서 코드를 넣는 실제 사용 시나리오에서는 병합 보호를 우회할 수 있으므로, 홈 카드도 verifyPartnerCode + 확인 시트 + confirmPartnerLink 또는 동등한 병합 포함 함수로 통일해야 한다.
세 가지 입력 순서로 나누면 다음과 같다. 첫째, A 가입 후 B 가입 후 파트너 성사까지 끝난 뒤 A가 데이터를 입력하면, 연결 이후 생성되는 데이터는 최종 공유 커플 ID에 붙기 때문에 두 사람이 함께 볼 수 있다. 둘째, A가 먼저 데이터를 입력하고 B가 나중에 가입·연결하면, A 데이터는 이미 최종 대상인 A 커플 ID에 있으므로 B도 연결 후 보게 된다. 셋째, A와 B가 각각 데이터를 입력한 뒤 연결하면, 홈 카드 경로에서는 A 데이터만 보이고 B old couple 데이터는 앱 표시 기준에서 orphan/invisible 상태가 될 수 있으며, 설정/확인 경로에서는 B old couple 데이터가 A 커플 ID로 병합된다. 따라서 실사용 리스크는 3번 케이스가 가장 크고, 홈 카드 입력 경로 통일이 핵심이다.