# T750 — product watch create assign lifecycle api

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

## Goal

真 API 可建立 product watch、一次補綁 generic、正確套用 ServiceProfile 門檻與 lifecycle guard。

## Depends on

- T734、T740、T741

## Inputs

- `apps/backend/internal/module/radar/usecase/watch.go`
- create/update/pause/resume/assign logics
- `../spec.md` §3.1、§3.5、§4.1

## Outputs

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/internal/module/radar/usecase/watch.go` | edit | product create、assign once、readiness、resume guards |
| `apps/backend/internal/logic/radar/*watch*_logic.go` | edit | request mapping、owner errors、public response |
| watch tests | edit/add | product/generic/profile/ownership/lifecycle |

## Behavior

- product IDs 成對且合法；product watch 無 ServiceProfile 也可 active。
- generic active 維持舊 profile gate。
- assign 只一次；product watch 不可 PUT 換產品。
- product_unavailable resume 回 conflict。

## Out of scope

- 排程處理無效產品（T751/T755）
- Product delete

## Acceptance

- [x] spec #1、#10、#13 API cases 通過。

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

Implementation result (2026-08-10): create and assign routes now accept paired
owned Brand／Product IDs, snapshot their context, allow active product watches
without a ServiceProfile, and keep generic profile／quota gates. Assignment is
one-way and update routes cannot replace a bound product.
