Skip to content

[spec] 13 of 49 declared field types have no Field.* builder, so authors silently drop to the literal { type: … } form #8656

Description

@qq9340100

Restart-when: any PR edits the Field builder object in packages/spec/src/data/field.zod.ts (add Field.time as the minimal declared rider — three packages/spec comments already name it as existing)

Observation recorded while implementing #6533 (adding a time field to showcase_invoice_line). Filed unassigned, not fixed — out of that card's scope.

What was measured

packages/spec/src/data/field.zod.ts declares 49 members in FieldType, and the Field convenience object next to it exposes 36 builders. Cross-referencing the two (allowing masterDetail for master_detail), 13 declared field types have no Field.* builder:

audio  checkboxes  composite  multiselect  progress  radio  record
repeater  tags  time  toggle  tree  video

An author reaching for one of these has to write the literal object instead — which is exactly what the showcase already does:

// examples/app-showcase/src/data/objects/field-zoo.object.ts
f_date: Field.date({ label: 'Date' }),
f_datetime: Field.datetime({ label: 'Date / Time' }),
f_time: { type: 'time', label: 'Time' },     // no Field.time

Why it is worth recording rather than shrugging at

The literal form is fully valid — the contract is FieldType plus the field schema, not the Field helper — so nothing is broken and no runtime behaviour differs. The cost is authoring-surface asymmetry:

  • the three temporal types split two-and-one (Field.date, Field.datetime, but a literal for time), which reads as an oversight at the call site rather than a decision;
  • the builders give parameter typing and discoverability that the literal form does not, so the 13 types are the ones an AI author is most likely to get wrong — the direction AGENTS.md's "make AI-written metadata hard to get wrong" argues against.

Whether the right answer is "add the missing builders", "document the literal form as the intended shape for these types", or "leave it, the helper is deliberately partial" is a judgement call, which is why this is a finding and not a fix.

Not claimed

No claim that any of the 13 is unsupported: time in particular is fully live end-to-end — validated by field-value.zod.ts as HH:mm[:ss], stored, and rendered by the inline grid's time control, all exercised on a real machine in #6533.

Anchors (verified on origin/main @ 189a7322)

  • packages/spec/src/data/field.zod.tsFieldType enum, and the Field builder object below it
  • examples/app-showcase/src/data/objects/field-zoo.object.ts — the literal-form precedent

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions