Skip to content

feat(analytics): propagate a measure's declared currency to the result field#2102

Merged
xuyushun441-sys merged 3 commits into
mainfrom
fix/dataset-measure-currency
Jun 21, 2026
Merged

feat(analytics): propagate a measure's declared currency to the result field#2102
xuyushun441-sys merged 3 commits into
mainfrom
fix/dataset-measure-currency

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

The gap

A dataset measure can declare a format (carried onto the analytics result field so the client renders $616,000), but there was no way to declare a currency CODE. The result enrichment in analytics-service set label + format on each measure field but never currency:

if (f.label == null && typeof m.label === 'string') f.label = m.label;
if (f.format == null && m.format) f.format = m.format;
// ← no currency

So the client's currency-aware formatting (Intl symbol from a declared currency — ADR-0021; objectui DatasetWidget and the dataset report renderer) could never fire against real data. Every amount fell back to a plain number, or to a $ literal baked into format — regardless of the actual currency. The client feature was effectively inert end-to-end.

(Found while verifying the objectui dataset-render currency work — no example ever rendered an Intl currency symbol, which traced back to here.)

The fix — symmetric with format

  • spec: DatasetMeasure.currency (ISO 4217, optional). Declared on the semantic layer when the aggregated field is a fixed-currency amount.
  • service-analytics: carry measure.currency onto the result field alongside label/format.
  • example (app-crm): opportunity_metrics total/avg amount now declare currency: 'USD' (and drop the legacy $ from format), so the pipeline reports render a locale-correct symbol via Intl.

Tests

  • service-analytics138 passed (+1: a measure's declared currency rides onto its result field).
  • Spec builds (with dts); the new field is additive + optional, so no existing dataset breaks.

Notes

🤖 Generated with Claude Code

…t field

A dataset measure could declare a `format` (carried onto the analytics result
field so the client renders "$616,000"), but there was NO way to declare a
currency CODE. The analytics result enrichment set `label` + `format` on each
measure field but never `currency` — so the client's currency-aware formatting
(Intl symbol from a declared currency, ADR-0021; objectui DatasetWidget/report
renderer) could never fire against real data: every amount fell back to a plain
number or a "$" literal baked into `format`, regardless of the actual currency.

This adds the missing link, symmetric with `format`:
- spec: `DatasetMeasure.currency` (ISO 4217, optional) — declared on the
  semantic layer when the aggregated field is a fixed-currency amount.
- service-analytics: carry `measure.currency` onto the result field alongside
  `label`/`format`, so the renderer gets a real currency code.
- example (app-crm): `opportunity_metrics` total/avg amount now declare
  `currency: 'USD'` (and drop the legacy `$` from `format`) so the pipeline
  reports render a locale-correct symbol via Intl.

Tests: service-analytics 138 passed (+1: a measure's declared currency rides
onto its result field). Spec builds; the new field is additive + optional.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 21, 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 21, 2026 7:06am

Request Review

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): packages/services, @objectstack/spec.

91 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/cloud-artifact-api.mdx (via packages/spec)
  • content/docs/concepts/cluster-semantics.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/implementation-status.mdx (via @objectstack/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via packages/spec)
  • content/docs/concepts/packages.mdx (via @objectstack/spec)
  • content/docs/concepts/setup-app.mdx (via @objectstack/spec)
  • content/docs/concepts/skills.mdx (via @objectstack/spec)
  • content/docs/concepts/webhook-delivery.mdx (via @objectstack/spec)
  • content/docs/getting-started/architecture.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.mdx (via @objectstack/spec)
  • content/docs/getting-started/core-concepts.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/guides/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/guides/ai-capabilities.mdx (via @objectstack/spec)
  • content/docs/guides/airtable-dashboard-analysis.mdx (via @objectstack/spec)
  • content/docs/guides/analytics-datasets.mdx (via @objectstack/spec)
  • content/docs/guides/api-reference.mdx (via @objectstack/spec)
  • content/docs/guides/business-logic.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/error-catalog.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-type-gallery.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/field-validation-rules.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/protocol-diagram.mdx (via packages/spec)
  • content/docs/guides/cheatsheets/query-cheat-sheet.mdx (via @objectstack/spec)
  • content/docs/guides/cheatsheets/quick-reference.mdx (via @objectstack/spec)
  • content/docs/guides/client-sdk.mdx (via @objectstack/spec)
  • content/docs/guides/common-patterns.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/auth-service.mdx (via packages/spec)
  • content/docs/guides/contracts/cache-service.mdx (via packages/spec)
  • content/docs/guides/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/index.mdx (via @objectstack/spec)
  • content/docs/guides/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/guides/contracts/storage-service.mdx (via packages/spec)
  • content/docs/guides/data-modeling.mdx (via @objectstack/spec)
  • content/docs/guides/deployment-vercel.mdx (via @objectstack/spec)
  • content/docs/guides/driver-configuration.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/guides/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/guides/formula.mdx (via @objectstack/spec)
  • content/docs/guides/hook-bodies.mdx (via packages/spec)
  • content/docs/guides/kernel-services.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/dashboard.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/field.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/flow.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/index.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/object.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/validation.mdx (via @objectstack/spec)
  • content/docs/guides/metadata/workflow.mdx (via @objectstack/spec)
  • content/docs/guides/packages.mdx (via packages/services, @objectstack/spec)
  • content/docs/guides/plugin-development.mdx (via @objectstack/spec)
  • content/docs/guides/plugins.mdx (via @objectstack/spec)
  • content/docs/guides/project-scoping.mdx (via @objectstack/spec)
  • content/docs/guides/public-forms.mdx (via @objectstack/spec)
  • content/docs/guides/runtime-services/audit-service.mdx (via packages/services)
  • content/docs/guides/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/index.mdx (via packages/services, packages/spec)
  • content/docs/guides/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/settings-service.mdx (via packages/services)
  • content/docs/guides/runtime-services/sharing-service.mdx (via packages/spec)
  • content/docs/guides/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/guides/security.mdx (via @objectstack/spec)
  • content/docs/guides/seed-data.mdx (via @objectstack/spec)
  • content/docs/guides/skills.mdx (via @objectstack/spec)
  • content/docs/guides/standards.mdx (via @objectstack/spec)
  • content/docs/guides/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/i18n-standard.mdx (via packages/services, @objectstack/spec)
  • content/docs/protocol/objectos/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/objectos/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via packages/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jun 21, 2026
@xuyushun441-sys
xuyushun441-sys merged commit a581385 into main Jun 21, 2026
17 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the fix/dataset-measure-currency branch June 21, 2026 07:12
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>
os-zhuang added a commit that referenced this pull request Jun 30, 2026
…s) (#2471)

Pins the vendored @objectstack/console to objectui d23d6ebfa so the served
console includes the kind:'react' renderer + the full HTML tag set for
kind:'html' (objectui #2105). Carries two small list inline-edit toggles
(#2102/#2103) since the previous pin. Activates the CRM Workbench showcase
page (ADR-0081) in the real serving path.

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:ui size/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants