Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .changeset/service-escalation-residue-cases-and-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
'hotcrm': patch
---

按 flow / hook 源码写实 `content/docs/service/cases.mdx` 的升级说法与 `content/docs/service/index.mdx`
生命周期第 2 步残留的虚构收件人,三语同步(#914、#915)。

#876 / #886(`service/sla-and-escalation`)、#887(`service/cases` 的《工作流自动化》一节)、
#904(`service/index` 的两处清单)已经把这一族说法逐条写实。剩下的两处是同族里没有被那几张
行清单枚举到的副本,而它们比已改的那几处更完整地复述了全部虚构 —— 于是读者在同一页上、
同一屏里同时读到两套互相矛盾的描述,更显眼的那一套是错的。

**`content/docs/service/cases.mdx`(+ `zh-Hans` / `zh-Hant`)**

- **优先级表下面那句话。** 原文写「设为 Critical 时支持经理会收到邮件通知;某个客户账户的
工单设为 High 时自动升级」——它上方 48 行就是 #887 已写实的《工作流自动化》第一条,那里写的
是收件人只有工单负责人一人。`src/flows/case-escalation.flow.ts` 的 `notify` 节点
`recipients` 只有 `{caseRecord.owner_id}` 这一项,`grep -rn "support_manager@" src/` 零命中;
start 条件全文只有 `record.priority == "critical"`,全仓没有任何一个 flow 读取账户类型。
现在写实为:Critical 提醒**工单负责人**(站内消息 + 邮件),并点名说清 `support_manager@example.com`
这个收件人不存在;High 永远不会自动升级,无论账户是什么,要升级它靠的是手动的
**Escalate Case** 按钮(`src/actions/case.actions.ts`)。
- **《工单升级》整节。** 原文是 #876 已在 sla 页逐条写实过的那份五步清单,原封不动地留在本页:
触发条件列着不存在的 `High + Customer` 分支;第 1 步「重新分配工单给客服的经理」不存在——
`update_record` 节点只写 `is_escalated` / `escalation_reason` / `escalated_date` / `status`,
注释开头即 `No owner reassignment`,通知正文自己写着 `It remains assigned to you.`;第 4 步的
跟进任务归属错——流程里根本没有任务节点,任务由 `src/objects/case.hook.ts` 的
`case_status_side_effects` 钩子开出,`owner_id` 取的是**账户负责人**,且仅限有关联账户的工单;
第 5 步的三方邮件不存在,`support-team@example.com` 同样零命中。整节按 sla 页已落地的口径
重写为:一个触发条件 + 三步真实动作 + 钩子开出的那条任务 + 三条「刻意不写什么」。
原清单中经核对属实的两条(标记已升级并标记升级日期、状态改为 *Escalated*)claim 文本一字未改,
仅因删除其前后条目而由 2./3. 重新编号为 1./2.。同页 #920 / #912 各自认领的两行(状态推进受
强制约束、《工作流自动化》标题)不在本次改动的任何一个 hunk 内。

**`content/docs/service/index.mdx`(+ `zh-Hans` / `zh-Hant`)**

生命周期第 2 步写着「*Critical* 会立即提醒支持经理」,而 #904 刚在其下方 10 行把《系统为你做的事》
那条写实为「只发给工单负责人……本应用中不存在 `support_manager@example.com` 这个收件人」。
两句说的是同一个 `notify` 节点。现在写实为:*Critical* 立即提醒**工单负责人**,而不是支持经理,
收件人列表只有 `{caseRecord.owner_id}` 一项。顺带把这一行的四个优先级名统一为兄弟页
(`service/cases` 的优先级表、本页其余各行)已用的拉丁写法 Low / Medium / High / Critical ——
中文两页此前只有这一行把 Critical 译作「紧急 / 緊急」。

