# 03. LiveDoc 실시간 동기화 파이프라인

> 이 문서는 Fricle의 **상태(세션) 저장 및 실시간 동기화** 구조를 비코딩 관점으로 정리한다.
>
> **사업 본질 정합** = **상태 손실 해소** (= 세션 자체 자동 저장 + 워크스페이스 단위 복원) + **협업 끊김 해소** (= 실시간 동시 편집 + 비동기 = 한 워크스페이스 안 통합) (= 사업 본질 출처 = [../README.md](../README.md)).
>
> **시장 정합 / 반례** = 이 영역 잘 해소: Figma (= 자동 저장 + autosave checkpoint) / VS Code (= 세션 복원) / Arc Browser (= 탭 / Spaces 복원) / Google Docs (= 자동 저장 + 실시간). 부재로 문제: 일반 SaaS = 문서 내용만 저장 = 앱 상태 / 캔버스 위치 / 멀티앱 레이아웃 = 잃음. 상세 = [MARKET_REFERENCES.md §2 / §3](./MARKET_REFERENCES.md).

---

## 개요

Fricle은 **파일 중심이 아니라 세션·상태 중심**. 유저가 체감하는 "창 닫았다 열어도 그대로"의 기반.

핵심 원칙: **앱 상태 전체를 이벤트 기반으로 저장**. 단순히 "문서 내용" 저장이 아니라:
- 스크롤 위치 / 줌
- 열려 있는 패널
- 선택된 객체
- Pin 상태 / Stage 배치 (Stage는 사용자×디바이스별 localStorage 저장 — LiveDoc 동기화 X)
- 멀티앱 레이아웃

전부 상태로 취급.

---

## 파이프라인 흐름

```
사용자 액션 발생
→ 앱 내부 상태 변경
→ 이벤트 단위로 추상화
→ 로컬 임시 상태 반영 (optimistic)
→ LiveDoc 엔진 전송
→ CRDT 자동 병합 (충돌 시)
→ DB 영속 (LiveDoc 스냅샷)
→ 참여자에게 동기화
→ 버전 / 히스토리 적재
```

> 파일 업로드는 이 흐름과 별도. 저장소 3종(Personal/AppData/External)으로 분기 → [05](./05-STORAGE_BILLING.md)

### 데이터 경로 분기

유저 행동에 따라 **다른 경로**로 흐른다:

```
[유저 입력]
   │
   ├─ 텍스트/데이터 편집 ─→ LiveDoc ─→ 동기화 서버 ─→ DB
   │                                    ↕
   │                               다른 참여자
   │
   ├─ 파일 업로드 ──→ 저장소 3종 중 하나 (→ 05)
   │
   └─ 배치/메타 ──→ DB (복원 기반)
```

- **LiveDoc 경로**: 실시간 동시 편집 데이터. CRDT 자동 병합
- **파일 경로**: LiveDoc에 안 들어감. Workspace AppData / Personal Drive / External Drive로 분기 (→ 05)
- **배치/메타 경로**: 캔버스 배치, 카메라 위치, 앱 크기 등. DB에 복원 기반으로 저장

### LiveDoc 기준

- **기본**: 앱 인스턴스 전용 문서(Instance Doc)
- **확장 가능**: 앱 공유 문서로 (미래)
- **협업 성능** (동시 편집자 수, 히스토리 보존): 워크스페이스 플랜으로 제어 (→ 05)

### 협업 동기화

```
[유저 A 입력]                         [유저 B 화면]
    │                                       ▲
    ▼                                       │
 LiveDoc ──────▶ 동기화 서버 ──────▶ LiveDoc
    │                                       │
    └────────── DB 영속 ────────────────────┘
```

- 동시 편집 시 CRDT 자동 병합 (덮어쓰기 걱정 없음)
- 유저 체감: "누가 먼저 쓰든 합쳐진다"

### 오프라인 / 재연결

- **오프라인 중**: LiveDoc 편집 가능 (로컬 Yjs 상태 유지) / 파일 업로드는 큐 대기
- **재연결 시**: 로컬 변경분 자동 동기화 + 큐에 쌓인 파일 업로드
- **UI 피드백**: 메뉴바 연결 상태 뱃지만

---

## 유저 체감 연결

01-USER_FLOW의 아래 단계와 연결:
- **5. 첫 작업 생성** — LiveDoc 초기화, 내용 쓰면 즉시 반영
- **6. 저장/복원** — 이 파이프라인이 "웹 OS 같네" 체감의 핵심 엔진
- **8. 공유 시도** — 실시간 동시 편집, 팀원 화면에 즉시 반영

유저 체감으로는 "내가 쓰면 다른 사람 화면에 바로 보인다, 닫았다 열어도 그대로". 내부적으로는 **이벤트 → LiveDoc → 동기화 서버 → DB** 흐름이 매 액션마다 돔.

---

## 다른 파이프라인과의 연결

- **선행 입력**: 02-APP_RUNTIME의 "초기 상태 로드" (LiveDoc/DB 일회성 읽기) + "LiveDoc 이벤트 구독 시작" 단계
- **영향 받는 문서**:
  - 04-PERMISSION_LICENSE (LiveDoc ↔ 라이선스 분리 원칙. 차단 경계 매트릭스)
  - 05-STORAGE_BILLING (파일 업로드는 AppData/Drive로 분기. LiveDoc 동기화량은 계측 대상. 협업 성능 한도는 플랜으로 제어)
- **사이드 이펙트**:
  - LiveDoc 이벤트 기준이 바뀌면 02의 앱 마운트 수정 필요
  - 저장 경로 분기가 바뀌면 05의 저장소 라우팅 수정 필요
  - 라이선스 차단 경계가 바뀌면 04의 판정 로직 수정 필요
  - 협업 성능 한도가 바뀌면 05의 플랜 정의 수정 필요

---

## 결정됨

- **LiveDoc = 앱이 공유하는 살아있는 데이터 층** (Yjs CRDT 기반)
- **상태 저장 = 이벤트 기반** (파일 저장 아님)
- **Instance Doc 기본** — 인스턴스별 독립
- **CRDT 자동 병합** — 동시 편집 시 덮어쓰기 걱정 없음
- **워크스페이스 영속성** — 다음 접속 시 상태 복원
- **데이터 범위**: `instance` / `shared` 중 앱이 선택

---

## 결정 필요

(비어있음)

---

## 논의 중

- **LiveDoc ↔ 라이선스 분리 원칙** — V2 [결정안]. 데이터 층 동적 차단 없음 방향. 라이선스 회수 / 만료 시 기존 인스턴스 / 데이터 운명 = [License & Seat](../architecture/01-license-seat.html) open issue = 결정 후 03 정합 갱신
- **협업 성능 플랜 제어** — V2 제시. 동시 편집자 수/히스토리 보존 등을 플랜으로 제어. 비즈니스 논의 시 확정
- **LiveDoc 차단 경계 매트릭스** — "Viewer + 앱 Operate 없음" 같은 조합별 실제 가능/불가 명세
- **오프라인 편집 정책** — Yjs가 하드 파트 처리하지만 정책(권한 변경/토큰 만료/충돌 엣지 케이스) 결정 필요

---

## 고려 사항

(없음)
