53 lines
1.6 KiB
Markdown
53 lines
1.6 KiB
Markdown
|
|
# 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.
|