- Add proto files for backtest and market domains - Generate Go code in packages/contracts/gen/go - Generate Dart code in apps/client/lib/src/generated - Add contracts-gen and contracts-check binaries - Update pubspec.yaml with protoc dependencies - Update go.work with new module
7.3 KiB
Plan - API Parser Map
이 파일을 읽는 구현 에이전트에게
CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 반드시 채운다. 검증 명령을 실행하고 실제 stdout/stderr를 기록한 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 최종화는 code-review 스킬 전용이다.
배경
Go API는 proto-socket session boundary를 맡지만 현재 ALT application payload parser map을 등록하지 않는다. 02+01_codegen_check가 generated Go contracts를 만든 뒤, API 내부에 표준 parser map 위치를 두면 다음 Socket Session Loop Milestone에서 handshake/request-response를 바로 얹을 수 있다.
분석 결과
읽은 파일
agent-roadmap/current.mdagent-roadmap/phase/foundation-alignment/PHASE.mdagent-roadmap/phase/foundation-alignment/milestones/contract-codegen-baseline.mdagent-ops/rules/project/domain/api/rules.mdagent-ops/rules/project/domain/contracts/rules.mdservices/api/go.modservices/api/internal/socket/server.goservices/api/internal/config/config.goservices/api/cmd/alt-api/main.gopackages/contracts/proto/alt/v1/common.protopackages/contracts/proto/alt/v1/market.protopackages/contracts/proto/alt/v1/backtest.proto../proto-socket/go/communicator.gobin/testbin/lint
테스트 커버리지 공백
- API parser map helper: 기존 테스트 없음. 새 unit test가 모든 ALT request/response/result message key와 parse success를 검증해야 한다.
socket.NewServerparser map 주입: 기존 테스트 없음. 최소한 helper가 non-empty이고 server construction이 컴파일되는 것을go test ./...로 검증한다.
심볼 참조
- renamed/removed symbols: none.
분할 판단
분할 정책을 먼저 평가했다. 이 plan은 03+02_api_parser_map이며 02+01_codegen_check가 complete.log를 만든 뒤 시작한다. Client Dart parser map은 별도 04+02_client_parser_map에서 병렬 처리한다.
범위 결정 근거
이 subtask는 services/api/**와 API module dependency만 다룬다. Flutter client parser map, UI, actual request handlers, worker execution은 범위 밖이다.
빌드 등급
build=cloud-G06, review=cloud-G06. Protocol parser registration이 API runtime boundary에 들어가고 generated module dependency를 추가하므로 cloud review가 필요하다.
의존 관계 및 구현 순서
03+02_api_parser_map은 같은 task group의 02+01_codegen_check가 complete.log를 만든 뒤 시작한다. 이 의존성은 directory name의 +02가 source of truth다.
구현 체크리스트
- [API-1] API 내부 contract parser map helper와 unit test를 추가한다.
- [API-2] socket server construction이 API parser map을 사용하도록 연결하고 module dependency를 정리한다.
- CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
[API-1] API contract parser map helper
문제
../proto-socket/go/communicator.go:20의 ParserMap은 map[string]func([]byte) (proto.Message, error)이고, parser가 없으면 ../proto-socket/go/communicator.go:304에서 error를 반환한다. ALT API에는 generated alt.v1 messages를 parser map으로 묶는 표준 위치가 없다.
Before:
// ../proto-socket/go/communicator.go:304
func (c *Communicator) parse(typeName string, data []byte) (proto.Message, error) {
c.mu.RLock()
parser := c.parserMap[typeName]
c.mu.RUnlock()
if parser == nil {
return nil, fmt.Errorf("protobuf parser is not registered for type %s", typeName)
}
return parser(data)
}
해결 후 형태:
package contracts
func ParserMap() protoSocket.ParserMap {
return protoSocket.ParserMap{
protoSocket.TypeNameOf(&altv1.HelloRequest{}): parserFor(func() proto.Message { return &altv1.HelloRequest{} }),
}
}
해결 방법
services/api/internal/contracts/parser_map.go를 만들고 generated altv1 message 전체를 등록한다. request/response/result payload를 모두 포함하고 helper는 map을 새로 반환해 호출자가 mutate해도 package 전역 상태가 생기지 않게 한다.
수정 파일 및 체크리스트
services/api/internal/contracts/parser_map.go:ParserMap()과 sharedparserForhelper 추가.services/api/internal/contracts/parser_map_test.go: map keys와 parse success 검증.services/api/go.mod: generated Go module require 추가.
테스트 작성
작성한다. TestParserMapIncludesAltMessages는 HelloRequest, HelloResponse, ListInstrumentsRequest, ListInstrumentsResponse, ListBarsRequest, ListBarsResponse, StartBacktestRequest, StartBacktestResponse, GetBacktestRunRequest, GetBacktestRunResponse, GetBacktestResultRequest, GetBacktestResultResponse, BacktestResult를 등록/parse한다.
중간 검증
cd services/api && go test ./internal/contracts
기대 결과: exit 0.
[API-2] Wire parser map into socket server
문제
services/api/internal/socket/server.go:12는 protoSocket.ParserMap{}를 전달해 ALT payload가 들어와도 parse할 수 없다.
Before:
// services/api/internal/socket/server.go:10
func NewServer(cfg config.Config) *protoSocket.WsServer {
return protoSocket.NewWsServer(cfg.Host, cfg.Port, cfg.SocketPath, func(conn *websocket.Conn) *protoSocket.WsClient {
return protoSocket.NewWsClient(conn, cfg.HeartbeatIntervalSec, cfg.HeartbeatWaitSec, protoSocket.ParserMap{})
})
}
해결 후 형태:
import (
apiContracts "git.toki-labs.com/toki/alt/services/api/internal/contracts"
)
return protoSocket.NewWsClient(conn, cfg.HeartbeatIntervalSec, cfg.HeartbeatWaitSec, apiContracts.ParserMap())
해결 방법
server.go에서 API contracts helper를 import하고 NewWsClient에 apiContracts.ParserMap()을 전달한다. go mod tidy로 generated contract module dependency를 정리한다.
수정 파일 및 체크리스트
services/api/internal/socket/server.go: empty parser map을 API parser map으로 교체.services/api/go.mod: generated contract module dependency 유지.services/api/go.sum: 필요한 checksum 변경 반영.
테스트 작성
별도 socket server unit test는 작성하지 않는다. 이 subtask는 parser map helper unit test와 go test ./... 컴파일 검증으로 충분하다. 실제 handshake/request-response behavior는 후속 Socket Session Loop Milestone 범위다.
중간 검증
cd services/api && go test ./...
기대 결과: exit 0.
수정 파일 요약
| 파일 | 항목 |
|---|---|
services/api/internal/contracts/parser_map.go |
API-1 |
services/api/internal/contracts/parser_map_test.go |
API-1 |
services/api/internal/socket/server.go |
API-2 |
services/api/go.mod |
API-1, API-2 |
services/api/go.sum |
API-2 |
최종 검증
cd services/api && go test ./...
bin/test
bin/lint
기대 결과: 모든 명령 exit 0. Go test cache output은 허용한다.
모든 코드 변경 완료 후 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.