Skip to content

showcase: eight authored validation messages on showcase_account / showcase_task are not on the translation channel, so they refuse in English on a zh-CN session #14518

Closed

Description

@hotlong

What

showcase_account and showcase_task declare seven and one author-written
validations[].message respectively, and none of them is on the #14253 translation
channel. On a zh-CN session those refusals arrive in English while the platform's own
built-in refusals (which have shipped zh-CN since #3957) arrive in Chinese — two
languages inside one error envelope.

This is the same defect #14311 fixed for showcase_project. That card's scope was the
New Project wizard, so only showcase_project's four rules were put on the channel
(PR #14517). The remaining eight were found while doing it and are recorded here rather
than widened into that PR.

Where

Untranslated authored rule messages, none of which has a
objects.OBJECT._validations.RULE.message entry in
examples/app-showcase/src/system/translations/index.ts:

  • examples/app-showcase/src/data/objects/account.object.ts — account_lifecycle,
    tax_id_format, billing_email_format, support_config_shape,
    churn_reason_consistency and its two nested conditional branches
    (churn_reason_present, churn_reason_absent).
  • examples/app-showcase/src/data/objects/task.object.ts — task_status_flow.

examples/app-crm has no _validations block at all, so every authored message in that
app is in the same position; whether the CRM demo is meant to be localised at all is a
separate question and is not assumed here.

Note that a nested conditional branch carries its own name and is addressed by that
name — the wrapping rule's message never reaches a user — so the two churn_reason_*
branches each need their own entry.

Why it is worth doing

The showcase is the app people read to learn what a correct ObjectStack app looks like.
An authored message with no bundle entry is the one way a refusal escapes the caller's
language, and the channel to fix it already exists and is already demonstrated on
showcase_project.

Suggested shape

Mirror what PR #14517 did for showcase_project: add en + zh-CN _validations
entries for each rule, and extend the pin in
examples/app-showcase/test/new-project-wizard-initial-status.test.ts (which today
asserts the invariant for showcase_project's whole rule set) to cover these objects
too — or lift it into a bundle-wide check so a newly declared rule without a translation
fails rather than rots.

Found while implementing #14311.

Generated by Claude Code

Activity

  1. added
    documentationImprovements or additions to documentation
    pm:queueReady for the PM dispatch loop
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    on Sep 2, 2026
  2. huangyiirene commented on Sep 2, 2026

    @huangyiirene
    Collaborator

    Triage — graded. Confirmed at origin/main 4a37870, with one correction to the count.

    Confirmed

    All eight rule names are where you say they are:

    • examples/app-showcase/src/data/objects/account.object.ts — :121 account_lifecycle, :138 tax_id_format, :150 billing_email_format, :162 support_config_shape, :184 churn_reason_consistency with :191 churn_reason_present and :199 churn_reason_absent.
    • examples/app-showcase/src/data/objects/task.object.ts:102 — task_status_flow.

    The channel is real and the control fires: packages/spec/src/system/i18n-resolver.ts:1863 returns `objects.${objectName}._validations.${ruleName}.message` (#14253), read by packages/objectql/src/validation/rule-validator.ts:396,2168.

    Correction — the population today is twelve, not eight

    git grep -rn "_validations" origin/main -- examples/app-showcase/ returns zero matches. Nothing in the showcase is on that channel yet.

    PR #14517 has not landed — it is open, draft, head 120d1d066, base a40c0f966. So showcase_project's four rules (end_after_start, spent_within_budget, project_status_flow, project_health_progression) are in the same position on main today as the eight you listed.

    That does not weaken the card — your eight are genuinely additional, and filing them separately rather than widening #14517 was right. But it changes two things for whoever picks this up:

    Scope ruled

    Add en + zh-CN _validations entries for every authored rule message on showcase_account and showcase_task, including a separate entry for each nested conditional branch — your note that a branch carries its own name and is addressed by it, while the wrapping rule's message never reaches a user, is the detail most likely to be missed, and it is correct.

    Prefer your second option for the pin: a bundle-wide check rather than extending the per-object one. There is already a lint rule in this area (packages/lint/src/validate-translation-references.ts) — establish whether it can carry "an authored validations[].message with no bundle entry" before writing a bespoke test. A per-object pin extended twice is on its way to being extended a third time, and this card exists because the first extension stopped at one object.

    Out of scope, as you framed it: examples/app-crm. You are right not to assume the CRM demo is meant to be localised at all — that is a separate question and it should not be answered by a translation PR. If someone wants it, separate card.

    Routing

    domain:engine — examples/* anchors to the subsystem it exercises (lane table), and the subsystem here is validation-rule message resolution (rule-validator.ts + the spec's i18n resolver). i18n, documentation.

    priority:p3: example-app content, no customer-facing runtime defect, and the channel already exists so nothing is blocked. It is a real card rather than nothing because the showcase is what people read to learn a correct app, and a mixed-language error envelope teaches the wrong thing — your argument, and it holds. pm:queue.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationdomain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they landi18npriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions