<!-- task=dart_legacy_refactor plan=0 tag=REFACTOR -->

# Code Review Reference - REFACTOR

## 개요

date=2026-04-25
task=dart_legacy_refactor, plan=0, tag=REFACTOR

## 이 파일을 읽는 리뷰 에이전트에게

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.

1. `CODE_REVIEW.md` → `code_review_0.log` (기존 code_review_*.log 수 = 0)
2. `PLAN.md` → `plan_0.log` (기존 plan_*.log 수 = 0)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REFACTOR-1] `communicator.dart` `send()` concrete 구현 + 레거시 삭제 | [x] |
| [REFACTOR-2] `communicator_test.dart` `_FakeCommunicator.send()` 오버라이드 제거 | [x] |

## 계획 대비 변경 사항

- 현재 작업트리에 nonce overflow 정책(`maxNonce`, `nextNonce()`)이 적용되어 있어, 새 `Communicator.send()`도 계획의 `++nonce` 대신 `nextNonce()`를 사용했다.
- 기존 테스트 수가 계획 작성 시점보다 늘어 `communicator_test.dart`는 8개, 전체 `dart test`는 45개가 실행되었다.

## 주요 설계 결정

- `initialize()`는 항상 명시적인 `Transport`를 받도록 유지하고, 레거시 fallback transport를 제거했다.
- `Communicator.send()` 기본 구현은 `queuePacket()`을 통해 동일한 직렬화 경로를 사용한다.
- `HeartbeatMixin.send()` 오버라이드는 전송 실패 시 `close()`하는 기존 동작을 보존했다.

## 리뷰어를 위한 체크포인트

- `dart/lib/src/communicator.dart` — `@Deprecated transmitPacket` 메서드 삭제 여부
- `dart/lib/src/communicator.dart` — `_LegacyCommunicatorTransport` 클래스 삭제 여부
- `dart/lib/src/communicator.dart` — `initialize()` `transport` 파라미터가 `required`인지
- `dart/lib/src/communicator.dart` — `send<T>()` 메서드가 concrete이고 `abstract` 키워드가 없는지
- `dart/lib/src/communicator.dart` — `HeartbeatMixin.send()` `@override`가 여전히 유효한지 (heartbeat_mixin.dart 확인)
- `dart/test/communicator_test.dart` — `_FakeCommunicator.send()` 오버라이드 삭제 여부
- `dart analyze` No issues / `dart test` 45개 PASS

## 검증 결과

### REFACTOR-1 중간 검증
```
$ cd dart && dart analyze lib/src/communicator.dart
Analyzing communicator.dart...
No issues found!
```

### REFACTOR-2 중간 검증
```
$ cd dart && dart test test/communicator_test.dart
00:00 +0: loading test/communicator_test.dart
00:00 +0: Communicator protocol guards response typeName mismatch completes sendRequest with error
00:00 +1: Communicator protocol guards close 후 sendRequest는 StateError로 완료된다
00:00 +2: Communicator protocol guards sendRequest가 timeout 내 응답 없으면 TimeoutException을 던진다
00:00 +3: Communicator protocol guards nonce wraps after int32 max without emitting zero
00:00 +4: Communicator protocol guards sendRequest matches response at nonce wrap boundary
00:00 +5: Communicator protocol guards cannot register addRequestListener for a type already using addListener
00:00 +6: Communicator protocol guards cannot register addListener for a type already using addRequestListener
00:00 +7: Communicator protocol guards queuePacket uses injected transport
00:00 +8: All tests passed!
```

