thread-master/old/docs/improvement-notes.md

166 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前後端改進建議
依「影響使用者 / 維護成本 / 風險」排序。細節背景見先前健康檢查;**架構導覽**見 `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 過胖 | 依域拆 bootstrapauth/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 失敗清 token5xx 顯示「後端暫時無法連線」。
### 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** 無 handlerpolicy 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` 通過