# T548 — reply-variant-model-repository

> Status: `done`  
> Milestone: `M3`  
> Kind: `feat`  
> Est. change: `~130 lines`

## Goal

完成後系統應：ReplyVariant domain 與 repository 就位，一個商機下每個 variant 至多一筆最新版本，並可記錄使用與送出管道。

## Depends on

- T501

## Inputs

- Spec：`../spec.md` §4.5、§8（`radar_replies`）、§9.3（RP-01）

## Outputs

### 程式變更（預期路徑）

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/domain/reply.go` | add | variant 枚舉 `public_comment|dm|no_sales|professional|humorous`＋struct |
| `apps/backend/internal/module/radar/repository/reply_mongo.go` | add | Upsert(owner, opportunity, variant)、ListByOpportunity、MarkUsed(channel) |
| `apps/backend/internal/module/radar/repository/reply_memory.go` | add | 測試用 |

### 行為變更

- 重新生成同 variant 為覆寫（保留 `used_at`／`sent_channel` 若已使用）。
- `MarkUsed` 記錄送出管道（`outbox`／`manual_copy`），供 T589 回覆版本成功率統計。

## Out of scope

- 生成邏輯與 forbidden 過濾（T549）
- 送出接線（T550）

## Acceptance

- [x] unit test：同 variant 兩次 upsert 只有一筆；`MarkUsed` 後重生仍保留使用紀錄
- [x] 指令：

```bash
cd apps/backend && go test ./internal/module/radar/... -count=1
```
