新增 Edit/Write/MultiEdit 事件攔截(原僅攔截 git commit Bash 指令), 補齊 getenv fallback 模式偵測,防止 hardcoded Token 透過工具直寫入檔案。 - .claude/hooks/commit-quality.js: 改寫為 PreToolUse JSON 格式,覆蓋 Edit/Write/MultiEdit - .claude/settings.json: 新增 Edit|Write|MultiEdit|Bash matcher 註冊 - .claude/hooks/__test__/commit-quality.test.sh: 4 case 自動化測試 - docs/guides/DISK_EXPANSION_GUIDE.md: 磁碟擴充 SOP 歸檔 - docs/p9_completion_report_*.md: P9-1 + P9-2 Sprint 完成報告 - docs/refactor/callback_prefix_proposal.md: 308 按鈕回呼前綴分析(Method C) - docs/refactor/openclaw_bot_routes_split_plan.md: 5999 行神檔拆分計畫 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
117 lines
6.1 KiB
Markdown
117 lines
6.1 KiB
Markdown
# Callback Prefix 統一評估報告(read-only)
|
||
|
||
> 產出日期:2026-04-24|狀態:評估中,未動程式碼
|
||
> 範圍:`routes/openclaw_bot_routes.py` + `services/telegram_bot_service.py` + `services/telegram_templates.py`
|
||
|
||
## 1. 範圍統計(實測)
|
||
|
||
| 類別 | 數量 | 說明 |
|
||
|------|------|------|
|
||
| 總 callback_data 字面值 | **308** | 含 f-string,含靜態字串 |
|
||
| 已有 `momo:` prefix | **5** | 全在 `telegram_templates.py`(pa/pr/bpa/bpr/eig)+ `telegram_bot_service.py` 的 `momo:ops:` |
|
||
| 冒號分隔但無 prefix | **272** | `cmd:*`、`menu:*`、`await:*` |
|
||
| 底線分隔(舊 TrendBot) | **31** | `menu_main/menu_trend/menu_search/menu_copy/menu_keywords/menu_daily/menu_settings`、`settings_*`、`trend_*`、`keywords_*` |
|
||
|
||
按檔案分布:
|
||
- `routes/openclaw_bot_routes.py`:**171 筆**(全冒號,僅 1-2 個已是 momo:)
|
||
- `services/telegram_bot_service.py`:**39 筆**(混用 — 30 底線 + 9 冒號)
|
||
- `services/telegram_templates.py`:**5 筆**(全 momo:,**已合規**,免改)
|
||
|
||
> 原始口述「80+」低估。實際 **待修 303 筆**(272 + 31)。
|
||
|
||
## 2. 修改點列表(按檔案精簡,完整 diff 見附錄 A)
|
||
|
||
### 2-a. `routes/openclaw_bot_routes.py`(171 筆,抽樣)
|
||
- L2896-2897:`cmd:import_confirm` / `cmd:import_cancel` → `momo:cmd:*`
|
||
- L2996-2999、3098-3101、3244-3247、3419-3429、3444-3450、3462-3482、3501-3517、3524-3590(主選單+子選單 blocks)
|
||
- L3267-3268、3474-3482(promo/competitor)
|
||
- L3392 `_BACK` 常數:`menu:main` → `momo:menu:main`
|
||
- L3635-3645 `sales_quick_kb`
|
||
- L4537-4538、4712-4719、4787-4790、4814-4816
|
||
- L5047-5257(搜尋/比價/類別鑽取回傳)
|
||
- L5414-5418、5536-5539、5658、5748、5810、5846、5859、5891、5902
|
||
|
||
### 2-b. `services/telegram_bot_service.py`(39 筆)
|
||
- L141-156(主選單 8 顆)
|
||
- L174、472、483(返回按鈕)
|
||
- L1059-1144(trend/keywords/daily 返回群 — 原為底線 `menu_main/menu_trend/menu_keywords/menu_daily`)
|
||
- L1208-1212、1265-1266(settings 面板)
|
||
- L1436、1445、1515-1516、1558-1559(取消/繼續)
|
||
|
||
### 2-c. `services/telegram_templates.py`
|
||
免改(已全 `momo:` 前綴)。
|
||
|
||
## 3. Handler(dispatcher)衝擊
|
||
|
||
### `routes/openclaw_bot_routes.py` 入口 L5610-5663
|
||
```
|
||
data.startswith('menu:') → 切 5 字 → _SUBMENUS[key]
|
||
data.startswith('await:') → 切 6 字 → _AWAIT_PROMPTS[action]
|
||
data.startswith('cmd:') → 切 4 字 → handle_cmd(parts[0], parts[1])
|
||
```
|
||
→ **必須在最外層先 strip `momo:`**,否則 `momo:menu:sales` 會落到無人接的分支。
|
||
|
||
### `services/telegram_bot_service.py::handle_callback` L426-540
|
||
```
|
||
data == "menu_main" or "menu:main"
|
||
data.startswith("menu:")
|
||
data == "menu_trend" / "menu_search" / "menu_copy" / "menu_keywords" / "menu_daily" / "menu_settings"
|
||
data.startswith("trend_") / "keywords_" / "settings_")
|
||
data.startswith("momo:pa:" / "momo:pr:" / "momo:ops:" / "momo:bpa:" / "momo:bpr:" / "momo:eig:")
|
||
data.startswith("cmd:")
|
||
```
|
||
→ 同樣需要 prefix strip;底線家族(`menu_*`、`trend_*`、`keywords_*`、`settings_*`)建議**一併**轉冒號並加 prefix,永久消滅舊 TrendBot 命名痕跡。
|
||
|
||
## 4. 推薦方案
|
||
|
||
| 方案 | 實作成本 | 安全性 | 歷史訊息相容 | 推薦 |
|
||
|------|---------|-------|------------|------|
|
||
| **A** 雙路徑(新發 momo:,handler 同收新舊,3 個月後砍舊) | 高(308 行 + 2 dispatcher 都改) | 最高 | 完整 | 備選 |
|
||
| **B** 破壞式升級(只收 momo:) | 中(僅改 dispatch 分支) | 低,歷史鈕變磚 | ❌ | 否決 |
|
||
| **C** Dispatcher 入口 strip `momo:`(發送端漸進升級) | **最低**(僅 2 個 dispatcher 頂端加 3 行) | 中高 | 完整 | ✅ **首推** |
|
||
|
||
### 方案 C 核心 patch(示意,非 apply)
|
||
```python
|
||
# routes/openclaw_bot_routes.py 在 L5627 後、L5630 前
|
||
if data.startswith('momo:'):
|
||
data = data[5:]
|
||
|
||
# services/telegram_bot_service.py handle_callback L443 後
|
||
if data.startswith('momo:') and not data.startswith(('momo:pa:','momo:pr:','momo:ops:','momo:bpa:','momo:bpr:','momo:eig:')):
|
||
data = data[5:] # 保留 ADR-012 L2 短碼分支原樣
|
||
```
|
||
→ **即時達成跨專案隔離**:OpenClaw/AWOOOI 送來的非 `momo:` callback 不會被 momo-pro 誤接;momo-pro 日後新發按鈕統一加 prefix,舊按鈕仍可被處理。
|
||
|
||
發送端(308 行)可在方案 C 上線後,分批以 sed 腳本加 `momo:` prefix(純文字替換,風險低)。
|
||
|
||
## 5. 風險與成本
|
||
|
||
| 風險/成本 | 等級 | 說明 |
|
||
|----------|------|------|
|
||
| 歷史未點擊按鈕失效 | 低(方案 C 下)| dispatcher 入口 strip 即可相容 |
|
||
| 誤觸他專案按鈕(當前實況) | **高** | 272 筆無 prefix callback 會讓 OpenClaw/AWOOOI 同名按鈕走到 momo-pro handler |
|
||
| 底線家族語意改變(`menu_main` → `momo:menu:main`)| 中 | 需同步處理 `settings_notify_on` 等 4 組 startswith |
|
||
| ADR-012 短碼分支(`momo:pa:` 等)被誤剝 | 中 | 方案 C patch 要加白名單,不可對這 6 個前綴 strip |
|
||
| 預估工時 | 方案 C 純 dispatcher:**0.5 小時 + critic 0.5 小時**;全量加 prefix:**3-4 小時 + 測試 2 小時** |
|
||
| 測試 | dispatcher 變更須在 staging 跑 smoke(主選單 6 條主幹 + ADR-012 confirm/reject 按鈕 + L2 ops 按鈕)|
|
||
|
||
## 6. 等統帥決策
|
||
|
||
1. **是否啟動?** 建議「是」——當前 272 筆跨專案外漏是真實資安/功能風險(三 bot 共用 Token)。
|
||
2. **採方案?** 首推 **C**(入口 strip + 分批 prefix);若統帥要求一次到位選 **A**。
|
||
3. **派誰執行?**
|
||
- 方案 C dispatcher 改動:`fullstack-engineer` + `critic`(0.5h)
|
||
- 308 行 prefix 批量加:`refactor-specialist`(P9 子任務,3-4h)
|
||
- 底線家族轉冒號:同上,獨立 commit
|
||
4. **驗收**:staging smoke(主選單點擊 → ADR-012 按鈕 → L2 ops 按鈕 → 歷史按鈕仍可觸發)+ critic 審查無 regression。
|
||
|
||
---
|
||
|
||
### 附錄 A:完整修改點行號索引
|
||
|
||
(需全量 diff 時再展開;檔案/行號已於第 2 節列出,可用以下指令重生)
|
||
```bash
|
||
grep -n "callback_data" routes/openclaw_bot_routes.py \
|
||
services/telegram_bot_service.py | grep -v "momo:"
|
||
```
|