feat(runtime): resolve tenant default currency onto ExecutionContext#2119
Merged
Conversation
ADR-0053 follow-up. The `localization.currency` setting (tenant-scoped, default USD, documented as "applied when a currency field omits its own") was declared but had ZERO runtime consumers — resolveExecutionContext read only timezone + locale, so no code path could reach the tenant default. This carries it onto the context, mirroring timezone/locale exactly: - spec: `ExecutionContext.currency` (ISO 4217, optional). - runtime: `resolveLocalization` reads `localization.currency` (canonical settings path + the direct sys_setting fallback), coerced to a 3-letter code; assigned to `ctx.currency`. - rest: the REST context mirror reads + carries it too. Foundation for the unified currency-resolution chain (field currencyConfig → tenant localization.currency); analytics/template/renderer consumers land in follow-ups. Undefined when unconfigured → consumers render a plain number. Tests: resolve-execution-context 17 passed (+2: canonical + fallback currency, ISO-code coercion/junk rejection). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 3 package(s): 96 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 21, 2026
…ig + tenant default (#2121) * feat(analytics): resolve a monetary measure's currency via field config + tenant default Phase 1b of unifying currency resolution (builds on ExecutionContext.currency). The dataset measure-currency enrichment honored ONLY an explicit measure `currency` literal — so a measure summing a currency field, or any measure on a tenant with a configured default currency, rendered symbol-less unless the author restated the code. Now a MONETARY measure resolves its display currency through the documented chain: explicit measure `currency` → source-field `currencyConfig.defaultCurrency` → tenant default (`ctx.currency`, from the localization setting wired in #2119). A measure is monetary iff it declares a currency OR aggregates a `currency`-type field — so count / avg-of-number measures never get a (wrong) currency code. - analytics-service: `AnalyticsServiceConfig.measureCurrency(object, field)` → source-field `{ type, defaultCurrency }`; enrichment applies the chain, gated on monetary type. - plugin: wires `measureCurrency` from the data engine's `getObject().fields` (same accessor the label resolver already uses). Tests: query-dataset 15 passed (+4: field-default inheritance, tenant-ctx fallback, explicit-override precedence, and non-currency measures staying code-less). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore: changeset for analytics measure-currency chain --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 21, 2026
…r every user (#2122) Phase 2a of unifying currency. The `localization` settings (currency/locale/ timezone) are gated to `setup.access`, and `discovery` is static/context-free — so a regular user's client has no way to learn the tenant's default currency or locale to format values consistently. This adds `GET /api/v1/auth/me/localization`, returning the resolved `{ currency, locale, timezone }` off the request ExecutionContext (the same values #2119 wired in) to every AUTHENTICATED user — without the setup.access gate on the underlying settings. A thin passthrough of `resolveCtx(c)`; the ctx resolution itself is covered by resolve-execution-context tests. Unblocks the objectui client (Phase 2): a LocalizationProvider can fetch this once and feed a single currency/number formatter the tenant default + locale, replacing ~20 ad-hoc per-site currency-resolution paths. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 21, 2026
…ode; showcase demo (#2123) * docs(currency): document the field→tenant resolution chain; fix currencyMode; showcase demo Follows the currency-resolution work (#2102/#2119/#2121/#2122). Brings the skills + showcase in line with the now-implemented chain. - objectstack-ui SKILL: document `DatasetMeasure.currency` (ISO 4217) and its resolution order (measure → field `currencyConfig` → tenant default). - objectstack-data field-types: FIX a real doc bug — `currencyMode` was documented as `'multi'/'single'`, the schema is `'fixed'/'dynamic'`; add a "Currency resolution (ADR-0053)" note (field default → tenant default → plain number, never a hardcoded `$`). - objectstack-i18n SKILL: note the workspace regional defaults (timezone / locale / currency) — the `localization` settings, resolved onto ExecutionContext and exposed at `/auth/me/localization`. - showcase: declare a fixed `currencyConfig.defaultCurrency` on field-zoo's currency field (demonstrates + smoke-covers the symbol path); refresh the chart-gallery `budget`/`spent` comment, which claimed an unspecified-currency amount "must not show a $" — now it falls back to the tenant default. Verified: app-showcase builds (field + dataset parse); check:skill-docs in sync. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(showcase): currencyConfig requires precision (typecheck) --------- Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of unifying currency resolution
Audit finding: the
localization.currencysetting (tenant-scoped, default USD, documented as "ISO 4217 code applied when a currency field omits its own") was declared but had zero runtime consumers.resolveExecutionContextread onlytimezone+locale, so no code path could ever reach the tenant default. LikewisecurrencyConfig.defaultCurrency(field-level) has no reader. The whole field→tenant currency fallback exists only as prose.This PR lays the foundation: carry the tenant default currency on every request context, mirroring
timezone/localeexactly.Changes
ExecutionContext.currency(ISO 4217, optional).resolveExecutionContext):resolveLocalizationnow readslocalization.currency— canonical settings-service path and the directsys_settingtenant fallback — coerced to a 3-letter ISO code, assigned toctx.currency.currencytoo.Undefined when no tenant default is configured → consumers render a plain number (no behavior change until consumers opt in).
Why phased
Per the unified plan (currency is declared everywhere but resolved nowhere, with ~25 divergent client sites): this keystone unblocks the rest. Follow-ups:
currencyConfig→ctx.currency, gated on monetary field type) + template-engine default.Tests
resolve-execution-context→ 17 passed (+2: canonical + sys_setting-fallback currency resolution; ISO-code upper-casing + junk rejection).🤖 Generated with Claude Code