# Milestone: Control Plane API 데이터 바인딩

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/control-plane-product-surface/PHASE.md`

## 목표

Flutter 콘솔 스켈레톤의 Overview, Runners, Pipelines/Jobs, Executions, Artifacts 화면을 기존 OTO Core HTTP API read path와 연결한다.
완료 후 사용자는 빈 상태뿐 아니라 실제 Core 응답, API 실패, loading/error 상태를 화면별로 확인할 수 있고, 후속 쓰기/운영 액션을 붙일 adapter 경계가 명확해야 한다.

## 상태

[완료]

## 승격 조건

- 없음

## 구현 잠금

- 상태: 해제
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 기존 OTO Core HTTP API를 소비하는 read-only UI 바인딩으로 시작하며, API/schema 변경은 범위 제외로 둔다.
- 잠금 해제 조건: 없음
- 결정 필요: 없음

## 범위

- `apps/client`의 Core HTTP client/adapter와 `packages/flutter/oto_console`의 화면 contract 경계를 유지한다.
- Overview health/readiness 외에 runners, jobs/pipelines, executions, logs/artifacts read path를 화면별 상태 모델에 연결한다.
- 실제 데이터가 없을 때의 empty state, 요청 중 loading state, 실패/error state를 화면별로 구분한다.
- Core API 호출은 `OTO_SERVER_HTTP_URL` 기준으로 수행하고, 브라우저 CORS 보강 상태를 전제로 한다.

## 기능

### Epic: [api-binding] Core API read binding

UI 스켈레톤을 실제 Core 응답을 소비하는 제품 표면으로 전환한다.

- [x] [client-ports] Flutter client에 runners/jobs/executions/logs/artifacts 조회 adapter를 추가하고 `OtoConsoleConfig.serverHttpUrl`을 source of truth로 사용한다. 검증: `cd apps/client && flutter test`에서 adapter 상태 변환 테스트가 통과한다.
- [x] [runner-surface] Runners 화면이 Core runner registry 응답을 loading/empty/error/data 상태로 표시한다. 검증: `cd packages/flutter/oto_console && flutter test`에서 runners surface 테스트가 통과한다.
- [x] [execution-surface] Pipelines/Jobs와 Executions 화면이 job/execution read model을 표시하고 로그/아티팩트 진입 위치를 제공한다. 검증: `cd packages/flutter/oto_console && flutter test`에서 jobs/executions surface 테스트가 통과한다.
- [x] [preview-data-smoke] 원격 preview `http://toki-labs.com:13020/` 기준으로 Core health/readiness와 최소 한 화면의 실제 API 상태가 렌더링된다. 검증: 원격 runner 또는 local smoke에서 browser/screenshot evidence와 `curl` evidence를 남긴다.

## 완료 리뷰

- 상태: 통과
- 요청일: 2026-06-18
- 완료 근거:
  - `agent-task/archive/2026/06/m-control-plane-api-data-binding/03+01,02_preview_smoke/complete.log` 기준 PASS.
  - Roadmap Completion의 `preview-data-smoke`가 이 Milestone의 기존 Task id와 일치한다.
  - Core `healthz`/`readyz`, preview HTTP 200, 원격 Playwright network capture, screenshot evidence로 API-backed 화면 상태 렌더링을 확인했다. 종료 전 코드레벨 재검토에서 `apps/client`, `packages/flutter/oto_console`, `services/core` 핵심 테스트와 analyze가 원격 임시 workspace 기준으로 통과했다.
- 리뷰 필요: 없음
- 리뷰 코멘트: 모든 기능 Task가 완료 근거와 함께 `[x]`가 되었고 구현 잠금은 해제 상태다. 코드레벨 재검토에서 차단 이슈가 발견되지 않아 완료 전환 및 archive 이동을 수행했다.

## 범위 제외

- job 생성, runner self-update, execution cancel/report 같은 쓰기 액션을 완성하지 않는다.
- auth, 권한, 감사 로그, durable persistence UI를 완성하지 않는다.
- 새로운 Core API/schema/proto 계약 변경은 이 Milestone의 기본 범위가 아니다. 필요성이 발견되면 별도 SDD 또는 후속 Milestone으로 분리한다.

## 작업 컨텍스트

- 관련 경로: `apps/client/**`, `packages/flutter/oto_console/**`, `services/core/internal/httpserver/**`
- 표준선(선택): `OtoConsoleConfig.serverHttpUrl`을 API base URL로 유지하고, UI 패키지는 transport 구현보다 상태/표현 contract에 집중한다.
- 표준선(선택): Core HTTP route는 현재 CORS/preflight를 제공하므로 web preview는 cross-origin API smoke를 포함한다.
- 진행 메모: [client-ports] `apps/client`에 Core read adapter와 상태 변환 테스트를 추가했고 `cd apps/client && flutter test`, `cd apps/client && flutter analyze`가 통과했다. (2026-06-17)
- 진행 메모: [runner-surface] `agent-task/archive/2026/06/m-control-plane-api-data-binding/01_runner_surface/complete.log` 기준 PASS. `cd packages/flutter/oto_console && flutter test`, `cd apps/client && flutter test`, 양쪽 `flutter analyze`가 통과했다. (2026-06-17)
- 진행 메모: [execution-surface] `agent-task/archive/2026/06/m-control-plane-api-data-binding/02+01_execution_surface/complete.log` 기준 PASS. `cd packages/flutter/oto_console && flutter test`, `cd apps/client && flutter test`, `git diff --check`가 통과했다. (2026-06-17)
- 진행 메모: [preview-data-smoke] `agent-task/archive/2026/06/m-control-plane-api-data-binding/03+01,02_preview_smoke/complete.log` 기준 PASS. Core health/readiness, preview HTTP 200, 원격 Playwright network capture와 screenshot evidence로 API-backed 화면 렌더링을 확인했다. (2026-06-17)
- 선행 작업: `Flutter 콘솔 스켈레톤`
- 후속 작업: 쓰기 액션, 인증/권한, 운영 대시보드 고도화
- 확인 필요: 없음
