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

166 lines
5.8 KiB
Markdown
Raw Normal View History

2026-07-09 03:45:28 +00:00
# 前後端改進建議
依「影響使用者 / 維護成本 / 風險」排序。細節背景見先前健康檢查;**架構導覽**見 `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` 通過