You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ui: record-mode currency — resolveFieldCurrency reads the sibling code field's value; form pre-fills the organization currency; grid / drawer / dashboard / footer per-row display; Studio field editor (multi-currency M0-4, epic #8345) #27188
Filing gate ③ (maintainer-directed). Ruling 6465431966 on #27119 (batch #421 item 2, Q1 = 乙-现在, maintainer 「同意立专题卡」 2026-10-28): the multi-currency epic resumes on #8345 in shape C′. Part of #8345. Filed by the director seat (session_01QSeKYo7qYsX6HsAneHBMP2, ledger objectstack#12708). ⛔ Not a claim. Workload row and precedents: 6464936321; design: 6464438764.
Ruling-ref: 6465431966
维护者速读
改了什么: 前端按每行自己的币种显示 record 模式金额:resolveFieldCurrency 读兄弟字段的值;表单里币种码下拉(ISO 4217 值域驱动,分「本组织可用」与「全部」两组)预填组织默认币种;金额框符号与小数位跟着币种走;页脚合计只对分组或影子列显示;Studio 字段编辑器加 record 模式与字段选择。
Resolver: record mode → the code field's value on the record in scope; no value ⇒ no symbol (never the tenant default for a record-mode field).
Form: the code field renders as a searchable select grouped "available" (home + rated + used) / "all ISO 4217"; pre-filled with localization.currency; the stored value is always explicit.
Amount inputs: symbol prefix and minor-unit decimals follow the selected code (CURRENCY_FRACTION_DIGITS reader).
Grid footer: sum only when grouped by code or over the home field; filters on a record-mode amount add the code condition.
Studio: record mode + currencyField picker listing only ISO-domain text fields, with a "create currency field" shortcut that writes explicit metadata.
Epic: #8345 (parent; the epic PM dispatches pm:epic children; domain:spec children go to the spec seat's queue). Dedupe: #8345 thread, #27119 (ruled), the workload list 6464936321; no open card carries this slice.
Claim: PM loop round 1 · 2026-10-28T13:59Z
Session: session_01Utp6CbTZrFqRYNgjSaSbN5 (epic PM, epic:#8345)
Account: os-bill
Branch: claude/project-thread-irhbgx (card thread session_01Utp6CXtadYa5QXb2PbXPev; the platform assigns the thread's one push branch — the recorded platform exception)
Worktree: objectstack-issue-27188
Domain: domain:ui
Seat: epic:#8345
File surface: ui/packages/{i18n,fields,plugin-dashboard,app-shell} and the Studio field editor, their tests, .changeset/ (stop on breach; explain in the report)
Container & model: M–L, mode:thread, model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds
Serial constraints cleared: no — builds on #27184's draft PR #27268 (branch claude/project-thread-0wmk7j) by maintainer-authorised acceleration; pm:blocked → pm:dispatched in this stroke, Blocked-by: lines stay as merge order; the PR stays draft and merges after #27268.
Release pairing: R1 — ⛔ not released alone, pairs with #27184, #27186, #27187.
Maintainer authority: Bill, project thread, 2026-10-28 「epic的卡你统一派」, 「并发可以5」, 「你自主完成后续阶段」, 「后续开发如何加速」 (audit 6467659191 on #8345).
{
"issue": 27188,
"status": "rework",
"branch": "claude/project-thread-irhbgx",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27340",
"session": "session_01Utp6CXtadYa5QXb2PbXPev",
"premise_still_valid": true,
"summary": "Record-mode currency on the UI side (ADR-0144 D2/D6/D8.4), built on #27268 at 5232c8b1. resolveFieldCurrency takes the record; record mode reads only the sibling code field, blank means no symbol, never the tenant default. Cells, CurrencyField (symbol/decimals/step), form renderer hand-off, mobile card, detail summary chips, dashboard table+drawer, Gantt tooltips pass the record. An iso_4217_currency text field renders a grouped searchable ISO 4217 select; create forms seed the pointed-at code field with localization.currency. Grid footer drops money aggregates over record mode; group headers keep them only when grouped by the code field. Studio inspector gains a currency section with record mode, a currencyField picker over ISO-domain text fields and a Create-currency-field shortcut. rework, not done: two card bullets left open (see open_questions): the 'used' half of the available group is only the record's own code, and the filter-builder code condition is not built.",
"tests": "head d59c3cbe: cd ui && pnpm exec vitest run (6 new + 9 neighbouring files) -> Test Files 15 passed (15), Tests 173 passed (173), lock VERDICT command-exit 0. type-check exit 0 for @object-ui/i18n, fields, components, plugin-form, plugin-grid, plugin-dashboard, plugin-detail, plugin-gantt, app-shell (after building their dependency closure). Ablation: ablation-replace on ui/packages/i18n/src/currency.ts record branch (anchor 1->0, blob fcefef92->6386e6f9) -> 7 failed / 6 passed across the i18n record-mode suite and the fields faces suite; restored blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands derived 116 families (the branch carries #27268's spec/skills/docs commits). Ran locally, each exit 0: the 19 families matched by this card's paths (check-adr-0087-registration x2, check-changeset-no-major, check-empty-changeset x2, check-sdui-manifest x2, release-rehearsal-clone --self-test, release-pending-publish --self-test, spec check:duration-unit-keys, check:changeset-gate-self-tests, check:closed-ceremony-text, check:dispatcher-error-vocabulary, check:pm-changeset-deadline-census, check:published-files, check:skill-identifier-liveness, check:test-source-alias, check:tier-file-adoption, check:undeclared-dep-imports) plus check:nul-bytes, check:cross-package-test-inputs, check:doc-authoring, check:issue-citations, check:type-check-coverage, check:keyed-text-bounds, check:role-word. --ran: 90 of 116 unrun locally, a declared narrowing (mostly #27268's families); CI runs the farm. PR check-runs: in_progress at report time. pnpm lint not run locally (CI's).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-② is no without an arm",
"mcp_calls": "4 — mcp__github__issue_read x4 (get, get_comments x3), no write tools",
"api_writes": "2 — fleet-write relay pr_create (objectstack#27340, assignee os-bill), post-stamped os-dev-report comment on #27188",
"open_questions": [
{
"question": "The card's 'available' group is home + rated + used. 'Used' (codes stored on the object's other records) needs a distinct query by object, and the field widget contract carries no object name. How should the select learn the used codes?",
"options": [
"A: the form host (ObjectForm/sectionFields) queries the distinct codes once per object and hands them to the code field through the field metadata it already passes (no widget-contract key); about 1 day, one more query per create form",
"B: add an objectName (or usedCurrencies) prop to the widget contract, produced by the form renderer; a contract change across every host",
"C: leave available = home + the record's own code until R2's rate table lands, and let 'rated' carry the enabled set"
],
"recommendation": "A, because it keeps the widget contract unchanged and the query lives where the object is already known; it can land as a follow-up before the R1 release."
},
{
"question": "'Filters on a record-mode amount add the code condition': which code does the added condition take?",
"options": [
"A: the filter row for a record-mode amount gains a required currency picker (defaulting to the organization currency) and the builder emits amount op X AND code = C",
"B: always the organization currency, no picker",
"C: no automatic condition; the builder warns that the comparison spans currencies"
],
"recommendation": "A, because B silently hides other-currency rows and C leaves a cross-currency comparison in place; it is a product call, so not built here."
}
],
"out_of_scope_findings": [
"none"
]
}
Activity
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 1 · 2026-10-28T13:59Z
Session:
session_01Utp6CbTZrFqRYNgjSaSbN5(epic PM,epic:#8345)Account:
os-billBranch:
claude/project-thread-irhbgx(card threadsession_01Utp6CXtadYa5QXb2PbXPev; the platform assigns the thread's one push branch — the recorded platform exception)Worktree:
objectstack-issue-27188Domain:
domain:uiSeat:
epic:#8345File surface:
ui/packages/{i18n,fields,plugin-dashboard,app-shell}and the Studio field editor, their tests,.changeset/(stop on breach; explain in the report)Container & model:
M–L,mode:thread,model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds
Serial constraints cleared: no — builds on #27184's draft PR #27268 (branch
claude/project-thread-0wmk7j) by maintainer-authorised acceleration;pm:blocked→pm:dispatchedin this stroke,Blocked-by:lines stay as merge order; the PR stays draft and merges after #27268.Release pairing: R1 — ⛔ not released alone, pairs with #27184, #27186, #27187.
Maintainer authority: Bill, project thread, 2026-10-28 「epic的卡你统一派」, 「并发可以5」, 「你自主完成后续阶段」, 「后续开发如何加速」 (audit 6467659191 on #8345).
objectstack-fleet commentedon Oct 28, 2026
epic:#8345#1 · os-bill · session_01Utp6CXtadYa5QXb2PbXPev
os-dev-report
{ "issue": 27188, "status": "rework", "branch": "claude/project-thread-irhbgx", "pr": "https://github.com/objectstack-ai/objectstack/pull/27340", "session": "session_01Utp6CXtadYa5QXb2PbXPev", "premise_still_valid": true, "summary": "Record-mode currency on the UI side (ADR-0144 D2/D6/D8.4), built on #27268 at 5232c8b1. resolveFieldCurrency takes the record; record mode reads only the sibling code field, blank means no symbol, never the tenant default. Cells, CurrencyField (symbol/decimals/step), form renderer hand-off, mobile card, detail summary chips, dashboard table+drawer, Gantt tooltips pass the record. An iso_4217_currency text field renders a grouped searchable ISO 4217 select; create forms seed the pointed-at code field with localization.currency. Grid footer drops money aggregates over record mode; group headers keep them only when grouped by the code field. Studio inspector gains a currency section with record mode, a currencyField picker over ISO-domain text fields and a Create-currency-field shortcut. rework, not done: two card bullets left open (see open_questions): the 'used' half of the available group is only the record's own code, and the filter-builder code condition is not built.", "tests": "head d59c3cbe: cd ui && pnpm exec vitest run (6 new + 9 neighbouring files) -> Test Files 15 passed (15), Tests 173 passed (173), lock VERDICT command-exit 0. type-check exit 0 for @object-ui/i18n, fields, components, plugin-form, plugin-grid, plugin-dashboard, plugin-detail, plugin-gantt, app-shell (after building their dependency closure). Ablation: ablation-replace on ui/packages/i18n/src/currency.ts record branch (anchor 1->0, blob fcefef92->6386e6f9) -> 7 failed / 6 passed across the i18n record-mode suite and the fields faces suite; restored blob == HEAD, git diff HEAD empty.", "gates": "dispatch-gates --commands derived 116 families (the branch carries #27268's spec/skills/docs commits). Ran locally, each exit 0: the 19 families matched by this card's paths (check-adr-0087-registration x2, check-changeset-no-major, check-empty-changeset x2, check-sdui-manifest x2, release-rehearsal-clone --self-test, release-pending-publish --self-test, spec check:duration-unit-keys, check:changeset-gate-self-tests, check:closed-ceremony-text, check:dispatcher-error-vocabulary, check:pm-changeset-deadline-census, check:published-files, check:skill-identifier-liveness, check:test-source-alias, check:tier-file-adoption, check:undeclared-dep-imports) plus check:nul-bytes, check:cross-package-test-inputs, check:doc-authoring, check:issue-citations, check:type-check-coverage, check:keyed-text-bounds, check:role-word. --ran: 90 of 116 unrun locally, a declared narrowing (mostly #27268's families); CI runs the farm. PR check-runs: in_progress at report time. pnpm lint not run locally (CI's).", "dogfood_battery": "n/a — no ! in the PR title and Clause-② is no without an arm", "mcp_calls": "4 — mcp__github__issue_read x4 (get, get_comments x3), no write tools", "api_writes": "2 — fleet-write relay pr_create (objectstack#27340, assignee os-bill), post-stamped os-dev-report comment on #27188", "open_questions": [ { "question": "The card's 'available' group is home + rated + used. 'Used' (codes stored on the object's other records) needs a distinct query by object, and the field widget contract carries no object name. How should the select learn the used codes?", "options": [ "A: the form host (ObjectForm/sectionFields) queries the distinct codes once per object and hands them to the code field through the field metadata it already passes (no widget-contract key); about 1 day, one more query per create form", "B: add an objectName (or usedCurrencies) prop to the widget contract, produced by the form renderer; a contract change across every host", "C: leave available = home + the record's own code until R2's rate table lands, and let 'rated' carry the enabled set" ], "recommendation": "A, because it keeps the widget contract unchanged and the query lives where the object is already known; it can land as a follow-up before the R1 release." }, { "question": "'Filters on a record-mode amount add the code condition': which code does the added condition take?", "options": [ "A: the filter row for a record-mode amount gains a required currency picker (defaulting to the organization currency) and the builder emits amount op X AND code = C", "B: always the organization currency, no picker", "C: no automatic condition; the builder warns that the comparison spans currencies" ], "recommendation": "A, because B silently hides other-currency rows and C leaves a cross-currency comparison in place; it is a product call, so not built here." } ], "out_of_scope_findings": [ "none" ] }fix(components): keep removeCondition's pinned match site (#27188)
test(census): ledger valueDomain and the used-codes `field` read (#27188
test(app-shell): a fixed-to-record switch writes no defaultCurrency (#…
feat(ui): dataset cells format a record-mode amount in its row's curr…
feat(plugin-report): the report table formats a record-mode amount in…
chore(spec): regenerate the authorable surface on the merged tree (#2…
docs(core): keep formatDimensionValue's docblock on its function (#27188