# T744 — product match merge primary arbitration > Status: `done` > Milestone: `M4` · Phase C > Kind: `feat` · Est. change: `~200 lines` ## Goal 把 fit 結果合併進既有 Opportunity,穩定選 PrimaryProduct 並正確換算 intent fit 10 分。 ## Depends on - T732、T743 ## Inputs - `apps/backend/internal/module/radar/usecase/judge_persist.go` - `../spec.md` §3.3、§4.2 ## Outputs | 路徑 | 動作 | 說明 | |------|------|------| | `apps/backend/internal/module/radar/usecase/product_match_merge.go` | add | merge decision、primary arbitration、score recompute | | `apps/backend/internal/module/radar/usecase/judge_persist.go` | edit | new/existing/same-product branches | | merge tests | add | first/higher/tie/manual override/same product | ## Behavior - 首 eligible 為 primary;更高分自動替換;tie 使用 spec 穩定規則。 - 有人工 override 不自動替換。 - primary 變更只改 fit reason 與總分,不重跑其他四問。 - 同 Product 再命中只 merge watch/term,不重判不計費。 ## Out of scope - 人工 override API(T754) - list filters(T753) ## Acceptance - [x] spec #4–#6 的 usecase tests 通過。 ```bash cd apps/backend && go test ./internal/module/radar/usecase/... -count=1 ``` Implementation result (2026-08-10): new and existing opportunities now carry ProductMatch snapshots through persistence. Same-product hits only merge watch/term sources; new eligible products arbitrate primary by score, band, time, and ID, while human overrides are preserved. Primary changes recompute only the existing fit reason and intent total (product fit 0–100 → fit 0–10).