┌─────────────────────────────────────────────────────────────────────┐
│ 群組開通完整流程 │
└─────────────────────────────────────────────────────────────────────┘
1. 邀請 Bot 加入群組
│
▼
2. 任意成員發送訊息
│
▼
3. 系統自動建立 Group 記錄
└─ status = "pending"
└─ line_group_id = LINE 群組 ID
│
▼
4. Bot 回應引導訊息(使用 group_intro prompt)
└─ 說明申請方式
└─ 提供網頁申請連結
│
├─────────────────────┬─────────────────────┐
│ │ │
▼ ▼ │
【方式 A】 【方式 B】 │
LINE 對話申請 網頁申請 │
│ │ │
│ Bot (AI) 引導 │ /board.html │
│ 收集資料: │ 填寫表單: │
│ • 群組名稱 │ • 群組名稱 │
│ • 聯絡方式 │ • LINE 群組 ID │
│ • 群組代碼 │ • 聯絡方式 │
│ │ • 群組代碼 │
└─────────────────────┴─────────────────────┘
│
▼
5. 系統建立 GroupApplication
└─ status = "pending"
└─ group_code = 申請者自訂
│
▼
6. 超級管理員審核(/admin.html)
│
├─ 拒絕
│ └─ application.status = "rejected"
│
└─ 通過
└─ application.status = "approved"
└─ group.status = "active"
└─ group.group_code = 申請的代碼
│
▼
7. 群組開通成功!
└─ 下次成員在群組發訊息時,Bot 會正常回應(不再引導申請)
└─ 成員可綁定管理員
⚠️ 注意:審核結果不會主動推送通知到 LINE 群組
群組成員需在群組中發送訊息,才會發現已開通
1. 成員輸入「管理員 [群組代碼]」
│
▼
2. 系統驗證
├─ 群組是否已啟用?(status = "active")
└─ 代碼是否正確?(group.group_code)
│
├─ 驗證失敗 → 回應「⚠️ 代碼錯誤或群組未啟用」
│
└─ 驗證成功
│
▼
3. 建立 GroupAdmin 記錄
└─ group_id = 群組 ID
└─ user_id = 使用者 ID
│
▼
4. 回應「✅ 已綁定為管理員」+ 可用指令說明
- 群組代碼用途:管理員綁定、LINE 管理員後台登入
- 群組代碼設定:申請時由申請者自訂,開通後可在 LINE 管理員後台變更
- 多群組共用代碼:同一公司可以多個群組使用相同代碼
┌─────────────────────────────────────────────────────────────────────┐
│ 開單點餐完整流程 │
└─────────────────────────────────────────────────────────────────────┘
1. 管理員設定今日店家
└─ 輸入「今日」查看可用店家
└─ 輸入店名或「加 [店名]」設定今日店家
│
▼
2. 成員輸入「開單」
│
├─ 檢查:今日店家是否已設定?
│ └─ 否 → 回應「⚠️ 尚未設定今日店家」
│
├─ 檢查:是否已有進行中的點餐?
│ └─ 是 → 回應「⚠️ 已經在點餐中了」
│
└─ 通過
│
▼
3. 建立 OrderSession
└─ status = "ordering"
└─ started_by = 發起者 ID
└─ 記錄系統訊息「=== 新的點餐開始 ===」
│
▼
4. 廣播 session_status 事件
└─ 前端看板即時更新
│
▼
5. 回應開單成功 + 今日菜單
└─ 「🍱 開始群組點餐!」
└─ 顯示店家菜單
└─ 「直接說出餐點即可,說「收單」結束」
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 點餐進行中 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
6. 成員發送點餐訊息
└─ 例如:「雞腿便當」「排骨飯不要酸菜」「幫小明點滷肉飯」
│
▼
7. 訊息前處理
├─ sanitize_user_input() 過濾惡意內容
└─ 記錄 ChatMessage (role = "user")
│
▼
8. 組建 AI Context(詳見架構文檔)
├─ mode: "group_ordering"
├─ user_name: 發言者名稱
├─ today_stores: 今日店家列表
├─ menus: 完整菜單(含價格、變體)
├─ session_orders: 本次所有人的訂單
└─ user_preferences: 發言者偏好設定
│
▼
9. 呼叫 Claude Code CLI
└─ 傳入 system_prompt (group_ordering)
└─ 傳入 context + history + 當前訊息
│
▼
10. AI 回應 JSON
{
"message": "好~幫你點一個雞腿便當 $85!",
"actions": [
{
"type": "group_create_order",
"data": {
"items": [{"name": "雞腿便當", "quantity": 1, "note": ""}]
}
}
]
}
│
▼
11. 執行 Actions
├─ group_create_order → 建立/更新 Order + OrderItem
├─ group_update_order → 修改訂單品項
├─ group_remove_item → 移除品項
└─ group_cancel_order → 取消整筆訂單
│
▼
12. 資料庫 Commit + 廣播 order_update 事件
└─ 前端看板即時更新訂單列表
│
▼
13. 記錄 AI 回應 (ChatMessage role = "assistant")
│
▼
14. 回覆使用者 AI 的 message
│
▼
(重複步驟 6-14 直到收單)
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 收單結算 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
15. 成員輸入「收單」或「結單」
│
▼
16. 結束 OrderSession
└─ status = "ended"
└─ ended_by = 收單者 ID
└─ ended_at = 當前時間
│
▼
17. 產生訂單摘要
├─ 每人點餐明細 + 金額
├─ 品項統計(雞腿便當 x3、排骨飯 x2...)
└─ 總金額
│
▼
18. 廣播 session_status 事件 (status = "ended")
│
▼
19. 回應收單成功 + 訂單摘要
| Action Type |
說明 |
data 結構 |
group_create_order |
建立訂單品項 |
{items: [{name, quantity, note, category}]} |
group_update_order |
修改訂單品項 |
{items: [...], replace: true/false} |
group_remove_item |
移除特定品項 |
{item_name: "品項名稱"} |
group_cancel_order |
取消整筆訂單 |
{} |
使用者訊息
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ LineService._handle_ai_chat() │
├─────────────────────────────────────────────────────────────────────┤
│ 1. 記錄使用者訊息 → chat_messages 表 │
│ 2. 廣播 chat_message 事件 │
│ 3. 組建 context (today_stores, menus, session_orders, preferences) │
│ 4. 取得對話歷史 (CHAT_HISTORY_LIMIT 則) │
│ 5. 呼叫 AiService.chat() │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ AiService.chat() │
├─────────────────────────────────────────────────────────────────────┤
│ 1. 格式化對話歷史 │
│ 2. 組合完整訊息 ([系統上下文] + [對話歷史] + [當前訊息]) │
│ 3. 執行 Claude Code CLI (subprocess) │
│ 4. 解析 JSON 回應 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ LineService._execute_group_actions() │
├─────────────────────────────────────────────────────────────────────┤
│ 1. 遍歷 actions 陣列 │
│ 2. 根據 type 執行對應方法: │
│ - _action_create_order() → 建立 Order + OrderItem │
│ - _action_update_order() → 更新品項 │
│ - _action_remove_item() → 刪除品項 │
│ - _action_cancel_order() → 刪除整筆訂單 │
│ 3. Commit + 廣播 order_update 事件 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
回覆使用者 + 前端即時更新
群組訊息進入
│
├─1. 特殊指令(help, id)
│ └─ 任何人、任何狀態都可用
│
├─2. 群組未啟用 → 引導申請並結束
│
├─3. 新增成員記錄
│ └─ 記錄用戶為群組成員(group_members 表)
│
├─4. 檢查是否點餐中
│
├─5. 快捷指令(開單、收單、菜單等)
│ └─ 匹配到快捷指令 → 執行並結束(所有人都可用)
│
├─6. 非點餐中 → 管理員指令處理
│ │
│ ├─「管理員 [群組代碼]」→ 綁定管理員(任何人可嘗試)
│ ├─「解除管理員」→ 解除管理員身份(僅管理員可用)
│ │
│ └─ 檢查是否為管理員
│ ├─ 是管理員:
│ │ ├─ 已知指令(今日、加、移除、清除)→ 執行
│ │ ├─ 關鍵字匹配店家(直接輸入店名)→ 設定今日店家
│ │ └─ 都不匹配 → 顯示管理員指令幫助
│ │
│ └─ 非管理員 → 繼續下一步
│
├─7. _should_respond_in_group 過濾
│ ├─ 點餐中 → 所有訊息都回應,繼續下一步
│ └─ 非點餐中 → 不回應(快捷指令已在步驟 5 處理)
│
└─8. AI 處理
└─ 交給 AI 處理點餐對話
| 身份 |
輸入內容 |
處理方式 |
| 一般 |
「社」 |
不回應 |
| 一般 |
「開單」 |
開始點餐 |
| 一般 |
「菜單」 |
顯示菜單 |
| 一般 |
「help」/ 「@呷爸」 |
顯示幫助 |
| 一般 |
「abc123」 |
不回應 |
| 管理員 |
「開單」 |
開始點餐 |
| 管理員 |
「菜單」 |
顯示菜單 |
| 管理員 |
「社」 |
設定今日店家(梁社漢) |
| 管理員 |
「今日」 |
顯示今日店家 + 可用店家 |
| 管理員 |
「加 XXX」 |
新增今日店家 |
| 管理員 |
「移除 XXX」 |
移除今日店家 |
| 管理員 |
「清除」 |
清除所有今日店家 |
| 管理員 |
「abc123」 |
顯示管理員指令幫助 |
| 身份 |
輸入內容 |
處理方式 |
| 一般 |
「社」 |
AI 處理(點餐) |
| 一般 |
「收單」/「結單」 |
結束點餐 |
| 一般 |
「菜單」 |
顯示菜單 |
| 一般 |
「目前訂單」 |
顯示訂單摘要 |
| 管理員 |
「社」 |
AI 處理(點餐) |
| 管理員 |
「今日店家」 |
AI 處理(點餐中不執行管理指令) |
| 管理員 |
「收單」 |
結束點餐 |
| 指令 |
說明 |
條件 |
開單 |
開始群組點餐 |
非點餐中 + 已設定今日店家 |
收單 / 結單 |
結束點餐並顯示摘要 |
點餐中 |
菜單 |
顯示今日菜單 |
任何狀態 |
目前訂單 / 訂單 / 查看訂單 / 訂單狀況 / 點了什麼 |
顯示目前訂單摘要 |
點餐中 |
| 指令 |
說明 |
條件 |
管理員 [群組代碼] |
綁定管理員身份 |
非點餐中 |
解除管理員 |
解除管理員身份 |
管理員 + 非點餐中 + 非唯一管理員 |
今日 |
查看今日店家 + 可用店家列表 |
管理員 + 非點餐中 |
[店名關鍵字] |
設定今日店家(模糊匹配) |
管理員 + 非點餐中 |
加 [店名] |
新增今日店家 |
管理員 + 非點餐中 |
移除 [店名] |
移除特定今日店家 |
管理員 + 非點餐中 |
清除 |
清除所有今日店家 |
管理員 + 非點餐中 |
| 指令 |
說明 |
條件 |
help / jaba / 呷爸 / @jaba / @呷爸 |
顯示幫助訊息 |
任何狀態 |
id / 群組id / groupid / userid |
顯示群組 ID 和用戶 ID |
任何狀態 |
- 快捷指令優先 - 快捷指令在管理員指令之前處理,所有人都可用
- 開單需要今日店家 - 未設定今日店家時無法開單
- 點餐中不允許變更今日店家 - 管理員店家指令在點餐中無效
- 管理員綁定 - 「管理員 [群組代碼]」只在非點餐中時可用
- 關鍵字匹配 - 管理員直接輸入店名,只在非點餐中時啟用
- 一般成員 - 非點餐中只能用快捷指令和 help
- 跟單功能 - AI 可解析「+1」「我也要」並複製上一筆訂單
- 代點功能 - AI 可解析「幫 XXX 點」並為他人建立訂單
| 資料表 |
說明 |
groups |
群組記錄(status: pending/active/suspended) |
group_applications |
群組申請記錄 |
group_members |
群組成員關聯 |
group_admins |
群組管理員關聯 |
group_today_stores |
今日店家設定 |
order_sessions |
點餐 Session(status: ordering/ended) |
orders |
訂單(每人每 session 一筆) |
order_items |
訂單品項 |
chat_messages |
對話記錄(含 AI 回應) |