Skip to content

fix(objects): drop scale from every currency field — objectstack main refuses it - #1968

Merged
hotlong merged 2 commits into
mainfrom
claude/issue-1965-currency-fields-drop-scale
Sep 28, 2026
Merged

hotlong merged 2 commits into
mainfrom
claude/issue-1965-currency-fields-drop-scale

Conversation

@hotlong

@hotlong hotlong commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #1965
Part of objectstack-ai/cloud#2440
Clause-②: no

What

This PR deletes scale from every currency field: 23 lines in 8 object files, one per field, with nothing added in their place. objectstack main refuses the key ("scale is not valid on a currency field"; semantic entry field-currency-scale-refused), and no forward conversion exists for it. A currency's decimals are its ISO 4217 minor unit, not a field setting. scale on number, percent, formula and summary fields is left alone (5 formula, 6 number, 4 percent and 1 summary are untouched).

The maintainer ruled this route on the card. First the card ruling (「平台修转换 + HotCRM 先删 scale(推荐)」), then comment 5864798033 on the display window (「现在删,cloud 两次抬版本同一次部署(推荐)」).

The two comments that the deletion made false are reworded, and nothing else changes in those files. src/revenue/flows/quote-generation.flow.ts said the quote's money fields refuse an unrounded product; after this PR they accept it. test/flow-quote.test.ts had the same claim in its docblock and in its title, which now reads "rounds discount_amount and total_price to whole cents (#1206)". The round() expressions and the value pins are unchanged.

This PR adds one patch changeset, .changeset/currency-fields-drop-scale.md.

Display window (measured, and accepted by the ruling)

At the pinned @objectstack/console 17.4.0 (built from objectui 53ded82bf7a4), two faces format a currency value with the field's scale ?? 0:

  • the grid summary footer: plugin-grid bundle, r?.scale??0, which feeds min/max fraction digits;
  • the object-metric tile: plugin-dashboard bundle, ie.scale??0, which picks 0,0.00 vs 0,0.

After this PR they show whole units. In hotcrm this reaches 17 currency summary: columns across 8 list views, plus the Revenue (Won) and Pipeline Value tiles on Sales Home. Record cells do not change: they already use the currency's own minor unit.

I measured this in the UI on two local objectstack dev servers with the same seed. Port 4801 ran main; port 4802 ran this deletion.

face main this PR
Sales Home, Revenue (Won) 1,290,000.00 1,290,000
Sales Home, Pipeline Value 2,017,500.00 2,017,500
Open Deals footer, Amount 合计:2,017,500.00 合计:2,017,500
Open Deals footer, Expected Revenue 合计:1,304,050.00 合计:1,304,050

Every seeded amount is a whole unit, so on the demo data the only change is the dropped .00. In the grid, the footer then matches the cells, which already show 94,000. Non-integer totals round to whole units. For example, the product view's avg list_price goes from 22,346.15 to 22,346; that figure is computed from the shipped formatter, not captured in the UI.

