Repository navigation
Commit a35fc66
fix(service-analytics): a consolidated measure over the home field works unchanged (proof), and the record-currency refusal names the home field (multi-currency M3-1) (#30176)
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgNdDwFvZLCevqYiyR8iafDv)_
epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d
Fixes #27195
Ruling-ref: 6465431966
Clause-②: yes (widening) — `AnalyticsServiceConfig.sourceFieldMeta` (an
exported config type) may answer one more optional key,
`homeAmountField`, which `AnalyticsServicePlugin` relays; nothing an
author writes changes
Metadata-protocol: none
## 维护者速读
- **改了什么:** 新增证明测试:三种记录币种(USD/EUR/CNY)的行经写入投影存入影子列后,数据集度量 `sum`
影子列在内存预览、SQLite、Postgres
上都直接得出本位币合计,代码路径零改动;未分组汇总原始金额的拒绝文案现在同时给出两个药方:指向影子列(宿主透传时点名),或按币种码分组。
- **为什么改:** 仪表盘是客户看合并数的地方;原文案只教「按币种分组」,没告诉作者要一个合计该指向影子列。
- **风险与回滚:** 小。错误码、状态、member/field/object 信封不变,只改文案;`sourceFieldMeta`
多一个可选键(Clause-② widening),宿主不答时文案不点名字段。回滚即撤 PR。
- **先看:**
`packages/services/service-analytics/src/cube-record-currency-door.ts`
的文案,再看 `home-amount-consolidated-measure.test.ts`。
- **两分钟验证:** `OS_TEST_POSTGRES_URL=… npx vitest run
src/__tests__/home-amount-consolidated-measure.test.ts`(36 条);在 main
上跑同一文件,证明部分全绿、文案断言红。
- **需要您做的:** 无。
## What changes
**The proof (no product code).**
`src/__tests__/home-amount-consolidated-measure.test.ts` writes four
invoices in three record currencies (USD, EUR and the home CNY) through
the engine, whose write-time projection (ADR-0144 D5,
`home-amount-projection.ts`) stores each amount converted into the home
currency in the declared `homeAmount.field`. A dataset measure `sum`
over that home field answers the home-currency total through
`queryDataset` (dataset compile + query), on:
- SQLite and PostgreSQL, each on both strategies (`NativeSQLStrategy`;
`ObjectQLStrategy`, narrowed to the engine aggregate);
- the draft-preview in-memory evaluator, over the very rows the
projection stored (read back from the store). This "memory" cell is that
evaluator, not `driver-memory`.
Pinned per cell: the projection fixture (home amounts and rates as
stored); the ungrouped KPI (2010 CNY); per-currency subtotals grouped by
the code field and a `totals` grand total equal to the KPI; the column
labelled with the home currency and no per-row `currencyField` (the home
field is `dynamic`); the inferred cube's `amount_home_sum`; a
relationship path (a line cube joined to the invoice: `invoice.amount`
refused naming `invoice.amount_home` and `invoice.currency_code`,
`invoice.amount_home` served on the native strategy); `INVALID_FIELD`
and status 400 on every refusal path (dataset, inferred cube, joined
cube, draft preview). Control: the raw amount grouped by code is served
per currency and adds to a different number (270). On `main` the proof
assertions already pass, so the consolidated path is the unchanged code
path.
**The door message (text only).**
`assertRecordCurrencyAggregatesGrouped` (#27187, PR #27338) refused an
ungrouped `sum` / `avg` / `min` / `max` over a record-mode amount with
one prescription: group by the code field. It now names both:
- for one total in the home currency, point the measure at the amount's
home field, by name (`homeAmount.field`) when the host relays it, or
else as "the field its `currencyConfig.homeAmount.field` names", with
the declaration to add if it has none (true whether or not the object
declares one);
- for one row per currency, add the dimension over the code field.
Code `INVALID_FIELD`, status 400, `member` / `param` / `cube` / `field`
/ `object` are unchanged; no new refusal code. The home field reaches
the door through `sourceFieldMeta`, which now answers `homeAmountField`
beside `currencyField` (record mode only), relayed by
`AnalyticsServicePlugin` from `currencyConfig.homeAmount.field`.
**Not in this diff.** The engine's own `aggregate()` door
(`packages/objectql/src/record-currency-aggregate-door.ts`) already
names a stored home-currency amount field generically; it is outside
this card's file surface. ⛔ No `ui/**` / `plugin-dashboard` change (ui
lane off). #27193 untouched.
## Why
ADR-0144 D6: a consolidated total aggregates the stored home field. The
proof shows that needs nothing new; the message makes the refusal
prescribe it.
## Verification
- `home-amount-consolidated-measure.test.ts`: 36/36 at the current head
(30/30 at `e430075a`) with `OS_TEST_POSTGRES_URL` set (PostgreSQL 16,
local). Ablation at `e430075a`: the same file on `main`'s three source
files: 14 failed, every one a message assertion; every proof assertion
passed.
- `pnpm --filter @objectstack/service-analytics typecheck`: exit 0.
`eslint` on the changed files: exit 0.
- Package suite with `OS_TEST_POSTGRES_URL` (at `e430075a`): 5267
passed, 1 failed: `read-scope-temporal-coercion.test.ts` "the server is
not on UTC (the premise of the PostgreSQL cells)", a premise check on
the local server's zone (local PostgreSQL runs on `Etc/UTC`; CI
provisions a skewed zone). Not touched by this diff.
- `dispatch-gates --commands` (at `e430075a`): 62 commands, exit codes
captured before any pipe: 61 exit 0; `pnpm check:dual-build-cjs-loads`
exit 3, NOT MEASURED (it reads every package's `dist/`, and this
worktree built only this package's closure), left to CI.
`check-plugin-teardown-shape --self-test` first exited 3 on the shallow
clone and passed (exit 0) after fetching its pinned fixture commit.
One changeset, `@objectstack/service-analytics` patch.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(spec not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; eslint passes on every changed file
(whole-repo `pnpm lint` left to CI).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Utp6CbmDUh2Sx7fvaGgu7r
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 968d645 commit a35fc66
5 files changed
Lines changed: 487 additions & 17 deletions
File tree
- .changeset
- packages/services/service-analytics/src
- __tests__
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
0 commit comments