Files
networkSetup/docs/code-design/02-project-model.md
T
jychoi4 24b624301c docs: define MSIX-first packaging design and roadmap
Document package formats, release workflows, deployment planning and UI concepts.

Closes #1
2026-10-27 16:30:00 +09:00

67 lines
7.0 KiB
Markdown

# 프로젝트와 데이터 모델
2026-10-19 실행 범위 변경: JSON 스키마 버전은 v2를 유지한다. 첫 구현은 formats.msix와 direct 대상만 활성화하고 formats.exe는 생략 가능하다. v1 EXE 가져오기·Store 출력은 후속이며 미지원 입력을 명시적으로 거부한다. 현재 예제는 [msix.package-project.json](examples/msix.package-project.json)이다. [현재 설계](12-msix-first-builder.md) 참조.
**현재 계약은 v2다.** [범용 출력 계약](11-generic-exe-msix-architecture.md)의 `formats`와 `targets`를 사용한다. 아래 MSI 컴포넌트·RegistryEntry·PatchRecord는 EXE 백엔드 전용 타입이며 MSIX 프로젝트의 필수 필드가 아니다.
[범용 v2 예제](examples/generic.package-project.json)는 두 형식을 요청하는 설계 초안이다. null인 UpgradeCode·Publisher·서명 참조, 실제 payload·로고·런타임을 확정하기 전 빌드할 수 없다. 최소 OS와 템플릿 이름도 예시이며 구현된 JSON Schema는 아직 없다. 아래 EG-BIM 예제는 이전 v1 입력으로 보존하고 백업 후 명시적으로 가져온다.
## 설정과 결과를 분리하는 파일 구조
2026-10-26 확정: 기본 확장자는 `.isproj`이며 내용은 UTF-8 JSON v2를 유지한다. 열기·저장·기존 JSON 거부와 로컬 파일 이름은 [프로젝트 파일 형식](13-isproj-project-format.md)을 따른다. 기본 파일명과 저장소에 적용했다.
```text
project/
EG-BIM.isproj # 사람이 편집하는 제품/패키지 설정 (JSON v2)
EG-BIM.isproj.local.json # PC별 소스 경로, 도구/서명 프로필 참조
identity.lock.json # 제품 계열 및 컴포넌트 식별자 이력
toolchain.lock.json # 승인한 도구/템플릿 버전
.work/jobs/<jobId>/ # 스냅샷, 대상별 스테이징, WXS/manifest, 로그
releases/<releaseId>/
release.json # 확정된 메타데이터
input.snapshot.json # 설정과 도구, 소스 정보
files.resolved.json # 실제 파일 목록, 원본/서명 후 해시
identity.snapshot.json
artifacts/ # 배포 가능한 파일
baseline/ # 대상별 입력·서명 payload; EXE는 MSI/wixpdb/설치 정의, MSIX는 manifest/identity
reports/ # 정적 검사와 빌드 당시 검증
patches/<patchId>/ # 기준→목표 패치와 동일 종류의 기록
attestations/<artifactDigest>/ # 이후 VM 시험 결과; 아티팩트는 수정 안 함
```
프로젝트·identity lock·toolchain lock은 형상 관리한다. local 파일, 자격 증명, 대용량 릴리스와 작업 폴더는 제외한다. 릴리스 저장소는 백업 가능한 별도 위치를 지정할 수 있다. 인증서 개인 키나 토큰은 어떤 JSON에도 넣지 않고 OS/CI 자격 증명 저장소의 참조만 사용한다.
## 주요 데이터
| 타입 | 핵심 필드와 규칙 |
| --- | --- |
| PackageProject v2 | schemaVersion, product, sources, files, formats, targets; 형식별 입력 분리. 별도 프로젝트 ID 없음 |
| InstallationFlow / InstallerUi | 단계 의존성·모드·조건, 테마/페이지/바인딩. [상세 계약](09-install-flow-and-ui.md) 참조 |
| ProductSpec | displayName, manufacturer, displayVersion; 제품별 선택 메타데이터. 설치 범위·GUID는 formats.exe, MSIX identity는 formats.msix |
| FileRule | 고유 id, source alias, include/exclude 패턴, targetRelativePath, required; v1 destinationDirectory는 형식별 루트와 상대 경로로 변환 |
| ResolvedFile | source-relative path, target-relative path, 크기, SHA-256, PE 정보, signingPolicy; EXE 전용 확장에 componentId/Guid |
| RegistryEntry | id, hive, view, key, name, typed value, component, 설치/제거 정책 |
| IdentityLock | 형식별 계열. EXE: ProductCode·컴포넌트 GUID·tombstone; MSIX: Name·Publisher·Architecture·버전 이력 |
| ReleaseRecord | releaseId, buildId, 설정 해시, 소스 커밋(선택), targets별 실제 MSI/Burn 또는 MSIX identity, artifacts, 호환성, 서명/도구 정보 |
| PatchRecord | patchId/PatchCode, 기준 상태, 목표 releaseId, family/sequence, 필요한 원본·패치, 전체 대체 경로 |
| Artifact | artifactId, kind, 상대 경로, u64 크기, 최종 SHA-256, dependsOn, 서명 결과 |
| ValidationReport | reportId, 대상 해시, 검사 항목, pass/fail/notRun, 환경, 도구 버전 |
시각은 UTC로 저장하고 화면에서 현지 시간으로 표시한다. 파일 크기는 Rust `u64`; JavaScript 정밀도 손실을 막기 위해 IPC의 바이트 수는 십진 문자열로 표현한다. 경로는 Rust `PathBuf`로 다루고 프로젝트 이식 경로는 `/`로 정규화한다. 직렬화 불가능한 파일명은 손실 변환하지 않고 오류로 표시한다.
## 프로젝트 예제와 검증
[egbim.package-project.json](examples/egbim.package-project.json)은 필드 형식을 보여 주는 **초안**이다. 제조사, 실제 스테이징 경로, 필수 런타임은 확인되지 않았으며 예제만으로 정식 패키지를 생성할 수 없다. `sources.alias`는 local 설정에서 실제 폴더로 연결한다. 레지스트리 예제도 실제 제품에서 요구하는 설정으로 확인해야 한다.
`schemaVersion`은 앱 버전과 분리한다. 알 수 없는 상위 스키마 버전과 알 수 없는 필드는 거부한다. 마이그레이션은 원본 백업과 변경 보고서를 만든 후 새 파일로 저장한다. JSON Schema와 Rust 검증이 일치하는지 계약 테스트를 수행한다.
버전·GUID 문자열 형식, 참조 id 존재 여부, 중복 대상 경로, 필수 파일 누락, hive와 설치 범위의 모순은 Rust에서 검사한다. 출력 경로는 소스 루트 밖이어야 한다. 검증 결과는 `severity`, `code`, `fieldPath`, `message`, `remediation`으로 반환하여 화면에서 해당 설정으로 이동하게 한다.
`release.json`은 고정된 프로젝트 설정을 복사하는 것으로 끝내지 않는다. 빌드된 MSI·MSP·EXE·MSIX에서 읽은 실제 제품 코드·버전과 파일 정보를 기록하고 기대값과 대조한다. 메타데이터 자신의 해시를 자기 안에 넣지 않는다. 메타데이터 서명을 사용할 경우 별도 서명 파일을 생성한다.
## 편집·빌드 동시성
프로젝트 저장은 `expectedRevision`을 받아 변경 충돌을 검사한다. 빌드 계획에는 프로젝트 스냅샷 해시, 기준 릴리스 해시, 도구 해시와 identity lock revision을 포함한다. 계획 후 입력이 바뀌면 이전 계획을 실행하지 않고 다시 계산한다.
`releaseId`와 `buildId`는 각각 불변 릴리스와 작업 시도를 구분한다. 실패한 빌드는 이력에 남지만 배포 가능한 릴리스가 아니다. 입력이 같아도 타임스탬프 서명 때문에 재빌드 결과가 바이트 단위로 같을 것이라고 보장하지 않는다. 정확한 재배포는 보존한 최종 아티팩트를 사용한다.