沿用 #876 / #886 / #887 / #904 已确立的写法:读者来找的那几个词 —— 支持经理、经理、资深客服、
支持团队、原客服 —— 都点名说清**不做**,并写出真正的归属,而不是静默删掉。两页只陈述当前行为,
不预判升级*是否应该*改派、High *是否应该*自动升级(#595 / #596 的产品问题)。顺带去掉了两个中文
cases 页内链上的英文锚点 `#case-escalation` —— 中文页的标题是中文,该锚点在那两页上落不到任何
位置(#755 / #762 惯例,#904 已按同一处理)。

纯文档改动,6 个文件。未触碰 `src/**`,没有任何 flow、hook、条件、收件人或字段发生变化 ——
是页面向已经在跑的行为对齐。
23 changes: 13 additions & 10 deletions content/docs/service/cases.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ A typical stuck case: **New → In Progress → Waiting on Customer → In Progr
| 🔴 **High** | 8 hours | Significant impact, customer is upset |
| 🔴 **Critical** | 4 hours | Production down, immediate response needed |

When a case is set to **Critical**, the support manager is notified by email. When set to **High** for a customer account, the case is auto-escalated.
When a case is set to **Critical**, the Case Escalation flow alerts the **case owner** by inbox message and email — its recipient list is the single entry `{caseRecord.owner_id}`, and there is no `support_manager@example.com` recipient anywhere in this app. A **High** case is never escalated automatically, whatever the account is: no escalation condition reads the account at all, and raising one is the manual **Escalate Case** button.

## Case types

Expand Down Expand Up @@ -86,18 +86,21 @@ The detail screen is organised into 6 sections:

## Case escalation

The [Case Escalation flow](/docs/service/sla-and-escalation#case-escalation) runs automatically when:

- Priority is **Critical**, OR
- Priority is **High** AND the account is a **Customer** (not a prospect)
The [Case Escalation flow](/docs/service/sla-and-escalation#case-escalation) runs on exactly one condition: **the case is at Critical priority**. There is no High-priority branch, and no escalation condition reads the account — a *Customer*'s High case and a prospect's High case are treated identically: neither escalates on its own, and raising one is the manual **Escalate Case** button.

It performs:

1. **Reassign** the case to the agent's manager.
2. **Flag** as escalated, stamp the escalated date.
3. **Set status** to *Escalated*.
4. **Create a follow-up task** on the original agent due tomorrow.
5. **Notify** the agent, the manager, and the support team via email.
1. **Flag** as escalated, stamp the escalated date.
2. **Set status** to *Escalated*.
3. **Notify the case owner** — inbox and email, carrying the case number and the priority.

The status change to *Escalated* then fires the `case_status_side_effects` hook, which opens an **Urgent follow-up task due tomorrow for the account owner** — and only for cases that have an account, since the task is keyed to it.

Three things this list deliberately does not claim, because the escalation does not do them:

- **The case is not reassigned.** The escalation write sets `is_escalated`, `escalation_reason`, `escalated_date` and `status`, and never touches `owner_id`. There is no hand-off to the agent's manager or to senior staff — which is what the escalation notice tells its recipient in so many words: `It remains assigned to you.`
- **The notification goes to the case owner alone.** Its recipient list is the single entry `{caseRecord.owner_id}` — not the manager, and not a broader `support-team@example.com` list, an address that exists nowhere in this app.
- **The follow-up task is not the original agent's.** It belongs to the **account owner**, not to the agent who was handling the case and not to a senior agent. The flow carries no task node at all — the hook is the single owner of escalation follow-up tasks, so there is exactly one task per escalation.

See [SLA & Escalation](/docs/service/sla-and-escalation) for the full mechanics.

Expand Down
23 changes: 13 additions & 10 deletions content/docs/service/cases.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ description: 客户支持工单——主题、优先级、状态、解决方案
| 🔴 **High** | 8 小时 | 影响显著,客户不满 |
| 🔴 **Critical** | 4 小时 | 生产中断,需要立即响应 |

当工单被设为 **Critical** 时,支持经理会收到邮件通知。当某个客户账户的工单被设为 **High** 时,工单会自动升级。
当工单被设为 **Critical** 时,工单升级流程通过站内消息 + 邮件提醒**工单负责人**——它的收件人列表只有 `{caseRecord.owner_id}` 这一项,本应用中不存在 `support_manager@example.com` 这个收件人。**High** 工单永远不会被自动升级,无论账户是什么:没有任何升级条件会读取账户,要升级它靠的是手动的 **Escalate Case** 按钮。

## 工单类型

Expand Down Expand Up @@ -86,18 +86,21 @@ description: 客户支持工单——主题、优先级、状态、解决方案

## 工单升级

[工单升级流程](/zh-Hans/docs/service/sla-and-escalation#case-escalation)在以下情况下自动运行:

- 优先级为 **Critical**,或
- 优先级为 **High** 且账户为 **Customer**(非潜在客户)
[工单升级流程](/zh-Hans/docs/service/sla-and-escalation)只在一个条件下运行:**工单处于 Critical 优先级**。不存在 High 优先级这一分支,也没有任何升级条件会读取账户——Customer 的 High 工单与潜在客户的 High 工单待遇完全相同:两者都不会自行升级,要升级它靠的是手动的 **Escalate Case** 按钮。

它会执行:

1. **重新分配**工单给客服的经理。
2. **标记**为已升级,标记升级日期。
3. **设置状态**为 *Escalated*。
4. **创建一个跟进任务**给原客服,明天到期。
5. **通过邮件通知**客服、经理和支持团队。
1. **标记**为已升级,标记升级日期。
2. **设置状态**为 *Escalated*。
3. **通知工单负责人**——通过站内消息与邮件送达,带上工单编号和优先级。

状态转为 *Escalated* 随后会触发 `case_status_side_effects` 钩子,由它开出一条**次日到期、优先级为紧急、归账户负责人的跟进任务**——且仅限有关联账户的工单,因为该任务是挂在那个账户上的。

以下三件事这份清单刻意不写,因为升级并不做:

- **工单不会被重新分配。** 升级写入的是 `is_escalated`、`escalation_reason`、`escalated_date` 和 `status`,从不碰 `owner_id`。不存在向客服的经理或资深员工的交接——升级通知的正文自己就是这么写的:`It remains assigned to you.`(工单仍分配给你)。
- **通知只发给工单负责人一人。** 收件人列表只有 `{caseRecord.owner_id}` 这一项——不含其经理,也不含更广泛的 `support-team@example.com` 列表,这个地址在本应用中根本不存在。
- **跟进任务不落在原客服身上。** 它归**账户负责人**所有,既不归正在处理该工单的客服,也不归某位资深客服。流程里根本没有任务节点——跟进任务由钩子独家创建,因此每次升级恰好一条。

完整机制参见 [SLA 与升级](/zh-Hans/docs/service/sla-and-escalation)。

Expand Down
23 changes: 13 additions & 10 deletions content/docs/service/cases.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ description: 客戶支援工單——主題、優先順序、狀態、解決方
| 🔴 **High** | 8 小時 | 影響顯著,客戶不滿 |
| 🔴 **Critical** | 4 小時 | 生產中斷,需要立即回應 |

當工單被設為 **Critical** 時,支援經理會收到郵件通知。當某個客戶帳戶的工單被設為 **High** 時,工單會自動升級。
當工單被設為 **Critical** 時,工單升級流程透過站內訊息 + 郵件提醒**工單負責人**——它的收件人列表只有 `{caseRecord.owner_id}` 這一項,本應用中不存在 `support_manager@example.com` 這個收件人。**High** 工單永遠不會被自動升級,無論帳戶是什麼:沒有任何升級條件會讀取帳戶,要升級它靠的是手動的 **Escalate Case** 按鈕。

## 工單類型

Expand Down Expand Up @@ -86,18 +86,21 @@ description: 客戶支援工單——主題、優先順序、狀態、解決方

## 工單升級

[工單升級流程](/zh-Hant/docs/service/sla-and-escalation#case-escalation)在以下情況下自動執行:

- 優先順序為 **Critical**,或
- 優先順序為 **High** 且帳戶為 **Customer**(非潛在客戶)
[工單升級流程](/zh-Hant/docs/service/sla-and-escalation)只在一個條件下執行:**工單處於 Critical 優先順序**。不存在 High 優先順序這一分支,也沒有任何升級條件會讀取帳戶——Customer 的 High 工單與潛在客戶的 High 工單待遇完全相同:兩者都不會自行升級,要升級它靠的是手動的 **Escalate Case** 按鈕。

它會執行:

1. **重新分配**工單給客服的經理。
2. **標記**為已升級,標記升級日期。
3. **設定狀態**為 *Escalated*。
4. **建立一個跟進任務**給原客服,明天到期。
5. **透過郵件通知**客服、經理和支援團隊。
1. **標記**為已升級,標記升級日期。
2. **設定狀態**為 *Escalated*。
3. **通知工單負責人**——透過站內訊息與郵件送達,帶上工單編號和優先順序。

狀態轉為 *Escalated* 隨後會觸發 `case_status_side_effects` 鉤子,由它開出一條**次日到期、優先順序為緊急、歸帳戶負責人的跟進任務**——且僅限有關聯帳戶的工單,因為該任務是掛在那個帳戶上的。

以下三件事這份清單刻意不寫,因為升級並不做:

- **工單不會被重新指派。** 升級寫入的是 `is_escalated`、`escalation_reason`、`escalated_date` 和 `status`,從不碰 `owner_id`。不存在向客服的經理或資深員工的交接——升級通知的正文自己就是這麼寫的:`It remains assigned to you.`(工單仍指派給你)。
- **通知只發給工單負責人一人。** 收件人列表只有 `{caseRecord.owner_id}` 這一項——不含其經理,也不含更廣泛的 `support-team@example.com` 列表,這個地址在本應用中根本不存在。
- **跟進任務不落在原客服身上。** 它歸**帳戶負責人**所有,既不歸正在處理該工單的客服,也不歸某位資深客服。流程裡根本沒有任務節點——跟進任務由鉤子獨家建立,因此每次升級恰好一條。

完整機制參見 [SLA 與升級](/zh-Hant/docs/service/sla-and-escalation)。

Expand Down
2 changes: 1 addition & 1 deletion content/docs/service/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ New ──► In Progress ──► Waiting on Customer ──► Resolved ─
```

1. **Case is created** (via email, web form, phone log or the **Service Copilot** triaging an inbound message).
2. **Priority is assigned** — Low, Medium, High or Critical. *Critical* alerts the support manager immediately.
2. **Priority is assigned** — Low, Medium, High or Critical. *Critical* alerts the **case owner** immediately, not a support manager: the alert's recipient list is `{caseRecord.owner_id}` alone.
3. **SLA target is calculated** — every case gets a deadline based on priority.
4. **Agent works the case**, moving status as they go.
5. **If it's Critical** (or its SLA due date passes), the [escalation process](/docs/service/sla-and-escalation#case-escalation) flags the case as *Escalated* and alerts its owner. It does **not** reassign it — there is no hand-off to senior staff or to a manager — and no escalation condition reads the account, so a *Customer*'s case gets no branch of its own.
Expand Down
2 changes: 1 addition & 1 deletion content/docs/service/index.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ New ──► In Progress ──► Waiting on Customer ──► Resolved ─
```

1. **创建工单**(通过电子邮件、网页表单、电话记录,或由 **Service Copilot** 对来访消息进行分流)。
2. **分配优先级**——低、中、高或紧急。*紧急*会立即提醒支持经理。
2. **分配优先级**——Low、Medium、High 或 Critical。*Critical* 会立即提醒**工单负责人**,而不是支持经理:这条提醒的收件人列表只有 `{caseRecord.owner_id}` 一项。
3. **计算 SLA 目标**——每个工单都会根据优先级获得一个截止时间。
4. **客服处理工单**,随进度推进状态。
5. **如果是 Critical**(或 SLA 截止日期已过),[升级流程](/zh-Hans/docs/service/sla-and-escalation)会把工单标记为 *Escalated* 并提醒它的负责人。它**不会**重新分配工单——不存在向资深员工或经理的交接——也没有任何升级条件会读取账户,所以 *Customer* 的工单没有属于自己的分支。
Expand Down
2 changes: 1 addition & 1 deletion content/docs/service/index.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ New ──► In Progress ──► Waiting on Customer ──► Resolved ─
```

1. **建立工單**(透過電子郵件、網頁表單、電話記錄,或由 **Service Copilot** 對來訪訊息進行分流)。
2. **分配優先順序**——低、中、高或緊急。*緊急*會立即提醒支援經理。
2. **分配優先順序**——Low、Medium、High 或 Critical。*Critical* 會立即提醒**工單負責人**,而不是支援經理:這條提醒的收件人列表只有 `{caseRecord.owner_id}` 一項。
3. **計算 SLA 目標**——每個工單都會根據優先順序獲得一個截止時間。
4. **客服處理工單**,隨進度推進狀態。
5. **如果是 Critical**(或 SLA 截止日期已過),[升級流程](/zh-Hant/docs/service/sla-and-escalation)會把工單標記為 *Escalated* 並提醒它的負責人。它**不會**重新指派工單——不存在向資深員工或經理的交接——也沒有任何升級條件會讀取帳戶,所以 *Customer* 的工單沒有屬於自己的分支。
Expand Down
Loading