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

# Overview

> Manage form-attachment rules in rating engine revision config

## Overview

Configuration rating form-logic rules determine which forms are attached to a policy or quote. Rules are stored in the rating engine revision's config JSON (`rating_engine_revisions.config.policyFormLogicConfigs`). Each rule has a `shouldAdd` conditional expression that is evaluated during rating against the policy, insured, coverage, and form data.

## Key Concepts

* **ratingEngineRevisionId**: The rating engine revision whose config holds the rules — must already exist.
* **revisionStrategy**: Controls how the revision is updated — `UpdateExistingRevision` modifies the specified revision in place. `CreateNewRevision` is not yet implemented.
* **ruleName**: Human-readable name for the rule.
* **rank**: Controls the position of attached forms in the output list (lower numbers appear first). Does not control evaluation order. Duplicates are permitted. Required on create, so returned rules always carry a rank.
* **step**: Optional — tag controlling which form-selection contexts the rule's output appears in. `"policies"` (appears during policy form selection), `"quotes"` (appears during quote form selection), or an array of these values. If omitted, the rule's output only appears during policy form selection.
* **shouldAdd**: A conditional expression that evaluates to true or false. When it evaluates to true, the form is attached. See [Expression Shapes](#expression-shapes) below.

## API Endpoints

| Method | Endpoint                                         | Description                                         |
| ------ | ------------------------------------------------ | --------------------------------------------------- |
| GET    | `/configuration/rating/form-logic`               | List form-logic rules in the revision config        |
| POST   | `/configuration/rating/form-logic`               | Create a new form-logic rule in the revision config |
| DELETE | `/configuration/rating/form-logic/{formLogicId}` | Remove a form-logic rule from the revision config   |

## Permissions

| Action      | Permission       |
| ----------- | ---------------- |
| List rules  | `company:read`   |
| Create rule | `company:update` |
| Delete rule | `company:update` |

## GET Query Parameters

| Parameter              | Type                       | Required | Description                                                                        |
| ---------------------- | -------------------------- | -------- | ---------------------------------------------------------------------------------- |
| ratingEngineRevisionId | string (UUID)              | Yes      | Rating engine revision whose config holds the rules                                |
| ruleName               | string                     | No       | Filter to rules whose `ruleName` matches exactly. Must be non-empty when provided. |
| id                     | string (UUID) \| string\[] | No       | Filter to a single rule ID or an array of rule IDs                                 |
| sortBy                 | `"ruleName"` \| `"rank"`   | No       | Sort field — default `ruleName`                                                    |
| sortDirection          | `"asc"` \| `"desc"`        | No       | Sort direction — default `asc`. Ties are broken by `id` in the same direction.     |

## GET Response Properties

Each item in `items` has the following shape.

| Property  | Type                        | Description                                                                                     |
| --------- | --------------------------- | ----------------------------------------------------------------------------------------------- |
| id        | string (UUID)               | Server-generated rule ID                                                                        |
| ruleName  | string                      | Human-readable name for the rule                                                                |
| rank      | number                      | Sort rank controlling output position (lower first)                                             |
| step      | string \| string\[] \| null | `"policies"`, `"quotes"`, an array of the two, or `null` if the rule was created without a step |
| shouldAdd | object                      | Conditional expression — see [Expression Shapes](#expression-shapes)                            |

Filters and sorts run on raw rules; response validation runs only on the surviving rows. A rule that survives filtering but has a missing or malformed `id`, `rank`, or `shouldAdd` returns a 400 `InvalidProperties` response. In practice, rules written through this API always pass validation, so this condition indicates a data-integrity issue with legacy config rather than a caller error.

## POST Request Properties

| Property               | Type                | Required | Description                                                        |
| ---------------------- | ------------------- | -------- | ------------------------------------------------------------------ |
| ratingEngineRevisionId | string (UUID)       | Yes      | Rating engine revision to add the rule to                          |
| revisionStrategy       | string              | Yes      | `"UpdateExistingRevision"` or `"CreateNewRevision"` (501)          |
| ruleName               | string              | Yes      | Human-readable name for the rule                                   |
| rank                   | number              | Yes      | Sort rank — lower values appear earlier in the attached forms list |
| step                   | string \| string\[] | No       | `"policies"`, `"quotes"`, or an array of the two                   |
| shouldAdd              | object              | Yes      | Conditional expression (see below)                                 |

## Expression Shapes

`shouldAdd` is a recursive structure built from three variants.

### Branch Expression

Combines child expressions with a logical operator.

```json theme={null}
{
  "operator": "AND",
  "conditions": [
    { "leftKey": "policy.data.state", "operator": "=", "rightValue": "CA" },
    { "leftKey": "form.number",       "operator": "=", "rightValue": "FM-0002" }
  ]
}
```

Supported `operator` values: `AND`, `OR`.

### Leaf Expression

Compares the value at `leftKey` against `rightValue` using the given operator.

```json theme={null}
{ "leftKey": "policy.data.state", "operator": "=", "rightValue": "CA" }
```

Supported `operator` values: `=`, `!=`, `<`, `<=`, `>`, `>=`, `IN`, `NOTIN`, `EXISTS`, `NOTEXISTS`, `SOME`.

Operator-specific behavior:

* `EXISTS` / `NOTEXISTS` — check only whether `leftKey` resolves to a defined, non-null value. `rightValue` is required structurally but ignored.
* `IN` / `NOTIN` — `rightValue` is either an array (membership: the `leftKey` value must be an element) or a string (substring: the `leftKey` value must appear within `rightValue`).
* `SOME` — `rightValue` is a nested expression evaluated against each element of the array at `leftKey`. Returns `false` if `leftKey` does not resolve to an array.
* `=`, `!=`, `<`, `<=`, `>`, `>=` — standard JavaScript-style comparison between the resolved `leftKey` value and `rightValue`.

`rightValue` may be a primitive, an array, `null`, or — for `SOME` — a nested expression.

### Inverted Leaf Expression

Checks whether a static `leftValue` appears in the array (or string) stored at `rightKey`. Only the `IN` operator is supported in this shape.

```json theme={null}
{ "leftValue": "FM-0001", "operator": "IN", "rightKey": "policy.attachedFormNumbers" }
```
