# T741 — product demand term suggestions

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

## Goal

依選定 Brand／Product 產出可追溯 basis 的需求詞與排除詞，而不是只搜尋品牌／產品名。

## Depends on

- T740

## Inputs

- `apps/backend/internal/module/radar/usecase/suggest.go`
- `../spec.md` §4.1、§5.2
- Threads searchable short-term rules

## Outputs

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/usecase/suggest.go` | edit | product context prompt／fallback／basis output |
| `apps/backend/internal/logic/radar/suggest_watch_terms_logic.go` | edit | 成對 IDs 與 mapping |
| suggestion tests | edit/add | pain/scenario/include/exclude／short-term cases |

## Behavior

- basis_kind 只來自 audience／pain／context／tag／capability／exclude。
- 品牌名與產品名只能輔助，不得是唯一建議理由。
- AI 失敗時明確錯誤或合法 fallback，不回空成功；計費沿用 radar.suggest。

## Out of scope

- 建立 watch（T750）
- 自動採用建議

## Acceptance

- [x] 每個 include suggestion 有 basis，全部通過短詞規則。

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

Implementation result (2026-08-10): paired Brand／Product requests now load an
immutable owned context, charge through `radar.suggest`, and return traceable
`basis_kind`／`basis_text`. Provider responses are structurally filtered; when
AI is unavailable or unusable, deterministic catalog terms are returned with
the same short-term and provenance rules. Unpaired IDs and empty fallback
contexts fail explicitly.
