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
80 changes: 80 additions & 0 deletions .changeset/objectstack-17-6-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
'hotcrm': minor
---

Upgrade the ObjectStack platform to 17.6.0

All 21 `@objectstack/*` dependencies move 17.5.0 → 17.6.0 together — 20 in
`dependencies`, `@objectstack/formula` in `devDependencies` — pinned exact, no
caret. `specVersion` and `engines.protocol` follow to `^17.6.0`, in
`objectstack.manifest.json` and in the stack manifest in `objectstack.config.ts`.
17.6.0 still implements protocol 17, so both declarations stay on major 17.
`pnpm-lock.yaml` was regenerated by `pnpm install` against the public registry:
725 `packages:` entries before, 727 after. 54 `@objectstack/*` and
`create-objectstack` keys moved 1:1, none added or removed. 14 third-party keys
moved: `@oclif/core` 4.14.0 → 5.1.2 (a major, taken by `@objectstack/cli`),
`@modelcontextprotocol/sdk` 1.30.0 → 1.31.0, `mongodb` 7.5.0 → 7.7.0, `bson`,
`@mongodb-js/saslprep`, `@noble/hashes`, `chalk`, `js-yaml`, `pinyin-pro` and
`sql.js` on patch or minor lines, and `@noble/ciphers`, `jose` and a second `tsx`
were added. `hono@4.13.3`, which the 17.5.0 lock kept for the MCP SDK, left the
tree.

The platform changes that reached this app:

