# 前後端改進建議

依「影響使用者 / 維護成本 / 風險」排序。細節背景見先前健康檢查；**架構導覽**見 `docs/architecture.md`。

---

## 後端：立刻值得修的問題

### 1. Job dedupe：改寫草稿全域互擋

`generate-rewrite-draft` 的 `DedupeKeys` 為空，但 `buildDedupeKey` 仍用 `type|scope` 產 key → 所有 `scope=persona` 的改寫 job 共用一把 lease。

- 檔案：`internal/model/job/usecase/usecase.go`、`helpers.go`
- 建議：`DedupeKeys: []string{"scope_id"}`，或空 keys 時回傳 `""` 不啟用 lease
- 補 test

### 2. CreateRun 失敗路徑用裸 `Update`

lease 失敗時 `runs.Update` 直接改 status，違反 guarded 規則。

- 改 `UpdateIfStatus(pending → cancelled)`

### 3. ClaimNext lock 失敗立刻 re-enqueue

可能 tight loop 打 Redis。應 delay / 檢查狀態後再入列，FindByID 失敗不要 silent drop。

### 4. Worker 忽略 Heartbeat 錯誤

`_ = step.Heartbeat(ctx)` 在 lock 過期後仍繼續跑。失敗應中止 step。

### 5. Refresh token 並發

先發新 token 再 blacklist 舊的 → 並發 refresh 可能雙活。應用原子輪替（Lua / 先 blacklist 再 issue，或 refresh family）。

---

## 後端：結構與可維護性

| 議題 | 建議 |
|------|------|
| ServiceContext 過胖 | 依域拆 bootstrap（auth/job/content/publish），減少單檔 400+ 行 DI |
| 每個 worker process 註冊全部 handler | 只 register 該 `workerType` 需要的 step；啟動時 assert template↔handler |
| ghost worker 在 compose | 已清理一輪；新增 template 時同步 `dev-all` / `docker-compose` |
| 列表 API 用 `limit` | 新 API 一律 `page/pageSize`；舊的雙讀後 deprecate |
| `time.Now().UnixNano()` 散落 | 統一 `clock.NowUnixNano()` 利於測試 |
| Secrets key 可空 | prod config validate：`HAIXUN_SECRETS_KEY` 必填 |
| copy_mission 半殘 | 見 `post-project-plan`：過渡期只留 inspire；完整 pipeline 勿再接，走 Post Project |
| 測試 | Job 較完整；auth refresh、ClaimNext race、logic 層幾乎無測 — 優先補 P0 |

### 錯誤處理慣例

- 好：`errs.For(code.X).…` + `response.Write`
- 差：`_, _ = FailRun` / `UpdateProgress` 吞錯誤 → 可觀測性差，長任務尤其危險

### 不建議做的事

- 為了 template-monorepo 相容引入 OAuth/OTP/Zitadel 重依賴
- 在 provider adapter 裡讀 Mongo / setting
- 裸 `Update` 蓋 job / publish_queue 狀態

---

## 前端：可明顯變好的地方

### 1. 登入態對 5xx 過於暴力

`AuthContext.reloadMember` 任何錯誤都 `clearTokens()`。gateway 短暫 502 會踢登出。

建議：僅 401 / refresh 失敗清 token；5xx 顯示「後端暫時無法連線」。

### 2. 巨型頁面

| 檔案 | 約略行數 | 建議 |
|------|----------|------|
| `PatrolPage.tsx` | ~1900 | 拆 list / graph / scan / outreach 子元件 + hooks |
| `MissionsPage.tsx` | ~1200 | 若走 Post Project 直接換 wizard，勿再膨脹 |
| `OwnPostsHub.tsx` | ~750 | 拆 formula / reply / list |

好處：可測、可讀、島民/自動化也較好掛 `data-islander-*`。

### 3. Hash 路由的限制

- 無巢狀 path、難做 deep link（例如 `#patrol/topic/xyz`）
- 中長期可考慮 React Router，或至少支援 `page + query` 狀態

### 4. 過時 UI / 死 client

| 項目 | 建議 |
|------|------|
| `GapsPage` | 對齊 `threads-automation-gap-plan` 真實進度，或改「已完成 checklist」 |
| `haixun.ts` 未呼叫方法 | 定期刪（inventory API client 等） |
| `extensionSync` 固定 reject | 文件與 UI 標「已停用」；重啟時勿再 postMessage JWT |
| jobLabels 幽靈 type | 隨 ghost template 刪 |

### 5. 設計系統（已做得不錯）

- 繼續只用 `--hx-*` / semantic Tailwind；勿引入 MUI/Ant
- 共用 `ui.tsx`（Button 必須有 children）
- 大頁面新功能優先組 Card / Field / Badge，不要另寫色票

### 6. API 層

`client.ts` 的 refresh single-flight、502 retry 是好的。可再：

- 對 `ApiError` 做 `isUnauthorized` / `isUnavailable` helper，頁面統一處理
- 長輪詢（jobs 3s）考慮 visibility API：分頁隱藏時降頻

### 7. 測試

目前幾乎無前端 test。最低投資：

- `client.ts` refresh + 502 retry
- `AuthContext` 5xx 不登出
- 純函式：`jobStatus`、`format` nano 轉換

### 8. AGENTS 寫了但未存在的功能

- **Islander agent runtime**（`web/src/lib/islander`）文件超前，程式沒有  
  → 實作或從 AGENTS 刪除描述，避免後續 agent 按空文件改碼

---

## 產品債（架構外但影響體感）

1. **Flow A 過渡態**：Missions 用 inspire + content_ops + drafts，舊 copy_mission CRUD 已移除/不可用；應盡快 Post Project 或明確標「精簡模式」。  
2. **Extension 同步關閉**：海巡 dev crawl 若依賴 browser session，需新安全協議（short-lived code，勿 JWT postMessage）。  
3. **Publish inventory refill job** 無 handler：policy API 可留，refill job 勿再 enqueue（應已清）。

---

## 建議迭代順序（若只做改進、不做大功能）

```text
Sprint A  正確性
  rewrite dedupe、CreateRun guarded cancel、ClaimNext、Heartbeat、AuthContext 5xx

Sprint B  可理解性
  拆 PatrolPage / Missions 邊界、GapsPage 對齊、AGENTS 修路徑與 auth matrix

Sprint C  可觀測
  worker 錯誤上報、job stranded reaper、prod secrets validate

Sprint D  產品
  Post Project（取代 Flow A）或凍結 Missions 只修 bug
```

---

## 自我檢查清單（PR 前）

後端：

- [ ] 列表是否 `page/pageSize` + pagination  
- [ ] Job 狀態是否 guarded  
- [ ] 長任務是否處理 Heartbeat 錯誤  
- [ ] 錯誤是否 `errs.For(code.X)`  
- [ ] 時間是否 unix nano UTC  

前端：

- [ ] 是否只用 semantic token  
- [ ] Button 是否有中文動詞 children  
- [ ] 是否經 `api/client` envelope  
- [ ] 錯誤是否區分 401 vs 5xx  
- [ ] `make web-build` 通過  
