Backup DB Viewer 설계
Backup DB Viewer 설계
Status: draft for review. Implementation plan not written yet.
문제
Backup Engine v2는 백업 목록과 메타데이터를 .vibelign/vibelign.db에 저장하고, 실제 파일 내용은 .vibelign/rust_objects/에 중복 없이 보관한다. GUI의 BACKUPS 화면은 사용자가 이해하기 쉬운 백업 목록을 보여주지만, 개발자/관리자가 DB 기준으로 상태를 확인하기는 어렵다.
- 백업 DB가 Rust v2 경로를 정상 사용 중인지
- 백업별 파일 수, 실제 저장 크기, 재사용 파일 수, 생성 이유가 무엇인지
- 자동 백업 설정과 정리 정책이 어떤 값인지
- GUI 목록에 보이는 백업이 DB row와 어떻게 매칭되는지
반대로 .vibelign/vibelign.db를 일반 SQLite 편집기처럼 직접 편집하게 하면 복원 무결성이 깨질 수 있다. 특히 checkpoint_files, cas_objects, object_hash, ref_count, engine_version, checkpoint_id는 복원·미리보기·정리 로직이 직접 의존한다. 첫 구현은 편집 기능을 넣지 않고, DB를 안전하게 볼 수 있는 읽기 전용 viewer로 제한한다.
목표
BACKUPS 탭 안에 자식 메뉴인 Backup DB Viewer를 추가해 .vibelign/vibelign.db의 상태와 백업 메타데이터를 읽기 전용으로 확인할 수 있게 한다.
핵심 원칙:
- 이 기능은 Raw SQL 편집기가 아니라 백업 DB 뷰어다.
- 첫 구현은 읽기 전용이다.
- DB 내용을 raw table dump처럼 노출하지 않고, 요약 카드·검색 가능한 목록·상세 패널로 읽기 쉽게 보여준다.
- 편집 기능은 후속 phase로 분리한다.
- React에서 SQL 문자열을 보내지 않는다.
- 복원에 필요한 내부 테이블과 해시/object 저장소 정보는 읽기 전용이다.
사용자에게 보이는 말 규칙:
| 내부 용어 | 사용자에게 보이는 말 |
|---|---|
| checkpoint | 백업 / 저장본 |
| checkpoint_id | 저장본 ID |
| trigger | 만들어진 이유 |
| post_commit | 코드 저장 뒤 자동 보관 |
| CAS object | 중복 없이 보관한 파일 |
| vibelign.db | 백업 관리 DB |
| raw SQL | 화면에 표시하지 않음 |
범위
포함
- BACKUPS 화면의 자식 메뉴로 들어갈 수 있는 Backup DB Viewer
- 백업 DB 상태 요약
- 백업 row 상세 조회
- object store 통계 조회
- 백업 관리 DB 파일 크기(
vibelign.db,vibelign.db-wal,vibelign.db-shm) 조회 - 자동 백업 설정 조회
- 정리 정책 조회
- GUI 백업 목록과 DB row 매칭 확인
- checkpoint table / object table / retention table의 읽기 전용 요약
제외
- 임의 SQL 실행창
- 모든 DB 편집 기능
checkpoint_files편집cas_objects편집- object 파일 직접 삭제/이동
- 백업 DB schema migration을 GUI에서 수동 실행하는 기능
- Python fallback JSON checkpoint를 같은 화면에서 편집하는 기능
Python fallback 백업은 .vibelign/checkpoints/ JSON manifest를 사용한다. 이번 기능은 Rust/SQLite 백업 DB viewer이며, fallback JSON 백업 viewer/edit 기능은 별도 후속 기능으로 둔다.
읽기 전용 정책
첫 구현은 DB를 수정하지 않는다. 다음 값은 표시할 수 있지만 편집할 수 없다.
checkpoints.checkpoint_idcheckpoints.created_atcheckpoints.engine_versioncheckpoints.parent_checkpoint_idcheckpoints.triggercheckpoints.git_commit_shacheckpoints.git_commit_messagecheckpoints.total_size_bytescheckpoints.file_countcheckpoints.original_size_bytescheckpoints.stored_size_bytescheckpoints.reused_file_countcheckpoints.changed_file_count- 모든
checkpoint_files.* - 모든
cas_objects.* db_meta.schema_versiondb_meta.created_at
trigger, git_commit_sha, git_commit_message는 provenance 정보이므로 처음에는 읽기 전용으로 둔다. 나중에 사용자가 수동 수정 필요성을 명확히 제기하면 별도 spec에서 다룬다.
DB 파일 성장 정책
기존 retention_policy.max_total_size_bytes는 백업 데이터와 CAS/object-store 정리 기준이다. SQLite 관리 파일인 .vibelign/vibelign.db 자체는 row 삭제 후에도 즉시 작아지지 않을 수 있고, WAL 모드에서는 .vibelign/vibelign.db-wal과 .vibelign/vibelign.db-shm도 함께 관찰해야 한다. 따라서 DB 파일 성장 정책은 object-store retention과 분리한다.
첫 구현에서 DB Viewer는 다음을 읽기 전용으로 표시한다.
vibelign.db크기vibelign.db-wal크기vibelign.db-shm크기- 세 파일의 합산 크기
운영 정책:
- 64MB 이상: 경고 상태로 표시하고, 백업 정리 뒤 DB 압축/정리 필요성을 안내한다.
- 256MB 이상: 강한 경고 상태로 표시하고, 별도 CLI maintenance 명령에서 compaction을 수행해야 한다.
- DB Viewer는 여전히 읽기 전용이다.
VACUUM,PRAGMA wal_checkpoint(TRUNCATE),incremental_vacuum같은 쓰기/정리 작업은 이 화면에서 직접 실행하지 않는다. - 실제 DB compaction은
vib backup-db-maintenance명령으로 분리한다. 기본은 dry-run이며, 실제 정리는--apply를 붙였을 때만 실행한다. 이 명령은 백업 작업 중이 아닐 때만 실행하고, 실행 전 quick-check/잠금 확인/DB 원본 파일 백업을 수행한다. - Rust와 Python fallback의 백업 대상 정책은 정렬해야 한다. Rust snapshot은
.vibelign/vibelign.db*를 제외하므로, Python fallback도 동일한 제외 정책을 갖는지 별도 확인·수정한다.
maintenance 명령의 동작:
- dry-run에서
vibelign.db*크기,page_size,page_count,freelist_count,quick_check, 실행 계획을 보고한다. --apply에서.vibelign/db_maintenance_backups/<timestamp>/에vibelign.db,vibelign.db-wal,vibelign.db-shm원본을 먼저 복사한다.PRAGMA wal_checkpoint(TRUNCATE)로 WAL을 먼저 비운다.- 삭제된 row가 많고 freelist가 큰 경우에만
VACUUM또는 안전한 compaction 전략을 수행한다. - compaction 전후의 DB/WAL/SHM 크기와 reclaim 추정치를 보고한다.
- 실패 시 원본 DB를 손상시키지 않고 명확한 복구 안내를 반환한다.
데이터 모델
첫 구현은 신규 테이블을 만들지 않는다. DB viewer는 기존 Rust/SQLite schema를 읽기만 한다.
읽는 테이블:
db_metacheckpointscheckpoint_files요약retention_policycas_objects요약
DB Viewer는 새 schema를 만들거나 migration을 수행하지 않는다.
Backend API 설계
React는 DB를 직접 열지 않는다. 다음 중 하나로 backend API를 제공한다.
- Rust 엔진 IPC command 추가
- Python CLI command 추가
- Tauri native command 추가
추천은 Rust 엔진 IPC command 추가 + Python wrapper + GUI wrapper다. 백업 DB schema와 restore invariants가 Rust 엔진에 있으므로, DB viewer도 같은 경계에서 읽는 편이 안전하다.
Engine requests
BackupDbViewerInspect { root: PathBuf }
첫 구현에는 update request를 추가하지 않는다.
Inspect response
{
"db_exists": true,
"db_file": {
"database_bytes": 40960,
"wal_bytes": 0,
"shm_bytes": 32768,
"total_bytes": 73728
},
"schema_version": "3",
"checkpoint_count": 2,
"rust_v2_count": 2,
"legacy_count": 0,
"cas_object_count": 861,
"cas_ref_count": 2144,
"total_original_size_bytes": 281637991,
"total_stored_size_bytes": 134709997,
"auto_backup_on_commit": true,
"retention_policy": {
"keep_latest": 30,
"keep_daily_days": 14,
"keep_weekly_weeks": 8,
"max_total_size_bytes": 1073741824,
"max_age_days": 180,
"min_keep": 20
},
"checkpoints": []
}
checkpoints[]에는 BACKUPS 화면보다 더 많은 읽기 전용 필드를 포함한다. 단, checkpoint_files 전체 목록은 기본 응답에 넣지 않는다. 대형 프로젝트에서 응답이 과도하게 커질 수 있기 때문이다. 파일 목록은 선택한 백업 상세에서 lazy load하는 후속 API로 확장한다.
Validation 규칙
첫 구현은 읽기 전용이므로 write validation은 없다. Inspect request는 다음만 검증한다.
root는 프로젝트 루트로 resolve되어야 한다.- DB path는 반드시
root/.vibelign/vibelign.db여야 한다. - schema version이 현재 엔진보다 높으면 writable state를 가정하지 않고 읽기 전용 경고만 표시한다.
Transaction / Audit 규칙
첫 구현은 write transaction과 audit row를 만들지 않는다. Inspect는 read-only connection으로 열고 가능한 경우 PRAGMA query_only=ON을 적용한다.
GUI 설계
진입점
초기 구현은 BACKUPS 화면 안에 자식 메뉴를 추가한다.
BACKUPS
├─ 백업 목록
└─ Backup DB Viewer
이유:
- 기능이 백업 DB에 직접 연결된다.
- Settings는 API 키와 전역 설정이 중심이라 백업 상세 관리와 거리가 있다.
- 사용자는 백업 목록을 보다가 바로 DB 상세로 들어가는 흐름이 자연스럽다.
화면 구조
Backup DB Viewer는 BACKUPS 페이지 안의 별도 child view로 연다. 상단에는 백업 목록 / DB Viewer 전환 탭을 둔다.
기존 BACKUPS UI는 BackupCard, SafetySummary, StorageSavings, FileHistoryTable, RestorePreviewPanel처럼 요약 카드, 검색 가능한 목록, 선택 항목 상세 패널을 조합한다. DB Viewer도 이 패턴을 따른다. SQLite table을 그대로 펼치는 화면이 아니라, DB row를 사람이 읽기 쉬운 백업 상태 정보로 번역해 보여준다.
섹션:
- DB 상태
- DB 경로
- DB 파일/WAL/SHM 크기
- schema version
- Rust v2 백업 수
- object 수
- 저장공간 재사용 요약
- 자동 백업 상태
- 백업 DB rows
- 백업 ID
- 표시 이름
- 생성 시간
- 보호 여부
- 만들어진 이유
- 파일 수
- 원본 크기 / 실제 저장 크기
- 재사용 파일 수 / 변경 파일 수
- GUI 표시 이름과 DB message 매칭
- 정리 정책
- 보존 개수
- 일/주 대표 백업 보존 기간
- 최대 저장 크기
- 최대 보존 기간
- Object store
- object 수
- ref count 합계
- 압축/저장 크기 요약
.vibelign/rust_objects/blake3존재 여부
가독성 요구사항
- 화면 첫 영역은 숫자 카드로 구성한다: 전체 백업 수, Rust v2 백업 수, object 수, 원본 대비 저장 크기, 자동 백업 상태.
- 백업 목록은 raw DB table이 아니라 검색 가능한 row list로 표시한다. 각 row는 백업 이름/생성 시간/만들어진 이유/파일 수/저장 효율을 우선 보여준다.
- 내부 column 이름은 기본 화면에 그대로 노출하지 않는다. 예:
checkpoint_id는 “저장본 ID”,trigger는 “만들어진 이유”,stored_size_bytes는 “실제 저장 크기”로 표시한다. checkpoint_id,object_hash,ref_count처럼 복원 무결성과 관련된 값은 상세 패널의 “고급 정보” 또는 “복원 내부값” 영역으로 접는다.- selected row 상세 패널에는 사람이 먼저 확인할 정보와 내부값을 분리한다.
- 먼저 표시: 표시 이름, 생성 시간, 만들어진 이유, git commit, 파일 수, 변경/재사용 파일 수, 원본 크기, 실제 저장 크기.
- 접어서 표시: 저장본 ID, parent ID, engine version, object hash 관련 요약, schema/debug 정보.
- 긴 git commit message와 긴 path/hash 값은 한 줄 요약 + 복사 버튼 또는 펼치기 UI로 처리한다.
- 경고/상태는 badge로 표시한다:
Rust v2,자동 백업,수동 백업,읽기 전용,schema 경고,DB 없음. - Object store는 파일 해시 목록부터 보여주지 않는다. 먼저 “얼마나 중복 제거됐는지”, “object store가 존재하는지”, “참조 수가 정상 범위인지”를 요약한다.
- 빈 상태와 오류 상태도 초보자가 이해할 문장으로 보여준다. 예: “아직 Rust 백업 DB가 없어요. 백업을 먼저 만들어 주세요.”
- 첫 구현에서 dense grid/table은 보조적인 고급 보기로도 넣지 않는다. 필요한 경우 후속 phase에서 export/read-only advanced view로 분리한다.
UX
- 기본은 읽기 전용이다.
- DB row를 선택하면 오른쪽 또는 하단에 상세 정보를 보여준다.
- 위험한 내부 필드는 “복원에 쓰이는 값” 배지를 붙여 편집할 수 없음을 분명히 한다.
- 새로고침 버튼은 inspect API를 다시 호출한다.
- 편집 버튼은 첫 구현에 넣지 않는다.
파괴적 표현을 피한다. 예를 들어 “DB 수정” 대신 “DB 상태 보기”, “백업 DB rows”, “저장소 요약”처럼 읽기 전용 표현을 사용한다.
Error handling
- DB 파일이 없으면 “아직 Rust 백업 DB가 없어요. 백업을 먼저 만들어 주세요.”를 표시한다.
- Rust 엔진을 찾지 못하면 “백업 관리 DB를 읽을 수 없어요. 설치된 앱/CLI의 백업 엔진을 확인해 주세요.”를 표시한다.
- schema version이 예상보다 높으면 읽기 전용 모드로만 연다.
- DB lock 때문에 read가 실패하면 “다른 백업 작업이 끝난 뒤 다시 새로고침해 주세요.”를 표시한다.
Security / Safety
- React webview에는 SQL 실행 권한을 주지 않는다.
run_vib로 raw SQL을 실행하는 명령은 만들지 않는다.- Tauri command를 만들 경우에도 command 이름은
backup_db_viewer_*처럼 목적을 좁힌다. - 모든 path는 project root 아래
.vibelign/vibelign.db로만 resolve한다. .vibelign전체 파일 브라우저를 열지 않는다.- DB Viewer 진입 시 “읽기 전용입니다. 복원에 쓰이는 값은 수정하지 않습니다.” 안내를 보여준다.
Testing
Rust engine tests
- DB viewer inspect returns DB summary
- missing DB returns
db_exists=false - inspect includes checkpoint row summaries
- inspect includes CAS/object-store summaries
- inspect does not mutate DB file
Python wrapper tests
- request builder emits expected
backup_db_viewer_*or inspect command - response parser handles inspect success
- Rust unavailable warning maps to user-readable error
GUI tests
- DB Viewer opens as BACKUPS child menu
- inspect data renders DB status and rows
- row selection renders checkpoint details
- no editable form controls are present in first implementation
- failed refresh displays error without clearing the last successful data
Rollout plan
- Add Rust read-only DB viewer module under
vibelign-core/src/backup/db_viewer.rs. - Add IPC inspect request/response variant.
- Add Python request/response wrapper.
- Add GUI lib wrapper in
vibelign-gui/src/lib/vib.ts. - Add BACKUPS child menu and DB Viewer panel component.
- Add targeted tests.
첫 구현에서 고정한 결정
The following decisions are intentionally fixed for the first implementation:
- No raw SQL mode.
- No password prompt.
- No DB editing in the first implementation.
- No editing
triggeror git metadata. - No editing
checkpoint_filesorcas_objects. - Notes/tags/archived are out of scope for this DB viewer spec.
If future users need lower-level DB repair, it should be a separate “repair tool” spec with export/import, checksum validation, dry-run, and explicit recovery workflow.