- **Six page headers drop `breadcrumb`.** 17.6.0 retires `page:header`'s
`breadcrumb` (`page-header-breadcrumb-removed`) because no renderer ever drew
a trail for it. *App Launcher*, *Sales Home*, *Account Detail*, *Lead Detail*,
*Opportunity Detail* and *Case Detail* set it, so `os migrate meta --from 17`
listed six edits. The keys are deleted. **What readers will see:** nothing
changes. The console's own breadcrumb trail above every record is drawn by the
app shell and is unchanged.
- **Grouped lists whose columns are objects load their rows again.** This
closes the known issue recorded with the 17.5.0 upgrade. On 17.5.0 the
*Products*, *Knowledge Articles* and *Forecasts* default lists showed
`Unknown field '[object Object]'` in every group. The 17.6.0 console carries
the fix (objectui#11105). A browser check on 17.6.0 shows rows in every group
of all three lists, and the same check on 17.5.0 still shows the error.
HotCRM's views did not change.
- **The audit-log docs now say what Setup → Audit Logs shows.** From 17.6.0
the audit log shows each reader, administrators included, only rows about
records that reader can still open. So a `delete` row, a `logout` row and a
`login` row whose session has ended no longer appear in the console, though
they are still stored. The FAQ said the audit log "records who deleted what and
when" for an administrator to read there. A browser check on 17.6.0 found the
delete row stored and shown in neither audit-log screen. The FAQ answer is
corrected, and the *Security & Compliance* page gains a note. Both changes are
in all three locales.
- **Decision nodes need no edit, again.** `os migrate meta --from 17` still
offers `mode: 'inclusive'` on the same 13 decisions it listed on 17.5.0. Each
one partitions its out-edges, as the 17.5.0 upgrade checked, so the key stays
unwritten.
- **Claims that named 17.5.0 as the current pin are re-scoped.** The
platform-version line on the *What's new* page and in `docs/STATUS.md` moves
to 17.6.0. Three source and maintainer-doc comments that called 17.5.0 the pin
now date themselves. Claims written as "not re-run on 17.5.0" are dated truth
and stay as they are. None was re-measured on 17.6.0 in this change.

The upgrade was exercised in place on a database that HotCRM on 17.5.0 had
created, seeded and written to. `os migrate meta --stored` found one stored
row (a list view saved on 17.5.0) and nothing to rewrite, and
`os migrate audit-metadata-bodies` found no copied metadata body to redact. The
17.6.0 server booted on that database with no errors.

**What operators should know:**

- **The public Web-to-Lead and Web-to-Case forms keep working.** They are
public forms, not anonymous endpoints, and HotCRM declares no
`authRequired: false` endpoint. An anonymous submission of each form on 17.6.0
created its record.
- **Imports read dates strictly.** A `date`, `datetime` or `time` cell must be
ISO 8601 (`2026-07-15`), the export's own `YYYY-MM-DD HH:mm:ss`, or year
first. A month-first cell such as `07/15/2026`, an Excel serial number or a day
that does not exist (`2026-02-30`) now fails its row with `invalid_date`. The
other rows of the file still import. Before 17.6.0, such cells imported as a
different date.
- **Studio refuses two saves at this console pin.** A new dataset measure saved
from the dataset designer is refused with `measures.0.field`, and a new
datasource set to *External* is refused with `requires 'external' settings`.
Both are known platform issues, fixed upstream after the pin. HotCRM's own
datasets are packaged and read-only in Studio, and HotCRM declares no
datasource, so neither issue reaches HotCRM metadata.
2 changes: 1 addition & 1 deletion content/docs/reference/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Likely a rejected approval. Check the **Approval History** section on the opport

### Where do deleted records go?

Nowhere — **a delete is permanent and immediate.** There is no recycle bin to restore from and no Setup entry for one: the platform ships no soft-delete runtime at all. `@objectstack/spec` retired the flag that used to promise one, and says why in as many words — *"every delete has always been a hard delete, and a default-true flag promising a recycle bin was a false affordance"*. Treat every delete as irreversible. The audit log at **Setup → Audit Logs** records who deleted what and when; it does not bring the record back.
Nowhere — **a delete is permanent and immediate.** There is no recycle bin to restore from and no Setup entry for one: the platform ships no soft-delete runtime at all. `@objectstack/spec` retired the flag that used to promise one, and says why in as many words — *"every delete has always been a hard delete, and a default-true flag promising a recycle bin was a false affordance"*. Treat every delete as irreversible. The platform still writes an audit row for every delete, but since ObjectStack 17.6.0 the audit log shows each reader only rows about records that reader can still open — administrators included. A deleted record can no longer be opened, so its rows, the delete among them, no longer appear in **Setup → Audit Logs**; only a server-side job running with system access reads them. Neither brings the record back.

### My import says "0 rows imported" — why?

Expand Down
2 changes: 1 addition & 1 deletion content/docs/reference/faq.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Copilot 遵守你的共享设置 —— 如果你看不到它,它也看不到

### 删除的记录去了哪里?

哪里也没去 —— **删除是立即且永久的。** 没有回收站可供恢复,系统设置里也没有对应入口:平台根本没有软删除运行时。`@objectstack/spec` 已经把当年承诺回收站的那个开关退役,并把理由写得很直白 —— *“每一次删除从来都是硬删除,一个默认为真、承诺回收站的开关是一种虚假的能力暗示”*。请把每一次删除都当作不可逆。**系统设置 → 审计日志** 里的审计日志会记录谁在何时删了什么;但它无法把记录找回来。
哪里也没去 —— **删除是立即且永久的。** 没有回收站可供恢复,系统设置里也没有对应入口:平台根本没有软删除运行时。`@objectstack/spec` 已经把当年承诺回收站的那个开关退役,并把理由写得很直白 —— *“每一次删除从来都是硬删除,一个默认为真、承诺回收站的开关是一种虚假的能力暗示”*。请把每一次删除都当作不可逆。平台仍会为每一次删除写下一条审计记录,但自 ObjectStack 17.6.0 起,审计日志只向读者展示其仍能打开的记录的相关行 —— 管理员也不例外。被删除的记录已无法打开,因此它的各条记录(包括那次删除)不再出现在 **系统设置 → 审计日志** 中;只有以系统权限运行的服务端任务才能读到。两者都无法把记录找回来。

### 我的导入显示"导入 0 行" —— 为什么?

Expand Down
2 changes: 1 addition & 1 deletion content/docs/reference/faq.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Copilot 遵守你的共享設定 —— 如果你看不到它,它也看不到

### 刪除的記錄去了哪裡?

哪裡也沒去 —— **刪除是立即且永久的。** 沒有資源回收筒可供還原,Setup 裡也沒有對應入口:平台根本沒有軟刪除執行時。`@objectstack/spec` 已經把當年承諾資源回收筒的那個開關退役,並把理由寫得很直白 —— *「每一次刪除從來都是硬刪除,一個預設為真、承諾資源回收筒的開關是一種虛假的能力暗示」*。請把每一次刪除都當作不可逆。**Setup → Audit Logs** 裡的稽核日誌會記錄誰在何時刪了什麼;但它無法把記錄找回來。
哪裡也沒去 —— **刪除是立即且永久的。** 沒有資源回收筒可供還原,Setup 裡也沒有對應入口:平台根本沒有軟刪除執行時。`@objectstack/spec` 已經把當年承諾資源回收筒的那個開關退役,並把理由寫得很直白 —— *「每一次刪除從來都是硬刪除,一個預設為真、承諾資源回收筒的開關是一種虛假的能力暗示」*。請把每一次刪除都當作不可逆。平台仍會為每一次刪除寫下一筆稽核紀錄,但自 ObjectStack 17.6.0 起,稽核日誌只向讀者顯示其仍能開啟的記錄的相關列 —— 管理員也不例外。被刪除的記錄已無法開啟,因此它的各筆紀錄(包括那次刪除)不再出現在 **Setup → Audit Logs** 中;只有以系統權限執行的伺服器端工作才能讀到。兩者都無法把記錄找回來。

### 我的匯入顯示「匯入 0 列」 —— 為什麼?

Expand Down
2 changes: 2 additions & 0 deletions content/docs/reference/security-and-compliance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ That sixth row used to read *Account teams*. **There is no account-team object a

`sys_audit_log` is real and it is genuinely immutable: the object is `managedBy: 'append-only'` and every field on it is `readonly: true`. It ships with `@objectstack/plugin-audit`, and **this app gets it** — declaring `auth` in `requires` makes the CLI register the auth, security and audit plugins as a set. Read it at **Setup → Audit Logs**, under *Diagnostics*, which ships six list views: *Recent*, *Writes*, *Auth*, *Record Views*, *Config* and *All*.

⚠️ **What Setup → Audit Logs shows changed in ObjectStack 17.6.0.** The log now shows every reader — administrators included — only rows about records that reader can still open. Rows stay stored, but these no longer appear in the console: every `delete` row (the record is gone), `logout` rows and `login` rows whose session has ended, and rows about records the reader cannot open. `config_change` rows are still shown. A review that must see every row needs a server-side job running with system access; the console offers no such view.

The category table was the unmeasured part. Re-judged against the writers that actually exist:

| Category | State | What is really recorded |
Expand Down
2 changes: 2 additions & 0 deletions content/docs/reference/security-and-compliance.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ description: SSO、MFA、审计日志、secret 字段通道、GDPR —— HotCRM

`sys_audit_log` 是真的,而且确实不可变:该对象是 `managedBy: 'append-only'`,其上每个字段都是 `readonly: true`。它随 `@objectstack/plugin-audit` 一起发布,而**本应用拿得到它** —— 在 `requires` 中声明 `auth` 会让 CLI 把 auth、security、audit 三个插件作为一组注册。在 **系统设置 → 审计日志**(位于 *诊断* 分组下)读取,它带了六个列表视图:*Recent*、*Writes*、*Auth*、*Record Views*、*Config* 与 *All*。

⚠️ **ObjectStack 17.6.0 改变了系统设置 → 审计日志显示的内容。** 审计日志现在只向每个读者(管理员也不例外)展示其仍能打开的记录的相关行。这些行仍然存储着,但以下几类不再出现在控制台中:每一条 `delete` 行(记录已不存在)、`logout` 行以及会话已结束的 `login` 行,还有读者无法打开的记录的相关行。`config_change` 行仍会显示。需要查看全部行的审查,必须由以系统权限运行的服务端任务来做;控制台不提供这样的视图。

分类表是没测过的那部分。对照真正存在的写入方重新判定:

| 分类 | 状态 | 真正被记录的内容 |
Expand Down
2 changes: 2 additions & 0 deletions content/docs/reference/security-and-compliance.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ description: SSO、MFA、稽核日誌、secret 欄位通道、GDPR —— HotCRM

`sys_audit_log` 是真的,而且確實不可變:該物件是 `managedBy: 'append-only'`,其上每個欄位都是 `readonly: true`。它隨 `@objectstack/plugin-audit` 一起發布,而**本應用拿得到它** —— 在 `requires` 中宣告 `auth` 會讓 CLI 把 auth、security、audit 三個外掛作為一組註冊。在 **Setup → Audit Logs**(位於 *Diagnostics* 群組下)讀取,它帶了六個列表檢視:*Recent*、*Writes*、*Auth*、*Record Views*、*Config* 與 *All*。

⚠️ **ObjectStack 17.6.0 改變了 Setup → Audit Logs 顯示的內容。** 稽核日誌現在只向每個讀者(管理員也不例外)顯示其仍能開啟的記錄的相關列。這些列仍然儲存著,但以下幾類不再出現在主控台中:每一筆 `delete` 列(記錄已不存在)、`logout` 列以及工作階段已結束的 `login` 列,還有讀者無法開啟的記錄的相關列。`config_change` 列仍會顯示。需要查看全部列的審查,必須由以系統權限執行的伺服器端工作來做;主控台不提供這樣的檢視。

分類表是沒測過的那部分。對照真正存在的寫入方重新判定:

| 分類 | 狀態 | 真正被記錄的內容 |
Expand Down
4 changes: 2 additions & 2 deletions content/docs/whats-new.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ http://localhost:4001 and create the first admin account.
refuses the load up front with a structured diagnostic instead of failing deep
in a schema parse.

Since 3.1.0 was cut, the app has moved to **ObjectStack 17.5.0** (manifest range
`^17.5.0`). That move ships with the next HotCRM release; until then, 3.1.0 is the
Since 3.1.0 was cut, the app has moved to **ObjectStack 17.6.0** (manifest range
`^17.6.0`). That move ships with the next HotCRM release; until then, 3.1.0 is the
release that runs on 17.4.0.

> **This page does not keep a second release table.** The release-by-release
Expand Down
2 changes: 1 addition & 1 deletion content/docs/whats-new.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ HOTCRM_TOKEN=... ./scripts/wow1-live-schema.sh
应用清单声明了与之匹配的 `^17.4.0` 协议区间,因此协议大版本不同的运行时会在
装载之初就带着结构化诊断拒绝加载,而不是在某次 schema 解析的深处才失败。

3.1.0 发布之后,应用已迁移到 **ObjectStack 17.5.0**(清单区间 `^17.5.0`)。这次迁移随下一个
3.1.0 发布之后,应用已迁移到 **ObjectStack 17.6.0**(清单区间 `^17.6.0`)。这次迁移随下一个
HotCRM 版本发布;在那之前,运行在 17.4.0 上的发布版本仍是 3.1.0。

> **这一页不维护第二张发布表。** 逐版本的发布历史在仓库的 `CHANGELOG.md` 里,由每个
Expand Down
2 changes: 1 addition & 1 deletion content/docs/whats-new.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ HOTCRM_TOKEN=... ./scripts/wow1-live-schema.sh
應用清單宣告了與之相符的 `^17.4.0` 協定區間,因此協定大版本不同的執行時會在
載入之初就帶著結構化診斷拒絕載入,而不是在某次 schema 解析的深處才失敗。

3.1.0 發行之後,應用已遷移到 **ObjectStack 17.5.0**(清單區間 `^17.5.0`)。這次遷移隨下一個
3.1.0 發行之後,應用已遷移到 **ObjectStack 17.6.0**(清單區間 `^17.6.0`)。這次遷移隨下一個
HotCRM 版本發行;在那之前,執行在 17.4.0 上的發行版本仍是 3.1.0。

> **這一頁不維護第二張發行表。** 逐版本的發行歷史在儲存庫的 `CHANGELOG.md` 裡,由每個
Expand Down
2 changes: 1 addition & 1 deletion docs/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pnpm verify
| --- | --- |
| Node.js | `^22.11 \|\| ^24 \|\| >=26` |
| pnpm | `>=10.0.0` |
| ObjectStack packages | `17.5.0` |
| ObjectStack packages | `17.6.0` |
| Local dev port | `4001` |

Each row above is asserted against `package.json` (`engines`, the `@objectstack/*`
Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/module-split-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ would otherwise slug the heading to `#上游缺口--upstream-gaps` — the exact
- Studio's writable verdict —
[objectstack#14430](https://github.com/objectstack-ai/objectstack/issues/14430).
- An objectstack release carrying both, and the version bump in this repository. HotCRM was
pinned to `@objectstack/*` 17.4.0 when this was written (PR #1814, #1807) and moved to 17.5.0
after it (this plan's own measurements were taken at the 17.2.0 pin and are labelled as such).
pinned to `@objectstack/*` 17.4.0 when this was written (PR #1814, #1807) and moved to 17.5.0,
then 17.6.0, after it (this plan's own measurements were taken at the 17.2.0 pin and are labelled as such).
Merged upstream is not the same as available
in the pin (AGENTS.md, *Platform Upgrades*).

Expand Down
2 changes: 1 addition & 1 deletion objectstack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default defineStack({
// enforces that pairing against `objectstack.manifest.json` instead of
// trusting this comment, because two platform upgrades in a row (rc.2, then
// rc.3) moved the manifest and left this line behind (#728).
engines: { protocol: '^17.5.0' },
engines: { protocol: '^17.6.0' },
},

// ─── Platform capabilities this app needs ─────────────────────────
Expand Down
4 changes: 2 additions & 2 deletions objectstack.manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
"name": "hotcrm",
"specVersion": "^17.5.0",
"specVersion": "^17.6.0",
"engines": {
"protocol": "^17.5.0"
"protocol": "^17.6.0"
},
"manifestId": "app.objectstack.hotcrm",
"displayName": "HotCRM",
Expand Down
42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,33 @@
},
"packageManager": "pnpm@10.33.0",
"dependencies": {
"@objectstack/account": "17.5.0",
"@objectstack/cli": "17.5.0",
"@objectstack/core": "17.5.0",
"@objectstack/driver-memory": "17.5.0",
"@objectstack/driver-sql": "17.5.0",
"@objectstack/driver-sqlite-wasm": "17.5.0",
"@objectstack/metadata": "17.5.0",
"@objectstack/objectql": "17.5.0",
"@objectstack/platform-objects": "17.5.0",
"@objectstack/plugin-approvals": "17.5.0",
"@objectstack/plugin-auth": "17.5.0",
"@objectstack/plugin-security": "17.5.0",
"@objectstack/plugin-sharing": "17.5.0",
"@objectstack/runtime": "17.5.0",
"@objectstack/service-analytics": "17.5.0",
"@objectstack/service-automation": "17.5.0",
"@objectstack/service-messaging": "17.5.0",
"@objectstack/service-storage": "17.5.0",
"@objectstack/spec": "17.5.0",
"@objectstack/trigger-record-change": "17.5.0"
"@objectstack/account": "17.6.0",
"@objectstack/cli": "17.6.0",
"@objectstack/core": "17.6.0",
"@objectstack/driver-memory": "17.6.0",
"@objectstack/driver-sql": "17.6.0",
"@objectstack/driver-sqlite-wasm": "17.6.0",
"@objectstack/metadata": "17.6.0",
"@objectstack/objectql": "17.6.0",
"@objectstack/platform-objects": "17.6.0",
"@objectstack/plugin-approvals": "17.6.0",
"@objectstack/plugin-auth": "17.6.0",
"@objectstack/plugin-security": "17.6.0",
"@objectstack/plugin-sharing": "17.6.0",
"@objectstack/runtime": "17.6.0",
"@objectstack/service-analytics": "17.6.0",
"@objectstack/service-automation": "17.6.0",
"@objectstack/service-messaging": "17.6.0",
"@objectstack/service-storage": "17.6.0",
"@objectstack/spec": "17.6.0",
"@objectstack/trigger-record-change": "17.6.0"
},
"optionalDependencies": {
"better-sqlite3": "^12.11.1"
},
"devDependencies": {
"@changesets/cli": "^3.0.3",
"@objectstack/formula": "17.5.0",
"@objectstack/formula": "17.6.0",
"@playwright/test": "^1.63.0",
"@vitest/coverage-v8": "^4.1.10",
"fumadocs-core": "16.9.3",
Expand Down
Loading
Loading