> ## Documentation Index
> Fetch the complete documentation index at: https://docs.clinia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Conditional Validation

> Apply conditional logic, nested constraints, and cardinality to Clinia schemas

Advanced validation rules let you react to contextual data, enforce dependencies between properties, and design predictable nested schemas.

## Conditional rules

Use the `when` clause to activate a rule only if a condition evaluates to `true`. The condition uses the same operators as the [search DSL](/explanation/operator) on the profile’s property paths.

```json {collectForTests=conditionalRules} theme={null}
{
  "properties": {
    "practiceNumber": { "type": "integer" },
    "specialties": {
      "type": "array",
      "rules": [
        {
          "required": true,
          "min": 1,
          "when": {
            "eq": {
              "practiceNumber": "*"
            }
          }
        }
      ],
      "items": { "type": "symbol" }
    }
  }
}
```

### Supported operators

| Operator                                      | Description                                                              |
| :-------------------------------------------- | :----------------------------------------------------------------------- |
| [`eq`](/explanation/operator#equal-eq)        | Checks equality. Use `*` as a wildcard to test for presence.             |
| [`lt`](/explanation/operator#less-than-lt)    | Valid for numeric or temporal fields to enforce “less than or equal.”    |
| [`gt`](/explanation/operator#greater-than-gt) | Valid for numeric or temporal fields to enforce “greater than or equal.” |

Combine multiple rules in the same array to express complex validation logic.

## Nested objects

`when` clauses reference properties from the root of the profile. For nested structures, use dot notation:

```json {collectForTests=nestedObjectCondition} theme={null}
{
  "properties": {
    "details": {
      "type": "object",
      "properties": {
        "contact": {
          "type": "contactpoint",
          "properties": {
            "system": {
              "rules": [
                {
                  "required": true,
                  "enum": ["phone", "fax", "email"]
                }
              ]
            }
          }
        },
        "emailCC": {
          "type": "symbol",
          "rules": [
            {
              "required": true,
              "when": {
                "eq": {
                  "details.contact.system": "email"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

## Arrays of objects

Similar to the above, when using an operator on a property that is inside of an array, two choices are possible:

1. If you want to test if at least one object/property of the array follows the clause, refer directly to the property (Inside or outside the array).
2. If you want to test against another property in the same object (Property with the rule must also be in the same object), you can use the `[current]` clause.

This could result in profile definitions such as:

Testing for the condition: "`emailCC` is required if ANY contact point `system` is of type `"email"`":

```json {collectForTests=arrayStarCondition} theme={null}
{
  "properties": {
    "contacts": {
      "type": "array",
      "items": {
        "type": "contactpoint"
      }
    },
    "emailCC": {
      "type": "symbol",
      "rules": [
        {
          "required": true,
          "when": {
            "eq": {
              // Referring to any items in "contacts"
              "contacts.system": "email"
            }
          }
        }
      ]
    },
    "aRootProperty": {
      "type": "symbol"
    }
  }
}
```

Creating the following resource is valid: since no contact point has a system of type "email", `emailCC` is not required.

```json {collectForTests=arrayStarConditionResourceCorrect} theme={null}
{
  "contacts": [{ "system": "phone" }]
}
```

Creating the following resource is *not valid*: since one contact point has a system of type "email", `emailCC` is required.

```json {collectForTests=arrayStarConditionResourceIncorrect} theme={null}
{
  "contacts": [{ "system": "email" }, { "system": "phone" }]
}
```

Testing for the condition: "`value` must be defined if the `contact` `system` value is of type `"email"`".

The key `contacts[current].system` refers to the current item being evaluated in the `contacts` array.

```json {collectForTests=arrayCurrentCondition} theme={null}
{
  "properties": {
    "contacts": {
      "type": "array",
      "items": {
        "type": "contactpoint",
        "properties": {
          "value": {
            "rules": [
              {
                "required": true,
                "when": {
                  "eq": {
                    "contacts[current].system": "email"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}
```

## Cardinality

Cardinality expresses how many instances of a property are allowed within a complex type.

| Notation | Name         | Description                                    | Validation                                                |
| -------- | ------------ | ---------------------------------------------- | --------------------------------------------------------- |
| `0:1`    | Zero to one  | Optional property, maximum one value           | Property can be omitted or appear once                    |
| `1:1`    | One to one   | Required property, exactly one value           | Missing or duplicate values fail validation               |
| `0:*`    | Zero to many | Optional property, unlimited values (arrays)   | Property can be omitted or contain any number of elements |
| `1:*`    | One to many  | Required property, at least one value (arrays) | Enforces a non-empty array                                |

```json theme={null}
{
  "patientName": {
    "family": "Wilson",              // 0:1
    "given": ["Sarah", "Elizabeth"], // 0:*
    "use": "official"                // 0:1
  }
}
```

<Warning>
  Cardinality rules are enforced during validation. Missing required properties or over-populated single-valued properties will fail ingestion.
</Warning>

***

Continue with [vocabulary binding](/explanation/field-validation/vocabulary) to link fields to controlled concept sets.
