# Validation Guide

Entity Builder uses a comprehensive two-stage validation system to catch errors before execution.

## Two-Stage Validation

### Stage 1: Operation Validation

Each operation validates its own specific requirements:

| Operation | Validates |
|-----------|-----------|
| `create_bundle` | Entity type exists, supports bundles |
| `create_field` | Field type exists, bundle valid |
| `configure_form_mode` | Widget exists, compatible with field type |
| `configure_view_mode` | Formatter exists, compatible with field type |
| `create_field_group` | Format type valid, parent exists |

### Stage 2: Validator Plugins

Cross-cutting validators check rules across all operations:

| Validator | Checks |
|-----------|--------|
| `DependencyValidator` | Referenced entities exist |
| `RequiredFieldsValidator` | Required properties present |
| `UniqueNameValidator` | No naming conflicts |
| `FieldTypeValidator` | Field type plugin exists |
| `WidgetCompatibilityValidator` | Widget supports field type |
| `FormatterCompatibilityValidator` | Formatter supports field type |
| `CircularDependencyValidator` | No circular dependencies |

## Common Validation Errors

### Field Type Errors

**Error:** `Field type "invalid_type" does not exist.`

**Cause:** Misspelled field type or missing module.

**Solution:**
```bash
# Check available field types
drush eb:discovery

# Install missing module
composer require drupal/datetime
drush en datetime -y
```

**Valid field types:**
- `string`, `string_long`
- `text`, `text_long`, `text_with_summary`
- `integer`, `decimal`, `float`
- `boolean`
- `datetime`, `daterange`
- `entity_reference`
- `image`, `file`
- `link`, `email`, `telephone`
- `list_string`, `list_integer`, `list_float`

### Widget/Formatter Errors

**Error:** `Widget "invalid_widget" not found.`

**Cause:** Misspelled widget or incompatible with field type.

**Solution:**
```bash
# Check available widgets for a field type
drush eb:discovery | grep text_long
```

**Error:** `Widget "string_textfield" is not compatible with field type "text_long".`

**Cause:** Wrong widget for the field type.

**Solution:** Use a compatible widget:

| Field Type | Compatible Widgets |
|------------|-------------------|
| `string` | `string_textfield` |
| `text_long` | `text_textarea` |
| `text_with_summary` | `text_textarea_with_summary` |
| `integer`, `decimal` | `number` |
| `boolean` | `boolean_checkbox`, `options_buttons` |
| `entity_reference` | `entity_reference_autocomplete`, `options_select`, `options_buttons` |

### Bundle Errors

**Error:** `Bundle "missing_bundle" not found for entity type "node".`

**Cause:** Referencing a bundle that doesn't exist.

**Solutions:**

1. Create the bundle in the same definition:
```yaml
bundle_definitions:
  - entity_type: node
    bundle_id: missing_bundle
    label: Missing Bundle

field_definitions:
  - entity_type: node
    bundle: missing_bundle  # Now valid
```

2. Or ensure the bundle exists in Drupal first.

### Entity Reference Errors

**Error:** `Target bundle "category" does not exist for entity type "taxonomy_term".`

**Cause:** Entity reference targets a non-existent bundle.

**Solution:** Create the target bundle first:
```yaml
bundle_definitions:
  - entity_type: taxonomy_term
    bundle_id: category
    label: Category

field_definitions:
  - entity_type: node
    bundle: article
    field_name: field_category
    field_type: entity_reference
    field_storage_settings:
      target_type: taxonomy_term
    field_config_settings:
      handler_settings:
        target_bundles:
          category: category  # Must exist or be created above
```

### Circular Dependency Errors

**Error:** `Circular dependency detected: A > B > C > A`

**Cause:** Operations depend on each other in a cycle.

**Example of circular dependency:**
```yaml
# BAD: Field A references Field B, Field B references Field A
field_definitions:
  - field_name: field_a
    field_type: entity_reference
    field_config_settings:
      handler_settings:
        target_bundles:
          bundle_b: bundle_b

  - field_name: field_b
    field_type: entity_reference
    field_config_settings:
      handler_settings:
        target_bundles:
          bundle_a: bundle_a  # Circular!
```

**Solution:** Remove one direction of the reference or use a different approach.

### Naming Errors

**Error:** `Field name must start with "field_".`

**Solution:**
```yaml
# BAD
field_name: body

# GOOD
field_name: field_body
```

**Error:** `Group name must start with "group_".`

**Solution:**
```yaml
# BAD
group_name: content

# GOOD
group_name: group_content
```

## Batch Context Awareness

Validators understand what will be created in the same batch:

```yaml
bundle_definitions:
  - entity_type: node
    bundle_id: article    # Created at position 0

field_definitions:
  - entity_type: node
    bundle: article       # References position 0 - VALID
    field_name: field_body
```

The field can reference the bundle even though it doesn't exist yet - because it will be created in the same batch.

## Validation Commands

### Validate a File

```bash
drush eb:validate path/to/definition.yml
```

**Output (success):**
```
Validating: definition.yml
Format: Flat YAML v5.0
Mode: sync

Validation successful!
  Bundles: 2
  Fields: 5
  Operations: 10
```

**Output (errors):**
```
Validating: definition.yml

Validation failed with 2 errors:

1. [field_type_not_found] Field type "invalid" does not exist.
   Field: field_type
   Context: field_definitions[2]

2. [bundle_not_found] Bundle "missing" not found.
   Field: bundle
   Context: field_definitions[3]
```

### Validate in UI

1. Click **Validate** in the toolbar
2. Errors show as red highlights
3. Hover over cells for error details

## Validation Severity

| Level | Meaning | Blocks Apply? |
|-------|---------|---------------|
| Error | Must fix | Yes |
| Warning | Should review | No |
| Info | FYI | No |

## Best Practices

1. **Validate frequently** during editing
2. **Fix errors immediately** - don't let them accumulate
3. **Preview before apply** to see the full operation list
4. **Check dependencies** are in the correct order
5. **Use discovery** to find correct plugin IDs
