- Add server_test.go for socket server testing - Update socket-session-loop.md roadmap milestone - Refactor services/api/internal/socket/server.go - Add agent-task documentation for socket session loop
185 lines
8.4 KiB
Markdown
185 lines
8.4 KiB
Markdown
<!-- task=m-socket-session-loop/01_client_socket_layer plan=0 tag=API -->
|
|
|
|
# Plan - API
|
|
|
|
## 이 파일을 읽는 구현 에이전트에게
|
|
|
|
`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채우는 것이 필수 마지막 단계다. 구현 후 검증을 실행하고 실제 출력, 계획 대비 변경, 설계 결정을 review stub에 기록한 뒤 active 파일을 유지하고 리뷰 준비를 보고한다. 사용자 결정, 외부 환경 준비, 범위 충돌 없이는 안전하게 진행할 수 없으면 review stub의 `사용자 리뷰 요청`에 정확한 증거를 남기고 중단한다. `USER_REVIEW.md`, archive, `complete.log` 작성은 code-review 전용이다.
|
|
|
|
## 배경
|
|
|
|
`Socket Session Loop`의 API Hello handler는 Go smoke test로 닫혔다. 남은 큰 작업은 Flutter client가 같은 `alt.v1` parser map과 proto-socket Dart implementation을 사용해 API socket endpoint에 연결하고 `HelloRequest`를 보낼 수 있는 integration layer를 갖추는 것이다. 이 작업은 dependency manifest, generated contracts, proto-socket Dart API를 함께 건드리므로 별도 plan으로 둔다.
|
|
|
|
## 사용자 리뷰 요청 흐름
|
|
|
|
구현 중 차단 조건은 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 그 내용을 검증해 실제 `USER_REVIEW.md` 작성 여부를 결정한다.
|
|
|
|
## 분석 결과
|
|
|
|
### 읽은 파일
|
|
|
|
- `agent-roadmap/current.md`
|
|
- `agent-roadmap/phase/foundation-alignment/PHASE.md`
|
|
- `agent-roadmap/phase/foundation-alignment/milestones/socket-session-loop.md`
|
|
- `apps/client/pubspec.yaml`
|
|
- `apps/client/lib/src/contracts/alt_contracts.dart`
|
|
- `apps/client/test/contracts/alt_contracts_test.dart`
|
|
- `../proto-socket/dart/pubspec.yaml`
|
|
- `../proto-socket/dart/lib/proto_socket.dart`
|
|
- `../proto-socket/dart/lib/src/communicator.dart`
|
|
- `../proto-socket/dart/lib/src/ws_protobuf_client_io.dart`
|
|
- `../proto-socket/dart/lib/src/ws_protobuf_client_web.dart`
|
|
- `../proto-socket/dart/lib/src/base_client.dart`
|
|
- `../proto-socket/dart/lib/src/transport.dart`
|
|
- `../proto-socket/dart/crosstest/go_dart_client.dart`
|
|
|
|
### 테스트 커버리지 공백
|
|
|
|
- Flutter parser map round-trip은 `apps/client/test/contracts/alt_contracts_test.dart`에 있다.
|
|
- Flutter socket connection wrapper, endpoint config, `HelloRequest -> HelloResponse` helper는 테스트가 없다.
|
|
- 실제 API 서버와 Flutter test process의 end-to-end WebSocket smoke는 이 plan에서 만들지 않는다. API-side smoke는 Go test로 이미 추가되었고, Flutter layer는 dependency와 wrapper 단위 테스트로 먼저 고정한다.
|
|
|
|
### 심볼 참조
|
|
|
|
- renamed/removed symbol: none.
|
|
|
|
### 분할 판단
|
|
|
|
- split decision policy를 먼저 평가했다.
|
|
- shared task group: `agent-task/m-socket-session-loop/`.
|
|
- `01_client_socket_layer`: proto_socket dependency, client integration API, wrapper tests를 만든다.
|
|
- `02+01_dashboard_socket_status`: `01_client_socket_layer` 완료 뒤 Riverpod/UI state surface를 연결한다.
|
|
- dependency boundary가 있다. UI provider는 socket wrapper API가 확정되어야 안정적으로 작성할 수 있으므로 split이 필요하다.
|
|
|
|
### 범위 결정 근거
|
|
|
|
- `services/api/**`는 이미 작은 작업으로 Hello handler와 Go smoke test를 처리했으므로 이 plan에서 수정하지 않는다.
|
|
- `packages/contracts/proto/**`와 generated outputs는 이미 완료된 contract milestone 산출물이므로 수정하지 않는다.
|
|
- 실제 market data, backtest, auth/session 권한 모델은 milestone 범위 제외다.
|
|
- Flutter 화면 표시와 provider wiring은 dependent plan `02+01_dashboard_socket_status`로 넘긴다.
|
|
|
|
### 빌드 등급
|
|
|
|
- build: `cloud-G06`, review: `cloud-G06`.
|
|
- Dart proto-socket dependency와 cross-platform WebSocket API, protocol request helper를 다루며 기존 테스트가 약해 cloud review가 맞다.
|
|
|
|
## 구현 체크리스트
|
|
|
|
- [ ] `apps/client/pubspec.yaml`에 `proto_socket` path dependency를 추가하고 `flutter pub get`으로 `apps/client/pubspec.lock`을 갱신한다.
|
|
- [ ] `apps/client/lib/src/integrations/socket/` 아래 endpoint config와 ALT WebSocket client wrapper를 추가한다. `altParserMap()`과 `WsProtobufClient`를 사용하고 `HelloRequest -> HelloResponse` helper를 제공한다.
|
|
- [ ] `apps/client/test/integrations/socket/` 아래 wrapper/config 단위 테스트를 추가한다. 검증: `cd apps/client && flutter test test/integrations/socket`.
|
|
- [ ] 최종 검증으로 `cd apps/client && flutter test`, `cd apps/client && flutter analyze --no-fatal-infos`를 실행한다.
|
|
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
|
|
|
|
### [API-1] Add proto_socket dependency
|
|
|
|
문제: `apps/client/pubspec.yaml:30`의 dependencies에는 `protobuf`만 있고 proto-socket Dart package가 없다. `../proto-socket/dart/lib/src/ws_protobuf_client_io.dart:17`는 WebSocket connect API를 제공하지만 ALT client가 package를 소비하지 않는다.
|
|
|
|
해결 방법:
|
|
|
|
```yaml
|
|
# apps/client/pubspec.yaml:37
|
|
go_router: ^17.2.3
|
|
protobuf: ^6.0.0
|
|
fixnum: ^1.1.1
|
|
```
|
|
|
|
```yaml
|
|
go_router: ^17.2.3
|
|
protobuf: ^6.0.0
|
|
fixnum: ^1.1.1
|
|
proto_socket:
|
|
path: ../../../proto-socket/dart
|
|
```
|
|
|
|
수정 파일 및 체크리스트:
|
|
|
|
- [ ] `apps/client/pubspec.yaml` dependency 추가
|
|
- [ ] `apps/client/pubspec.lock` 갱신
|
|
|
|
테스트 작성: 별도 테스트 없음. dependency resolution은 `flutter pub get`, `flutter test`, `flutter analyze --no-fatal-infos`로 검증한다.
|
|
|
|
중간 검증:
|
|
|
|
```bash
|
|
cd apps/client && flutter pub get
|
|
```
|
|
|
|
기대 결과: dependency resolution이 성공하고 `pubspec.lock`에 `proto_socket` path package가 기록된다.
|
|
|
|
### [API-2] Add ALT socket client wrapper
|
|
|
|
문제: `apps/client/lib/src/contracts/alt_contracts.dart:7`은 parser map만 제공하고, `../proto-socket/dart/lib/src/communicator.dart:125`의 `sendRequest`를 ALT `HelloRequest`에 연결하는 wrapper가 없다.
|
|
|
|
해결 방법:
|
|
|
|
```dart
|
|
// apps/client/lib/src/contracts/alt_contracts.dart:7
|
|
Map<String, GeneratedMessage Function(List<int>)> altParserMap() {
|
|
return {
|
|
```
|
|
|
|
```dart
|
|
// apps/client/lib/src/integrations/socket/alt_socket_client.dart
|
|
class AltSocketClient extends WsProtobufClient {
|
|
AltSocketClient(dynamic ws) : super(ws, 30, 10, altParserMap());
|
|
|
|
static Future<AltSocketClient> connect(AltSocketEndpoint endpoint) async {
|
|
final ws = await WsProtobufClient.connect(
|
|
endpoint.host,
|
|
endpoint.port,
|
|
path: endpoint.path,
|
|
);
|
|
return AltSocketClient(ws);
|
|
}
|
|
|
|
Future<HelloResponse> hello({Duration timeout = const Duration(seconds: 2)}) {
|
|
return sendRequest<HelloRequest, HelloResponse>(
|
|
HelloRequest()
|
|
..clientName = 'alt-client'
|
|
..clientVersion = 'dev'
|
|
..altProtocolVersion = 'alt.v1',
|
|
timeout: timeout,
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
Implementer note: constructor details must match the actual `WsProtobufClient` signature from the current `proto_socket` package; if the sketch above differs, record the exact adjustment in review.
|
|
|
|
수정 파일 및 체크리스트:
|
|
|
|
- [ ] `apps/client/lib/src/integrations/socket/socket_endpoint.dart` 추가
|
|
- [ ] `apps/client/lib/src/integrations/socket/alt_socket_client.dart` 추가
|
|
- [ ] `apps/client/lib/src/contracts/alt_contracts.dart`는 parser map 유지. 필요 시 export/helper만 보강
|
|
|
|
테스트 작성: 작성한다. `apps/client/test/integrations/socket/alt_socket_client_test.dart`에서 endpoint default, request payload construction, parser map usage를 검증한다. 실제 network E2E는 이 plan에서 제외한다.
|
|
|
|
중간 검증:
|
|
|
|
```bash
|
|
cd apps/client && flutter test test/integrations/socket
|
|
```
|
|
|
|
기대 결과: 새 socket integration 테스트가 통과한다.
|
|
|
|
## 수정 파일 요약
|
|
|
|
| 파일 | 항목 |
|
|
|------|------|
|
|
| `apps/client/pubspec.yaml` | API-1 |
|
|
| `apps/client/pubspec.lock` | API-1 |
|
|
| `apps/client/lib/src/integrations/socket/socket_endpoint.dart` | API-2 |
|
|
| `apps/client/lib/src/integrations/socket/alt_socket_client.dart` | API-2 |
|
|
| `apps/client/test/integrations/socket/alt_socket_client_test.dart` | API-2 |
|
|
|
|
## 최종 검증
|
|
|
|
```bash
|
|
cd apps/client && flutter test
|
|
cd apps/client && flutter analyze --no-fatal-infos
|
|
```
|
|
|
|
기대 결과: 모든 Flutter test와 analyze가 통과한다. cached output은 허용하지 말고 명령을 실제 재실행한다.
|
|
|
|
모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|