# T566 — contact-touch-model-timeline-repo

> Status: `done`  
> Milestone: `M4`  
> Kind: `feat`  
> Est. change: `~140 lines`

## Goal

完成後系統應：ContactTouch 只增不改地記錄階段變更／送出回覆／備註／成交回報，並可依時間軸讀出。

## Depends on

- T565

## Inputs

- Spec：`../spec.md` §4.6.5、§8（`crm_touches`）、§9.4（CR-02、CR-03）

## Outputs

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

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/crm/domain/touch.go` | add | `type: stage|reply|note|conversion`＋`from_stage`／`to_stage`／`body`／`actor_uid` |
| `apps/backend/internal/module/crm/repository/touch_mongo.go` | add | Append、ListByContact（時間序、分頁） |
| `apps/backend/internal/module/crm/repository/touch_memory.go` | add | 測試用 |
| `apps/backend/internal/module/crm/usecase/touch.go` | add | Append 時同步更新 Contact `last_touch_at` |

### 行為變更

- Touch **不可更新或刪除**；成交修改／刪除寫新一筆（T573）。
- Append 與 `last_touch_at` 更新在同一 usecase，避免時間軸與列表排序不一致。

## Out of scope

- 階段轉移規則（T568）
- 詳情 API（T570）

## Acceptance

- [x] unit test：三種 type 各 append 一筆，時間序正確；Contact `last_touch_at` 同步
- [x] 嘗試更新既有 touch 被拒
- [x] 指令：

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