### 최종 검증
```
$ cd dart && dart analyze
Analyzing dart...
No issues found!

$ cd dart && dart test
00:00 +0: loading test/communicator_test.dart
00:00 +0: test/communicator_test.dart: Communicator protocol guards response typeName mismatch completes sendRequest with error
00:00 +1: test/communicator_test.dart: Communicator protocol guards close 후 sendRequest는 StateError로 완료된다
00:00 +2: test/communicator_test.dart: Communicator protocol guards sendRequest가 timeout 내 응답 없으면 TimeoutException을 던진다
00:00 +3: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +4: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +5: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +6: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +7: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +8: test/socket_test.dart: ProtobufServer (plain) 서버가 정상 시작된다
00:00 +9: test/socket_test.dart: ProtobufClient (plain) 클라이언트가 서버에 연결된다
00:00 +10: test/socket_test.dart: ProtobufClient (plain) TestData 메시지를 서버가 수신한다
00:00 +11: test/socket_test.dart: ProtobufClient (plain) 여러 메시지를 순서대로 수신한다
00:01 +12: test/socket_test.dart: ProtobufClient (plain) 서버에서 클라이언트로 메시지를 전송한다
00:01 +13: test/socket_test.dart: ProtobufClient (plain) nonce가 송신마다 증가한다
00:01 +14: test/socket_test.dart: ProtobufClient (plain) 클라이언트 disconnect 시 서버 콜백이 호출된다
00:02 +15: test/socket_test.dart: ProtobufClient (plain) 서버 stop 시 클라이언트 disconnect 콜백이 호출된다
00:02 +16: test/socket_test.dart: ProtobufClient (plain) HeartBeat interval 동안 연결이 유지된다
00:04 +17: test/socket_test.dart: ProtobufClient (plain) close 후 isAlive가 false다
00:05 +18: test/socket_test.dart: ProtobufClient (plain) 서버가 모든 클라이언트에게 브로드캐스트한다
00:05 +19: test/socket_test.dart: ProtobufClient (plain) close 후 send는 무시된다
00:05 +20: test/socket_test.dart: ProtobufClient (plain) TCP closes on oversized packet length
00:06 +21: test/socket_test.dart: Heartbeat timeout TCP heartbeat 타임아웃 시 disconnect 콜백이 호출된다
00:08 +22: test/socket_test.dart: Heartbeat timeout WS heartbeat 타임아웃 시 disconnect 콜백이 호출된다
00:10 +23: test/socket_test.dart: ProtobufServer (SSL) SSL 서버가 정상 시작된다
00:10 +24: test/socket_test.dart: ProtobufClient (SSL) SSL 클라이언트가 서버에 연결된다
00:10 +25: test/socket_test.dart: ProtobufClient (SSL) SSL TestData 메시지를 서버가 수신한다
00:10 +26: test/socket_test.dart: ProtobufClient (SSL) SSL 서버에서 클라이언트로 메시지를 전송한다
00:11 +27: test/socket_test.dart: ProtobufClient (SSL) SSL disconnect 시 서버 콜백이 호출된다
00:11 +28: test/socket_test.dart: WsProtobufServer (plain) WS 서버가 정상 시작된다
00:11 +29: test/socket_test.dart: WsProtobufClient (plain) WS 클라이언트가 서버에 연결된다
00:11 +30: test/socket_test.dart: WsProtobufClient (plain) WS TestData 메시지를 서버가 수신한다
00:11 +31: test/socket_test.dart: WsProtobufClient (plain) WS 서버에서 클라이언트로 메시지를 전송한다
00:12 +32: test/socket_test.dart: WsProtobufClient (plain) WS 클라이언트 disconnect 시 서버 콜백이 호출된다
00:12 +33: test/socket_test.dart: WsProtobufClient (plain) WS 서버 stop 시 클라이언트 disconnect 콜백이 호출된다
00:12 +34: test/socket_test.dart: WsProtobufClient (plain) WS close 후 isAlive가 false다
00:12 +35: test/socket_test.dart: WsProtobufClient (plain) WS 서버가 모든 클라이언트에게 브로드캐스트한다
00:13 +36: test/socket_test.dart: WsProtobufClient (plain) WS close 후 send는 무시된다
00:13 +37: test/socket_test.dart: WsProtobufServer (SSL) WSS 서버가 정상 시작된다
00:13 +38: test/socket_test.dart: WsProtobufClient (SSL) WSS 클라이언트가 서버에 연결된다
00:13 +39: test/socket_test.dart: WsProtobufClient (SSL) WSS TestData 메시지를 서버가 수신한다
00:14 +40: test/socket_test.dart: WsProtobufClient (SSL) WSS disconnect 시 서버 콜백이 호출된다
00:14 +41: test/socket_test.dart: Request-Response (TCP plain) sendRequest로 서버 응답을 받는다
00:14 +42: test/socket_test.dart: Request-Response (TCP plain) 여러 sendRequest가 각각 올바른 응답을 받는다
00:14 +43: test/socket_test.dart: Request-Response (WS plain) WS sendRequest로 서버 응답을 받는다
00:15 +44: test/socket_test.dart: Request-Response (WS plain) WS 여러 sendRequest가 각각 올바른 응답을 받는다
00:15 +45: All tests passed!
```
