<!-- task=m-paper-trading-command-workflow/03+02_order_lifecycle plan=1 tag=REVIEW_PAPER_ORDER -->

# Plan - REVIEW_PAPER_ORDER

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

이 plan은 `code_review_cloud_G09_0.log`의 FAIL 판정에서 나온 Required 이슈만 처리한다. 사용자에게 직접 질문하지 말고, 사용자 결정이 꼭 필요한 경우에만 `CODE_REVIEW-local-G06.md`의 `사용자 리뷰 요청`을 증거와 함께 채운 뒤 중단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/trading-expansion/milestones/paper-trading-command-workflow.md`
- Task ids:
  - `paper-order-command`: virtual order lifecycle command
- Completion mode: check-on-pass

## 배경

order lifecycle 구현은 핵심 happy path와 contract/API/CLI 연결은 갖췄지만, 리뷰에서 두 가지 correctness/API contract 문제가 발견됐다.

- 같은 account를 다시 start하면 기존 order book이 남아 새 run state를 가린다.
- order lifecycle decimal 입력이 non-empty 여부만 검사해 invalid quantity/price가 pending order로 저장되거나 fill 시점에 rejected/internal error로 흘러간다.

## 범위 결정 근거

새 contract, 새 command surface, UI handoff, real API/DB-backed scenario 실행은 이 follow-up 범위가 아니다. 이미 추가된 order lifecycle surface 안에서 상태 초기화와 invalid request 검증만 보강한다.

## 구현 체크리스트

- [ ] [REVIEW_PAPER_ORDER-1] `StartPaperTrading`이 같은 account의 기존 order book을 새 run state와 함께 초기화하고, restart regression test를 추가한다.
- [ ] [REVIEW_PAPER_ORDER-2] order lifecycle quantity/price decimal을 저장/체결 전에 typed invalid request로 검증하고, malformed/zero/negative input regression tests를 추가한다. 검증: `go test -count=1 ./services/worker/internal/papertrading ./services/worker/internal/socket`, `go test -count=1 ./apps/cli/internal/operator`, `PATH="/tmp/protoc293/bin:$PATH" bin/test` 통과.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## REVIEW_PAPER_ORDER-1

### 문제

`services/worker/internal/papertrading/service.go:127` records a new `states[accountID]` entry but leaves `books[accountID]` untouched. Because `GetPaperTradingState` checks `books` first, a restart after manual submit/fill continues to expose the old order-book snapshot and order sequence.

### 해결 방법

Inside the same mutex section that records the new state, delete the account's order book. Add a regression test that:

- starts a paper account
- submits and fills or cancels a manual order so an order book exists
- starts the same account again
- verifies `GetPaperTradingState` reflects the new run seed rather than the old manual state
- verifies the next submitted order starts from the fresh book sequence

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

- [ ] `services/worker/internal/papertrading/service.go`
- [ ] `services/worker/internal/papertrading/service_test.go`

### 중간 검증

```bash
go test -count=1 ./services/worker/internal/papertrading
```

## REVIEW_PAPER_ORDER-2

### 문제

`services/worker/internal/papertrading/service.go:450` only checks `quantity.Amount.Value != ""`, and `services/worker/internal/socket/paper_mapping.go:49` only checks non-empty price amounts. Invalid decimals such as `abc`, zero quantity, negative quantity, and malformed/negative price can enter the lifecycle and later surface as rejected orders or internal fill errors instead of typed `invalid_request`.

### 해결 방법

Validate order lifecycle decimals before state mutation:

- `quantity` must parse as a decimal and be `> 0`
- `limit_price` and market `fill_price`, when present, must parse as decimal and be non-negative
- malformed `quantity`, `limit_price`, and `fill_price` must map to typed `invalid_request` at the worker socket boundary
- service-level validation should remain defensive so direct package callers cannot store malformed `PaperOrder`

Add regression tests at the lowest meaningful layer:

- service submit rejects zero, negative, and non-numeric quantity
- worker socket submit returns `invalid_request` for malformed quantity/limit price
- worker socket fill returns `invalid_request` for malformed or negative fill price
- CLI operator test covers typed invalid_request output for at least one lifecycle invalid input, or existing lower-level socket tests make the CLI path unnecessary and the review notes why

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

- [ ] `services/worker/internal/papertrading/service.go`
- [ ] `services/worker/internal/papertrading/service_test.go`
- [ ] `services/worker/internal/socket/paper_mapping.go`
- [ ] `services/worker/internal/socket/paper_test.go`
- [ ] `apps/cli/internal/operator/runner_paper_test.go` if CLI typed error evidence is added

### 중간 검증

```bash
go test -count=1 ./services/worker/internal/papertrading ./services/worker/internal/socket
go test -count=1 ./apps/cli/internal/operator
```

## 최종 검증

```bash
go test -count=1 ./services/worker/internal/papertrading ./services/worker/internal/socket
go test -count=1 ./apps/cli/internal/operator
PATH="/tmp/protoc293/bin:$PATH" bin/test
```

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