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

# Models

> Understanding performance models for athlete evaluation

## Overview

A **Model** is a hierarchical scoring system that evaluates athletes against configurable performance metrics. Models transform raw athlete data (statistics, measurements, assessments) into normalized scores that roll up to an overall valuation between 0 and 1.

### Purpose

Models enable teams to:

* **Evaluate athletes objectively** using data-driven metrics with customizable weighting
* **Compare athletes** across different positions using position-specific scoring criteria
* **Track performance** against defined targets and benchmarks
* **Segment evaluation** by athlete characteristics (position, experience, etc.)

### Use Cases

* Recruitment evaluation and ranking
* Transfer portal analysis
* Performance benchmarking against team standards
* Position-specific athlete assessment
* Multi-factor valuation for roster decisions

## Model Structure

Every model is a **tree of metrics** that aggregate into an overall score.

### Root Metric

All models have a single root metric called "Overall Valuation" (id: `root`). This is the top-level aggregation point where all child metric scores bubble up. The root metric:

* Cannot be deleted or renamed
* Has a fixed path of `""`
* Aggregates all direct children using weighted scoring

### Metric Hierarchy

Metrics are organized as a tree using **paths**. Each metric's path represents its position in the hierarchy:

| Path                   | Description            |
| ---------------------- | ---------------------- |
| `""`                   | Root metric            |
| `abc123`               | Direct child of root   |
| `abc123/def456`        | Child of `abc123`      |
| `abc123/def456/ghi789` | Nested two levels deep |

A metric's parent is determined by its path. The path `abc123/def456` has parent path `abc123`.

## Metric Types

### AUTO

Data-driven metrics that pull values from athlete variables (statistics, measurements).

* Requires an `variable_id` linking to the data source
* Requires an `agg_type` specifying how to aggregate multiple data points
* Value is fetched and calculated automatically based on configuration

### MANUAL

Static metrics where values are entered directly by users.

* No automatic data fetching
* Values are stored as athlete metric values
* Useful for subjective assessments or data not captured in variables

### GROUP

Composite metrics that aggregate child metrics.

* Act as organizational containers in the tree
* Score is calculated from weighted child scores
* Can be static (just aggregates children) or dynamic (has its own data source)

<Note>
  GROUP metrics with no children and non-zero weight are invalid. A group's
  score derives from its children.
</Note>

## Metric Configuration

### Weight

Each metric has a **weight** (0-1) representing its contribution to the parent's score.

* Weights of all siblings should sum to 1 (100%)
* A weight of 0.25 means this metric contributes 25% of the parent's score
* Weight of 0 effectively disables the metric

### Interpolation Methods

Interpolation defines how raw values map to scores. Every interpolation has three boundary values:

* **Worst**: The raw value that produces score 0
* **Target**: The raw value that produces the full weighted score
* **Best**: The upper bound of the value range

| Type          | Behavior                                                       |
| ------------- | -------------------------------------------------------------- |
| `linear`      | Linear interpolation from worst to best                        |
| `exponential` | Slow start, accelerating gains (uses `base` parameter)         |
| `logarithmic` | Fast start, diminishing returns (uses `base` parameter)        |
| `binary`      | Score is 0 below target, full weight at or above target        |
| `bell_curve`  | Maximum score at target, decreasing toward both worst and best |
| `stepwise`    | Discrete steps with defined thresholds and weights             |

#### Stepwise Configuration

Stepwise interpolation uses an array of steps, each with:

```typescript theme={null}
{
  target: number; // Threshold value
  weight: number; // Score at this step (0-1)
  label: string | null; // Optional label (e.g., "Good", "Excellent")
}
```

### Units

Units define how values are displayed and interpreted:

| Unit Type                     | Description                                |
| ----------------------------- | ------------------------------------------ |
| `decimal`                     | Decimal number with configurable precision |
| `integer`                     | Whole number                               |
| `percentage`                  | Displayed as percentage                    |
| `boolean`                     | True/false toggle                          |
| `custom`                      | Discrete options from a defined list       |
| `yards`, `feet`, `inches`     | Distance measurements                      |
| `seconds`, `minutes`, `hours` | Time measurements                          |

### Fallback Behavior

When data is missing for a metric, the **fallback** determines behavior:

| Fallback Type | Behavior                                                    |
| ------------- | ----------------------------------------------------------- |
| `value`       | Use a specified default value                               |
| `ignore`      | Exclude this metric from calculation (redistributes weight) |
| `none`        | Model cannot calculate without this data                    |

## Model Groups

Model groups enable **segmentation** - different metric configurations for different athlete types.

### Group Hierarchy

Groups form a tree structure similar to metrics:

* Groups can have parent groups (creating nested segments)
* Each group can filter by athlete **position**
* Each group can filter by **data conditions** (e.g., "Total Points > 100")

