# Defs & Rules

Typed computed values and validation rules

Canonical URL: https://docs.paradoc.dev/schemas/artifacts/shared/logic/

Defs and Rules enable conditional behavior and validation in forms and bundles.

* **Defs** define typed computed values that can be referenced in field/annex conditions (`visible`, `required`)
* **Rules** define form-level validation constraints evaluated at fill time

## DefsSection

A mapping of named typed expressions keyed by camelCase identifier.

Each entry specifies a `type` and `value`. For scalar types the value is a string expression; for composite types (money, address, etc.) the value is an object with component expressions, in the same shape as the matching field value. A bbox value has `southWest` and `northEast` corners, each with `lat` and `lon` expressions.

The keys `fields` and `parties` are reserved for the context roots, and `item` and `parent` for list row references. A def with one of these keys fails validation.

| Name | Type | Description |
| --- | --- | --- |
| `[key]` | `Expression` | A typed computed value entry. Key must be camelCase (starts with lowercase letter) |

## RulesSection

A mapping of form-level validation rules keyed by camelCase identifier. Rules are evaluated at fill time.

| Name | Type | Description |
| --- | --- | --- |
| `[key]` | `ValidationRule` | A validation rule entry. Key must be camelCase (starts with lowercase letter) |

## CondExpr

A conditional expression used in `include`, `required`, and `visible` fields.

```typescript
type CondExpr = boolean | string
```

When a string is provided, it can reference:

* Named defs from the `defs` section
* Field values using `fields.<fieldName>` (composite parts as `fields.<fieldName>.<part>`, e.g. `fields.rent.amount`)
* Inside a list item, the current row as `item` and, in a nested list, the enclosing row as `parent` (e.g. `item.kind == 'other'`)
* Comparison operators (`==`, `!=`, `>`, `<`, `>=`, `<=`)
* Logical operators (`and`, `or`, `not`)
* Membership operators (`in`, `not in`)

Validation rules (`rules`) may also reference field values unprefixed (e.g. `creditScore`). See [Logic](/concepts/logic) for the full expression language.

## Examples



**YAML**

```yaml
$schema: https://schema.paradoc.dev/2026-10-02.json
kind: form
name: loan-application
defs:
  isEmployed:
    type: boolean
    value: "fields.employmentStatus == 'employed'"
  needsCoSigner:
    type: boolean
    value: "fields.creditScore < 650"
  showIncomeFields:
    type: boolean
    value: "isEmployed"

rules:
  creditScoreRange:
    expr: "creditScore >= 300 and creditScore <= 850"
    message: "Credit score must be between 300 and 850"
  incomeRequired:
    expr: "not isEmployed or monthlyIncome.amount > 0"
    message: "Monthly income is required for employed applicants"
    severity: error

fields:
  employmentStatus:
    type: enum
    label: Employment Status
    enum: [{ value: "employed" }, { value: "self-employed" }, { value: "unemployed" }, { value: "retired" }]

  creditScore:
    type: number
    label: Credit Score
    min: 300
    max: 850

  employer:
    type: text
    label: Employer Name
    visible: showIncomeFields
    required: showIncomeFields

  monthlyIncome:
    type: money
    label: Monthly Income
    visible: showIncomeFields
    required: showIncomeFields

  coSignerName:
    type: person
    label: Co-Signer
    visible: needsCoSigner
    required: needsCoSigner
```

**JSON**

```json
{
  "$schema": "https://schema.paradoc.dev/2026-10-02.json",
  "kind": "form",
  "name": "loan-application",
  "defs": {
    "isEmployed": {
      "type": "boolean",
      "value": "fields.employmentStatus == 'employed'"
    },
    "needsCoSigner": {
      "type": "boolean",
      "value": "fields.creditScore < 650"
    },
    "showIncomeFields": {
      "type": "boolean",
      "value": "isEmployed"
    }
  },
  "rules": {
    "creditScoreRange": {
      "expr": "creditScore >= 300 and creditScore <= 850",
      "message": "Credit score must be between 300 and 850"
    },
    "incomeRequired": {
      "expr": "not isEmployed or monthlyIncome.amount > 0",
      "message": "Monthly income is required for employed applicants",
      "severity": "error"
    }
  },
  "fields": {
    "employmentStatus": {
      "type": "enum",
      "label": "Employment Status",
      "enum": [
        { "value": "employed" },
        { "value": "self-employed" },
        { "value": "unemployed" },
        { "value": "retired" }
      ]
    },
    "creditScore": {
      "type": "number",
      "label": "Credit Score",
      "min": 300,
      "max": 850
    },
    "employer": {
      "type": "text",
      "label": "Employer Name",
      "visible": "showIncomeFields",
      "required": "showIncomeFields"
    },
    "monthlyIncome": {
      "type": "money",
      "label": "Monthly Income",
      "visible": "showIncomeFields",
      "required": "showIncomeFields"
    },
    "coSignerName": {
      "type": "person",
      "label": "Co-Signer",
      "visible": "needsCoSigner",
      "required": "needsCoSigner"
    }
  }
}
```

## Related

* [Form](/schemas/artifacts/form) - Interactive form artifact
* [Bundle](/schemas/artifacts/bundle) - Container artifact with conditional inclusion
* [FormField](/schemas/artifacts/form/field) - Field definitions with conditional properties
* [FormAnnex](/schemas/artifacts/form/annex) - Attachment slots with conditional visibility and requirements
