# Cross Device Handoff And Session Continuity

## 목적

메신저는 단일 기기 앱이 아니라 `흐름이 이어지는 도구`여야 한다.  
사용자는 PC에서 읽다가 모바일에서 이어 보고, 모바일에서 초안을 쓰다가 데스크톱에서 마무리한다.  
이 흐름이 부자연스럽다면 기능이 많아도 실제 체감은 낮다.

이 문서는 Windows 데스크톱, 모바일 웹, 안드로이드가 병렬로 존재하는 상황에서 `세션이 끊기지 않고`, `문맥이 보존되며`, `같은 일을 다시 하지 않아도 되는` 제품 설계를 정의한다.

## 현재 산출물의 핵심 리스크

- 모바일 웹에서 세션 만료가 발생하면 사용자는 제품 전체를 불안정하게 느낀다.
- 기기 전환 시 마지막으로 보던 대화, 읽지 않은 구간, 작성 중 초안이 유지되지 않는다.
- 실제 구현보다 문서가 앞서 있어 사용자 기대와 현실 사이의 간극이 생긴다.
- `다른 기기에서 다시 해야 하는 일`이 많을수록 메신저의 신뢰도는 빠르게 하락한다.

## 핵심 원칙

### 1. 세션 연속성은 편의 기능이 아니라 신뢰 기능이다

- 사용자는 토큰 구조를 이해하지 않는다.
- 사용자가 이해하는 것은 `갑자기 다시 로그인해야 했는가`, `쓰던 것이 남아 있었는가` 뿐이다.
- 따라서 세션 설계는 보안과 UX를 함께 다뤄야 한다.

### 2. 기기 전환 비용은 거의 0에 가까워야 한다

- 다른 기기에서 앱을 열었을 때 마지막 대화와 읽지 않은 구간이 보여야 한다.
- 최소한 `어디서 멈췄는지`는 기억돼야 한다.
- 사용자는 다시 검색하고 다시 스크롤하고 다시 정리하는 과정을 반복하고 싶어 하지 않는다.

### 3. 작성 중 상태는 로컬과 서버를 함께 활용해 지킨다

- 로컬 캐시는 즉시성에 강하고, 서버 초안은 기기 간 이동에 강하다.
- 둘 중 하나만 있으면 경험이 끊긴다.

## 지원해야 하는 전환 시나리오

### PC -> 모바일 웹

- 퇴근 직전 PC에서 읽던 업무방을 모바일에서 바로 이어 본다.
- 방금 입력하던 초안은 `이어쓰기` 카드로 복원된다.
- PC에서 연 파일과 링크는 모바일에서 `최근 작업 항목`으로 보인다.

### 모바일 웹 -> PC

- 이동 중 모바일에서 가볍게 읽고, 자리로 돌아와 PC에서 자세히 답변한다.
- 읽음 커서는 서버 기준으로 즉시 동기화된다.
- 긴 답장이나 파일 첨부가 예상될 때 `PC에서 이어쓰기` 제안을 보여 줄 수 있다.

### 안드로이드 -> PC

- 푸시 알림에서 확인만 해 둔 대화가 PC에서 `방금 모바일에서 본 대화`로 우선 노출된다.
- 사진 업로드 직후 PC에서 해당 스레드가 자동 포커스된다.

### 다중 데스크톱 창

- 메인 창과 팝아웃 창이 동시에 열려 있어도 상태 충돌이 없어야 한다.
- 읽기 커서와 드래프트는 창 단위가 아니라 사용자 단위로 동기화되어야 한다.

## 세션 정책

## 인증 수명 정책

- 액세스 토큰은 짧게 가져가되, 리프레시 경로는 사용자가 느끼지 못하도록 매끄럽게 동작해야 한다.
- 세션 만료 예정 시 조용히 갱신을 시도하고 실패할 때만 명시적으로 안내한다.
- 사용자가 작성 중일 때는 로그인 강제 이동을 하지 않는다.
- 먼저 드래프트 보존, 그 다음 세션 복구, 마지막으로 재인증 순서를 따른다.

## 장치 등록 정책

- 각 기기는 `신뢰 장치`로 등록된다.
- 등록 시 보이는 항목:
  - 장치명
  - OS
  - 최근 사용 시각
  - 대략적 지역
- 사용자는 활성 장치를 한눈에 보고 원격 로그아웃할 수 있어야 한다.

## 안전 장치

- 낯선 장치 로그인 시 기존 기기에 약한 알림을 보낸다.
- 비밀번호 없는 Alpha 단계에서도 장치 목록과 강제 로그아웃은 제공한다.
- 민감한 장치 작업은 최근 인증 재확인을 붙인다.

## 상태 동기화 모델

### 반드시 동기화할 상태

- 마지막으로 보던 대화
- 각 대화의 읽음 위치
- 임시 저장된 초안
- 고정/무음/업무방/친한 대화 상태
- 최근 검색 기록
- 최근 연 파일과 링크
- 알림 선호도

### 로컬 전용으로 남길 상태

- 창 분할 비율
- 특정 기기의 로컬 UI 밀도 설정
- 최근 열어 본 팝아웃 창 배치
- 임시 개발용 진단 토글

### 서버 우선 상태

- 읽음 커서
- 초안 메타데이터
- 장치 목록
- 멀티 디바이스 충돌 해결 버전

## 충돌 해결 원칙

- 같은 대화 초안을 두 기기에서 동시에 수정하면 가장 최근 수정본을 기본 제안으로 둔다.
- 다만 최근 이전본도 `다른 기기 초안`으로 되돌릴 수 있어야 한다.
- 읽음 커서는 더 뒤로 간 위치를 우선으로 한다.
- 무음, 고정 상태는 마지막 변경 시각 기준으로 반영한다.

## UI 설계

## 데스크톱

- 사이드바 상단에 `다른 기기에서 이어보기` 섹션을 둘 수 있다.
- 설정의 계정 화면에서 장치 목록과 세션 상태를 보여 준다.
- 세션 이상 시 화면 전체 차단 대신 상단 배너를 사용한다.
- 팝아웃 창은 세션 만료 후에도 즉시 닫히지 않고 복구 시도 후 상태를 안내한다.

## 모바일 웹

- 로그아웃 공포를 줄이기 위해 `세션을 확인하는 중` 상태를 자연스럽게 보여 준다.
- 브라우저 재시작 후 첫 진입 시 마지막 대화를 가장 먼저 복원한다.
- 초안 복원은 배너보다 입력창 안의 작은 힌트로 노출한다.

## 안드로이드

- 푸시에서 진입한 대화가 이미 다른 기기에서 읽혔더라도 관련 문맥은 남겨 준다.
- 이미지 업로드, 카메라 전환, 백그라운드 재개 중 세션 갱신 실패를 견디는 설계가 필요하다.

## 업무적 소통 강화 장치

- 회의 전 `최근 사용 장치`를 기준으로 가장 적합한 기기에서 열어 보게 유도한다.
- 데스크톱에서는 회의방, 작업방, 나에게 보내기 메모를 서로 다른 창으로 띄울 수 있어야 한다.
- 모바일에서 `나중에 PC에서 정리` 플래그를 남기면 PC에서 바로 보인다.
- 링크와 파일은 기기 전환 후에도 같은 문맥에서 이어서 열린다.

## 친근한 소통 강화 장치

- 사진과 음성 중심 대화는 모바일에서 이어 쓰기 쉬워야 한다.
- 데스크톱에서 읽던 사적 대화는 모바일에서 `가볍게 이어보기` 수준으로 복원한다.
- 친구 대화의 경우 장치 목록 노출이 과도하게 불안감을 주지 않도록 문구를 차분하게 설계한다.

## 실패 시나리오

- 세션 갱신 실패
- 오프라인 상태에서 앱 재실행
- 장치 시간이 어긋난 상태
- 장치 간 읽음 커서 지연
- 초안 충돌
- 서버 점검 또는 배포 직후 재연결 실패

각 실패는 `사용자에게 무슨 일이 일어났는지`, `다음에 무엇이 보장되는지`, `무엇을 눌러야 하는지`가 1문장 안에 설명되어야 한다.

## QA 기준

- 토큰 만료 후 재진입 시 90% 이상이 재로그인 없이 복구돼야 한다.
- 작성 중 초안 손실률은 0에 가깝게 관리해야 한다.
- 기기 전환 후 마지막 대화 복원 성공률을 핵심 KPI로 둔다.
- 모바일 웹은 브라우저 종료/재개, PWA 홈 진입, 백그라운드 복귀를 반드시 반복 검증한다.

## 단계별 범위

### Alpha

- 장치 등록
- 읽음 커서 동기화
- 마지막 대화 복원
- 로컬 초안 보존

### Beta

- 서버 초안 동기화
- 장치 목록/원격 로그아웃
- 세션 자동 갱신
- 모바일에서 PC로 이어쓰기 제안

### Later

- 패스키 기반 신뢰 장치
- 다중 창/다중 계정 고급 정책
- 작업 흐름 기반 장치 추천

## 완료 기준

- 사용자가 `어느 기기에서 열어도 이어진다`고 느껴야 한다.
- 세션 만료는 보안 문제로는 엄격하되, 사용자 체감으로는 거의 드러나지 않아야 한다.
- 기기 전환이 불편해서 특정 메신저를 포기하지 않도록 해야 한다.
