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
33 changes: 33 additions & 0 deletions .changeset/1892-demo-bootstrap-run-once.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
'hotcrm': patch
---

Retire the `Demo Bootstrap` flow: seeded records get their owner from the platform, once

HotCRM shipped a scheduled flow, **Demo Bootstrap** (`demo_bootstrap`), that ran every ten
minutes forever in every tenant. Each run filtered twelve objects for records with no owner
and gave them to the first user. A seed cannot name a user, so seeded demo records arrive
with no owner, and the flow existed to fix that after the fact. On a production tenant it ran
1,776 times in 13 days, took up to 26 minutes, and changed nothing after its first pass.

From ObjectStack 17.6.0 the platform does this itself, on a new install's first boot: when the
seed data finishes loading, it hands every seeded record that has no owner to the first
administrator. A fresh `pnpm dev` boot on this release, with the flow kept from running,
leaves no ownerless record on any of the twelve objects the flow used to cover. So the flow is
removed.

**What changes for you:**

- A fresh install no longer carries a `flow-schedule:demo_bootstrap` job (`*/10 * * * *`) in
`sys_job`, and **Flow Runs** no longer shows a Demo Bootstrap run every ten minutes.
- HotCRM now ships 30 flows, eight of them scheduled. The admin *Automation* page says so in
all three locales.
- Seeded demo records are still owned by the first administrator, as before. Known limit: seed
records that a later upgrade adds to an existing install do not get an owner from the
platform yet (tracked in objectstack-ai/objectstack#21486). `pnpm demo:staff` works unchanged.
- The `saas` composition no longer differs from the community app in its flows. It already
left this flow out.

**Upgrading an existing install:** the platform leaves the old
`flow-schedule:demo_bootstrap` row in `sys_job`, still marked active, when the flow disappears.
Nothing runs it any more. An operator who wants the table clean can delete that one row.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# HotCRM

> **The reference app for AI-written enterprise software.** A complete CRM —
> 18 objects, 31 flows, 5 dashboards, 6 AI skills, 4 languages — built as four
> 18 objects, 30 flows, 5 dashboards, 6 AI skills, 4 languages — built as four
> packages (sales, service, revenue, marketing) that compile to one artifact.
> The **sales package**, the one a customer installs, carries its whole
> business semantics (objects, flows, actions, hooks) in **~54k tokens**
Expand Down Expand Up @@ -69,7 +69,7 @@ HotCRM is a complete, opinionated CRM built as the **first official application*
| `crm_event` | | | |
| `crm_event_attendee` | | | |

Plus **6 AI skills** (a skills-only surface — HotCRM defines no agents of its own; the skills attach to the platform `ask` assistant), **5 dashboards**, **31 flows**, **31 actions**, **9 datasets**, **4 language bundles** (en, zh-CN, es-ES, ja-JP), **6 permission profiles**, **12 positions**, and **9 sharing rules**.
Plus **6 AI skills** (a skills-only surface — HotCRM defines no agents of its own; the skills attach to the platform `ask` assistant), **5 dashboards**, **30 flows**, **31 actions**, **9 datasets**, **4 language bundles** (en, zh-CN, es-ES, ja-JP), **6 permission profiles**, **12 positions**, and **9 sharing rules**.

> **Business reader?** The ObjectStack docs tour every one of these capabilities in plain business language — [What Can It Do?](https://objectstack.ai/docs/capabilities) — with HotCRM as the running example on every page.

Expand Down
9 changes: 4 additions & 5 deletions content/docs/administration/automation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ A flow fires one of three ways, set by its start node:

> **Auto-launch needs the `triggers` capability.** Record-change and scheduled flows only fire when the stack's `requires` list includes `triggers` — it installs the record-change + schedule trigger providers (schedule triggers also use the job service). Screen flows are always launched manually.

**Built-in flows in HotCRM** (31). Each row carries the flow's own label — the name listed in **Studio → Automation → Flows**, and the name you pick from in **Studio → Developer → Flow Runs**, so a run you are chasing can be looked up here verbatim:
**Built-in flows in HotCRM** (30). Each row carries the flow's own label — the name listed in **Studio → Automation → Flows**, and the name you pick from in **Studio → Developer → Flow Runs**, so a run you are chasing can be looked up here verbatim:

| Flow | Trigger | What it does |
| --- | --- | --- |
Expand Down Expand Up @@ -84,21 +84,20 @@ A flow fires one of three ways, set by its start node:
| **Contract Renewal Reminder** | Schedule (daily 8 AM) | Open renewal tasks/opportunities for contracts nearing their `end_date` |
| **Case SLA Monitor** | Schedule (hourly) | Flag and escalate open cases past their SLA due date |
| **Task Due Reminder** | Schedule (hourly) | Notify owners of tasks whose reminder time has arrived |
| **Demo Bootstrap** | Schedule (every 10 min) | Claim ownerless seeded records for the first user by stamping `owner_id` |

Two entries carry an **(on create)** twin. Record-change flows subscribe to one trigger type each — `record-after-create` *or* `record-after-update` — so automation that has to catch both a newly created record and a later edit is authored as a pair of flows with the same condition. They are separate rows here because they are separate runs in **Flow Runs**.

**Demo Bootstrap** is scaffolding, not business automation. Seed writes bypass the security middleware, so seeded rows arrive with no owner — which empties every *My …* view and sends owner-addressed notifications to nobody. This sweep stamps them onto the first user. On an org whose records already have owners it selects nothing and does nothing, every ten minutes.
Seeded demo records get their owner from the platform, not from a flow: when the seed data finishes loading, the platform hands every seeded record that has no owner to the first administrator. HotCRM's former **Demo Bootstrap** flow, which re-checked for ownerless records every ten minutes, has been retired.

Notifications inside flows are delivered by the **`notify` node** (inbox + email via the messaging service) — not the legacy `script`/email step, which is a no-op in 7.4.

See [Customization › Extending Objects](/docs/customization/extending-objects) if you need to build new flows.

## Scheduled automation

Time-based automation is implemented as **scheduled flows** — flows whose start node carries a cron schedule. The nine `Schedule` rows above are the complete set; there is no separate scheduled-job metadata to look for. They run via the job service, so the `triggers` capability is paired with `job` (both ship in the default slate).
Time-based automation is implemented as **scheduled flows** — flows whose start node carries a cron schedule. The eight `Schedule` rows above are the complete set; there is no separate scheduled-job metadata to look for. They run via the job service, so the `triggers` capability is paired with `job` (both ship in the default slate).

> **From ObjectStack 17.5.0, scheduled flows are off until the deployment turns them on.** The platform runs package-authored scheduled work only when the deployment sets `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true` (`1`, `on` and `yes` also count). Without it, none of the nine flows above runs — no contract or quote expiry, no SLA monitor, no reminders, no forecast snapshots — and `os doctor` prints the effective value. Under the `isolated` tenancy posture a scheduled flow must also name the organization it acts as; these nine do not, so they are not armed there.
> **From ObjectStack 17.5.0, scheduled flows are off until the deployment turns them on.** The platform runs package-authored scheduled work only when the deployment sets `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true` (`1`, `on` and `yes` also count). Without it, none of the eight flows above runs — no contract or quote expiry, no SLA monitor, no reminders, no forecast snapshots — and `os doctor` prints the effective value. Under the `isolated` tenancy posture a scheduled flow must also name the organization it acts as; these eight do not, so they are not armed there.

Date-driven field logic that needs no orchestration — defaulting a quote's expiration date, freezing an expired/accepted quote, deriving a forecast period — lives in lightweight **object hooks** (`beforeInsert` / `beforeUpdate`) rather than a scheduled sweep.

Expand Down
9 changes: 4 additions & 5 deletions content/docs/administration/automation.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ description: 验证规则、流程、计划作业与审批 —— 无需你动

> **自动触发需要 `triggers` 能力。** 记录变更与计划类流程,只有当 stack 的 `requires` 列表包含 `triggers` 时才会触发 —— 它会安装记录变更与计划触发器提供方(计划触发器还依赖 job 服务)。屏幕类流程始终为手动启动。

**HotCRM 中的内置流程**(31 个)。每一行用的都是流程自身的标签 —— 也就是 **Studio → 自动化 → 流程** 里列出、并在 **Studio → 开发者 → 流程运行记录** 里供你挑选的那个名字,因此一次运行可以逐字回到这张表里查:
**HotCRM 中的内置流程**(30 个)。每一行用的都是流程自身的标签 —— 也就是 **Studio → 自动化 → 流程** 里列出、并在 **Studio → 开发者 → 流程运行记录** 里供你挑选的那个名字,因此一次运行可以逐字回到这张表里查:

| 流程 | 触发 | 它做什么 |
| --- | --- | --- |
Expand Down Expand Up @@ -84,21 +84,20 @@ description: 验证规则、流程、计划作业与审批 —— 无需你动
| **合同续约提醒** | 计划(每日 8 点) | 为临近 `end_date` 的合同开出续约任务/商机 |
| **工单 SLA 监控** | 计划(每小时) | 标记并升级超过 SLA 到期时间的未结工单 |
| **任务到期提醒** | 计划(每小时) | 通知负责人:其任务的提醒时间已到 |
| **演示数据引导** | 计划(每 10 分钟) | 为首位用户认领无归属的种子记录,写入其 `owner_id` |

有两组条目带 **(新建时)** 孪生流程。记录变更类流程每条只订阅一种触发类型 —— `record-after-create` *或* `record-after-update` —— 所以「新建与后续修改都要管」的自动化会被写成条件相同的一对流程。它们在这里各占一行,因为在 **Flow Runs** 里它们就是两次独立运行。

**演示数据引导** 属于脚手架,而非业务自动化。种子写入会绕过安全中间件,因此种子记录落地时没有负责人 —— 这会让所有「我的 …」视图变空,并让所有寄给负责人的通知无人可达。这条清扫把它们写到首位用户名下。在记录本就有负责人的组织里,它每十分钟选中零条记录、什么也不做。
演示种子记录的负责人由平台指定,而不是由流程指定:种子数据写入完成时,平台会把所有没有负责人的种子记录交给首位管理员。HotCRM 以前每十分钟检查一次无主记录的 **演示数据引导** 流程已经退役。

流程内的通知由 **`notify` 节点** 投递(通过消息服务发送站内信 + 邮件)—— 而非旧的 `script`/邮件步骤(在 7.4 中已是空操作)。

如果你需要构建新的流程,请参见 [定制化 › 扩展对象](/zh-Hans/docs/customization/extending-objects)。

## 计划类自动化

基于时间的自动化以 **计划类流程** 实现 —— 即起始节点带 cron 计划的流程。上表中九个 `计划` 行就是全部;不存在另一套需要另找的「计划作业」元数据。它们通过 job 服务运行,因此 `triggers` 能力需与 `job` 搭配(两者都在默认能力集中)。
基于时间的自动化以 **计划类流程** 实现 —— 即起始节点带 cron 计划的流程。上表中八个 `计划` 行就是全部;不存在另一套需要另找的「计划作业」元数据。它们通过 job 服务运行,因此 `triggers` 能力需与 `job` 搭配(两者都在默认能力集中)。

> **自 ObjectStack 17.5.0 起,计划类流程默认关闭,需由部署方开启。** 平台只在部署设置了 `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true`(`1`、`on`、`yes` 同样有效)时,才运行包内编写的计划类工作。不设置时,上表九个计划类流程一个都不会运行 —— 没有合同与报价的自动过期、没有 SLA 监控、没有提醒、没有预测快照;`os doctor` 会打印当前生效的取值。在 `isolated` 租户隔离模式下,计划类流程还必须声明它代表哪个组织运行;这九个流程都没有声明,因此在该模式下不会被挂载。
> **自 ObjectStack 17.5.0 起,计划类流程默认关闭,需由部署方开启。** 平台只在部署设置了 `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true`(`1`、`on`、`yes` 同样有效)时,才运行包内编写的计划类工作。不设置时,上表八个计划类流程一个都不会运行 —— 没有合同与报价的自动过期、没有 SLA 监控、没有提醒、没有预测快照;`os doctor` 会打印当前生效的取值。在 `isolated` 租户隔离模式下,计划类流程还必须声明它代表哪个组织运行;这八个流程都没有声明,因此在该模式下不会被挂载。

无需编排的日期驱动字段逻辑 —— 例如为报价设置默认过期日、冻结已过期/已接受的报价、推导预测周期 —— 放在轻量的 **对象钩子**(`beforeInsert` / `beforeUpdate`)中,而非计划清扫。

Expand Down
9 changes: 4 additions & 5 deletions content/docs/administration/automation.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ description: 驗證規則、流程、排程作業與審批 —— 無需你動

> **自動觸發需要 `triggers` 能力。** 記錄變更與排程類流程,只有當 stack 的 `requires` 列表包含 `triggers` 時才會觸發 —— 它會安裝記錄變更與排程觸發器提供方(排程觸發器還依賴 job 服務)。螢幕類流程始終為手動啟動。

**HotCRM 中的內建流程**(31 個)。每一行用的都是流程自身的標籤 —— 也就是 **Studio → Automation → Flows** 裡列出、並在 **Studio → Developer → Flow Runs** 裡供你挑選的那個名字,因此一次執行可以逐字回到這張表裡查:
**HotCRM 中的內建流程**(30 個)。每一行用的都是流程自身的標籤 —— 也就是 **Studio → Automation → Flows** 裡列出、並在 **Studio → Developer → Flow Runs** 裡供你挑選的那個名字,因此一次執行可以逐字回到這張表裡查:

| 流程 | 觸發 | 它做什麼 |
| --- | --- | --- |
Expand Down Expand Up @@ -86,21 +86,20 @@ description: 驗證規則、流程、排程作業與審批 —— 無需你動
| **合約續約提醒** | 排程(每日 8 點) | 為臨近 `end_date` 的合約開出續約任務/商機 |
| **工單 SLA 監控** | 排程(每小時) | 標記並升級超過 SLA 到期時間的未結工單 |
| **任務到期提醒** | 排程(每小時) | 通知負責人:其任務的提醒時間已到 |
| **展示資料啟動** | 排程(每 10 分鐘) | 為首位使用者認領無歸屬的種子記錄,寫入其 `owner_id` |

有兩組條目帶 **(新建時)** 孿生流程。記錄變更類流程每條只訂閱一種觸發類型 —— `record-after-create` *或* `record-after-update` —— 所以「新建與後續修改都要管」的自動化會被寫成條件相同的一對流程。它們在這裡各占一行,因為在 **Flow Runs** 裡它們就是兩次獨立執行。

**展示資料啟動** 屬於腳手架,而非業務自動化。種子寫入會繞過安全中介層,因此種子記錄落地時沒有負責人 —— 這會讓所有「我的 …」檢視變空,並讓所有寄給負責人的通知無人可達。這條清掃把它們寫到首位使用者名下。在記錄本就有負責人的組織裡,它每十分鐘選中零條記錄、什麼也不做。
展示種子記錄的負責人由平台指定,而不是由流程指定:種子資料寫入完成時,平台會把所有沒有負責人的種子記錄交給首位管理員。HotCRM 以前每十分鐘檢查一次無主記錄的 **Demo Bootstrap** 流程已經退役。

流程內的通知由 **`notify` 節點** 投遞(透過訊息服務傳送站內信 + 郵件)—— 而非舊的 `script`/郵件步驟(在 7.4 中已是空操作)。

如果你需要建構新的流程,請參見 [客製化 › 擴展物件](/zh-Hant/docs/customization/extending-objects)。

## 排程類自動化

基於時間的自動化以 **排程類流程** 實作 —— 即起始節點帶 cron 排程的流程。上表中九個 `排程` 行就是全部;不存在另一套需要另找的「排程作業」中繼資料。它們透過 job 服務執行,因此 `triggers` 能力需與 `job` 搭配(兩者都在預設能力集中)。
基於時間的自動化以 **排程類流程** 實作 —— 即起始節點帶 cron 排程的流程。上表中八個 `排程` 行就是全部;不存在另一套需要另找的「排程作業」中繼資料。它們透過 job 服務執行,因此 `triggers` 能力需與 `job` 搭配(兩者都在預設能力集中)。

> **自 ObjectStack 17.5.0 起,排程類流程預設關閉,需由部署方開啟。** 平台只在部署設定了 `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true`(`1`、`on`、`yes` 同樣有效)時,才執行套件內撰寫的排程類工作。未設定時,上表九個排程類流程一個都不會執行 —— 沒有合約與報價的自動到期、沒有 SLA 監控、沒有提醒、沒有預測快照;`os doctor` 會列印目前生效的取值。在 `isolated` 租戶隔離模式下,排程類流程還必須宣告它代表哪個組織執行;這九個流程都沒有宣告,因此在該模式下不會被掛載。
> **自 ObjectStack 17.5.0 起,排程類流程預設關閉,需由部署方開啟。** 平台只在部署設定了 `OS_AUTOMATION_SCHEDULED_WORK_ENABLED=true`(`1`、`on`、`yes` 同樣有效)時,才執行套件內撰寫的排程類工作。未設定時,上表八個排程類流程一個都不會執行 —— 沒有合約與報價的自動到期、沒有 SLA 監控、沒有提醒、沒有預測快照;`os doctor` 會列印目前生效的取值。在 `isolated` 租戶隔離模式下,排程類流程還必須宣告它代表哪個組織執行;這八個流程都沒有宣告,因此在該模式下不會被掛載。

無需編排的日期驅動欄位邏輯 —— 例如為報價設定預設過期日、凍結已過期/已接受的報價、推導預測週期 —— 放在輕量的 **物件鉤子**(`beforeInsert` / `beforeUpdate`)中,而非排程清掃。

Expand Down
Loading
Loading