Skip to content

lint: a form section with a label but no name can never be translated and nothing warns — 70/70 HotCRM form sections are in that state #5417

Description

@yinlianghui

A form section authored with a label but no name is structurally
untranslatable — _sections is keyed by section name, so there is no key for a
bundle to carry. Nothing in the toolchain says so: not the schema (name is
optional), not os lint, and — after #5405 — not the coverage report either,
because a walker that emits sections[].name emits nothing for a section that
has no name. The heading silently stays in the source locale in every locale,
and coverage reads 100%.

The renderer keys off name, and correctly so

objectui resolves form section headings through the same resolver the detail
page uses, useObjectLabel().sectionLabel(objectName, section.name, authored):

  • packages/plugin-form/src/ObjectForm.tsx:165-167 (tSec, feeding all five
    form-type branches) and :966-968 (stacked section divider)
  • packages/plugin-form/src/ModalForm.tsx:588, :684
  • detail half: packages/plugin-detail/src/renderers/record-details.tsx:199

All of them guard on section.name and fall back to the authored label when it
is absent. That guard is right — the alternative (slugify the label and go
fishing for a second key) would fossilize a second de-facto contract. The defect
is that authoring a nameless section is silently accepted while being
permanently unreachable by translation.

Why #5405 and #5415 do not cover this

Both operate on sections that HAVE names:

The set relationship #5415 states ("every key the coverage walker DEMANDS must
be a key the reference validator ACCEPTS") is about keys that exist. This issue
is the third leg: a rendered heading that no key can ever address.

Measured impact (HotCRM @ 0899b4f)

Every form-view section in the app — 70 of 70, across all 14 view files —
is authored with label (+ columns/fields) and no name:

account 5/5   campaign 3/3   case 4/4      contact 3/3   contract 4/4
event 4/4     event_attendee 2/2           forecast 3/3  knowledge_article 3/3
lead 25/25    opportunity 4/4              product 3/3   quote 4/4   task 3/3
TOTAL: 70 sections, 0 named, 70 nameless

So after objectstack-ai/hotcrm#697 brought all four locales to full declared
coverage, and after #5405 lands, HotCRM's form section headings will still be
English in all four locales with zero warnings — the gap is invisible to
every gate we are currently building.

This is also the actual cause of #5408, which was filed as a renderer bug: the
crm_case detail page sections carry names (info/status/description
in src/pages/case_detail.page.ts) and translate, while its form view
sections ({ label: 'Case' }, { label: 'SLA' }, { label: 'Resolution' } in
src/views/case.view.ts) carry none — producing exactly the reported
Case / SLA / Resolution strip. The renderer half was verified correct against
objectui origin/main and is now pinned by objectstack-ai/objectui#3373.

Suggested fix shape

A diagnostic at the producer, not tolerance at the consumer. Two candidates,
not mutually exclusive:

  1. Lint rule (packages/lint, alongside validate-translation-references):
    a section that declares a label but no name, on an object that has any
    translations at all, warns — "this heading can never be translated; give the
    section a stable name". Cheap, non-breaking, and it is the rule that would
    have caught all 70.
  2. Schema (packages/spec): consider requiring name on FormSection
    outright. Stronger (declared = enforced, and it makes AI-authored metadata
    hard to get wrong), but it is a breaking authoring change and needs the
    usual migration — worth a maintainer decision rather than a drive-by.

Whichever route, the co-derivation point from #5405 holds: the set of headings
the renderer displays should equal the set of headings the toolchain can
address.

Blocked-by: #5405 (the walker's section-awareness is the natural place for the
name-set to come from; this rule reads the same anchors).

Found while verifying #5408 (whose stated renderer premise was disproven — see
objectstack-ai/objectui#3373). Related: #5415, #5164.

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions