# Milestone: Artifact 탐색과 다운로드

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/usable-mvp/PHASE.md`

## 목표

사용자가 Jenkins job 목록에서 대상 job을 고르고, 해당 job의 최근 build 중 설치 가능한 `.apk` artifact가 있는 build만 확인해 바로 설치 흐름으로 넘길 수 있게 한다. build 목록은 build number보다 빌드한 사람을 중심으로 요약해 오설치 가능성을 낮춘다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- 결정 필요: 없음

## 범위

- Jenkins job 목록 조회와 대상 job 선택
- 선택한 job의 recent build 조회
- `.apk` artifact가 있는 build만 listing
- 빌드한 사람 중심의 build 요약 표시
- 선택한 build/artifact에서 바로 설치 CTA 노출
- 설치 시 필요한 `.apk` artifact 임시 다운로드와 설치 흐름 handoff
- 권한 없음, artifact 없음, 실패 build 상태 표시

## 기능

### Epic: [job-select] Jenkins job 선택

로그인 이후 접근 가능한 Jenkins job을 먼저 보여주고 사용자가 설치 대상 job을 고른다.

- [x] [job-list] Jenkins job 목록을 조회하고 검색 가능한 리스트로 표시한다.
- [x] [job-select] 사용자가 job을 선택하면 해당 job의 build 목록으로 진입한다.
- [x] [job-empty] 접근 가능한 job이 없거나 권한이 없을 때 상태를 구분해 표시한다.

### Epic: [build-list] build 목록

Jenkins Remote API에서 선택한 job의 최근 build와 `.apk` artifact metadata를 가져온다.

- [x] [job-query] 선택한 Jenkins job의 build 목록을 조회한다. 검증: mock HTTP 응답 기반 parser test에서 build/requestedBy/result/artifact parsing이 통과한다.
- [x] [apk-only] `.apk` artifact가 있는 build만 목록에 남긴다.
- [x] [requested-by] Jenkins cause의 userName/userId를 우선하고 없으면 trigger source 또는 commit author를 fallback으로 사용해 빌드한 사람을 1차 정보로 표시한다.
- [x] [state-badges] success/failure/running/aborted 상태를 구분해 표시한다.
- [x] [summary-row] build number, branch, flavor, result, 시간, artifact 이름은 보조 정보로 요약 표시한다.
- [x] [search-filter] 빌드한 사람, build number, branch, flavor, artifact 이름 기준 검색/필터를 제공한다.
- [x] [empty-error] 권한 없음, 네트워크 실패, artifact 없음 상태를 구분해 사용자에게 보여준다.

### Epic: [install-ready] 설치 진입

사용자가 build를 선택하면 별도 깊은 탐색 없이 설치 버튼을 바로 노출하고, 설치 요청 시 필요한 파일만 임시로 내려받는다.

- [x] [install-cta] build/artifact item 선택 시 설치 CTA를 바로 노출한다.
- [x] [download-progress] artifact 다운로드 진행률과 취소 상태를 표시한다.
- [x] [temp-download] 다운로드 파일을 앱 임시/staging 경로에 저장하고, handoff 전 폐기 또는 설치 대기 취소 시 삭제한다. 실제 ADB 설치 완료 후 삭제는 `USB 설치와 device 선택`의 `[install-cleanup]`에서 처리한다.
- [x] [artifact-verify] 다운로드 완료 후 파일 존재, 확장자, 크기 정보를 확인한다.
- [x] [handoff] 다운로드된 APK 경로를 device 선택과 USB 설치 흐름으로 넘긴다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-06-10
- 완료 근거:
  - `download-progress`, `temp-download`, `artifact-verify`는 `agent-task/archive/2026/06/m-artifact-browser/04+03_download_staging/complete.log`의 Roadmap Completion과 local/remote Flutter 검증 근거로 완료 처리했다.
  - `handoff`는 `agent-task/archive/2026/06/m-artifact-browser/05+04_install_handoff/complete.log`의 Roadmap Completion과 path 표시, device callback, null callback disabled widget coverage 근거로 완료 처리했다.
  - 2026-06-11 코드 레벨 검토에서 verified APK handoff 중복 요청 방어를 보강했고, local/remote `flutter analyze`, `flutter test`가 통과했다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 사용자 요청에 따라 코드 레벨 종료 검토 후 완료 승인 및 archive 이동.

## 범위 제외

- split APK/APKS/AAB 다운로드/설치
- Teams deep link로 build를 직접 여는 흐름
- 중앙 다운로드 감사 로그
- 실제 ADB 설치 완료 이벤트에 따른 staging 파일 삭제
- 설치 완료 후 다운로드 파일을 장기 보관하는 cache 정책

## 작업 컨텍스트

- 관련 경로: `lib/src/features/builds/`, `lib/src/models/jenkins_build.dart`, `lib/src/services/jenkins_client.dart`
- 표준선(선택): Jenkins Remote API JSON tree를 사용하고, parsing은 모델/서비스 테스트로 보호한다.
- 표준선(선택): 다운로드 파일은 설치를 위한 임시 staging 산출물이다. 이 마일스톤은 handoff 전 폐기와 설치 대기 취소 cleanup을 책임지고, 실제 ADB 설치 완료 cleanup은 `USB 설치와 device 선택` 마일스톤의 `[install-cleanup]`에서 책임진다.
- 표준선(선택): build 목록의 주 정보는 빌드한 사람이며, build number와 branch/flavor/result는 보조 정보다.
- 완료 반영(2026-06-09): `job-list`, `job-select`, `job-empty`는 `agent-task/archive/2026/06/m-artifact-browser/02+01_job_select_ui/complete.log`의 Roadmap Completion 근거로 완료 처리했다.
- 완료 반영(2026-06-09): `job-query`, `apk-only`는 `JenkinsClient.fetchRecentBuilds`, `JenkinsBuild.requestedBy`, `BuildArtifact.isApk`와 mock HTTP/parser test 근거로 완료 처리했다. 검증: remote runner `flutter analyze`, `flutter test` 통과.
- 완료 반영(2026-06-09): `requested-by`, `state-badges`, `summary-row`, `search-filter`, `empty-error`는 `agent-task/archive/2026/06/m-artifact-browser/03+02_build_list_ui/complete.log`의 Roadmap Completion 근거로 완료 처리했다.
- 완료 반영(2026-06-09): `install-cta`는 `BuildsPage.onInstallRequested`, 선택 가능한 build row, `install-cta`/`install-cta-button` widget test 근거로 완료 처리했다. 검증: `git diff --check`, local `flutter test`, local `flutter analyze`, remote runner `flutter analyze`, remote runner `flutter test` 통과.
- 완료 반영(2026-06-10): `download-progress`, `temp-download`, `artifact-verify`는 `agent-task/archive/2026/06/m-artifact-browser/04+03_download_staging/complete.log`의 Roadmap Completion 근거로 완료 처리했다.
- 완료 반영(2026-06-10): `handoff`는 `agent-task/archive/2026/06/m-artifact-browser/05+04_install_handoff/complete.log`의 Roadmap Completion 근거로 완료 처리했다.
- 선행 작업: Jenkins 로그인과 credential 수명주기
- 후속 작업: USB 설치와 device 선택
- 확인 필요: 없음
