# T569 — contacts-list-api-filters-sort

> Status: `done`  
> Milestone: `M4`  
> Kind: `feat`  
> Est. change: `~160 lines`

## Goal

完成後系統應：`GET /api/v1/crm/contacts` 可搜尋名稱／帳號，依階段、待追蹤、意向分數、最後接觸時間篩選排序並分頁；`DELETE /contacts/:id` 可安全移出工作名單。

## Depends on

- T565

## Inputs

- Spec：`../spec.md` §4.6.4、§5.1、§5.2

## Outputs

### 程式變更（預期路徑）

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/backend/generate/api/crm.api` | edit | list req（`stage`／`needs_follow_up`／`band`／`sort`／`page`／`pageSize`）／resp |
| `apps/backend/internal/logic/crm/listContactsLogic.go` | edit | 查詢與排序 |
| `apps/backend/internal/module/crm/repository/contact_mongo.go` | edit | 依 filter 組 query；`band` 以關聯商機最高分推導 |

### 行為變更

- 回 `pagination` + `list`；`pageSize ≤ 50`；`query` 最多 80 字，對名稱與帳號做不分大小寫搜尋。
- 每列附：`stage`、`needs_follow_up`、最高 `intent_band`、`last_touch_at`、關聯商機數。
- 排序支援 `last_touch_at`（預設倒序）與 `intent_score`。
- DELETE 設 `removed_at` 並完成活躍 FollowUp；歷史不刪，同作者再次 accept 時恢復原 Contact。

## Out of scope

- 詳情與時間軸（T570）
- 前端工作清單（T574）

## Acceptance

- [x] 各 filter 與排序組合結果正確
- [x] `needs_follow_up=true` filter 可跨所有階段取到資料
- [x] 搜尋、20 筆分頁、owner guard、安全移除與重新加入皆有測試
- [x] 指令：

```bash
cd apps/backend && make gen-api && go test ./internal/logic/crm/... -count=1
```
