Skip to content

Commit a666e94

Browse files
docs(data-modeling): stop crediting field format with validation (#19847)
Fixes #19764 Clause-②: no Two hand-written data-modeling pages credited a field's `format` key with validation. The write-time record validator keys its email / url / phone shape checks on the field `type` and reads a field's `format` zero times; three rows also declared a `format` default that does not exist. Every rewritten row now names only behaviour a reader delivers. Refs read: objectstack `245e161a` (base `71ef2219`), objectui pin `87af769e9a3e` (the `.objectui-sha` on `main` when this was worked). ## Rows: old text, new text, the reader that makes the new text true | # | Row | Old | New | Reader | |---|---|---|---|---| | 1 | `field-types.mdx` `### text`, `format` | "Validation format pattern" | Display hint, not validation; the server runs no check from it. Lists the word set the UI resolver maps (`phone`/`tel`/`telephone`, `email`, `url`/`uri`/`link`, `currency`/`money`, `percent`/`percentage`); any other word renders as plain text; to reject malformed values use the field `type` or a `format` validation rule | objectui `packages/fields/src/index.tsx:2915` `FORMAT_TO_RENDERER`, `:2929` `TEXTUAL_BASE_TYPES`, `:2943-2944` promotion; pinned by `packages/plugin-grid/src/__tests__/formatHintedColumnRenderer-8920.test.tsx:135`. No-server-check: `packages/objectql/src/validation/record-validator.ts` reads `def.format` 0 times. Spec agreement: `packages/spec/src/data/field.zod.ts:1090` describe | | 2 | `field-types.mdx` `### phone`, `format` | "Phone format pattern" | Row removed | No reader: the resolver promotes only textual base types (`:2943`), and objectui `packages/fields/src/widgets/PhoneField.tsx` mentions `format` 0 times; record-validator `:752` checks `t === 'phone'` with a fixed `PHONE_RE` (`:108`) | | 3 | `validation-rules.mdx` `### text`, `format` | "Validates against format pattern (e.g., regex)" | **Not validated**; a regex here is accepted and ignored; on `text` it is a display hint (links to the gallery); to constrain shape use the `email`/`url`/`phone` type or a `format` validation rule | Same as row 1; the real regex enforcer is the `format` validation rule, `packages/objectql/src/validation/rule-validator.ts:2765` `checkFormat`, documented at `content/docs/data-modeling/validation.mdx:146` | | 4 | `validation-rules.mdx` `### email`, `format` default `email` | "Validates a basic `local@domain` shape" | Row replaced by `maxLength` / `minLength`; the Default constraints line adds that the check keys on `type: 'email'` and a field-level `format` is not read | record-validator `:746` (`t === 'email'`), `:91` `EMAIL_RE`; bounds `:693` `BOUNDED_STRING_FIELD_TYPES` branch, `:696` / `:699`; `email` is in that set (`field.zod.ts:136`) | | 5 | `validation-rules.mdx` `### url`, `format` default `url` | "Validates URL format (protocol required)" | Same shape as row 4, keyed on `type: 'url'` | record-validator `:749`, `:107` `URL_RE`; bounds as row 4 | | 6 | `validation-rules.mdx` `### phone`, `format` default `phone` | "Validates a permissive phone-number character set" | Same shape as row 4, keyed on `type: 'phone'`, plus a pointer to a `format` validation rule with a `regex` for a stricter shape | record-validator `:752`, `:108` `PHONE_RE`; bounds as row 4; `checkFormat` as row 3 | | 7 (beyond the six) | `validation-rules.mdx` Quick Validation Summary, `text` Key Constraints | "`maxLength`, `minLength`, `format`, `valueDomain`" | "`maxLength`, `minLength`, `valueDomain` (`format` is a display hint, not a constraint)" | As rows 1 and 3 | Six was a floor. Instrument for the census: `git grep -nE` for a backticked `format`, for `format: 'email|url|phone|tel'`, and for `Field.text({ ... format` over `content/docs/**` minus `references/` and `releases/` (14 files hit). Control: backticked `maxLength` hits 14 times in `validation-rules.mdx`. Rows in the two pages: the six plus row 7 above. Autonumber: neither page documents the `format` reading on `autonumber` (both document `autonumberFormat`), so that meaning is untouched and nothing here contradicts `field.zod.ts:1091`. The spec wins where they meet. These rows now agree with the landed `format` describe (`field.zod.ts:1090-1094`): no vocabulary, no server check off `autonumber`, a display hint the UI owns, and constrain values through `type` or a `format` validation rule. ## Changeset Docs-only. `content/docs/**` ships in no package's `files[]`, so this is `skip-changeset` territory. Per the dispatch, no label write from this seat. ## Verification (at `245e161a`) `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` derived 40 commands for this diff. All 40 exit 0. Four first exited 3 with PREREQUISITE NOT MET, which is not a measurement: `check:doc-formula-expressions`, `check:doc-security-posture`, `check:skill-examples` and `check:docs-transcript-drift`. After building `@objectstack/spec`, the `@objectstack/lint` closure, `@objectstack/formula` and `@objectstack/client-react`, they exited 0 when re-run. `--ran` reconciliation: "40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3)". It includes `check:doc-anchors` (0) and `check:nul-bytes` (0). NOT MEASURED locally: the CI-only lanes the tool lists outside the 40, including Build Docs and the type-check lanes. ## Acceptance notes - `content/docs/api/error-catalog.mdx:201` (`INVALID_FORMAT` Fix line) says to match "the field's `format` constraint". That is the same false claim on another page. Out of this card's file surface, so it is not edited here. Class (b); dedupe words: `INVALID_FORMAT`, `error-catalog`, `field format constraint`. - `content/docs/ui/forms.mdx:229` lists `format` among "object schema validators". It is ambiguous: it may name the `format` validation rule, which is real. Noted only. - `textarea` is in the resolver's `TEXTUAL_BASE_TYPES`, but its tables list no `format` row. No false claim, so nothing was added. --- _Generated by [Claude Code](https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 67ebc84 commit a666e94

2 files changed

Lines changed: 12 additions & 10 deletions

File tree

‎content/docs/data-modeling/field-types.mdx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Single-line plain text input.
2121
|:---|:---|:---|:---|
2222
| `maxLength` | `number` | — | Maximum character length |
2323
| `minLength` | `number` | — | Minimum character length |
24-
| `format` | `string` | — | Validation format pattern |
24+
| `format` | `string` | — | Display hint, **not validation** — the server runs no check from it. The UI's cell-renderer resolver reads a small set of words and renders the cell as the richer type: `phone` / `tel` / `telephone` (a `tel:` link), `email` (a `mailto:` link), `url` / `uri` / `link` (a clickable link), `currency` / `money`, `percent` / `percentage`; any other word renders as plain text. To reject a malformed email, URL or phone number, use that field `type` instead, or a [`format` validation rule](/docs/data-modeling/validation#format-validation) |
2525
| `valueDomain` | `'iana_time_zone' \| 'iso_4217_currency' \| 'iso_3166_alpha2'` | — | Standard the written value must be a member of (IANA time zone, ISO 4217 currency code, ISO 3166-1 alpha-2 country code); `text` only |
2626

2727
```typescript
@@ -68,7 +68,6 @@ Phone number field.
6868
| Property | Type | Default | Description |
6969
|:---|:---|:---|:---|
7070
| `maxLength` | `number` | — | Maximum character length |
71-
| `format` | `string` | — | Phone format pattern |
7271

7372
```typescript
7473
{ name: 'phone', label: 'Phone', type: 'phone' }

‎content/docs/data-modeling/validation-rules.mdx‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ These properties apply to **all** field types and are validated by the base `Fie
4343
|:---|:---|:---|:---|
4444
| `maxLength` | `number` | — | Rejects values exceeding character count |
4545
| `minLength` | `number` | — | Rejects values below character count |
46-
| `format` | `string` | — | Validates against format pattern (e.g., regex) |
46+
| `format` | `string` | — | **Not validated.** No write-time check reads it — a regex here is accepted and ignored. On `text` it is a display hint only (a small set of words such as `phone`, `email` or `url` promote the cell to a richer renderer; see the [Field Type Gallery](/docs/data-modeling/field-types)). To constrain the value's shape, use the `email` / `url` / `phone` field type or a [`format` validation rule](/docs/data-modeling/validation#format-validation) |
4747
| `valueDomain` | `'iana_time_zone' \| 'iso_4217_currency' \| 'iso_3166_alpha2'` | — | Constrains the written value to a published standard — an IANA time zone (judged by the `Intl.DateTimeFormat` probe, so `UTC` and `Asia/Kolkata` are members and `Europe/Munich` is not), an ISO 4217 currency code or an ISO 3166-1 alpha-2 country code (both exact uppercase). Membership, not shape: a pattern such as `^[A-Z]{2}$` admits `ZZ`; the domain does not. The same closed vocabulary and the same membership test as a settings specifier's `valueDomain`; a non-member is refused on the write path with the field error code `value_domain`. `text` only — declaring it on any other type is refused at parse. |
4848

4949
**Default constraints:** None. Unbounded text unless `maxLength` is set.
@@ -61,25 +61,28 @@ These properties apply to **all** field types and are validated by the base `Fie
6161

6262
| Property | Type | Default | Validation Behavior |
6363
|:---|:---|:---|:---|
64-
| `format` | `string` | `email` | Validates a basic `local@domain` shape |
64+
| `maxLength` | `number` | — | Rejects values exceeding character count |
65+
| `minLength` | `number` | — | Rejects values below character count |
6566

66-
**Default constraints:** Must contain an `@` and a domain with a dot — a lightweight pattern check, not full RFC 5322 validation.
67+
**Default constraints:** Must contain an `@` and a domain with a dot — a lightweight pattern check, not full RFC 5322 validation. The check is keyed on `type: 'email'` itself and has nothing to configure; a field-level `format` key is not read.
6768

6869
### `url`
6970

7071
| Property | Type | Default | Validation Behavior |
7172
|:---|:---|:---|:---|
72-
| `format` | `string` | `url` | Validates URL format (protocol required) |
73+
| `maxLength` | `number` | — | Rejects values exceeding character count |
74+
| `minLength` | `number` | — | Rejects values below character count |
7375

74-
**Default constraints:** Must be a valid URL with protocol prefix.
76+
**Default constraints:** Must be a valid URL with protocol prefix. The check is keyed on `type: 'url'` itself and has nothing to configure; a field-level `format` key is not read.
7577

7678
### `phone`
7779

7880
| Property | Type | Default | Validation Behavior |
7981
|:---|:---|:---|:---|
80-
| `format` | `string` | `phone` | Validates a permissive phone-number character set |
82+
| `maxLength` | `number` | — | Rejects values exceeding character count |
83+
| `minLength` | `number` | — | Rejects values below character count |
8184

82-
**Default constraints:** Accepts digits, `+ ( ) - .` and spaces (minimum 5 characters) — a lenient character-set check, not strict E.164 structural validation.
85+
**Default constraints:** Accepts digits, `+ ( ) - .` and spaces (minimum 5 characters) — a lenient character-set check, not strict E.164 structural validation. The check is keyed on `type: 'phone'` itself and has nothing to configure; a field-level `format` key is not read. For a stricter shape, add a [`format` validation rule](/docs/data-modeling/validation#format-validation) with a `regex`.
8386

8487
### `password`
8588

@@ -515,7 +518,7 @@ section above). See the
515518

516519
| Field Type | Required Props | Key Constraints |
517520
|:---|:---|:---|
518-
| `text` | — | `maxLength`, `minLength`, `format`, `valueDomain` |
521+
| `text` | — | `maxLength`, `minLength`, `valueDomain` (`format` is a display hint, not a constraint) |
519522
| `textarea` | — | `maxLength`, `minLength` |
520523
| `email` | — | Basic `local@domain` shape (not full RFC 5322) |
521524
| `url` | — | Valid URL with protocol |

0 commit comments

Comments
 (0)