# T754 — primary product override api > Status: `done` > Milestone: `M5` · Phase C > Kind: `feat` · Est. change: `~160 lines` ## Goal 會員可將既有 ProductMatch 設為主推產品,並以 audit 鎖定人工選擇與重算 fit 分數。 ## Depends on - T744、T750、T753 ## Inputs - goctl primary-product route from T700 - ProductMatch repository guarded update - `../spec.md` §3.3、§4.4、§5.3 ## Outputs | 路徑 | 動作 | 說明 | |------|------|------| | `apps/backend/internal/module/radar/usecase/primary_product.go` | add | owner/match/override validation、score recompute | | `apps/backend/internal/logic/radar/set_primary_product_logic.go` | edit | JWT owner、request、response mapping | | primary tests | add | eligible、weak reason、excluded reason、cross owner、future merge | ## Behavior - Product 不在 match 中失敗;weak/excluded 無 reason 失敗。 - 寫 actor uid、時間、reason;後續自動 merge 不覆蓋。 - 已送出回覆/touch 不在此 task 回寫。 ## Out of scope - 回覆/CRM propagation(T770/T771) - ProductMatch 分數人工修改 ## Acceptance - [x] spec #6、#13 API cases 通過。 ```bash cd apps/backend && go test ./internal/module/radar/... ./internal/logic/radar/... -count=1 ``` Implementation result (2026-08-10): the generated primary-product route now validates owner and ProductMatch membership, requires an audit reason, stores actor/UTC nanoseconds, and recomputes only the existing fit dimension. Weak or excluded matches need an explicit reason; later automatic merges cannot replace the human override.