---
domain: artifact-flow
last_rule_review_commit: fea3860d011f006a058506cb1f054407a5975a87
last_rule_updated_at: 2026-06-24
---

# artifact-flow

## 목적 / 책임

Jenkins 인증, Web Login token 발급 bridge, session restore, job/build/artifact 조회, 다운로드 stream, APK staging/검증/cleanup, 설치 handoff 직전까지의 흐름을 담당한다.

## 포함 경로

- `lib/src/features/builds/` — build와 artifact 목록 UI
- `lib/src/features/settings/` — Jenkins base URL, job, 인증 방식 설정 UI
- `lib/src/models/jenkins_build.dart` — Jenkins build/artifact 모델
- `lib/src/services/jenkins_client.dart` — Jenkins Remote API 호출
- `lib/src/services/jenkins_artifact_session.dart` — 저장된 Jenkins session 복원과 조회/다운로드/staging facade
- `lib/src/services/artifact_staging_service.dart` — 다운로드된 APK 임시 staging, 검증, cleanup
- `lib/src/services/token_store.dart` — 사용자별 Jenkins credential 저장

## 제외 경로

- `lib/src/services/adb_service.dart` — 실제 설치 실행은 `device-console` 책임
- `lib/src/features/devices/`, `lib/src/features/console/` — 연결 기기와 logcat UI는 `device-console` 책임
- `lib/src/models/pending_install.dart` — staged APK를 device-console으로 넘기는 handoff DTO는 `app-shell` 책임
- `macos/Runner/` — Keychain, network entitlement, URL scheme은 `macos-platform` 책임

## 주요 구성 요소

- `BuildsPage` — Jenkins build/artifact 탐색 화면
- `SettingsPage`, `JenkinsWebLoginPage` — Jenkins URL 입력, Web Login, token 저장/clear UI와 injected ADB 진단 표시 surface
- `JenkinsJob`, `JenkinsBuild`, `BuildArtifact` — job, build, artifact 도메인 모델
- `JenkinsClient` — build 조회와 artifact 다운로드 HTTP client
- `DownloadTask`, `DownloadProgressEvent` — artifact 다운로드 stream과 취소 가능한 progress 이벤트
- `JenkinsArtifactSession`, `JenkinsSessionRestoreResult` — credential 복원, 권한 확인, 조회/다운로드/staging orchestration
- `ArtifactStagingService`, `StagedApk`, `ArtifactVerifyException` — APK staging, 확장자/크기 검증, cleanup
- `TokenStore`, `JenkinsSessionConfig` — macOS Keychain credential/session 저장소 wrapper
- `JenkinsCrumb`, `JenkinsGeneratedToken`, `JenkinsBridgeTokenResult` — Jenkins Web Login token bridge parsing 모델

## 유지할 패턴

- Jenkins credential은 사용자별로 저장하고, tracked 파일이나 앱 bundle에 secret을 넣지 않는다.
- Jenkins API 응답 parsing은 모델 factory 또는 전용 parser에 둔다.
- Jenkins URL path 조합은 context path를 보존하는 helper를 사용하고, 문자열 덧붙이기로 login/API 경로를 만들지 않는다.
- WebView token bridge는 same-origin fetch로 `whoAmI`, crumb, token 발급 응답을 확인하고, token 이름에는 secret을 넣지 않는다.
- `whoAmI` 응답이 anonymous이거나 사용자 id가 비어 있으면 인증 실패로 취급한다.
- `JenkinsClientException.toString`은 Authorization, token, password, crumb 값을 redaction한 문자열만 노출한다.
- `DownloadProgressEvent`는 누적 byte와 chunk byte를 함께 전달하고, 취소 시 stream을 닫아 partial staging이 남지 않게 한다.
- staging된 파일은 `.apk` 확장자와 non-empty 조건을 검증하고, 취소/오류/설치 완료/대기 취소 시 cleanup 경로를 유지한다.
- session 저장은 저장 직후 restore 검증까지 성공했을 때만 완료로 보고, 실패하면 저장값을 rollback한다.
- 다운로드 파일명과 build number, job, flavor, branch를 UI에서 함께 노출해 오설치 가능성을 낮춘다.
- Jenkins WebView 자동 token 발급을 구현할 때도 LDAP 비밀번호 원문을 앱 상태나 로그에 남기지 않는다.

## 다른 도메인과의 경계

- **device-console**: artifact-flow는 staged APK와 build/artifact metadata까지만 만들고, `adb install`, logcat, ADB 진단 타입/loader semantics는 device-console에서 담당한다.
- **app-shell**: 로그인/동기화 상태, loader, staged APK handoff만 shell에 전달하고, 상세 상태와 오류는 artifact-flow 화면/서비스에서 관리한다.
- **macos-platform**: 인증 callback deep link, sandbox/network 권한은 macos-platform과 함께 변경한다.

## 금지 사항

- 공용 Jenkins API token, service account token을 소스/설정/README에 기록하지 않는다.
- Jenkins 권한 확인을 단순 boolean 로그인 상태만으로 대체하지 않는다.
- artifact URL을 외부 네트워크에 노출하거나 로그에 token 포함 URL을 출력하지 않는다.
- staged APK를 tracked 경로에 쓰거나 cleanup 없는 장기 캐시로 전환하지 않는다.
