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

# Workflows — plan actions

> The CREATE_OR_GET_PLAN and ADD_ITEMS_TO_PLAN actions: every config field, per plan type, with all strategies and scopes.

The two plan-building actions create (or reuse) a plan and then fill it. The other two
actions — webhook and email — are on the
[Integrations](/en/developers/workflows/integrations) page.

## CREATE\_OR\_GET\_PLAN

Creates a plan, or reuses a matching one, for the run. Common fields: `name` and
`description` (both interpolated). The rest depends on `planType`.

<AccordionGroup>
  <Accordion title="RESTOCK">
    ```json theme={null}
    {
      "actionType": "CREATE_OR_GET_PLAN",
      "planType": "RESTOCK",
      "brandSource": { "kind": "static", "brandId": "<uuid>" },
      "collectionSource": { "kind": "static", "collectionId": "<uuid>" },
      "deadline": { "kind": "relative", "offsetDays": 30 }
    }
    ```

    `brandSource` and `collectionSource` are each `{ kind: "static", … }` or
    `{ kind: "fromTrigger" }` (resolve from the triggering entity). `deadline` is a
    [date offset](/en/developers/workflows/integrations#date-offsets).
  </Accordion>

  <Accordion title="REBALANCE">
    ```json theme={null}
    {
      "planType": "REBALANCE",
      "outgoingShopId": "<uuid>",
      "ingoingShopId": "<uuid>",
      "collectionSource": { "kind": "fromTrigger" },
      "deadline": { "kind": "relative", "offsetDays": 14 }
    }
    ```

    `outgoingShopId` / `ingoingShopId` (source / destination) are required.
  </Accordion>

  <Accordion title="MARKDOWN">
    ```json theme={null}
    {
      "planType": "MARKDOWN",
      "season": "SS26",
      "startDate": { "kind": "relative", "offsetDays": 0 },
      "endDate": { "kind": "relative", "offsetDays": 30 },
      "collectionSource": { "kind": "fromTrigger" }
    }
    ```

    `season`, `startDate`, `endDate` are optional.
  </Accordion>

  <Accordion title="SUPPLIER_RETURN">
    ```json theme={null}
    { "planType": "SUPPLIER_RETURN", "supplierId": "<uuid>", "sourceShopId": "<uuid>", "deadline": { "kind": "relative", "offsetDays": 21 } }
    ```

    `supplierId` is the required discriminator for find-or-create; `sourceShopId` is optional.
  </Accordion>

  <Accordion title="SUPPLIER_EXCHANGE">
    ```json theme={null}
    { "planType": "SUPPLIER_EXCHANGE", "supplierId": "<uuid>", "sourceShopId": "<uuid>", "destinationShopId": "<uuid>", "deadline": { "kind": "relative", "offsetDays": 21 } }
    ```

    `supplierId` required; `sourceShopId` (RETURN side) and `destinationShopId` (RECEIVE side) optional.
  </Accordion>
</AccordionGroup>

**Output:** `planId`, `planType`, `planName`, `isNew` — available downstream as
`{{steps.<nodeId>.output.planId}}` etc.

## ADD\_ITEMS\_TO\_PLAN

Adds items to the plan created by a `CREATE_OR_GET_PLAN` node. Common fields:

| Field              | Meaning                                                                        |
| ------------------ | ------------------------------------------------------------------------------ |
| `sourcePlanNodeId` | The id of the create-plan node this fills.                                     |
| `planType`         | Must match the source plan.                                                    |
| `entityFilters`    | Optional `{ includeTags, excludeTags }` to narrow which entities become items. |
| `maxItems`         | Optional hard cap on how many items are added.                                 |

### Scopes

* **Shop scope** (`shopScope`): `{ kind: "all" }`, `{ kind: "specific", shopIds: [...] }`,
  or `{ kind: "fromTrigger" }`. (Not used for rebalance — shops come from the plan header.)
* **Size scope** (`sizeScope`): `{ kind: "all" }` or
  `{ kind: "belowStockThreshold", threshold: <n> }`.

### Strategies

<AccordionGroup>
  <Accordion title="Quantity strategy (restock / rebalance / supplier)">
    ```json theme={null}
    { "kind": "fixed", "quantity": 10 }
    { "kind": "fillToTarget", "target": 50 }
    { "kind": "scoreDriven" }
    ```

    * `fixed` — add a literal quantity per item.
    * `fillToTarget` — top each item up to `target` (only the delta is added).
    * `scoreDriven` — the data platform's resolver reads the decision vector to set the
      quantity (no app-side parameters).
  </Accordion>

  <Accordion title="Matching strategy (REBALANCE only)">
    ```json theme={null}
    { "kind": "fixed" }
    { "kind": "scoreDriven" }
    ```

    `scoreDriven` routes to the rebalance matching resolver (surplus/deficit/transfer-urgency
    scores → bipartite matching of source to destination shops).
  </Accordion>

  <Accordion title="Discount strategy (MARKDOWN only)">
    ```json theme={null}
    { "kind": "fixed", "percent": 30 }
    { "kind": "scoreDriven" }
    { "kind": "recommended", "fallbackPercent": 15, "maxDiscountPct": 70, "marginFloorPct": 0 }
    ```

    * `fixed` — apply a literal `percent` (0–100).
    * `scoreDriven` — the decision layer's recommended-discount resolver.
    * `recommended` — decision-layer discount with three bounded knobs; defaults shown
      (`fallbackPercent` 15, `maxDiscountPct` 70, `marginFloorPct` 0).
  </Accordion>
</AccordionGroup>

### Per-plan-type fields

| Plan type           | Item config                                                         |
| ------------------- | ------------------------------------------------------------------- |
| `RESTOCK`           | `quantityStrategy`, `shopScope`, `sizeScope`                        |
| `REBALANCE`         | `quantityStrategy`, `sizeScope`, `matchingStrategy` (no shop scope) |
| `MARKDOWN`          | `discountStrategy`, `shopScope`, `sizeScope`                        |
| `SUPPLIER_RETURN`   | `quantityStrategy`, `reasonCode` (applied to every item)            |
| `SUPPLIER_EXCHANGE` | `side` (`RETURN`/`RECEIVE`), `quantityStrategy`                     |

**Output:** `addedCount`, `skippedCount` — available as
`{{steps.<nodeId>.output.addedCount}}`.

<Note>
  Items added by a workflow carry their decision-vector attribution into the plan's
  [activity log](/en/inventory-plans/lifecycle#activity--audit-trail), and the same
  [business rules](/en/intelligence-layer/rules-and-rulesets) apply as for manual edits.
</Note>
