← 목록
기타 2026-07-17 5KB 읽기 5분

크라우니 오피스 Phase 2 — 자동저장·복구

개요

크라우니 오피스 문서 편집기(crowny://office)에 크래시/강제종료/실수로 닫아도 편집 내용을 잃지 않는 자동저장·복구 계층을 추가했다. 앱 번들(bundle/office/app) 무수정, 기존 Phase 2-1 cdf(CWDv2) 엔진을 재사용. 회귀 하니스 27/27 유지.

무엇을 했는지

설계

  • 자동저장 스냅샷: ~/Documents/CrownyOffice/.autosave/<sanitize(title)>.cdf — 문서당 파일 1개
(디바운스 재저장은 같은 파일을 덮어씀, 무한 누적 없음).
  • 8초 간격 폴링(더티 플래그 + 경과시간 게이트, 정본 자동복구.한선 저장필요판정 미러).
  • 부팅 1회 native에 "고아 스냅샷 있는지" 문의(check) → 있으면 JS가 상단에 배너
"복구할 문서가 있습니다: <제목> [복구] [삭제]" 렌더 → 선택 시 native에 정리(discard) 통보.
  • ⌘S 정식 저장 성공 시 같은 문서의 autosave 스냅샷도 함께 정리(중복 복구 안내 방지).
  • 파일 I/O는 임시경로에 먼저 쓰고 최종 위치로 rename(move) — 크래시 시점에 쓰다 만 파일이
.autosave/ 최종 경로에 노출되지 않는다.

구현

  • bundle/office/bridge/crownyBridge.js §13(자동저장·복구, 파일 끝부분): 8초 폴링(더티 게이트),
postToNative('caAutosave', {action:'save'|'check'|'discard', ...}), 복구 배너 DOM, window.__crownyAutosaveOffer (native → JS 콜백), 복구 시 punch#3 undo스택 연동 (flushHistory/restoreHTML/commitSnapshot 재사용, 새 복원 로직 없음).
  • native/crowny-ai-content.m §Phase2:
  • caOfficeAutosaveDir().autosave/ 디렉토리(자동 생성).
  • caAutosave WKScriptMessageHandler 채널 신설(_ucc addScriptMessageHandler).
  • caHandleAutosaveMessage: — action 화이트리스트 3종(save/check/discard) 라우팅,
  • 8MB 페이로드 상한, JSON 파싱 실패/타입 불일치 조용히 폐기.
  • caAutosaveSaveWithTitle:html: — 문서저장.한선 save 모드(cdf 엔진) 재사용, 백그라운드 큐,
  • 임시파일→rename.
  • caAutosaveCheckForRecovery.autosave/ 스캔(최근 수정 파일) → cdf open 모드로 본문/제목
  • 복원 → base64(JSON) + TextDecoder('utf-8')로 JS에 안전 전달.
  • caAutosaveDiscardKey: — 경로탈출 방어(구분자·.. 거부) 후 스냅샷 삭제.
  • caSaveOfficeDocument(⌘S) 끝에 같은 키의 autosave 스냅샷 정리 추가.
  • 한선씨 정본: bundle/office/bridge/자동복구.한선 — crowny-word 자동저장복구.한선
  • (상태생성/저장필요판정/복구검출/복구실행/복구폐기)과 살균정책.한선 §5 파일명살균을 오피스 cdf 문맥으로 이식·재사용. 자체시험 23/23(스냅샷생성·복구판정·정상저장후정리· 크래시시나리오·주기·키생성 6그룹).

    실측 검증 (실셸, CrownyAI 네이티브 앱 — 헤드리스 아님)

    1. 앱 기동 → 오피스 → 문서 편집(⌘S 안 함) → ls ~/Documents/CrownyOffice/.autosave/
    문서.cdf 생성 확인, 내용에 편집한 마커 텍스트 포함 확인.
    1. kill -9로 강제종료 → 스냅샷 파일 디스크에 생존 확인.
    2. 재기동 → 오피스 진입 → "복구할 문서가 있습니다: 문서" 배너 자동 등장(스크린샷) →
    [복구] 클릭 → 편집 내용(마커 텍스트 포함) 정상 복원 확인(스크린샷), 배너 사라짐.
    1. ⌘S 정식 저장 → 저장 토스트 확인 → .autosave/ 디렉토리 빈 것 확인(정리 성공).
    2. 추가로 편집→8초 폴링 대기→autosave 파일 재생성 확인→⌘S→autosave 파일 삭제 재확인.

    버그 발견 및 수정 (실측 중 발견)

    1차 구현에서 native→JS 전달에 atob(base64) 결과를 바로 JSON.parse했더니 한글이 mojibake로 깨짐(atob는 바이트당 1문자 이진 문자열만 반환, UTF-8 디코딩을 하지 않음). Uint8Array + TextDecoder('utf-8')로 정식 디코딩 후 JSON.parse하도록 수정, 재검증으로 정상 복원 확인.

    관련 파일

    • /Users/ef/crownybrowser/bundle/office/bridge/crownyBridge.js (§13 자동저장·복구 섹션 추가)
    • /Users/ef/crownybrowser/bundle/office/bridge/자동복구.한선 (신규, 자체시험 23/23)
    • /Users/ef/crownybrowser/native/crowny-ai-content.m (§Phase2 자동저장·복구, caAutosave 채널)
    • /Users/ef/crownybrowser/spec/오피스-개발계획.md (Phase 2 항목 — 후속 업데이트 필요)
    • /Users/ef/crownybrowser/spec/문서-회귀리포트.md (27/27 최신 리포트)

    잔여 이슈

    • 자동저장 대상 탭 판정이 self.activeTab 기반(신셸 전반 관용구와 동일) — 사용자가 오피스
    탭에서 편집 후 다른 탭으로 전환하면 그 순간 이후 autosave 폴링이 멈춘다(활성 탭이 아니므로). 편집 자체가 활성 탭에서만 일어나므로 실사용 영향은 낮음.
    • 여러 오피스 탭을 동시에 열어 각기 다른 문서를 편집하는 시나리오는 아직 문서별 tab 식별자가
    없어 키 충돌 가능성이 있음(현재는 제목 기반 키만 사용). Phase 2 후속(cdf 왕복 무손실 강화) 단계에서 함께 검토 필요.
    • cdf 저장 자체가 아직 "본문 HTML 통짜" 저장(구조 분해 전, Phase2 설계 문서에 명시된 1단계
    방침) — 자동저장도 동일 한계를 상속(무손실이지만 셀 단위 구조화는 아님).