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

# Dart Communicator 레거시 정리

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

각 항목의 체크리스트를 완료 표시하고, 중간 검증 명령을 실행한 뒤 출력을 CODE_REVIEW.md의 `검증 결과` 섹션에 붙여 넣는다. 최종 검증까지 완료한 후 CODE_REVIEW.md의 각 항목을 `[x]`로 체크한다.

## 배경

Dart `Communicator`는 `send<T>()` 메서드가 `abstract`로 선언되어 모든 서브클래스나 믹스인이 구현해야 한다. Go·Kotlin·Python·TypeScript 4개 언어는 `Communicator.send()`가 직접 `queuePacket`을 호출하는 concrete 구현을 제공한다. Dart의 이 설계 차이는 `HeartbeatMixin`이 `Communicator`에 믹스인되는 초기 구조에서 비롯된 레거시로, `@Deprecated transmitPacket`과 `_LegacyCommunicatorTransport` 데드코드를 동반한다. 테스트의 `_FakeCommunicator`도 동일한 이유로 불필요한 `send()` 오버라이드를 포함한다. 이번 작업으로 Dart를 다른 언어 구현과 동일한 구조로 맞춘다.

---

## [REFACTOR-1] `communicator.dart` — `send()` concrete 구현 + 레거시 삭제

### 문제

- `dart/lib/src/communicator.dart:63` — `send()`가 `abstract`여서 서브클래스 모두 구현 강제
- `dart/lib/src/communicator.dart:47-53` — `@Deprecated transmitPacket` 데드코드
- `dart/lib/src/communicator.dart:35,37` — `initialize()`의 `transport` 파라미터가 nullable이며, null 시 이미 삭제 대상인 `_LegacyCommunicatorTransport(this)` 폴백을 사용
- `dart/lib/src/communicator.dart:192-204` — `_LegacyCommunicatorTransport` 클래스 데드코드

### 해결 방법

1. `initialize()`의 `{Transport? transport}` → `{required Transport transport}` 변경
2. `_transport = transport ?? _LegacyCommunicatorTransport(this)` → `_transport = transport`
3. `@Deprecated transmitPacket` 메서드 삭제
4. `abstract Future<void> send<T>(T data)` → concrete 구현으로 교체
5. `_LegacyCommunicatorTransport` 클래스 삭제

**Before (communicator.dart:33-38):**
```dart
  void initialize(
      Map<String, GeneratedMessage Function(List<int>)> instanceGenerator,
      {Transport? transport}) {
    _instanceGenerator = instanceGenerator;
    _transport = transport ?? _LegacyCommunicatorTransport(this);
  }
```

**After:**
```dart
  void initialize(
      Map<String, GeneratedMessage Function(List<int>)> instanceGenerator,
      {required Transport transport}) {
    _instanceGenerator = instanceGenerator;
    _transport = transport;
  }
```

**Before (communicator.dart:47-53):**
```dart
  /// Deprecated compatibility path for subclasses that still override writes.
  ///
  /// New clients should pass a [Transport] to [initialize] instead.
  @Deprecated('Pass a Transport to initialize instead.')
  Future<void> transmitPacket(PacketBase base) {
    return Future.error(StateError('transport is not initialized'));
  }
```

**After:** 전체 삭제

**Before (communicator.dart:63):**
```dart
  Future<void> send<T extends GeneratedMessage>(T data);
```

**After:**
```dart
  Future<void> send<T extends GeneratedMessage>(T data) async {
    if (isAlive) {
      await queuePacket(PacketBase()
        ..typeName = data.info_.qualifiedMessageName
        ..nonce = ++nonce
        ..data = data.writeToBuffer());
    }
  }
```

**Before (communicator.dart:192-204):**
```dart
class _LegacyCommunicatorTransport implements Transport {
  final Communicator _communicator;

  _LegacyCommunicatorTransport(this._communicator);

  @override
  Future<void> writePacket(PacketBase base) {
    return _communicator.transmitPacket(base);
  }

  @override
  Future<void> close() async {}
}
```

**After:** 전체 삭제 (이 클래스 바로 아래의 `abstract class IDataHandler` 이후는 그대로 유지)

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

- `dart/lib/src/communicator.dart`
  - [x] `initialize()` 파라미터: `{Transport? transport}` → `{required Transport transport}`
  - [x] `initialize()` 바디: `_transport = transport ?? _LegacyCommunicatorTransport(this)` → `_transport = transport`
  - [x] `@Deprecated transmitPacket` 메서드 전체 삭제 (docstring 포함)
  - [x] `abstract Future<void> send<T extends GeneratedMessage>(T data)` → concrete 구현으로 교체
  - [x] `_LegacyCommunicatorTransport` 클래스 전체 삭제

### 테스트 작성

추가 테스트 불필요. 기존 `communicator_test.dart` 6개 테스트가 `send()` 경로를 포함해 충분히 커버한다.

### 중간 검증

```
$ cd dart && dart analyze lib/src/communicator.dart
(No issues found!)
```

---

## [REFACTOR-2] `communicator_test.dart` — `_FakeCommunicator.send()` 오버라이드 제거

### 문제

`dart/test/communicator_test.dart:24-33` — `_FakeCommunicator.send()` 오버라이드가 REFACTOR-1 이후 `Communicator.send()`와 동일한 로직을 중복 구현한다.

```dart
  @override
  Future<void> send<T extends GeneratedMessage>(T data) async {
    if (isAlive) {
      await queuePacket(PacketBase()
        ..typeName = data.info_.qualifiedMessageName
        ..nonce = ++nonce
        ..data = data.writeToBuffer());
    }
    return Future.value();
  }
```

### 해결 방법

`_FakeCommunicator.send()` 오버라이드 블록 전체 삭제. `Communicator.send()` 기본 구현이 그대로 사용된다.

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

- `dart/test/communicator_test.dart`
  - [x] `_FakeCommunicator.send()` 오버라이드 삭제 (lines 24-33, `@override`부터 닫는 `}` 포함)

### 테스트 작성

기존 6개 테스트 그대로 사용.

### 중간 검증

```
$ cd dart && dart test test/communicator_test.dart
00:00 +6: All tests passed!
```

---

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `dart/lib/src/communicator.dart` | REFACTOR-1 |
| `dart/test/communicator_test.dart` | REFACTOR-2 |

## 의존 관계 및 구현 순서

REFACTOR-1 먼저, 이후 REFACTOR-2 진행. REFACTOR-2는 REFACTOR-1이 완료된 상태에서만 컴파일된다.

## 최종 검증

```
$ cd dart && dart analyze
No issues found!

$ cd dart && dart test
00:xx +43: All tests passed!
```
