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

# Core concepts

# Core Concepts

Understanding the fundamental building blocks of Function Lab.

## Overview

Function Lab configurations consist of **rules** that evaluate **conditions** and execute **events**. Optional **facts** enable complex data transformations.

```
Input Data → Facts → Conditions → Events → Output
```

## Rules

A rule is the basic unit of logic in Function Lab.

### Structure

```json theme={null}
{
  "rules": [
    {
      "facts": { /* optional data transformations */ },
      "conditions": { /* when to apply this rule */ },
      "events": [ /* what to do when conditions match */ ]
    }
  ]
}
```

### Required Fields

* `conditions`: Object defining when the rule applies
* `events`: Array of actions to take when conditions are met

### Optional Fields

* `facts`: Named calculations for reuse in conditions and events
* `if-not-events`: Alternative events when conditions don't match

## Conditions

Conditions determine when a rule should fire. They query the input data using dot notation and predicates.

### Simple Condition

```json theme={null}
{
  "conditions": {
    "customer.tags": {
      "includes": "VIP"
    }
  }
}
```

Checks if customer tags array includes "VIP".

### Multiple Conditions (AND)

```json theme={null}
{
  "conditions": {
    "customer.tags": {
      "includes": "VIP"
    },
    "cart.totalAmount": {
      "gte": 100
    }
  }
}
```

Both conditions must be true (implicit AND).

### OR Logic

```json theme={null}
{
  "conditions": {
    "or": [
      { "customer.tags": { "includes": "VIP" } },
      { "customer.tags": { "includes": "WHOLESALE" } }
    ]
  }
}
```

### Available Predicates

| Predicate              | Description           | Example                                          |
| ---------------------- | --------------------- | ------------------------------------------------ |
| `equal`, `eq`, `is`    | Exact match           | `"customer.email": { "is": "user@example.com" }` |
| `includes`, `contains` | Array contains value  | `"customer.tags": { "includes": "VIP" }`         |
| `gt`, `greater`        | Greater than          | `"cart.totalAmount": { "gt": 100 }`              |
| `gte`, `greaterEq`     | Greater than or equal | `"cart.totalAmount": { "gte": 100 }`             |
| `lt`, `less`           | Less than             | `"cart.lineCount": { "lt": 5 }`                  |
| `lte`, `lessEq`        | Less than or equal    | `"cart.lineCount": { "lte": 10 }`                |
| `exists`               | Field exists          | `"customer.id": { "exists": true }`              |
| `empty`                | Array/string is empty | `"customer.tags": { "empty": false }`            |

See [Predicates Reference](../reference/api/predicates.md) for complete list.

## Events

Events define what happens when conditions match. Event structure depends on the function type.

### Product Discount Event

```json theme={null}
{
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "discount_type": "percentage",
        "value": 15,
        "message": "15% Off Sale"
      }
    }
  ]
}
```

### Multiple Events

A rule can have multiple events:

```json theme={null}
{
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "handles": ["t-shirt"],
        "discount_type": "percentage",
        "value": 20,
        "message": "20% off T-Shirts"
      }
    },
    {
      "discount": "product_discount",
      "params": {
        "handles": ["jeans"],
        "discount_type": "percentage",
        "value": 15,
        "message": "15% off Jeans"
      }
    }
  ]
}
```

## Facts

Facts are named calculations that transform input data for reuse in conditions and events.

### Basic Fact

```json theme={null}
{
  "facts": {
    "total_quantity": "cart.lines[].quantity | sum(@)"
  },
  "conditions": {
    "$total_quantity": { "gte": 10 }
  }
}
```

The `$` prefix references a fact in conditions.

### Why Use Facts?

* **Reusability**: Calculate once, use everywhere
* **Readability**: Name complex expressions
* **Performance**: Avoid redundant calculations
* **Power**: Use JMESPath or custom filters for complex queries

### Example: Collection Filtering

```json theme={null}
{
  "facts": {
    "sale_items": "cart.lines[?merchandise.product.collections[?handle=='sale']].id"
  },
  "conditions": {
    "$sale_items": { "empty": false }
  },
  "events": [
    {
      "discount": "product_discount",
      "params": {
        "selector": "$sale_items",
        "discount_type": "percentage",
        "value": 25,
        "message": "25% off Sale Items"
      }
    }
  ]
}
```

See [Facts System](../advanced/facts/README.md) for deep dive.

## Input Data Structure

Function Lab receives cart and customer data from Shopify in a standardized format:

```json theme={null}
{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/...",
        "quantity": 2,
        "merchandise": {
          "id": "gid://shopify/ProductVariant/...",
          "title": "Size M",
          "product": {
            "id": "gid://shopify/Product/...",
            "title": "Cool T-Shirt",
            "handle": "cool-t-shirt",
            "vendor": "Awesome Brand",
            "collections": [...]
          }
        }
      }
    ],
    "totalAmount": 100.00,
    "buyerIdentity": {
      "customer": {
        "id": "gid://shopify/Customer/...",
        "email": "customer@example.com",
        "tags": ["VIP", "WHOLESALE"]
      }
    }
  }
}
```

See [Input Structure Reference](../reference/api/input.md) for complete schema.

## Path Notation

Access nested data using dot notation:

| Path                                      | Accesses                      |
| ----------------------------------------- | ----------------------------- |
| `customer.email`                          | Customer's email address      |
| `customer.tags`                           | Array of customer tags        |
| `cart.lines`                              | Array of cart line items      |
| `cart.lines[].merchandise.product.handle` | Product handles for all lines |

### Array Access

Arrays are automatically traversed:

```json theme={null}
{
  "customer.tags": { "includes": "VIP" }
}
```

Checks if **any** tag equals "VIP" (automatic ANY semantics).

## Execution Flow

1. **Input Received**: Shopify sends cart/checkout data
2. **Facts Computed**: Named calculations evaluated once
3. **Conditions Evaluated**: Check if rule should fire
4. **Events Executed**: Generate discounts/operations
5. **Output Returned**: Results sent back to Shopify

## Next Steps

* [How It Works](how-it-works.md) - Detailed execution model
* [Testing](testing.md) - Test and debug your functions
* [Common Patterns](common-patterns.md) - Real-world examples
* [Function Types](../function-types/product-discounts/overview.md) - Explore specific function types
