# Mapping Config

## Format

File: `ingest/scenarios/<scenario>/<entity-name>/entity.json`

### Basic (pass-through)

```json
{
  "name": "<EntityName>",
  "dataFile": "data.jsonl",
  "graphqlFile": "../../../mutations/create<EntityName>.graphql",
  "mapping": {
    "input": "$"
  }
}
```

### With outputCapture (capture server-generated IDs)

```json
{
  "name": "Company",
  "dataFile": "data.jsonl",
  "graphqlFile": "../../../mutations/createCompany.graphql",
  "outputCapture": {
    "key": "$.legalName",
    "fields": { "id": "$.createCompany.id" }
  },
  "mapping": {
    "legalName": "$.legalName",
    "baseCurrencyId": "$.baseCurrencyId"
  }
}
```

- `outputCapture.key` — JSONPath into the **input row** that uniquely identifies this record (e.g., company name, SKU)
- `outputCapture.fields` — map of field names to JSONPaths into the **mutation response** to capture

### With $ref (reference captured IDs from upstream entities)

```json
{
  "name": "BusinessPartner",
  "dataFile": "data.jsonl",
  "graphqlFile": "../../../mutations/createBusinessPartner.graphql",
  "mapping": {
    "name": "$.name",
    "companyId": { "$ref": "Company", "key": "$.companyRef", "field": "id" }
  }
}
```

- `$ref` — entity name to look up in the output store
- `key` — JSONPath into the **current input row** to get the lookup key value
- `field` — which captured field to use from the referenced entity

At runtime: reads `row.companyRef` → looks up `outputStore["Company"][value].id` → uses as `companyId`.

### Data-level $ref (inside data arrays)

For nested arrays like PO lines where `itemId` references a baseline entity, put `$ref` objects directly in the data:

**entity.json** — passes lines through:
```json
{
  "mapping": {
    "companyId": { "$ref": "Company", "key": "$.companyRef", "field": "id" },
    "lines": "$.lines"
  }
}
```

**data.jsonl** — `$ref` inside the array:
```jsonl
{"companyRef":"Acme Corp","lines":[{"itemId":{"$ref":"Item","key":"FAB-COT-001","field":"id"},"quantity":"100"}]}
```

For data-level `$ref`, `key` is a **literal lookup value** (not a JSONPath), unless it starts with `$.`.

### With $ref in arrays (e.g., roleIds)

```json
{
  "mapping": {
    "name": "$.name",
    "roleIds": [{ "$ref": "Role", "key": "$.roleRef", "field": "id" }]
  }
}
```

## Path Resolution

Paths in `entity.json` are relative to the **entity directory** (the directory containing the `entity.json` file).

## Rules

- `mapping: { "input": "$" }` maps the entire JSONL row to the mutation's `$input` variable
- The `name` field is required — gql-ingest uses it for dependency resolution and logging
- One `entity.json` per entity per scenario
- Add `outputCapture` to any entity whose ID is referenced by downstream entities
- Use `$ref` instead of hardcoded UUIDs for all cross-entity references
- Dependency waves ensure upstream entities are captured before downstream entities resolve `$ref`
