feat: add operator-client-api-core-integration task documents and update client README

This commit is contained in:
toki 2026-06-02 09:42:57 +09:00
parent baeb66b32b
commit fc1b94bf5c
9 changed files with 888 additions and 0 deletions

View file

@ -0,0 +1,101 @@
<!-- task=m-operator-client-api-core-integration/01_contract_mapping plan=0 tag=API -->
# Code Review Reference - API
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves.
> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.
## 개요
date=2026-06-02
task=m-operator-client-api-core-integration/01_contract_mapping, plan=0, tag=API
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `client-contracts`: generated/mapped contracts를 client core에서 사용할 수 있게 정리한다.
- Completion mode: check-on-pass
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다.
각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [API-1] Client result/error mapping 추가 | [ ] |
| [API-2] Response error extraction helper 추가 | [ ] |
## 구현 체크리스트
- [ ] `AltApiResult<T>`, `AltApiError`, `AltTransportState` 등 UI copy 없는 client core result 타입을 추가하고 `ErrorInfo` mapping test를 작성한다. 검증: `cd apps/client && flutter test test/contracts/alt_api_result_test.dart`
- [ ] response별 `ErrorInfo` 추출 helper를 추가해 market/backtest response에서 공통으로 쓸 수 있게 한다. 검증: `cd apps/client && flutter test test/contracts/alt_api_result_test.dart`
- [ ] `cd apps/client && flutter test`를 실행해 기존 parser/socket/widget 회귀를 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
## 코드리뷰 전용 체크리스트
> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.
- [ ] `코드리뷰 결과``PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [ ] active `CODE_REVIEW-*-G??.md``code_review_{review_lane}_GNN_N.log`로 아카이브한다.
- [ ] active `PLAN-*-G??.md``plan_{build_lane}_GNN_M.log`로 아카이브한다.
- [ ] PASS이면 `complete.log`를 작성하고 active task directory를 archive로 이동한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 완료 이벤트 메타데이터를 보고하고 roadmap은 직접 수정하지 않는다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._
- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
- generated 파일을 손수 수정하지 않았는가
- typed `ErrorInfo`와 transport failure가 UI copy 없이 stable state로 남는가
- 후속 repository plan이 재사용할 수 있는 API인가
## 검증 결과
_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._
### API-1 중간 검증
```text
$ cd apps/client && flutter test test/contracts/alt_api_result_test.dart
(output)
```
### API-2 중간 검증
```text
$ cd apps/client && flutter test test/contracts/alt_api_result_test.dart
(output)
```
### 최종 검증
```text
$ cd apps/client && flutter test
(output)
```

View file

@ -0,0 +1,165 @@
<!-- task=m-operator-client-api-core-integration/01_contract_mapping plan=0 tag=API -->
# Plan - API Contract Mapping
## 이 파일을 읽는 구현 에이전트에게
`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션 작성까지가 구현의 마지막 단계다. 구현 후 검증을 실행하고 실제 변경 내용, 설계 결정, stdout/stderr를 채운 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 사용자 결정, 사용자 소유 외부 환경, 범위 충돌로 막히면 review stub의 `사용자 리뷰 요청`에 근거를 채우고 멈춘다. 후속 에이전트가 재실행으로 해소할 수 있는 증거 공백은 사용자 리뷰 요청이 아니다.
## 배경
Milestone은 Flutter 화면 전에 generated ALT protobuf를 client core에서 안정적으로 쓰는 것을 요구한다. 현재 `altParserMap()`은 parser 등록만 검증하며, 응답 payload의 `ErrorInfo`와 success payload를 repository가 다룰 공통 result 형태가 없다. 후속 socket/market/backtest 계획이 같은 result 모델을 재사용하도록 첫 split에서 기반을 만든다.
## 사용자 리뷰 요청 흐름
구현 중 사용자 전용 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review만 `USER_REVIEW.md` 작성, log archive, `complete.log` 생성을 수행한다.
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `client-contracts`: generated/mapped contracts를 client core에서 사용할 수 있게 정리한다.
- Completion mode: check-on-pass
## 분석 결과
### 읽은 파일
- `agent-test/local/rules.md`
- `agent-test/local/client-smoke.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `apps/client/pubspec.yaml`
- `apps/client/analysis_options.yaml`
- `apps/client/lib/src/contracts/alt_contracts.dart`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/lib/src/integrations/socket/socket_connection_controller.dart`
- `apps/client/lib/src/integrations/socket/socket_endpoint.dart`
- `apps/client/lib/src/features/dashboard/presentation/dashboard_screen.dart`
- `apps/client/test/contracts/alt_contracts_test.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `apps/client/test/widget_test.dart`
- `apps/client/test/app/bootstrap_test.dart`
- `packages/contracts/proto/alt/v1/common.proto`
- `packages/contracts/proto/alt/v1/market.proto`
- `packages/contracts/proto/alt/v1/backtest.proto`
### 테스트 환경 규칙
`test_env=local`. `agent-test/local/rules.md`와 matched profile `agent-test/local/client-smoke.md`를 읽었다. client 변경의 기본 검증은 `cd apps/client && flutter test`; generated contracts나 analysis options가 바뀌면 `bin/lint` 가능 여부를 확인한다. 이번 plan은 generated 파일을 손수 수정하지 않으며, fallback 명령은 필요 없다.
### 테스트 커버리지 공백
공통 client result/error mapping은 아직 테스트가 없다. 이 plan에서 `apps/client/test/contracts/alt_api_result_test.dart`를 추가해 success/error/transport failure mapping을 덮는다.
### 심볼 참조
renamed/removed symbol: none.
### 분할 판단
split decision policy를 먼저 평가했다. 공유 result 모델은 socket state, market repository, backtest repository의 선행 API/foundation 변경이므로 `01_contract_mapping`으로 분리한다. sibling 계획은 `01_contract_mapping`, `02+01_socket_state`, `03+01_market_repository`, `04+02,03_backtest_error`이며, 이 plan은 predecessor가 없다.
### 범위 결정 근거
`apps/client/lib/src/generated/**`는 generated 출력이므로 제외한다. Flutter 화면, dashboard layout, API server/worker 구현은 Milestone 범위 밖이므로 제외한다. 이 plan은 client core에서 쓸 result/error mapper와 tests만 다룬다.
### 빌드 등급
build=`cloud-G06`, review=`cloud-G06`. 후속 여러 plan이 의존할 public-ish client core API라 local보다 신중한 review가 필요하다.
## 구현 체크리스트
- [ ] `AltApiResult<T>`, `AltApiError`, `AltTransportState` 등 UI copy 없는 client core result 타입을 추가하고 `ErrorInfo` mapping test를 작성한다. 검증: `cd apps/client && flutter test test/contracts/alt_api_result_test.dart`
- [ ] response별 `ErrorInfo` 추출 helper를 추가해 market/backtest response에서 공통으로 쓸 수 있게 한다. 검증: `cd apps/client && flutter test test/contracts/alt_api_result_test.dart`
- [ ] `cd apps/client && flutter test`를 실행해 기존 parser/socket/widget 회귀를 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
### [API-1] Client result/error mapping 추가
#### 문제
`apps/client/lib/src/contracts/alt_contracts.dart:7`에는 parser map만 있고, `packages/contracts/proto/alt/v1/common.proto:37``ErrorInfo`를 stable client state로 보존하는 result 타입이 없다.
```dart
// apps/client/lib/src/contracts/alt_contracts.dart:7
Map<String, GeneratedMessage Function(List<int>)> altParserMap() {
```
#### 해결 방법
`apps/client/lib/src/contracts/alt_api_result.dart`를 추가한다. `AltApiResult<T>.success`, `AltApiResult<T>.apiError`, `AltApiResult<T>.transportFailure``AltApiError.fromErrorInfo(ErrorInfo)`를 제공한다. UI 문구 대신 `code`, `message`, `transportKind` 같은 안정 필드만 둔다.
```dart
import 'package:alt_client/src/generated/alt/v1/common.pb.dart';
sealed class AltApiResult<T> {
const AltApiResult();
}
final class AltApiSuccess<T> extends AltApiResult<T> {
const AltApiSuccess(this.value);
final T value;
}
```
#### 수정 파일 및 체크리스트
- [ ] `apps/client/lib/src/contracts/alt_api_result.dart` 추가
- [ ] `apps/client/test/contracts/alt_api_result_test.dart` 추가
#### 테스트 작성
작성한다. `AltApiError.fromErrorInfo``code/message`를 보존하고, transport failure가 `ErrorInfo` 없이도 stable state로 남는지 확인한다.
#### 중간 검증
`cd apps/client && flutter test test/contracts/alt_api_result_test.dart` exit code 0.
### [API-2] Response error extraction helper 추가
#### 문제
market/backtest response는 `error` field를 각자 갖지만, client repository가 이를 통일해서 읽을 helper가 없다. 관련 response field는 `packages/contracts/proto/alt/v1/market.proto:44`, `packages/contracts/proto/alt/v1/backtest.proto:39` 이후에 흩어져 있다.
#### 해결 방법
`alt_api_result.dart``AltResponseErrorReader<T>` 또는 top-level helper를 두고 supported response type별 `hasError()`/`error`를 안전하게 추출한다. unsupported type은 `null`을 반환해 success path를 깨지 않는다.
```dart
ErrorInfo? altResponseError(Object response) {
return switch (response) {
ListInstrumentsResponse(:final error) when response.hasError() => error,
_ => null,
};
}
```
#### 수정 파일 및 체크리스트
- [ ] `apps/client/lib/src/contracts/alt_api_result.dart`
- [ ] `apps/client/test/contracts/alt_api_result_test.dart`
#### 테스트 작성
작성한다. `ListInstrumentsResponse`, `ListBarsResponse`, `ListBacktestRunsResponse`, `GetBacktestRunDetailResponse`, `GetBacktestResultResponse`, `StartBacktestResponse`의 typed error 추출을 확인한다.
#### 중간 검증
`cd apps/client && flutter test test/contracts/alt_api_result_test.dart` exit code 0.
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `apps/client/lib/src/contracts/alt_api_result.dart` | API-1, API-2 |
| `apps/client/test/contracts/alt_api_result_test.dart` | API-1, API-2 |
## 최종 검증
```bash
cd apps/client && flutter test
```
기대 결과: exit code 0. Go/Dart test cache 여부와 무관하게 Flutter test 전체가 통과해야 한다.
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.

View file

@ -0,0 +1,84 @@
<!-- task=m-operator-client-api-core-integration/02+01_socket_state plan=0 tag=API -->
# Code Review Reference - API
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> Fill implementation-owned sections, then stop with active files in place and report ready for review. Finalization is review-agent-only.
## 개요
date=2026-06-02
task=m-operator-client-api-core-integration/02+01_socket_state, plan=0, tag=API
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `socket-core`: API socket 연결, 해제, timeout 상태를 화면 없는 client state로 표현한다.
- `error-core`: unavailable/error/disconnected 상태가 UI copy가 아닌 안정적인 client state로 남는다.
- Completion mode: check-on-pass
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 종결 절차는 리뷰 에이전트 전용이다.
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [API-1] Socket core state 타입 도입 | [ ] |
## 구현 체크리스트
- [ ] socket core state 타입을 추가하고 `disconnected/connecting/connected/error/timeout`의 stable code를 보존한다. 검증: `cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart`
- [ ] `SocketConnectionController`가 성공, disconnect callback, connect failure, hello timeout/failure를 state로 남기게 한다. 검증: `cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart`
- [ ] 기존 dashboard/widget 테스트가 깨지지 않도록 presentation label adapter를 최소 수정한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
## 코드리뷰 전용 체크리스트
- [ ] PASS/WARN/FAIL 판정을 append한다.
- [ ] active files를 log로 archive한다.
- [ ] PASS이면 `complete.log` 작성 후 archive 이동한다.
- [ ] roadmap은 직접 수정하지 않는다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다._
- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
- predecessor `01_contract_mapping` completion을 확인했는가
- UI copy가 core state에 들어가지 않았는가
- timeout/transport failure가 안정 필드로 검증되는가
## 검증 결과
### API-1 중간 검증
```text
$ cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart
(output)
```
### 최종 검증
```text
$ cd apps/client && flutter test
(output)
```

View file

@ -0,0 +1,128 @@
<!-- task=m-operator-client-api-core-integration/02+01_socket_state plan=0 tag=API -->
# Plan - Socket State Core
## 이 파일을 읽는 구현 에이전트에게
구현 완료 전 active `CODE_REVIEW-*-G??.md`의 구현 소유 섹션을 실제 내용과 검증 출력으로 채운다. 사용자 전용 blocker만 `사용자 리뷰 요청`에 기록하고 멈춘다. code-review 전용 종결 작업은 수행하지 않는다.
## 배경
현재 socket state는 enum 네 값뿐이라 timeout, disconnect reason, handshake failure 같은 운영 상태를 UI copy 밖에서 보존하지 못한다. Milestone의 `socket-core``error-core` 일부를 만족하려면 core state object와 controller test가 필요하다. 이 작업은 `01_contract_mapping`의 transport/result 용어를 재사용한다.
## 사용자 리뷰 요청 흐름
구현 중 blocker는 review stub의 `사용자 리뷰 요청`에 기록한다. code-review가 검증 후 `USER_REVIEW.md` 필요 여부를 판단한다.
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `socket-core`: API socket 연결, 해제, timeout 상태를 화면 없는 client state로 표현한다.
- `error-core`: unavailable/error/disconnected 상태가 UI copy가 아닌 안정적인 client state로 남는다.
- Completion mode: check-on-pass
## 분석 결과
### 읽은 파일
- `agent-test/local/rules.md`
- `agent-test/local/client-smoke.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `apps/client/lib/src/integrations/socket/socket_connection_controller.dart`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/lib/src/integrations/socket/socket_endpoint.dart`
- `apps/client/lib/src/features/dashboard/presentation/dashboard_screen.dart`
- `apps/client/test/widget_test.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `apps/client/pubspec.yaml`
### 테스트 환경 규칙
`test_env=local`; client-smoke 적용. 기본 명령은 `cd apps/client && flutter test`; socket runtime behavior는 관련 integration/unit test 실행 가능 여부를 확인한다. 이 plan은 fake connector 단위 test로 처리하고 실제 API socket smoke는 생략 근거를 review에 남긴다.
### 테스트 커버리지 공백
`SocketConnectionController``connect/disconnect/error` 전이는 직접 test가 없다. timeout 상태도 현재 enum에 없다. 이 plan에서 controller unit test를 추가한다.
### 심볼 참조
`SocketConnectionState``dashboard_screen.dart`, `widget_test.dart`, `socket_connection_controller.dart`에서 참조된다. 제거하지 말고 필요하면 compatible getter/label adapter를 유지한다.
### 분할 판단
dependent split plan이다. predecessor `01_contract_mapping`의 active/archived `complete.log`가 필요하다. 구현 시작 전 `agent-task/m-operator-client-api-core-integration/01_contract_mapping/complete.log` 또는 matching archive complete.log를 확인한다. 현재 계획 작성 시점에는 predecessor가 아직 active plan 상태라 미충족이다.
### 범위 결정 근거
화면 layout 변경은 제외한다. dashboard는 기존 enum 의존이 깨질 때 최소 adapter만 수정한다. 실제 WebSocket 서버, API service, worker는 제외한다.
### 빌드 등급
build=`cloud-G06`, review=`cloud-G06`. state model 변경이 widget/controller call site를 건드리며 timeout/error semantics가 review 대상이다.
## 의존 관계 및 구현 순서
디렉터리명 `02+01_socket_state`에 따라 sibling `01_contract_mapping` PASS `complete.log`가 먼저 필요하다. 구현자는 시작 전에 predecessor completion을 확인하고 review에 경로를 기록한다.
## 구현 체크리스트
- [ ] socket core state 타입을 추가하고 `disconnected/connecting/connected/error/timeout`의 stable code를 보존한다. 검증: `cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart`
- [ ] `SocketConnectionController`가 성공, disconnect callback, connect failure, hello timeout/failure를 state로 남기게 한다. 검증: `cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart`
- [ ] 기존 dashboard/widget 테스트가 깨지지 않도록 presentation label adapter를 최소 수정한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
### [API-1] Socket core state 타입 도입
#### 문제
`apps/client/lib/src/integrations/socket/socket_connection_controller.dart:8`의 enum은 상태 이유나 timeout/error code를 담을 수 없다.
```dart
// apps/client/lib/src/integrations/socket/socket_connection_controller.dart:8
enum SocketConnectionState {
disconnected,
connecting,
connected,
error,
}
```
#### 해결 방법
기존 enum을 유지하거나 대체하되, presentation이 stable `status`와 optional `error`를 읽을 수 있게 한다. 후속 UI copy가 아닌 core field로 `reasonCode`, `endpoint`, `lastError`를 둔다.
#### 수정 파일 및 체크리스트
- [ ] `apps/client/lib/src/integrations/socket/socket_connection_controller.dart`
- [ ] `apps/client/test/integrations/socket/socket_connection_controller_test.dart`
- [ ] `apps/client/lib/src/features/dashboard/presentation/dashboard_screen.dart`
- [ ] `apps/client/test/widget_test.dart`
#### 테스트 작성
작성한다. fake connector를 주입해 connecting -> connected, connected -> disconnected, failure -> error, timeout -> timeout/error reason을 확인한다.
#### 중간 검증
`cd apps/client && flutter test test/integrations/socket/socket_connection_controller_test.dart` exit code 0.
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `apps/client/lib/src/integrations/socket/socket_connection_controller.dart` | API-1 |
| `apps/client/lib/src/features/dashboard/presentation/dashboard_screen.dart` | API-1 |
| `apps/client/test/integrations/socket/socket_connection_controller_test.dart` | API-1 |
| `apps/client/test/widget_test.dart` | API-1 |
## 최종 검증
```bash
cd apps/client && flutter test
```
기대 결과: exit code 0. 실제 API socket integration smoke는 이 plan 범위에서 실행하지 않으며 fake connector state test로 대체한다.
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.

View file

@ -0,0 +1,81 @@
<!-- task=m-operator-client-api-core-integration/03+01_market_repository plan=0 tag=API -->
# Code Review Reference - API
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> Fill implementation-owned sections, then stop with active files in place and report ready for review. Finalization is review-agent-only.
## 개요
date=2026-06-02
task=m-operator-client-api-core-integration/03+01_market_repository, plan=0, tag=API
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `market-call`: market data status/list 기본 API 호출을 client core에서 수행할 수 있다.
- Completion mode: check-on-pass
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 종결 절차는 리뷰 에이전트 전용이다.
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [API-1] Market repository 추가 | [ ] |
## 구현 체크리스트
- [ ] market repository/provider boundary를 추가하고 `listInstruments`, `listBars``AltApiResult`로 반환한다. 검증: `cd apps/client && flutter test test/features/market/market_repository_test.dart`
- [ ] fake client로 request payload와 parsed result/status key를 확인한다. 검증: `cd apps/client && flutter test test/features/market/market_repository_test.dart`
- [ ] typed `ErrorInfo``AltApiError`로 보존되는 test를 추가한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
## 코드리뷰 전용 체크리스트
- [ ] PASS/WARN/FAIL 판정을 append한다.
- [ ] active files를 log로 archive한다.
- [ ] PASS이면 `complete.log` 작성 후 archive 이동한다.
- [ ] roadmap은 직접 수정하지 않는다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
- predecessor `01_contract_mapping` completion을 확인했는가
- repository가 raw protobuf error를 success처럼 반환하지 않는가
- request payload와 parsed result key가 test에 고정됐는가
## 검증 결과
### API-1 중간 검증
```text
$ cd apps/client && flutter test test/features/market/market_repository_test.dart
(output)
```
### 최종 검증
```text
$ cd apps/client && flutter test
(output)
```

View file

@ -0,0 +1,117 @@
<!-- task=m-operator-client-api-core-integration/03+01_market_repository plan=0 tag=API -->
# Plan - Market Repository Calls
## 이 파일을 읽는 구현 에이전트에게
구현 후 active `CODE_REVIEW-*-G??.md`의 구현 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 최종 archive, `complete.log`, roadmap 수정은 수행하지 않는다.
## 배경
`AltSocketClient``listInstruments``listBars` wrapper를 갖고 있지만, provider/repository 경계에서 request payload, parsed result, typed error를 검증하는 client core가 없다. 화면 구현 전에 market data status/list 계열 호출을 repository level에서 증명해야 한다.
## 사용자 리뷰 요청 흐름
사용자 전용 blocker만 review stub의 `사용자 리뷰 요청`에 기록한다. 재실행 가능한 evidence gap은 일반 후속 이슈로 남긴다.
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `market-call`: market data status/list 기본 API 호출을 client core에서 수행할 수 있다.
- Completion mode: check-on-pass
## 분석 결과
### 읽은 파일
- `agent-test/local/rules.md`
- `agent-test/local/client-smoke.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `apps/client/lib/src/contracts/alt_contracts.dart`
- `packages/contracts/proto/alt/v1/market.proto`
- `packages/contracts/proto/alt/v1/common.proto`
- `apps/client/pubspec.yaml`
### 테스트 환경 규칙
`test_env=local`; client-smoke 적용. 작은 client 변경은 `cd apps/client && flutter test`; socket runtime smoke는 fake socket/repository unit test로 검증하고 실제 API 연결은 후속 runtime smoke로 남긴다.
### 테스트 커버리지 공백
low-level `AltSocketClient` request/response loop는 `alt_socket_client_test.dart:379``:419`에서 있다. repository result mapping, typed `ErrorInfo`, status key extraction은 없다.
### 심볼 참조
renamed/removed symbol: none.
### 분할 판단
dependent split plan이다. predecessor `01_contract_mapping` PASS `complete.log`가 필요하다. `02_socket_state`와는 병렬 가능하므로 dependency는 `+01`만 둔다.
### 범위 결정 근거
market repository만 다룬다. backtest 호출, dashboard UI, API server handler, generated contract 수정은 제외한다.
### 빌드 등급
build=`cloud-G06`, review=`cloud-G06`. repository API와 typed error semantics가 후속 UI에 영향을 준다.
## 의존 관계 및 구현 순서
디렉터리명 `03+01_market_repository`에 따라 sibling `01_contract_mapping` PASS `complete.log`가 필요하다. 구현 시작 전 경로를 review에 기록한다.
## 구현 체크리스트
- [ ] market repository/provider boundary를 추가하고 `listInstruments`, `listBars``AltApiResult`로 반환한다. 검증: `cd apps/client && flutter test test/features/market/market_repository_test.dart`
- [ ] fake client로 request payload와 parsed result/status key를 확인한다. 검증: `cd apps/client && flutter test test/features/market/market_repository_test.dart`
- [ ] typed `ErrorInfo``AltApiError`로 보존되는 test를 추가한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
### [API-1] Market repository 추가
#### 문제
`apps/client/lib/src/integrations/socket/alt_socket_client.dart:95``:105`는 raw protobuf response만 반환한다. provider/repository 경계에서 status key와 typed error를 보존하지 않는다.
```dart
// apps/client/lib/src/integrations/socket/alt_socket_client.dart:95
Future<ListInstrumentsResponse> listInstruments(
```
#### 해결 방법
`apps/client/lib/src/features/market/data/market_repository.dart` 또는 기존 패턴에 맞는 경로를 추가한다. socket client abstraction을 constructor로 받고 `Future<AltApiResult<ListInstrumentsResponse>> listInstruments(...)`, `Future<AltApiResult<ListBarsResponse>> listBars(...)`를 제공한다.
#### 수정 파일 및 체크리스트
- [ ] `apps/client/lib/src/features/market/data/market_repository.dart`
- [ ] `apps/client/test/features/market/market_repository_test.dart`
#### 테스트 작성
작성한다. fake client가 받은 `ListInstrumentsRequest.market/provider`, `ListBarsRequest.instrumentId/timeframe`를 assert하고, success/error result를 모두 확인한다.
#### 중간 검증
`cd apps/client && flutter test test/features/market/market_repository_test.dart` exit code 0.
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `apps/client/lib/src/features/market/data/market_repository.dart` | API-1 |
| `apps/client/test/features/market/market_repository_test.dart` | API-1 |
## 최종 검증
```bash
cd apps/client && flutter test
```
기대 결과: exit code 0. 실제 API 연결 smoke는 이 plan의 pass 조건이 아니며 fake client payload/result 검증으로 제한한다.
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.

View file

@ -0,0 +1,82 @@
<!-- task=m-operator-client-api-core-integration/04+02,03_backtest_error plan=0 tag=API -->
# Code Review Reference - API
> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> Fill implementation-owned sections, then stop with active files in place and report ready for review. Finalization is review-agent-only.
## 개요
date=2026-06-02
task=m-operator-client-api-core-integration/04+02,03_backtest_error, plan=0, tag=API
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `backtest-call`: backtest list/detail/result/start 기본 API 호출을 client core에서 수행할 수 있다.
- `error-core`: unavailable/error/disconnected 상태가 UI copy가 아닌 안정적인 client state로 남는다.
- Completion mode: check-on-pass
## 이 파일을 읽는 리뷰 에이전트에게
> **[REVIEW AGENT ONLY]** 종결 절차는 리뷰 에이전트 전용이다.
## 구현 항목별 완료 여부
| 항목 | 완료 여부 |
|------|---------|
| [API-1] Backtest repository 추가 | [ ] |
## 구현 체크리스트
- [ ] backtest repository/provider boundary를 추가하고 list/detail/result/start를 `AltApiResult`로 반환한다. 검증: `cd apps/client && flutter test test/features/backtest/backtest_repository_test.dart`
- [ ] fake client로 request payload, success result, typed `ErrorInfo` mapping을 확인한다.
- [ ] transport failure/disconnected/unavailable 상태가 UI copy 없는 stable error로 남는지 확인한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
## 코드리뷰 전용 체크리스트
- [ ] PASS/WARN/FAIL 판정을 append한다.
- [ ] active files를 log로 archive한다.
- [ ] PASS이면 `complete.log` 작성 후 archive 이동한다.
- [ ] roadmap은 직접 수정하지 않는다.
## 계획 대비 변경 사항
_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._
## 주요 설계 결정
_구현 에이전트가 주요 설계 결정 사항을 기록한다._
## 사용자 리뷰 요청
- 상태: 없음
- 사유 유형: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음
## 리뷰어를 위한 체크포인트
- predecessor `02_socket_state``03_market_repository` completion을 확인했는가
- backtest success/error/transport failure가 모두 result로 표현되는가
- UI 화면이나 chart scope가 섞이지 않았는가
## 검증 결과
### API-1 중간 검증
```text
$ cd apps/client && flutter test test/features/backtest/backtest_repository_test.dart
(output)
```
### 최종 검증
```text
$ cd apps/client && flutter test
(output)
```

View file

@ -0,0 +1,118 @@
<!-- task=m-operator-client-api-core-integration/04+02,03_backtest_error plan=0 tag=API -->
# Plan - Backtest Repository And Error Core
## 이 파일을 읽는 구현 에이전트에게
구현 후 active `CODE_REVIEW-*-G??.md`의 구현 소유 섹션을 모두 채운다. 검증 stdout/stderr 없이 완료를 주장하지 않는다. code-review 전용 archive와 roadmap 갱신은 수행하지 않는다.
## 배경
Milestone의 backtest list/detail/result/start와 typed error mapping은 가장 넓은 client core surface다. socket state와 market repository가 정리된 뒤 같은 result/error 모델로 backtest repository를 만들면 Flutter MVP가 화면 없이 의존할 API readiness evidence를 얻는다.
## 사용자 리뷰 요청 흐름
구현 중 사용자 결정이나 외부 환경 prerequisite이 필요하면 review stub의 `사용자 리뷰 요청`에 기록하고 멈춘다. evidence gap만으로는 사용자 리뷰 요청을 만들지 않는다.
## Roadmap Targets
- Milestone: `agent-roadmap/phase/operator-surface/milestones/operator-client-api-core-integration.md`
- Task ids:
- `backtest-call`: backtest list/detail/result/start 기본 API 호출을 client core에서 수행할 수 있다.
- `error-core`: unavailable/error/disconnected 상태가 UI copy가 아닌 안정적인 client state로 남는다.
- Completion mode: check-on-pass
## 분석 결과
### 읽은 파일
- `agent-test/local/rules.md`
- `agent-test/local/client-smoke.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `apps/client/lib/src/integrations/socket/alt_socket_client.dart`
- `apps/client/test/integrations/socket/alt_socket_client_test.dart`
- `apps/client/lib/src/contracts/alt_contracts.dart`
- `packages/contracts/proto/alt/v1/backtest.proto`
- `packages/contracts/proto/alt/v1/common.proto`
- `apps/client/pubspec.yaml`
### 테스트 환경 규칙
`test_env=local`; client-smoke 적용. 기본 검증은 `cd apps/client && flutter test`. 이 plan은 broad client API/repository surface라 focused test와 전체 Flutter test를 모두 요구한다.
### 테스트 커버리지 공백
low-level socket wrapper tests는 list/detail/result/start success path 일부를 확인한다. repository-level typed error, transport failure, unavailable/disconnected result mapping은 없다.
### 심볼 참조
renamed/removed symbol: none.
### 분할 판단
dependent split plan이다. directory `04+02,03_backtest_error`는 predecessor `02_socket_state``03_market_repository` PASS `complete.log`를 요구한다. `02`는 transport state, `03`은 repository pattern을 제공하므로 둘 다 필요하다.
### 범위 결정 근거
backtest client repository와 error mapping만 다룬다. compare backtests, chart view model, Flutter screen, API server/worker 변경은 제외한다.
### 빌드 등급
build=`cloud-G07`, review=`cloud-G07`. 여러 predecessors, broad API surface, typed error semantics가 결합되어 상위 등급이 필요하다.
## 의존 관계 및 구현 순서
구현 시작 전 같은 task group에서 predecessor `02+01_socket_state``03+01_market_repository`의 active 또는 archived `complete.log`를 확인한다. 두 complete 경로를 review에 기록한다.
## 구현 체크리스트
- [ ] backtest repository/provider boundary를 추가하고 list/detail/result/start를 `AltApiResult`로 반환한다. 검증: `cd apps/client && flutter test test/features/backtest/backtest_repository_test.dart`
- [ ] fake client로 request payload, success result, typed `ErrorInfo` mapping을 확인한다.
- [ ] transport failure/disconnected/unavailable 상태가 UI copy 없는 stable error로 남는지 확인한다.
- [ ] `cd apps/client && flutter test`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
### [API-1] Backtest repository 추가
#### 문제
`apps/client/lib/src/integrations/socket/alt_socket_client.dart:44`부터 `:93`까지 raw protobuf wrappers만 있고 repository boundary와 typed error result가 없다.
```dart
// apps/client/lib/src/integrations/socket/alt_socket_client.dart:44
Future<ListBacktestRunsResponse> listBacktestRuns(
```
#### 해결 방법
`apps/client/lib/src/features/backtest/data/backtest_repository.dart`를 추가한다. list/detail/result/start method는 request builder 입력을 받아 `AltApiResult<...Response>`로 반환한다. response에 `ErrorInfo`가 있으면 `AltApiError`, thrown transport failure는 transport result로 바꾼다.
#### 수정 파일 및 체크리스트
- [ ] `apps/client/lib/src/features/backtest/data/backtest_repository.dart`
- [ ] `apps/client/test/features/backtest/backtest_repository_test.dart`
#### 테스트 작성
작성한다. list/detail/result/start 각각 success request payload와 typed error mapping을 확인한다. disconnected/transport failure는 fake client throwing path로 확인한다.
#### 중간 검증
`cd apps/client && flutter test test/features/backtest/backtest_repository_test.dart` exit code 0.
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `apps/client/lib/src/features/backtest/data/backtest_repository.dart` | API-1 |
| `apps/client/test/features/backtest/backtest_repository_test.dart` | API-1 |
## 최종 검증
```bash
cd apps/client && flutter test
```
기대 결과: exit code 0. 실제 API socket integration smoke는 predecessor handoff와 후속 runtime evidence로 남기고, 이 plan은 fake client repository test로 제한한다.
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.

View file

@ -13,6 +13,18 @@ Do not edit generated files by hand; run `../../bin/contracts-gen`.
The shell is intentionally a skeleton. Quant-specific screens such as market data, backtests, portfolio, and research remain placeholders until the API/worker/domain headless paths are ready to mount real surfaces.
## API/Core Readiness Handoff
Before adding operator console screens, client work should prove the screenless API boundary first:
- request/response parser coverage for generated ALT protobuf messages
- socket connect, disconnect, timeout, and transport failure states represented outside UI copy
- market data status/list calls with parsed result/status keys
- backtest list/detail/result/start calls with success and typed error paths
- reproducible `flutter test` output plus fixture/fake notes for the next UI milestone
The CLI scenario evidence that feeds this client boundary lives in `apps/cli/testdata/operator/headless_validation.md`.
```bash
flutter pub get
flutter run -d chrome