# F6-L3 Import Spec (Promoted)

**Extracted from:** `2026-04-25-dogfood-feedback.md` F6 §"L3 — 수동 전체 export / import"
**Plan:** `docs/superpowers/plans/2026-04-26-f6-l3-import.md`
**Status:** 🚀 promoted — implemented 2026-04-26
**Depends on:** F5 (`2026-04-26-f5-export.md`) — 본 항목은 F5 의 export 트리를 inverse 한다.

## 결정 (mini-brainstorm 결과)

| 결정 항목 | 값 | 근거 |
|----------|-----|------|
| 파싱 범위 | F5 export 포맷만 (`inkling_export_version: 1` 가정) | YAML 일반 파서 의존 회피 — F5 가 emit 하는 변형만 다룸 → dep 0, 코드 단순 |
| frontmatter parser | 자체 구현 (plain / single-quoted / `\|-` block / tags-flow / images-block) | composeFrontmatter 와 1:1 round-trip 가능. 일반 YAML 채택 시 `j-yaml` 등 dep 추가 + 호환 매트릭스 부담 |
| raw_text 추출 | 본문 구조 기반 (h1 / blockquote / image-ref 제거 후 잔여) | F5 의 composeMarkdown 출력을 정확 inverse. 모호 케이스 0 |
| 충돌 정책 | id 매치 + raw_text 동일 → skip · id 매치 + raw_text 상이 → 새 uuidv7 발급 후 INSERT (forked) · id 신규 → INSERT | slice §1.1 raw_text 불변 invariant 보호. 사용자에게 묻는 다이얼로그 회피 (현 dogfood 단일 사용자) |
| 미디어 복사 | 항상 (해당 노트가 inserted 또는 forked 일 때만) | skip 노트는 DB 에 이미 미디어 있음 → 중복 복사 회피 |
| 미디어 저장 경로 | `<profileDir>/media/{noteId}/{n}.{ext}` (MediaStore 컨벤션) | 기존 코드와 동일. media row 의 `relPath` 도 동일 형식 |
| AI 메타 보존 | ai_title, ai_summary, ai_provider, ai_generated_at, edited flags 모두 복원. ai_status='done' | 가져온 노트는 이미 AI 처리 완료 상태. pending_jobs 큐 추가 안 함 |
| 태그 source | ai/user 보존 | F5 에 정확히 emit 되어 있음 |
| 트리거 | 트레이 메뉴 "백업에서 복원..." | F5 의 "내보내기..." 와 대칭 |
| Preview UX | 디렉터리 선택 → preview (신규/스킵/충돌 카운트 + 이미지 수) → confirm 메시지박스 → run | 손상 가능 작업이라 한 번 확인. F5 와 톤 동일 |

## 구현 (PR 안에 포함됨)

- `src/main/services/importFormat.ts` — pure parser (300 lines)
- `src/main/services/ImportService.ts` — 오케스트레이터 (132 lines)
- `src/main/repository/NoteRepository.ts` — `findRawTextById()`, `importNote()` 추가
- `src/main/index.ts` — `ImportService` 인스턴스화 + 5번째 트레이 콜백
- `src/main/tray.ts` — "백업에서 복원..." 메뉴 항목
- `tests/unit/importFormat.test.ts` (18 단위 테스트)
- `tests/unit/ImportService.test.ts` (6 단위 테스트)

## 후속 (별 spec 또는 후속 항목 후보)

- 충돌 시 사용자 선택 다이얼로그 (덮어쓰기 vs skip vs 새 id) — 현재는 자동 forked
- 미디어 누락 (`media/foo.png` 가 export 트리에 없음) 시 graceful skip + 경고. 현재는 throw
- 부분 import (사용자 선택 노트만)
- import 후 dirty 노트 redirect (Inbox 자동 새로고침)
- 다중 export 트리 병합 (manifest.json 의 exported_at 기반 merge order)
- F1 (due_date) 필드가 promoted 되면 import 도 동기 — 현재 frontmatter 에 추가 키 무시되므로 forward-compatible
- 멀티 `inkling_export_version` 지원 — v2 도입 시 dispatch
- L2 git sync 와 자연스럽게 연결 (clone 직후 import 트리거)
- Round-trip 자동 회귀 테스트 — 전체 DB → export → wipe → import → diff (e2e)
- 한 번에 여러 sourceDir 머지 (예: 두 디바이스의 export 트리 합치기)
- 파일별 진행률 표시 (현재는 시작/완료만)
