# Datasets

Datasets provide lookup data from the KASKO Data Service. They enable autocomplete inputs, field mapping, and dynamic data integration.

## How Datasets Work

1. A field is configured with the `in_dataset:DATASET_ID` validation rule
2. The user selects/enters a value using a dataset component
3. The selected item's ID (prefixed with `dai_`) is stored in the field
4. The framework fetches the full dataset item
5. The dataset item is exposed under the `dataset` namespace

## Dataset Item Structure

When a dataset item is loaded, it looks like this:

```typescript
{
  id: string;           // Dataset item ID (e.g., "dai_abc123...")
  dataset_id: string;   // Dataset ID (e.g., "dat_xyz789...")
  [key: string]: any;   // Arbitrary data fields from the dataset
}
```

## Dataset Components

### `form-data-input`

Typeahead/autocomplete input:

```json
{
  "type": "form-data-input",
  "config": {
    "field_name": "data.company",
    "data_field_name": "name",
    "content_key": {
      "label": "form.company.label",
      "placeholder": "form.company.placeholder"
    },
    "field_map": {
      "data.company_code": "code",
      "data.company_name": "name"
    },
    "sort": "asc",
    "wait_ms": 300,
    "min_length": 2,
    "clear_fields_on_change": ["data.company_code"]
  }
}
```

| Config                   | Description                                                 |
| ------------------------ | ----------------------------------------------------------- |
| `field_name`             | Field that stores the dataset item ID                       |
| `data_field_name`        | Dataset field used for search/display                       |
| `field_map`              | Maps form fields to dataset fields (auto-fill on selection) |
| `filter_by`              | Filter dataset results by criteria                          |
| `sort`                   | Sort results: `"asc"` or `"desc"`                           |
| `wait_ms`                | Debounce time in milliseconds                               |
| `min_length`             | Minimum characters before search triggers                   |
| `clear_fields_on_change` | Fields to clear when selection changes                      |

### `form-data-lookup`

Dropdown lookup:

```json
{
  "type": "form-data-lookup",
  "config": {
    "field_name": "data.location",
    "data_field_name": "city",
    "source_field_name": "region",
    "content_key": {
      "placeholder": "form.location.placeholder"
    }
  }
}
```

### `dataset-map`

Invisible mapper that fills additional fields when a dataset item loads:

```json
{
  "type": "dataset-map",
  "config": {
    "field_name": "data.company",
    "field_map": {
      "data.company_address": "address",
      "data.company_phone": "phone"
    }
  }
}
```

## Validation

Fields using datasets must include the `in_dataset` rule:

```json
{
  "name": "company",
  "path": "data",
  "validation": "required|string|in_dataset:dat_XXXXXXXXXXXXXXXXXXXX"
}
```

* First argument is the dataset ID (starts with `dat_`)
* Backend validates the value exists in the dataset
* Frontend ignores validation for `in_dataset`, but dataset lookup still requires it

## Accessing Datasets in JsonLogic

Dataset items are available under the `dataset` namespace:

```json
{ "var": "dataset.data.company" }
```

Access fields:

```json
{ "var": "dataset.data.company.name" }
{ "var": "dataset.data.company.code" }
{ "var": "dataset.data.company.address.city" }
```

## Accessing Datasets in Content

Use dataset tokens in translations:

```
"Company: {dataset.data.company.name}"
"Code: {dataset.data.company.code}"
"Address: {dataset.data.company.address}"
```

## Repeaters

Datasets work with repeater fields:

```json
{
  "name": "agents.*.location",
  "path": "data",
  "validation": "in_dataset:dat_locations"
}
```

Each repeater item has its own dataset entry:

* `dataset.data.agents.0.location`
* `dataset.data.agents.1.location`

## Filtering Results

Basic filters:

```json
{
  "filter_by": {
    "type": "fruit",
    "active": true
  }
}
```

Advanced filters:

```json
{
  "filter_by": {
    "price": {
      "type": "operator",
      "operator": ">=",
      "search": 100
    },
    "region": {
      "type": "operator",
      "operator": "IN",
      "search": ["US", "UK", "DE"]
    }
  }
}
```

## Automatic Cleanup

When a dataset field is cleared or changed:

* The old dataset item is removed from state
* Prevents stale data from accumulating

## Tips

* Use `field_map` or `dataset-map` to auto-fill related fields
* Keep `field_name` aligned with the form field path (e.g., `data.company`)
* Use `clear_fields_on_change` to reset dependent fields when selection changes
