Skip to content

fix(example-crm): make formula fields compute + allow historical closed deals; bump objectui#1927

Merged
os-zhuang merged 1 commit into
mainfrom
fix/example-crm-formula-validation-and-objectui-bump
Jun 15, 2026
Merged

fix(example-crm): make formula fields compute + allow historical closed deals; bump objectui#1927
os-zhuang merged 1 commit into
mainfrom
fix/example-crm-formula-validation-and-objectui-bump

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Why

Release-prep browser test of example-crm (9.5.x) surfaced three "passes build, silently wrong at runtime" defects — the failure class this project's AI-authoring guardrails target. All three are in the flagship demo app.

Fixes

# Defect Root cause Fix
1 full_name, is_closed, expected_revenue all rendered empty Formulas used bare identifiers (amount, status, first_name). Formula scope is {record, previous, input, os} with no field flattening, so bare names resolve to nothing → null rewrite to record.<field>
2 expected_revenue still null after #1 … / 100cel-js has no double × int arithmetic overload, so <number field> / 100 faults and the formula returns null float literal / 100.0 (both operands double)
3 Opportunity list showed only 4 rows; dashboard "Won This Quarter" empty opp_close_date_not_past validation fired on every insert, rejecting closed_won/closed_lost seed rows that legitimately carry historical close dates (5 of 9 wins dropped) scope the rule to open stages only

Also bumps .objectui-sha 26da1a2a3731 → ac2de168d487 and rebuilds the bundled @objectstack/console dist for the release.

Verification (live dev server + API)

  • Opportunities seed 4 → 12 (all closed_won/closed_lost now persist)
  • expected_revenue computes: 84000, 180000, 16000, 21000, … (= amount × probability / 100)
  • full_name → "Ada Lovelace", is_closed → correct boolean
  • pnpm build → 75/75 tasks pass; example-crm builds clean (ADR-0032 expression validation green)

Follow-up (deferred)

The cel-js double × int arithmetic gap is systemic — any AI-authored formula like price * 2, total - fee, amount / 100 silently returns null; only float literals work, and cel-js rejects registering operator overloads. validate-expressions.ts (ADR-0032) catches neither this nor the bare-identifier case. Tracking issue to follow for a build-time lint and/or engine-level int→double promotion.

🤖 Generated with Claude Code

…ed deals; bump objectui

Release-prep browser test of example-crm surfaced three "passes build,
silently wrong at runtime" defects:

- Formula fields (`full_name`, `is_closed`, `expected_revenue`) referenced
  bare field identifiers (`amount`, `status`, `first_name`). Formula scope
  exposes only `{record, previous, input, os}` with no field flattening, so
  bare names resolve to nothing and every formula evaluated to null. Rewrite
  to `record.<field>`.
- `expected_revenue` additionally divided by the int literal `100`. cel-js
  has no `double × int` arithmetic overload, so `<number field> / 100` faults
  and the formula returns null. Use the float literal `100.0` (both operands
  `double`). The systemic guardrail for this footgun is tracked separately.
- `opp_close_date_not_past` validation fired on every insert, rejecting the
  legitimate `closed_won`/`closed_lost` seed rows that carry historical close
  dates (5 of 9 wins were dropped, breaking the pipeline dashboard's
  "Won This Quarter" KPIs). Scope the rule to open stages only.

Also bumps `.objectui-sha` 26da1a2a3731 → ac2de168d487 and rebuilds the
bundled @objectstack/console dist for the release.

Verified live: opportunities seed 4 → 12; expected_revenue computes
(84000, 180000, …); full_name / is_closed populate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 15, 2026 5:32pm

Request Review

@os-zhuang

Copy link
Copy Markdown
Contributor Author

Systemic guardrail tracked in #1928 (build-time lint and/or engine int→double promotion).

@os-zhuang
os-zhuang merged commit 1104c24 into main Jun 15, 2026
13 checks passed
@os-zhuang
os-zhuang deleted the fix/example-crm-formula-validation-and-objectui-bump branch June 15, 2026 17:59
os-zhuang added a commit that referenced this pull request Jun 16, 2026
… (#1931)

A Field.formula and an object validation predicate evaluate against the
`record` namespace only (no field flattening), so a bare top-level identifier
(`amount`, `status`) resolves to nothing and the expression silently evaluates
to null / never fires — the silent-at-runtime class behind #1927.

`validateExpression` gains an evaluation `scope`; for `scope: 'record'` it
reports a bare reference with the corrective `record.<field>` form. It acts only
on cel-js's `Unknown variable` fault, so it cannot false-positive on
arithmetic/comparison/null-guard overloads. Flow & automation conditions keep
the default `scope: 'flattened'` — the record's fields are spread to top-level
there alongside flow variables, so bare refs are correct and NOT flagged.
`objectstack compile` wires record scope for field formulas + validation
predicates; flow conditions stay flattened.

Also fixes three latent bare-ref bugs surfaced by the new check:
- crm_lead validation `lead_score_range` (rule silently never fired)
- showcase field_zoo `f_formula`, showcase project `budget_remaining` (null)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant