# T831 — memory review audit tombstone

> Status: `done`
> Milestone: `M3`
> Est. change: `~190 lines`

## Goal

完成後 memory repository 可原子保存 review transition、audit 與 removed source tombstone，重複命中不建立新卡。

## Depends on

- T830

## Inputs

- `apps/backend/internal/module/radar/repository/opportunity_memory.go`
- `apps/backend/internal/module/radar/domain/opportunity_review.go`
- Spec §3.1–§3.3、§10、驗收 #2–#4

## Outputs

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

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/repository/opportunity_memory.go` | edit | review update、audit、tombstone merge |
| `apps/backend/internal/module/radar/repository/opportunity_review_memory.go` | add | review event／dedupe store |
| `apps/backend/internal/module/radar/repository/opportunity_memory_test.go` | edit | transition、owner、duplicate tests |

### 行為變更

- removed 再命中只合併 watch／term／last matched，不新建、不恢復、不深判。
- `other` note、duplicate target owner 與 idempotency 皆由 repository 邊界守住。

### API / 契約（若有）

- repository 回 domain error；不得吞掉 audit／tombstone 寫入失敗。

## Out of scope

- 不接 Mongo、不改 HTTP handler。

## Acceptance

- [x] 同來源併發只保留一筆 Opportunity。
- [x] review transition 會 append audit；idempotent 重送不新增 event。
- [ ] 指令：

```bash
cd apps/backend && go test ./internal/module/radar/repository -run 'Review|Tombstone|Opportunity' -count=1
```

## Notes

沿用既有 owner＋external identity unique semantics。
