Skip to content

GET /meta/email_template can collapse an i18n bundle back to one row — the list merge dedups by (package, name), no locale #7774

Description

@os-zhuang

What

MetadataProtocol's unscoped metadata list merges the registry's items with the
MetadataService's items under metaItemKey(packageId, name)
(packages/metadata-protocol/src/protocol.ts:988, used at :4363 and :4377).
That key is (package, name) with no discriminator, so two rows of the same
email template in different locales — an i18n bundle, per
EmailTemplateDefinitionSchema — map to ONE map entry and the second
itemMap.set(...) in the first loop overwrites the first. The list serves one
locale of the bundle.

Why it is filed now

Found while fixing #7730. Until that fix, SchemaRegistry itself held only one
locale per name, so this collapse was masked — there was never a second row to
drop. With the registry keeping the bundle (<packageId>:<name>@<locale>),
listItems('email_template') returns both members and this merge is the next
place they can be lost.

Not a regression from #7730 and not on that issue's reported path: the
sys_email_template materializer (bootstrapDeclaredEmailTemplates) reads
registry.listItems directly and never goes through this merge, so the reported
symptom is fixed. What is affected is GET /meta/email_template (Studio's
metadata list), and only when a metadata service is installed and returns a
non-empty list for the type — the merge block is skipped otherwise.

Why it was not fixed in the same PR

The discriminator table lives in @objectstack/objectql
(ITEM_KEY_DISCRIMINATORS, packages/objectql/src/registry.ts), and
@objectstack/metadata-protocol does not depend on @objectstack/objectql
so sharing it needs a home decision (@objectstack/metadata-core is a
dependency of both and is the obvious candidate) rather than a new package
dependency added in passing. #7730's claimed file surface was
packages/objectql/src/registry.ts + tests + changeset.

Suggested shape

Move (or re-export) the per-type discriminator table into a package both sides
depend on, and give metaItemKey the discriminator when the type declares one —
(package, name, locale) for email_template, unchanged for every other type.
The sys_metadata overlay merge at :4207 needs no change: overlay rows are
unique on type+name+org and carry no locale.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions