Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions content/docs/data-modeling/field-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,15 @@ Calculated field using a CEL expression (see [Expressions](/docs/data-modeling/f
{ name: 'total', label: 'Total', type: 'formula', expression: 'record.quantity * record.unit_price', returnType: 'number' }
```

#### `expression` on a stored field

`expression` is not only a `formula` key. On a field of any other type, the engine computes it from the row each write stores and **stores** the result in the field's column, so a `summary` can roll the column up. It is computed on every insert and every update by id (the stored row merged with the patch). On a predicate update it is computed only when the patch moves an input: one value is stored for every matched row, and the update is refused (`VALIDATION_FAILED`, an `invalid_value` error on the field) when the rows would compute different values. Update those rows by id instead. A value a client sends for the field never stands: it is overwritten by the computed one, with no refusal and no dropped-field report. The full contract is the `expression` row of [`FieldSchema`](/docs/references/data/field).

```typescript
// Stored, so a parent `summary` can sum it. A client-sent amount is overwritten.
Field.currency({ label: 'Amount', expression: 'record.quantity * record.unit_price' })
```

### `summary`
Roll-up summary from child records.

Expand Down
2 changes: 2 additions & 0 deletions content/docs/data-modeling/validation-rules.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ application-level emptiness check is needed.
}
```

**`expression` on a stored field.** A field of any other type may declare `expression` too, and it validates differently from a `formula`. The engine computes the value on every insert and every update by id, and stores it. A value a client sends for the field is not refused and not reported as dropped: it is overwritten by the computed one. The one refusal is a predicate update that moves an input: when the matched rows would compute different values, the update is refused with `VALIDATION_FAILED` and an `invalid_value` error naming the field, and nothing is written. See [`expression` on a stored field](/docs/data-modeling/field-types#expression-on-a-stored-field) and the `expression` row of [`FieldSchema`](/docs/references/data/field).

### `summary`

| Property | Type | Default | Validation Behavior |
Expand Down
Loading