The window closes when the console includes objectui 0651e7ab4 (objectui#10348):

  • It is not in the 17.4.0 console: merge-base --is-ancestor exits 1, and the control leg exits 0.
  • It is not in cloud's current .objectui-sha efead6c6: exits 1, control exits 0.
  • It is in objectstack main's console pin f8a9d0fb: exits 0.

Cloud avoids the window by shipping the framework re-cut (cloud#2332) and the objectui pin move (cloud#2441) in one deploy. That constraint is recorded on both cloud cards. The hotcrm-local half (pnpm dev / objectstack start at 17.4.0) closes when hotcrm bumps to 17.5.x.

Verification, on HEAD 8d558193

pnpm verify chain, command by command:

gate main 2f7b2326 this PR 8d558193
pnpm validate exit 0 exit 0 (same 12 warnings, verdict lines identical)
pnpm typecheck exit 0 exit 0
pnpm lint exit 0 exit 0 (same 5 warnings, verdict lines identical)
pnpm lint:i18n-gate exit 0 exit 0 ("0 i18n/missing-* issues")
pnpm hygiene exit 0 exit 0
pnpm hygiene:tokens exit 0 exit 0 (src/revenue business semantics ~15,626 → ~15,594)
pnpm build exit 0 exit 0
pnpm test exit 0: 173 files, 3716 passed, 1 skipped see below

pnpm test on this PR hit only 5000 ms or 60000 ms timeouts, with the box's load average between 40 and 77 (other agents' builds):

  • Run 1 (466 s): 7 timeouts in global-actions, lint-i18n-gate and source-token-ratchet.
  • Run 2 (288 s): 2 timeouts in case-sla-matrix and source-token-ratchet.
  • Every one of those files passed on this same HEAD when re-run on its own. The source-token-ratchet file passed 40/40 once at the default timeout, and later timed out again at the default. global-actions + source-token-ratchet + case-sla-matrix passed 119/119 with --testTimeout=60000. lint-i18n-gate + flow-quote (and the others in that rerun) passed.

No assertion failed in any run. CI owns the clean full-suite reading.

Artifact probe. The objectstack 862b6ce dist ran ObjectStackDefinitionSchema.safeParse(applyArtifactForwardConversions(...)) on this branch's dist/objectstack.json:

runtime label main's artifact this PR's artifact
17.4.0 (authored-current) 63 issues, 23 on currency scale 40 issues, 0 on currency scale: the chart keys (16 type, 9 xAxis, 9 yAxis) and assignedProfiles (6) remain, pending objectstack#20390
17.5.0 (converted-forward) 23 issues, all currency scale PARSE OK, 0 issues

This PR's artifact is identical, section by section, to main's artifact with only those 23 keys stripped. The comment edits do not reach it.

Other checks.

Acceptance notes

  • max_scale lift at the pin. objectql 17.4.0 enforces max_scale on a currency field only through the field's scale (dist/core.js, numeric branch). With the key gone, a money write with more than 2 decimals on these 23 fields is accepted where it used to be refused. That is the platform's ruled contract for currency from 17.5 on, arriving early here. No hotcrm test pins the old refusal (0 hits for max_scale under test/). The Generate Quote flow still rounds to whole cents, so its amounts do not change.
  • Draft feat(opportunity): REQ-0006 qualification, the customer calendar, narrative and approval on status change #1950 adds scale: 2 to two new currency fields, expected_tender_amount and expected_signing_amount. That PR's author needs to drop them before it lands, or objectstack main will refuse them. Its textual merge with this PR is clean.
  • What this leaves of the objectstack-main refusal list (card acceptance 3): only the chart-key and assignedProfiles families, 40 issues at a 17.4.0 runtime label. At a 17.5.0 label both families convert forward and nothing remains.
  • The PR adds no gate and no test file. The removal is guarded by the platform's own refusal once hotcrm runs on 17.5.

Generated by Claude Code

hotlong and others added 2 commits September 28, 2026 14:41
objectstack main refuses `scale` on a `currency` field (semantic entry
`field-currency-scale-refused`, no forward conversion), so hotcrm's
artifact cannot boot there with it. A currency's decimals are the
currency's ISO 4217 minor unit, not a field setting. `scale` is
optional at the pinned @objectstack/spec 17.4.0, so the deletion is
legal on both versions.

23 lines deleted in 8 object files, one per currency field; nothing
added. `scale` on number, percent, formula and summary fields is
untouched.

Co-authored-by: Claude <noreply@anthropic.com>
… refuses the tail

With `scale` gone from currency fields, the quote's money fields accept
a write with more than 2 decimals, so the two comments that said the
field refuses an unrounded product are no longer true. They now say
what the rounding does: it keeps discount_amount and total_price in
whole cents. The round() expressions and the value pins are unchanged;
only the flow comment, the test docblock and the test title move.

Adds the patch changeset for the currency `scale` removal.

Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 28, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Sep 28, 2026 7:05am UTC

Request Review

@github-actions github-actions Bot added ci/cd CI plumbing and the verification pipeline metadata Declarative metadata — schema, security posture, UI surfaces backend Server-side behaviour — hooks, flows, actions labels Sep 28, 2026
@hotlong hotlong self-assigned this Sep 28, 2026
@hotlong
hotlong marked this pull request as ready for review September 28, 2026 07:08
@hotlong
hotlong added this pull request to the merge queue Sep 28, 2026
Merged via the queue into main with commit 5bec6eb Sep 28, 2026
10 checks passed
hotlong pushed a commit that referenced this pull request Oct 3, 2026
Conflict: docs/STATUS.md, resolved by recomputing from the merged tree's
own `pnpm validate` rather than by picking a side: main retired the
demo_bootstrap flow (30 Flows) and this branch adds
opportunity_status_change_approval, so the merged stack registers
18 Objects / 361 Fields / 31 Flows.

Semantic conflict, resolved in this merge: main dropped `scale` from every
currency field (#1968) and the 17.6.0 pin now refuses the key outright
("`scale` is not valid on a `currency` field — delete the key"). The two
currency fields this branch adds, expected_tender_amount and
expected_signing_amount, carried `scale: 2`; it is removed so the merged
tree validates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ER8ntXZhYebyQ66aXWdjfT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Server-side behaviour — hooks, flows, actions ci/cd CI plumbing and the verification pipeline metadata Declarative metadata — schema, security posture, UI surfaces

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove scale from currency fields: objectstack main refuses it and no forward conversion exists (cloud re-cut floor 1)

1 participant