Skip to content

Commit 0d73ff6

Browse files
docs(data-modeling): currency is a bare number in both modes; defaultCurrency is the column currency only under fixed (#20120)
Part of #20090 Clause-②: no Docs half of the card: the two `content/docs/data-modeling` pages triage named as the declared cross-domain surface (the card's item 1 and the addendum). The `skills/**` half lands separately on `claude/issue-20090-currency-mode-teaching` (Tier H, awaits human approval); #20090 stays open until both have landed and the seat closes it. Not a governed surface; no `meta.json` change (both pages already exist). ## What changed Text only, re-derived from the spec (`packages/spec/src/data/field-value.zod.ts`: `currency` is in `NUMERIC_VALUE_TYPES`, "`currency` IS a bare number"; `field.zod.ts`: `currencyMode` `'dynamic' | 'fixed'` default `'dynamic'`, `defaultCurrency` default `'CNY'`, and the guidance "a fixed currency is declared as `currencyConfig: { currencyMode: 'fixed', defaultCurrency: … }` … A field without one uses the tenant default at runtime"; the tenant default's producer is the `localization.currency` setting in `packages/services/service-settings/src/manifests/localization.manifest.ts`). ### `content/docs/data-modeling/field-types.mdx` (676 → 677 lines) - The `currency` section's lead sentence now says the stored value is a bare number in both modes and the currency code lives in `currencyConfig`, never in the value. - `currencyConfig.currencyMode` row: "Whether currency is per-record or fixed" → "Whether the column is pinned to `defaultCurrency` (`fixed`) or displays in the tenant default currency, the `localization.currency` setting (`dynamic`); the value is a bare number either way". - `currencyConfig.defaultCurrency` row: "Default currency code" → "The column's currency code under `fixed`; not the displayed currency under `dynamic`" (the row's own default is `'CNY'`, so the old description read as "every dynamic column shows CNY"). ### `content/docs/data-modeling/fields.mdx` (459 → 465 lines) - The "Currency Configuration" example authored `currencyMode: 'dynamic', defaultCurrency: 'USD'` and never said USD is not the displayed currency under `dynamic`. It now authors `'fixed'`, so the `defaultCurrency` it shows is the currency it displays, with the two modes explained in the comments. - One short paragraph under the example states the rule: bare number in both modes, never `{ value, currency }`; under `dynamic` (the default) the amount displays in the tenant's `localization.currency` setting and `defaultCurrency` is not the displayed currency; `fixed` pins the column to `defaultCurrency`. The generated reference `content/docs/references/data/field.mdx` is untouched (auto-gen; its "dynamic (user selectable)" wording is the spec describe's and is reported to the seat, not edited here). ## Changeset `skip-changeset`: `content/docs/**` only — docs-only, nothing published moves. ## Verification (head `c982ebfa`) `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` in this worktree, no paths, derives 40 families; every one run in the foreground with the exit captured before any pipe, then reconciled: `--ran` verdict "40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN", exit 0. All 40 exit 0: `check-ci-filter-parity` · `check-closing-keyword-parity` (+ `--self-test`) · `check-comment-mask-corpus` · `check-doc-frontmatter` (+ `--self-test`) · `check-doc-route-spelling --advisory` (+ `--self-test`) · `check-docs-section-name` (+ `--self-test`) · `check-section-landing-index` (+ `--self-test`) · `@objectstack/lint check:doc-formula-expressions` · `check:doc-security-posture` · `@objectstack/spec check:docs` (spec built first under the verify lock) · `check:empty-state` · `check:liveness` · `check:skill-examples` ("259 prose examples type-check across 3 surface(s)") · `check:strictness-ledger` · `check:variant-docs` · `check:yaml-examples` · `check:corpus-claim-drift` · `check:cross-package-test-inputs` · `check:doc-anchors` · `check:doc-authoring` · `check:docs-audit-scope` · `check:docs-redirects` · `check:docs-single-h1` · `check:docs-spec-enumerations` · `check:docs-transcript-drift` · `check:driver-memory-census` · `check:gitlink-declared` · `check:nul-bytes` · `check:published-readme-links` · `check:react-page-adapter-contract` · `check:refd-timer-probe` · `check:role-word` · `check:skill-identifier-liveness` · `check:vendor-version-stamps` · `check:watch-hint-literal`. Prerequisite builds (`@objectstack/spec`, `@objectstack/formula` + `@objectstack/lint`, `@objectstack/client-react` closure) ran under `scripts/pm/os-verify-lock.sh`, each with `VERDICT command-exit 0`. No reverse verification or ablation applies: prose with no consumer that parses it. ## Acceptance notes - `content/docs/api/data-api.mdx` calls the server-side resolution "the ADR-0053 currency chain"; ADR-0053 is the date/datetime record and never names currency. That page is outside this card's surface; #20091 (the runtime half of the mode rule) remains open and is the carrier for the chain and its comments. carrier: #20091. --- _Generated by [Claude Code](https://claude.ai/code/session_0148fenvVvyQV9HYxgVDQ33q)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7b06887 commit 0d73ff6

2 files changed

Lines changed: 12 additions & 5 deletions

File tree

‎content/docs/data-modeling/field-types.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ Numeric value with optional precision.
143143
```
144144

145145
### `currency`
146-
Monetary value with currency configuration.
146+
Monetary value. The stored value is a bare number in both modes; the currency
147+
code lives in `currencyConfig`, never in the value.
147148

148149
| Property | Type | Default | Description |
149150
|:---|:---|:---|:---|
@@ -152,8 +153,8 @@ Monetary value with currency configuration.
152153
| `min` | `number` | — | Minimum value |
153154
| `max` | `number` | — | Maximum value |
154155
| `currencyConfig.precision` | `number` | `2` | Decimal precision for currency |
155-
| `currencyConfig.currencyMode` | `'dynamic' \| 'fixed'` | `'dynamic'` | Whether currency is per-record or fixed |
156-
| `currencyConfig.defaultCurrency` | `string` | `'CNY'` | Default currency code |
156+
| `currencyConfig.currencyMode` | `'dynamic' \| 'fixed'` | `'dynamic'` | Whether the column is pinned to `defaultCurrency` (`fixed`) or displays in the tenant default currency, the `localization.currency` setting (`dynamic`); the value is a bare number either way |
157+
| `currencyConfig.defaultCurrency` | `string` | `'CNY'` | The column's currency code under `fixed`; not the displayed currency under `dynamic` |
157158

158159
```typescript
159160
{ name: 'price', label: 'Price', type: 'currency', currencyConfig: { precision: 2, currencyMode: 'fixed', defaultCurrency: 'USD' } }

‎content/docs/data-modeling/fields.mdx‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,18 @@ price: Field.currency({
7474
label: 'Price',
7575
currencyConfig: {
7676
precision: 2,
77-
currencyMode: 'dynamic', // 'dynamic' | 'fixed'
78-
defaultCurrency: 'USD',
77+
currencyMode: 'fixed', // 'fixed' pins the column to defaultCurrency;
78+
// 'dynamic' (default) shows the tenant default
79+
defaultCurrency: 'USD', // the column's currency under 'fixed'
7980
},
8081
}),
8182
```
8283

84+
The stored value is a bare number in both modes — never `{ value, currency }`.
85+
Under `dynamic` (the default) the amount displays in the tenant's
86+
`localization.currency` setting and `defaultCurrency` is not the displayed
87+
currency; `fixed` pins the column to `defaultCurrency`.
88+
8389
### Date & Time Types
8490

8591
| Type | Factory | Description |

0 commit comments

Comments
 (0)