<!-- task=m-contract-codegen-baseline/04+02_client_parser_map plan=0 tag=API -->

# Plan - Client Parser Map

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 반드시 채운다. 검증 명령을 실행하고 실제 stdout/stderr를 기록한 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 최종화는 code-review 스킬 전용이다.

## 배경

Flutter client는 generated ALT contracts를 소비해야 하지만 현재 parser map 표준 위치가 없다. `02+01_codegen_check`가 Dart generated output을 만든 뒤, `lib/src/contracts`에 작은 helper를 두면 후속 socket client adoption이 UI와 generated code를 직접 엮지 않아도 된다.

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/foundation-alignment/PHASE.md`
- `agent-roadmap/phase/foundation-alignment/milestones/contract-codegen-baseline.md`
- `agent-ops/rules/project/domain/client/rules.md`
- `agent-ops/rules/project/domain/contracts/rules.md`
- `apps/client/pubspec.yaml`
- `apps/client/README.md`
- `apps/client/lib/main.dart`
- `apps/client/lib/src/app/app.dart`
- `apps/client/lib/src/app/router.dart`
- `apps/client/lib/src/features/dashboard/presentation/dashboard_screen.dart`
- `apps/client/test/widget_test.dart`
- `packages/contracts/proto/alt/v1/common.proto`
- `packages/contracts/proto/alt/v1/market.proto`
- `packages/contracts/proto/alt/v1/backtest.proto`
- `../proto-socket/dart/lib/src/communicator.dart`
- `bin/test`
- `bin/lint`

### 테스트 커버리지 공백

- Client parser map helper: 기존 테스트 없음. 새 Dart unit test가 qualified message name keys와 fromBuffer parse success를 검증해야 한다.
- Generated Dart import stability: 기존 widget test는 generated contracts를 import하지 않는다. 새 parser map test가 generated files를 컴파일 경로에 포함한다.

### 심볼 참조

- renamed/removed symbols: none.

### 분할 판단

분할 정책을 먼저 평가했다. 이 plan은 `04+02_client_parser_map`이며 `02+01_codegen_check`가 `complete.log`를 만든 뒤 시작한다. API parser map은 별도 `03+02_api_parser_map`으로 분리되어 있고, 두 subtask는 codegen 이후 병렬 가능하다.

### 범위 결정 근거

이 subtask는 `apps/client/lib/src/contracts`, generated Dart imports, client tests, client README만 다룬다. Socket connection lifecycle, WebSocket configuration, UI state, Go API 변경은 범위 밖이다.

### 빌드 등급

build=`cloud-G06`, review=`cloud-G06`. Generated Dart contracts와 proto-socket wire type conventions를 client boundary에 묶는 protocol/client 작업이다.

## 의존 관계 및 구현 순서

`04+02_client_parser_map`은 같은 task group의 `02+01_codegen_check`가 `complete.log`를 만든 뒤 시작한다. 이 의존성은 directory name의 `+02`가 source of truth다.

## 구현 체크리스트

- [ ] [API-1] Flutter client contract parser map helper와 unit test를 추가한다.
- [ ] [API-2] client README에 generated contract와 parser map 표준 위치를 문서화한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [API-1] Flutter parser map helper

#### 문제

`apps/client/README.md:5`는 ALT protobuf bindings를 `lib/src` 아래에 추가하라고만 안내한다. `../proto-socket/dart/lib/src/communicator.dart:45`는 `Map<String, GeneratedMessage Function(List<int>)>` parser map을 요구하고, `../proto-socket/dart/lib/src/communicator.dart:98`은 outgoing `typeName`에 `data.info_.qualifiedMessageName`을 쓴다. Client에는 generated ALT messages의 qualified names를 모으는 helper가 없다.

Before:

```markdown
<!-- apps/client/README.md:5 -->
This app uses Riverpod for state and dependency boundaries, and `go_router` for navigation. ALT protobuf bindings and the proto-socket client layer should be added under `lib/src` after `packages/contracts` generation is introduced.
```

```dart
// ../proto-socket/dart/lib/src/communicator.dart:45
void initialize(
    Map<String, GeneratedMessage Function(List<int>)> instanceGenerator,
    {required Transport transport}) {
  _instanceGenerator = instanceGenerator;
  _transport = transport;
}
```

해결 후 형태:

```dart
import 'package:protobuf/protobuf.dart';

Map<String, GeneratedMessage Function(List<int>)> altParserMap() {
  return {
    HelloRequest.getDefault().info_.qualifiedMessageName: HelloRequest.fromBuffer,
    HelloResponse.getDefault().info_.qualifiedMessageName: HelloResponse.fromBuffer,
  };
}
```

#### 해결 방법

`apps/client/lib/src/contracts/alt_contracts.dart`를 만들고 generated `common.pb.dart`, `market.pb.dart`, `backtest.pb.dart`의 request/response/result message를 등록한다. helper는 새 map을 반환하고, UI/presentation layer에는 import하지 않는다.

#### 수정 파일 및 체크리스트

- [ ] `apps/client/lib/src/contracts/alt_contracts.dart`: `altParserMap()` 추가.
- [ ] `apps/client/test/contracts/alt_contracts_test.dart`: qualified key와 parse success 검증.

#### 테스트 작성

작성한다. `altParserMap contains generated ALT message parsers`는 `HelloRequest`, `HelloResponse`, `ListInstrumentsRequest`, `ListInstrumentsResponse`, `ListBarsRequest`, `ListBarsResponse`, `StartBacktestRequest`, `StartBacktestResponse`, `GetBacktestRunRequest`, `GetBacktestRunResponse`, `GetBacktestResultRequest`, `GetBacktestResultResponse`, `BacktestResult`를 map에서 찾아 `fromBuffer` round-trip으로 검증한다.

#### 중간 검증

```bash
cd apps/client && flutter test test/contracts/alt_contracts_test.dart
```

기대 결과: exit 0.

### [API-2] Client contract location documentation

#### 문제

`apps/client/README.md:5`의 문장은 codegen 도입 전 placeholder라서 generated output path와 parser map helper 위치를 알려주지 않는다.

Before:

```markdown
<!-- apps/client/README.md:5 -->
ALT protobuf bindings and the proto-socket client layer should be added under `lib/src` after `packages/contracts` generation is introduced.
```

해결 후 형태:

```markdown
Generated ALT protobuf files live under `lib/src/generated/alt/v1`.
Client parser map helpers live under `lib/src/contracts`.
Do not edit generated files by hand; run `../../bin/contracts-gen`.
```

#### 해결 방법

README에 generated output path, parser map helper path, regeneration command만 짧게 남긴다.

#### 수정 파일 및 체크리스트

- [ ] `apps/client/README.md`: generated contract and parser map section 추가.

#### 테스트 작성

문서 변경이므로 테스트 파일은 작성하지 않는다. deterministic search로 앵커 존재를 확인한다.

#### 중간 검증

```bash
rg --sort path -n "lib/src/generated/alt/v1|lib/src/contracts|contracts-gen" apps/client/README.md
```

기대 결과: 모든 앵커가 검색된다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/client/lib/src/contracts/alt_contracts.dart` | API-1 |
| `apps/client/test/contracts/alt_contracts_test.dart` | API-1 |
| `apps/client/README.md` | API-2 |

## 최종 검증

```bash
cd apps/client && flutter test test/contracts/alt_contracts_test.dart
rg --sort path -n "lib/src/generated/alt/v1|lib/src/contracts|contracts-gen" apps/client/README.md
bin/test
bin/lint
```

기대 결과: 모든 명령 exit 0. Flutter test cache output은 해당 없음.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
