Repository navigation
fix: the zh-CN Activity group and the forecast period fields get labels of their own; approval names measured upstream (#2060 item 13) - #2199
Merged
objectstack-fleet[bot] merged 2 commits intoOct 20, 2026
Conversation
…t labels of their own zh-CN labelled the Activity navigation group and its Events item both 活动. The item keeps 活动, crm_event's own label and the heading of the page it opens; the group becomes 互动, the word the pack already uses for the interactions it gathers. The zh-Hans meetings page quotes the sidebar path and follows. en, es-ES and ja-JP labelled crm_forecast.period_label the same as the period picklist beside it. It now reads Period Label / Etiqueta del periodo / 期間ラベル; zh-CN already kept them apart. A pin holds both pairs apart in every pack. Approval flow and step names are not translated here: the platform's translation contract reaches neither on any approval surface. Claude-Session: https://claude.ai/code/session_01KqkTQNLcxVc588eZpJmp1r Co-authored-by: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
Author
席位核对ACCEPT (#2060 item 13) · PR #2199 at
Landing: once every check on the head is green, this seat flips the PR ready and arms auto-merge, bringing |
This was referenced Oct 20, 2026
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.
Part of #2060 (item 13)
Clause-②: no
Item 13 of the list card (locales), under claim
6289299906, starting frommain39dee2beon@objectstack/*18.0.0-next.5. #2060 remains open. This PR delivers two of item 13's three rows: C-16 (the zh-CN Activity group) and the forecast fold from6287935636(two fields labelled "Period"). The third row, C-15 (approval names), cannot be delivered in this app. The platform's translation contract reaches neither name on any approval surface, so that half goes upstream. Nothing for C-15 is written here: no pack key, and no localized label in a flow source.The approval flows this app ships
These are all the flows under
src/that carry anapprovalnode (grep "type: 'approval'"oversrc/). Every one is registered inappFlows.name)account_approvalaccount_review: Account Reviewlead_conversion_approvalconversion_review: Lead Conversion Reviewopportunity_approvalmanager_review: Sales Manager Review ·director_signoff: Sales Director Sign-offopportunity_approval_on_createopportunity_qualification_approvalqualification_review: Qualification Reviewopportunity_status_change_approvalstatus_review: Status Change ReviewC-15: the translation contract reaches neither name
The contract (
TranslationItemSchema.flows,@objectstack/spec/system) has a key for a flow'slabel. For a node, it hasscreens.NODE(screen nodes only) andrefusals.NODE(refusedendnodes only). No key names an approval node. Two probes, each held on disk withablation-replace.mjs --holdand restored afterwards (blob equals HEAD,git diff HEADempty):flows.account_approval.labelandflows.opportunity_approval_on_create.label(marker text)pnpm buildexits 0, and the servedGET /api/v1/i18n/translations/zh-CNcarries both keys. Two requests opened after that storeprocess_label"Account Approval" and "Large Deal Approval (on create)".GET /api/v1/approvals/requestswithAccept-Language: zh-CNanswers those English labels. The zh-CN inbox and the record's approval panel show them too. The marker text appears 0 times on any of these surfaces.flows.opportunity_approval.screens.manager_review.titlepnpm validateexits 1 withtranslation-target-unknown: "Translations are keyed to screen "manager_review", which flow "opportunity_approval" declares as aapprovalnode, not ascreen, so nothing resolves these keys."Why, read in the pinned packages.
@objectstack/plugin-approvalswritesprocess_labelandcurrent_step_labelwhen a request opens. Each is a copy of the authoredFlow.labelandnode.label("engine-written snapshots … a list reads them as stored and never re-derives a label from flow metadata"). The approval history'sstep_labelis copied the same way. The console inbox drawsprocess_label, falling back to the humanizedprocess_name, andstep_label, falling back to the humanizedcurrent_step. Neither consults the bundle.@objectstack/cli's i18n extractor asks forflows.FLOW.labelonly on a flow with a screen node. In its own words: "A flow that can never pause there (record-triggered, scheduled, an API flow with no screen) has no surface that shows its translated label".Surfaces measured in headless Chromium at 1440×900 as the dev admin, on two requests opened through REST (
crm_accountinsert and a 150,000crm_opportunityinsert). The table holds the same reading before and after this PR, in zh-CN, ja-JP and es-ES:/component/approvals/inbox)So the app's half of C-15 is empty until the platform carries a reader, plus a key for the step. The report asks the seat to file the upstream card. When it lands,
os lint'si18n/missing-flowis the platform's signal for which keys the packs owe. The extractor states that its predicate "widens in the same change as that reader". Not done here, on purpose: pre-writingflows.FLOW.labelfor the six flows now. Those keys parse and are served, but nothing reads them. A key that is declared and not honoured is the pattern the rulings refuse.C-16: the zh-CN Activity group gets its own word
Why 互动. In every pack, the item's label is
crm_event's plural label, which is also the heading of the page it opens. In zh-CN, that word is 活动 (the object, its views 全部活动 / 活动日历, its sections and fields). So the item keeps 活动 and the group changes. The other packs name the group by the activity it gathers. zh-CN already has a word for that: 互动 iscrm_event's own description ("与客户的会议、通话及其他已安排的互动"), the 互动历史 view, and the Sales Activity tiles (每周互动数, 已记录互动, 商机上的互动). The reason sits beside the key inzh-CN/app.ts.The docs:
content/docs/sales/meetings-and-calls.zh-Hans.mdxcited the sidebar path as 活动 › 活动 and now cites 互动 › 活动. The en and zh-Hant pages cite Activity › Events (zh-Hant keeps English per the repo rule) and are unchanged. No other page undercontent/docs/quotes the zh-CN group (uncapped grep, all three locales).The forecast fold: the two period fields read apart
New Forecast form, field labels in order (
Owner,Period,Period Start,Period End, then the free-text field):periodperiod_labelbeforeperiod_labelafterThe
period_endhelp texts name the picklist ("Period", "Periodo", 「期間」), which keeps its label, so they still read right.Tests
test/locale-label-collisions.test.ts(new, 14 cases). In every shipped pack, the Activity group shares its label with none of its items, and the Events item reads ascrm_event's plural label. The forecast form'speriodandperiod_labeldiffer in every pack, and en reads both as declared. Only these pairs are asserted; a general "no two labels collide" rule would be a lint, and lint is the platform's.group_activityset back to 活动 (ablation-replace.mjs: anchor 1 → 0, blobcbc232d3→25591599). Result:zh-CN: the Activity group shares its label with none of its itemsfailed with "the group and these items both read "活动": expected [ 'nav_event' ] to deeply equal []". 1 failed, 37 passed. Restored (blob equals HEAD). Observed direction: I predicteddocs-setup-navigation-names.test.tswould also turn red, because the zh-Hans page then cites a group that no pack ships. It stayed green: that guard's group matcher is generated from the shipped labels, so a renamed group drops out of its sight (see Acceptance notes). The new pin is the only thing holding C-16.period_labelset back to "Period" (blob9df36971→adabbad8). Two cases failed: "expected 'Period' not to be 'Period'" and "expected 'Period' to be 'Period Label'". 2 failed, 12 passed. Restored (blob equals HEAD).pnpm verifyon992ac772, heavy steps through the verify lock.validate0 ("✓ Validation passed").typecheck0.lint0.lint:i18n-gate0 ("0i18n/missing-*issues").hygiene0.hygiene:tokens0.build0.vitest run --shard=k/3 --maxWorkers=2: shard 1 is 69 files and 1135 tests passed; shard 2 is 68 files and 1278 passed, 1 skipped; shard 3 is 68 files and 1619 passed. That is all 205 test files.pnpm changeset status --since=origin/main: hotcrm patch.content/docsline), Link Check, E2E, CodeQL.Acceptance notes
test/docs-setup-navigation-names.test.ts, rule 3, cannot see a citation whose group was renamed, because its matcher is built from shipped group labels. Ablation 1 measured it: a zh-Hans page citing 活动 › 活动 after the group became 互动 stays green. This is an observation about this repo's guard. It is not filed.content/docs/sales/forecasting.mdx:16lists the record's sections as Period / Numbers / Derived / Source / Narrative. The form's sections are Snapshot / Amounts / Source (forecast.object.tsfieldGroups). This is item 16's family (docs that describe the app as it was) and is left to that item.Generated by Claude Code