# T731 — opportunity product match domain

> Status: `done`  
> Milestone: `M3` · Phase C  
> Kind: `feat` · Est. change: `~180 lines`

## Goal

定義可驗證、可快照、可人工覆寫的 ProductMatch 與 PrimaryProduct 領域模型。

## Depends on

- T724（Phase B UX 已批准）

## Inputs

- `../spec.md` §2、§3.2–§3.4、§6
- `apps/backend/internal/module/radar/domain/opportunity.go`

## Outputs

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/domain/product_match.go` | add | reasons、bands、eligible、snapshot、override validation |
| `apps/backend/internal/module/radar/domain/opportunity.go` | edit | matches、primary fields、list filters、stable sort fields |
| `apps/backend/internal/module/radar/domain/product_match_test.go` | add | score／evidence／primary invariants |

## Behavior

- 四維理由齊全；正分須 excerpt＋basis；score 為四維總和。
- 同 Product 最多一 match；primary 必須存在，weak/excluded 需人工理由。
- Product 更新不改舊 snapshot；legacy 可無 matches。

## Out of scope

- AI／deterministic scoring（T742/T743）
- persistence merge（T732）

## Acceptance

- [x] strong／possible／weak 與 eligible 邊界有 table tests。

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

Implementation result (2026-08-10): added four-dimensional ProductMatch
validation, score bands, evidence requirements, snapshots, primary metadata,
and legacy-safe Opportunity fields with boundary tests.
