# Rust + Tauri 구조와 모듈 ## 실행 구조 ```mermaid flowchart TD UI[Tauri 웹 UI] --> IPC[타입이 지정된 Tauri Command] IPC --> APP[Rust 작업 서비스] CLI[CI용 CLI] --> APP APP --> DOMAIN[프로젝트 검증 · 파일 해석 · 버전/패치 정책] APP --> ADAPTER[도구와 저장소 어댑터] ADAPTER --> WIX[WiX · Burn] ADAPTER --> SIGN[SignTool · 서명 공급자] ADAPTER --> STORE[작업 디렉터리 · 불변 릴리스 저장소] APP --> REPORT[진행 이벤트 · 검증 보고서] ``` 화면은 설정 편집과 결과 표시만 담당한다. 파일 수집, GUID 할당, 패치 판정, 외부 프로세스 실행, 서명, 최종 상태 변경은 모두 Rust에서 처리한다. CLI도 같은 서비스를 호출하므로 화면 없이 CI에서 동일한 검증을 수행한다. ## 제안 저장소 구조 ```text Cargo.toml # Cargo workspace Cargo.lock rust-toolchain.toml apps/ desktop/ src/ # TypeScript + React 화면 src-tauri/ # Tauri Command, 이벤트, capabilities cli/ # package-builder 명령 crates/ package-domain/ # 타입과 순수 검증/비교 규칙 package-engine/ # 작업 흐름, 취소, 상태, 포트 정의 package-infra/ # 파일 I/O, WiX, 서명, Windows 프로세스 templates/wix/ # 버전 관리되는 설치 정의 템플릿 schemas/ # 프로젝트/매니페스트/IPC JSON Schema tests/fixtures/ # 작은 가상 제품과 기준 MSI 정의 docs/ ``` 의존 방향은 UI/CLI → engine → domain이다. infra는 engine이 정의한 포트를 구현하고 실행 시작점에서 주입한다. domain은 Tauri·네트워크·프로세스에 의존하지 않는다. Rust 공통 의존성은 workspace에서 관리하고 `Cargo.lock`을 저장한다. [Cargo workspaces](https://doc.rust-lang.org/cargo/reference/workspaces.html) ## 핵심 서비스와 포트 | 구성 | 책임 | | --- | --- | | ProjectService | 열기·저장·스키마 마이그레이션·편집 revision 관리 | | ManifestResolver | 파일 규칙을 정렬된 실제 파일 목록으로 확장 | | IdentityPlanner | 기존 identity lock을 기준으로 컴포넌트와 제품 식별자 계획 | | ReleasePlanner / PatchPlanner | 실행 전 검사, 차이 보고, 출력과 적용 경로 확정 | | InstallFlowCompiler | 단계 의존성과 설치 모드 검증, MSI/Burn 실행 정의로 변환 | | InstallerUiCompiler | UI 템플릿·리소스·바인딩 검증, 백엔드 기능 지원 검사 | | BuildCoordinator | 작업 잠금, 단계 실행, 체크포인트, 취소, 실패 기록 | | WixBackend | 설치 정의 생성, MSI/MSP/Burn 빌드, 결과 메타데이터 추출 | | Signer | 서명 정책 적용, 타임스탬프, 실제 서명 검증 결과 반환 | | ArtifactRepository | 기준 릴리스 조회, 콘텐츠 검증, 불변 결과 등록 | | ProcessRunner | 허용 도구 실행, 로그 스트리밍, 시간 제한, 자식 종료 | 포트는 외부 도구를 가짜 구현으로 바꿀 수 있게 한다. 실제 Rust trait의 비동기 형태는 구현 시 확정하되, 모든 작업은 `BuildContext`, 취소 토큰, 타입이 지정된 요청과 결과를 받는다. 도구 종료 코드만 성공 기준으로 삼지 않는다. 후보 라이브러리는 `serde/serde_json`, `uuid`, `sha2`, `quick-xml`, `tokio`, `clap`, `tracing`이다. 도입 시 유지보수 상태·라이선스·Windows 지원을 확인하고 버전을 고정한다. WiX CLI와 확장, Windows SDK SignTool도 정확한 버전·파일 해시를 `toolchain.lock.json`에 기록한다. WiX 세대가 다른 명령 구문을 혼용하지 않는다. ## 작업 수명과 장애 복구 생성 작업은 UI 스레드 밖에서 실행한다. 최초 버전은 한 프로세스에서 빌드 한 건씩 수행하며, CLI와 GUI 간에도 프로젝트/출력 저장소에 OS 파일 잠금을 사용한다. 프로젝트 편집은 가능하지만 실행 중인 작업은 시작 시점 스냅샷을 사용한다. 작업 기록은 `job.json`, 단계별 구조화 로그와 체크포인트 파일로 저장한다. 임시 파일 작성 후 동일 볼륨 내 교체로 저장하며 프로세스 종료 후 다시 읽어 마지막 단계를 복원한다. 기존 작업을 무조건 이어서 실행하지 않고 입력·도구·서명 완료 파일의 해시를 재검사한다. 확정 결과를 변경하는 재개는 금지한다. GUI 종료 시 실행 중 작업을 안내하고 취소를 요청할 수 있다. 프로세스 중단 후의 작업은 `Interrupted`로 복구한다. 최초 버전은 GUI를 닫아도 계속 도는 서비스가 아니다. 무인 장시간 실행은 CLI를 사용한다. ## 권한 경계 생성기는 일반 사용자 권한으로 동작한다. 대상 HKLM 레지스트리를 편집하는 것은 생성된 설치기의 역할이다. 빌드 중 사용자 PC에 MSI/MSP를 설치하지 않는다. 웹 UI에는 임의 셸 실행·임의 파일 쓰기 API를 노출하지 않는다. Rust가 허용한 프로젝트와 소스 루트 안에서 요청을 검증한다. 외부 도구는 절대 경로와 인자 배열로 실행하며 `.bat`, `cmd /c`, PowerShell 문자열 조합을 허용하지 않는다. Windows Job Object로 자식 프로세스 수명을 관리하고 실패·취소 시 남은 프로세스를 정리한다. [Rust Command](https://doc.rust-lang.org/std/process/struct.Command.html) Tauri의 로컬 번들 UI만 사용하고 원격 페이지에 IPC 권한을 주지 않는다. 사용자 입력·로그는 HTML로 렌더링하지 않으며 CSP와 capabilities를 제한한다. 사용자 정의 Command는 등록만 하면 기본적으로 모든 앱 창에서 호출할 수 있으므로 `AppManifest::commands`와 명시적 권한을 함께 구성한다. capability가 Rust 내부의 경로 검증을 대신하지 않는다. [Tauri capabilities](https://v2.tauri.app/security/capabilities/)