Skip to content

Commit c064f4b

Browse files
committed
fix(driver-sql,lint): classify dueLike and settledWhen in FIELD_KEY_STORAGE_CLASS; settledWhen joins the docs gate's field-rule slots and the consumer census's behaviour segments
FIELD_KEY_STORAGE_CLASS is pinned against Object.keys(FieldSchema.shape) (builtin-column-collision.test.ts): both keys are presentation, read by the renderer's date cells and never by createColumn. The docs-corpus gate now root-judges a settledWhen example (slot list and text tripwire together, three self-test cases), and validate-field-consumers counts a settledWhen read as behaviour beside its three siblings. Claude-Session: https://claude.ai/code/session_01VZqqwTj2wsihZEbfT6yyYN Co-authored-by: Claude <noreply@anthropic.com>
1 parent a520b4e commit c064f4b

3 files changed

Lines changed: 29 additions & 3 deletions

File tree

‎packages/drivers/driver-sql/src/builtin-column-collision.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ export const FIELD_KEY_STORAGE_CLASS: Readonly<Record<string, FieldKeyClass>> =
120120
readonlyWhen: 'presentation',
121121
requiredWhen: 'presentation',
122122
conditionalRequired: 'presentation',
123+
dueLike: 'presentation', // declares a date a deadline (#22227) — read by the renderer's date cells, never by `createColumn`: the column is the date the type already sizes
124+
settledWhen: 'presentation', // the deadline's settle predicate (#22227), display only like `visibleWhen` — no DDL reads it
123125
requiredPermissions: 'presentation',
124126
maskingRule: 'presentation',
125127
ackPlaintextMasking: 'presentation',

‎packages/lint/scripts/check-doc-formula-expressions.mjs‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,12 @@ function scan(files) {
635635
* same rule would fail the build on correct docs. The loudness requirement is
636636
* met by the skip list instead — printed, counted, and pinned by the self-test.
637637
*/
638-
const FIELD_RULE_SLOTS = ['visibleWhen', 'readonlyWhen', 'requiredWhen'];
638+
// `settledWhen` (#22227) is the deadline's settle predicate, judged by the
639+
// metadata walk exactly as `visibleWhen` is — so a docs example of it gets the
640+
// same verdict here. Keep this list and FIELD_RULE_TEXT_RE below in step: the
641+
// text tripwire reconciles against the parse, so a slot in one and not the
642+
// other is either an invisible site or a phantom skip.
643+
const FIELD_RULE_SLOTS = ['visibleWhen', 'readonlyWhen', 'requiredWhen', 'settledWhen'];
639644

640645
/** The property key of a property assignment, when it is a plain name. */
641646
function keyText(p) {
@@ -751,7 +756,7 @@ function fieldRuleSkipReason(prop) {
751756
* `docs/adr/0089-unify-visibility-predicate-naming.md` quotes the SCHEMA rather
752757
* than authoring a predicate — three text hits that are not sites at all.
753758
*/
754-
const FIELD_RULE_TEXT_RE = /\b(visibleWhen|readonlyWhen|requiredWhen)\s*:\s*(?:[A-Za-z_$][\w$]*\s*)?["'`]/g;
759+
const FIELD_RULE_TEXT_RE = /\b(visibleWhen|readonlyWhen|requiredWhen|settledWhen)\s*:\s*(?:[A-Za-z_$][\w$]*\s*)?["'`]/g;
755760

756761
export function textFieldRuleSites(code) {
757762
const out = [];
@@ -1742,6 +1747,23 @@ const FIELD_RULE_SELF_TEST_CASES = [
17421747
code: "ObjectSchema.create({ fields: { due_date: { type: 'date', requiredWhen: 'stage == \"closed\"' } } })",
17431748
expect: { admitted: 1, errors: 1, match: /bare reference `stage`/ },
17441749
},
1750+
{
1751+
// #22227 — the deadline's settle predicate is a field-rule slot, so a docs
1752+
// example of it is root-judged exactly as `visibleWhen` is.
1753+
name: 'RED — `settledWhen` on a deadline is the same field-rule slot: a bare reference is refused',
1754+
code: "due_date: Field.date({ dueLike: true, settledWhen: P`status == 'done'` }),",
1755+
expect: { admitted: 1, errors: 1, match: /bare reference `status`/ },
1756+
},
1757+
{
1758+
name: 'RED — `settledWhen` reading `current_user` gets the family\'s root verdict',
1759+
code: "due_date: Field.date({ dueLike: true, settledWhen: \"current_user.profile == 'admin'\" }),",
1760+
expect: { admitted: 1, errors: 1, match: /`settledWhen` reads `current_user`/ },
1761+
},
1762+
{
1763+
name: 'GREEN — the `fields.mdx` deadline example: a record-scoped `settledWhen`',
1764+
code: "due_date: Field.date({ label: 'Due Date', dueLike: true, settledWhen: P`record.status == 'done'` }),",
1765+
expect: { admitted: 1, errors: 0 },
1766+
},
17451767
{
17461768
name: 'GREEN — the canonical record-scoped predicate',
17471769
code: "x: Field.text({ visibleWhen: \"record.status == 'closed'\" }),",

‎packages/lint/src/validate-field-consumers.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,9 @@ const BEHAVIOUR_SEGMENTS: ReadonlySet<string> = new Set([
310310
'titleField', 'colorField', 'latitudeField', 'longitudeField', 'locationField',
311311
'addressField', 'parentField', 'statusField', 'kanban', 'calendar', 'gantt', 'timeline',
312312
'map', 'tree', 'rowColor', 'rowTint', 'conditionalFormatting',
313-
'expression', 'formula', 'visibleWhen', 'readonlyWhen', 'requiredWhen', 'validations',
313+
// `settledWhen` (#22227) is the fourth field-rule predicate slot, a deadline's
314+
// settle condition — a read of the fields it names, like its three siblings.
315+
'expression', 'formula', 'visibleWhen', 'readonlyWhen', 'requiredWhen', 'settledWhen', 'validations',
314316
'rules', 'summaryOperations', 'dimensions', 'measures', 'handler', 'body', 'script',
315317
'nameField', 'displayNameField', 'externalId', 'upsertKey',
316318
]);

0 commit comments

Comments
 (0)