### Universal vs Group-Specific Metrics

* **Universal metrics** (`model_group_id: null`) apply to all athletes
* **Group-specific metrics** only appear when evaluating athletes matching that group

### Metric Overrides

Overrides allow customizing a metric's configuration for specific groups without duplicating the entire metric.

An override can modify:

* Weight
* Interpolation type and details
* Fallback behavior
* Data filters

Overrides are applied by depth - deeper group overrides take precedence over shallower ones.

### Applicability

When evaluating an athlete, the system:

1. Finds all groups the athlete matches (by position and data filters)
2. Builds "branches" from root to each applicable leaf group
3. Collects all universal metrics plus group-specific metrics from applicable branches
4. Merges overrides from shallowest to deepest group

## Score Calculation

### Flow

1. **Data Aggregation**: For AUTO metrics, fetch and aggregate raw data
2. **Interpolation**: Map raw value to normalized score using interpolation method
3. **Weighting**: Multiply normalized score by metric weight
4. **Propagation**: Roll up child scores to parent groups

### Group Score Calculation

For GROUP metrics, the score is derived from children:

1. Sum all child weighted scores
2. Calculate the sum of all child weights
3. Determine children's performance ratio (scores sum / weights sum)
4. Adjust base weight by children's performance

<Note>
  If any child has a null score and no fallback, the parent group's score
  becomes null.
</Note>

### Example

Consider a model with:

```
Root (weight: 1.0)
├── Athleticism (GROUP, weight: 0.4)
│   ├── Speed (AUTO, weight: 0.5)
│   └── Strength (AUTO, weight: 0.5)
└── Production (GROUP, weight: 0.6)
    ├── Points (AUTO, weight: 0.7)
    └── Assists (AUTO, weight: 0.3)
```

If an athlete scores:

* Speed: 0.8 (80% of target)
* Strength: 0.6 (60% of target)
* Points: 0.9 (90% of target)
* Assists: 0.7 (70% of target)

Calculation:

* Athleticism = (0.8 × 0.5 + 0.6 × 0.5) × 0.4 = 0.28
* Production = (0.9 × 0.7 + 0.7 × 0.3) × 0.6 = 0.504
* **Overall = 0.28 + 0.504 = 0.784**

## Key Types Reference

### ClientSideModel

The complete model object containing all data:

```typescript theme={null}
{
  data: Variable;        // Model metadata
  groups: ModelGroup[];         // Segmentation groups
  metrics: ClientSideModelMetric[]; // All metrics
}
```

### ModelMetric

A single metric in the tree:

```typescript theme={null}
{
  id: ModelMetricId;
  name: string | null;
  path: string;                 // Hierarchy position
  type: "auto" | "manual" | "group";
  value_type: "static" | "dynamic";
  weight: number;               // 0-1

  // Data source (AUTO metrics)
  variable_id: VariableId | null;
  agg_type: AggregationType | null;

  // Scoring configuration
  interpolation_type: InterpolationType;
  interpolation_details: { worst, target, best, ... };

  // Unit display
  unit_type: UnitType;
  unit_details: { decimal_places?, steps?, ... };

  // Missing data handling
  fallback_type: "value" | "ignore" | "none";
  fallback_details: { value? } | null;

  // Segmentation
  model_group_id: ModelGroupId | null;
  layout: { x, y };             // UI position
}
```

### ModelGroup

A segmentation group:

```typescript theme={null}
{
  id: ModelGroupId;
  name: string | null;
  parent_group_id: ModelGroupId | null;
  position: AthletePosition | null;     // Position filter
  data_filters: DataFilter[] | null;    // Data-based filters
  order: number | null;
}
```

### ModelMetricOverride

Group-specific metric customization:

```typescript theme={null}
{
  id: ModelMetricOverrideId;
  metric_id: ModelMetricId;
  model_group_id: ModelGroupId;

  // All fields nullable - only set fields override
  weight: number | null;
  interpolation_type: InterpolationType | null;
  interpolation_details: { ... } | null;
  fallback_type: FallbackType | null;
  fallback_details: { ... } | null;
  data_filters: DataFilter[] | null;
}
```

## Validation

A model is valid when all metrics pass validation. Common validation errors:

| Error                          | Cause                                                  |
| ------------------------------ | ------------------------------------------------------ |
| `missing_metric_data`          | AUTO metric without variable or aggregation            |
| `invalid_metric_configuration` | Invalid interpolation bounds, zero weight on non-group |
| `incomplete_group_metrics`     | GROUP with non-zero weight but no children             |
| `structural_issues`            | Orphaned metric (parent doesn't exist)                 |
| `variable_not_available`       | Linked variable is disabled                            |
| `child_weight_sum_over_1`      | Children weights exceed 100%                           |
