Skip to content

Commit 4e6b91c

Browse files
os-zhuangclaude
andauthored
feat!: upgrade ObjectStack platform 14.7 → 16.0.0-rc.1 (spec 16) (#457)
Bump all 11 @objectstack/* packages to 16.0.0-rc.1 (pinned exact for the RC), crossing the entire 15.x line. App → 2.2.0, manifest specVersion → ^16.0.0-rc.1. Breaking / behavioural changes migrated: - Drop `ai` from stack `requires`: ObjectStack 11.3.0 (ADR-0025 S2) removed @objectstack/service-ai from the open edition (AI runtime is cloud-only now), and under 16 `requires: ['ai']` is a fail-fast capability that hard-aborts boot when the package is absent. Agents/skills metadata still ship in the artifact; local open-edition boot omits the AI service. - The agent `visibility` removal (spec 15 / ADR-0056 D8) already landed on main via #449, so this branch (rebased onto it) is a no-op there. Dashboard fixes (found by rendering the app, not by `verify`): - dateRange picker now filters every widget query (ObjectStack 15, framework#2501); widgets on objects without the bound field (crm_account/contact/lead/product, no close_date) crashed with `no such column`. Opt them out via filterBindings: { dateRange: false }. - Remove non-functional dashboard header action buttons (Export PDF / Schedule Email / Customize / New-record / broken /reports links) from all 4 dashboards and the orphaned action-label translations from all 4 locale bundles. Toolchain: install under Node 22 (.nvmrc) — nanoid@6 engines + engine-strict reject the environment's odd-numbered Node 25. Verified: validate + typecheck + build + vitest (17/17) green; server boots (38 plugins); all 4 dashboards render with live seeded data and zero analytics/ console errors. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 6da5656 commit 4e6b91c

13 files changed

Lines changed: 614 additions & 621 deletions

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,38 @@
22

33
All notable changes to HotCRM are documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); HotCRM follows [Semantic Versioning](https://semver.org/).
44

5+
## [2.2.0] — 2026-07-20
6+
7+
Platform upgrade to ObjectStack **16.0.0-rc.1** — the 16 release-candidate line (from 14.7, skipping the entire 15.x line). Manifest `specVersion` now declares `^16.0.0-rc.1` (was `^14.0.0`); app version `2.2.0`. ObjectStack 16 finishes the ADR-0049 "enforce-or-remove" sweep (dead metadata props now fail loudly instead of parsing inert), converges the hook/action org identifier on `organizationId`, flips `.strict()` on dashboard-widget / view-form / page schemas, and — most consequentially for this app — makes the `ai` capability a **fail-fast hard requirement** resolved to the closed `@objectstack/service-ai` package. Built, validated, type-checked, unit-tested (17/17), and browser-verified against `@objectstack/* 16.0.0-rc.1` (boot → 38 plugins loaded → 17 flows / 15 trigger-bound → `/_console/` login renders at HTTP 200 with no boot or console errors).
8+
9+
Upgrade migration was driven from the official release notes at <https://objectstack.ai/docs/releases/v16> (and `/v15`), cross-checked against the per-package `CHANGELOG.md`, per [`AGENTS.md`](AGENTS.md).
10+
11+
> **Toolchain note:** install under Node **22** (the `.nvmrc` LTS pin). A transitive dep (`nanoid@6`) declares `engines.node` excluding odd-numbered releases, so `pnpm install` fails under Node 25 with `engine-strict=true`.
12+
13+
### Changed
14+
15+
- **ObjectStack platform → 16.0.0-rc.1** across all 11 `@objectstack/*` packages (from `14.7`), pinned to the exact RC version.
16+
- **Dropped `ai` from the stack's `requires` ([objectstack.config.ts](objectstack.config.ts)).** ObjectStack 11.3.0 (ADR-0025 S2) removed `@objectstack/service-ai` from the open edition — the AI runtime ships only in the closed cloud package, whose latest open-registry version is `10.3.0`. Under 16, `requires: ['ai']` is a **fail-fast** capability: the serve command hard-aborts boot when the package is absent (the AI block runs before every other capability resolves), so `objectstack start`/`dev` for this open-edition app failed with `[AI] required but @objectstack/service-ai is not installed`. The AI **metadata is unaffected** — both agents + all skills still validate, compile into the artifact, and run wherever a runtime provides the `ai` tier (cloud's `objectos-runtime`). A local open-edition boot simply omits the AI service and hides its Console surface. (This was never caught before because the `verify` script boots nothing — `validate`/`typecheck`/`build`/`test` all resolve metadata only, not capability provider packages.)
17+
- **Removed the dead `visibility` field from both agents** ([sales-copilot](src/agents/sales-copilot.agent.ts), [service-copilot](src/agents/service-copilot.agent.ts)). ObjectStack 16 removes `AgentSchema.visibility` (ADR-0049 / ADR-0056 D8): it was never enforced — a `private`/`organization` value never restricted an agent — so a security-shaped field with no runtime consumer is a liability. `AgentSchema` is not `.strict()`, so it was being silently stripped; removed for honesty. Restrict agent access via the enforced `access`/`permissions` surfaces instead.
18+
19+
### Fixed
20+
21+
- **Dashboard date-range picker no longer crashes widgets on objects without the date field.** ObjectStack 15 (framework#2501, `GlobalFilterSchema.name` + `DashboardWidgetSchema.filterBindings`) wired dashboard-level filters — including the built-in `dateRange` picker (reserved filter name `dateRange`) — into **every widget's analytics query**. At 14.7 the picker didn't propagate; under 16 it injects its `field` into each widget's SQL. The Executive and CRM dashboards bind `dateRange` to `close_date`, which only exists on `crm_opportunity` — so every widget on `crm_account` / `crm_contact` / `crm_lead` / `crm_product` failed with `SqliteError: no such column: close_date` and rendered as an error card. Each affected widget now declares `filterBindings: { dateRange: false }` to opt out of the picker (they carry their own `created_at` / count semantics): 5 widgets on [executive.dashboard.ts](src/dashboards/executive.dashboard.ts) (`total_accounts`, `total_contacts`, `open_leads`, `new_accounts_by_month`, `accounts_by_industry`) and 1 on [crm.dashboard.ts](src/dashboards/crm.dashboard.ts) (`top_products`). The Sales dashboard (all-`opportunity_metrics`) and Service dashboard (`dateRange` bound to `created_date`, which `crm_case` has) needed no change. Browser-verified: all four dashboards load with live data and zero analytics/SQL errors. (This surfaces only when the dashboards are actually rendered against seeded data — `verify` builds the artifact but never queries it.)
22+
23+
### Removed
24+
25+
- **Dead dashboard header action buttons.** All four dashboards declared header `actions` (Export PDF, Schedule Email, Customize, New Opportunity/Deal/Lead/Case, Forecast, Reports, My Queue, SLA Report) that pointed at actions or routes which were never implemented — `export_dashboard_pdf` / `schedule_dashboard_email` / `customize_dashboard` / `create_opportunity` / `create_lead` / `create_case` are not defined actions, and the `url` targets (`/reports/forecast`, `/reports/sla`, `/reports`, `/objects/case?owner=current_user`) match no in-app view route. They rendered as buttons that did nothing when clicked. Removed the `header.actions` block from [executive](src/dashboards/executive.dashboard.ts), [sales](src/dashboards/sales.dashboard.ts), [crm](src/dashboards/crm.dashboard.ts), and [service](src/dashboards/service.dashboard.ts) dashboards (titles/descriptions kept), plus the now-orphaned action-label translations from all four locale bundles (`en`, `zh-CN`, `ja-JP`, `es-ES`). Pre-existing dead affordance, unrelated to the upgrade; re-add real, wired-up actions when those features exist.
26+
27+
### Verified clean (no change needed)
28+
29+
The rest of the 15→16 enforce-or-remove surface did not touch this app, confirmed by source scan + a clean build:
30+
31+
- **Hook/action `ctx.session.tenantId``organizationId`** — no `tenantId` reads anywhere.
32+
- **Removed object props** (`versioning`/`softDelete`/`search`/`recordName`/`keyPrefix`/`tags`/`active`/`abstract`) and **field props** (`vectorConfig`/`fileAttachmentConfig`/`dependencies`/`columnName`/`index`/`referenceFilters`) — none authored (only historical comments).
33+
- **Dashboard-widget `.strict()`** — the pivot's `rowField`/`columnField`/`valueField` live inside the `options: {}` escape hatch; widgets use the canonical `dataset`/`dimensions`/`values` shape.
34+
- **Collapsed hook events** (18 → 8), **validation `events: ['delete']`**, **webhook `undelete`/`api` triggers**, **`aiStudio`/`aiSeat` capability aliases**, **feed contracts**, **formula date arithmetic** (now a build error), **`managedBy: 'system'` data-API lockdown**, **`ObjectOS*``Kernel*` class renames**, and the **tenancy config** removal — none present.
35+
- **Approver types** already use the canonical `type: 'position'` (migrated in 2.1.0), not the now-removed `role` alias.
36+
537
## [2.1.0] — 2026-07-14
638

739
Platform upgrade to ObjectStack **14.7** — a major line bump (from 12/13). Manifest `specVersion` now declares `^14.0.0` (was `^12.0.0`); app version `2.1.0`. ObjectStack 14 completes the ADR-0090 permission-model vocabulary convergence and turns the object `enable.*` capability flags into real runtime gates. This release migrates HotCRM's metadata off every 14.0 breaking surface and hardens the seed + opportunity-lifecycle hook so a fresh-DB boot is completely clean. Built, validated, type-checked, linted (zero warnings), unit-tested (17/17), and browser-verified against `@objectstack/* ^14.7.0` (login → HotCRM app → Executive / Sales / Service / CRM Overview dashboards with live seeded data → Accounts / Opportunities / Cases lists → account record detail with grouped field sections; no boot errors, no post-login console errors).

objectstack.config.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default defineStack({
3131
manifest: {
3232
id: 'app.objectstack.hotcrm',
3333
namespace: 'crm',
34-
version: '2.1.0',
34+
version: '2.2.0',
3535
type: 'app',
3636
name: 'HotCRM',
3737
description: 'AI-Native CRM for the ObjectStack marketplace — Accounts, Contacts, Leads, Opportunities, Cases, Knowledge, Forecasts, Campaigns, Contracts.',
@@ -58,7 +58,20 @@ export default defineStack({
5858
// actually fire autolaunched flows (record_change & schedule types). Without
5959
// it the `automation` engine registers flows but nothing ever launches them.
6060
// Schedule triggers run via the job service (in the always-on slate).
61-
requires: ['ai', 'automation', 'triggers', 'analytics', 'auth', 'ui', 'approvals', 'sharing'],
61+
//
62+
// `ai` is deliberately NOT listed. ObjectStack 11.3.0 (ADR-0025 S2) removed
63+
// `@objectstack/service-ai` from the open edition — the AI runtime now ships
64+
// only in the closed cloud package, and the framework CLI does not depend on
65+
// it. Under ObjectStack 16, `requires: ['ai']` is a *fail-fast* capability:
66+
// the serve command hard-aborts boot when the package is absent, so keeping it
67+
// here would break `objectstack start`/`dev` for this open-edition app (the AI
68+
// block runs before every other capability resolves). The AI metadata is
69+
// unaffected — the two agents + skills still validate, build into the artifact,
70+
// and run wherever a runtime provides the `ai` tier (cloud's objectos-runtime).
71+
// A local open-edition boot simply omits the AI service and hides its console
72+
// surface. To run AI locally, declare `@objectstack/service-ai` (cloud) in
73+
// package.json — its mere presence best-effort auto-loads it.
74+
requires: ['automation', 'triggers', 'analytics', 'auth', 'ui', 'approvals', 'sharing'],
6275

6376
objects: Object.values(objects),
6477
actions: Object.values(actions),

objectstack.manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
33
"name": "hotcrm",
4-
"specVersion": "^14.0.0",
4+
"specVersion": "^16.0.0-rc.1",
55
"manifestId": "app.objectstack.hotcrm",
66
"displayName": "HotCRM",
77
"description": "AI-Native CRM for the ObjectStack marketplace — Accounts, Contacts, Leads, Opportunities, Cases, Knowledge, Forecasts, Campaigns, and Contracts in one production-grade workspace.",

package.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hotcrm",
3-
"version": "2.1.0",
3+
"version": "2.2.0",
44
"description": "HotCRM - Production CRM built on ObjectStack",
55
"private": true,
66
"main": "./objectstack.config.ts",
@@ -26,17 +26,17 @@
2626
},
2727
"packageManager": "pnpm@10.33.0",
2828
"dependencies": {
29-
"@objectstack/account": "^14.7.0",
30-
"@objectstack/cli": "^14.7.0",
31-
"@objectstack/driver-memory": "^14.7.0",
32-
"@objectstack/driver-sql": "^14.7.0",
33-
"@objectstack/driver-sqlite-wasm": "^14.7.0",
34-
"@objectstack/metadata": "^14.7.0",
35-
"@objectstack/objectql": "^14.7.0",
36-
"@objectstack/runtime": "^14.7.0",
37-
"@objectstack/service-analytics": "^14.7.0",
38-
"@objectstack/service-automation": "^14.7.0",
39-
"@objectstack/spec": "^14.7.0"
29+
"@objectstack/account": "16.0.0-rc.1",
30+
"@objectstack/cli": "16.0.0-rc.1",
31+
"@objectstack/driver-memory": "16.0.0-rc.1",
32+
"@objectstack/driver-sql": "16.0.0-rc.1",
33+
"@objectstack/driver-sqlite-wasm": "16.0.0-rc.1",
34+
"@objectstack/metadata": "16.0.0-rc.1",
35+
"@objectstack/objectql": "16.0.0-rc.1",
36+
"@objectstack/runtime": "16.0.0-rc.1",
37+
"@objectstack/service-analytics": "16.0.0-rc.1",
38+
"@objectstack/service-automation": "16.0.0-rc.1",
39+
"@objectstack/spec": "16.0.0-rc.1"
4040
},
4141
"optionalDependencies": {
4242
"better-sqlite3": "^12.11.1"

0 commit comments

Comments
 (0)