---
title: "Schéma grafu — Workflows for Laravel | Roundly"
description: "Dokument roundly.workflows.graph/v1 — pravidlá, odkazy na hodnoty, trvania, strany — a úplné JSON Schemas grafu, šablóny a spoločných definícií."
url: https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel/schema-grafu
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Workflows for Laravel](https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel.md)

# Schéma grafu

Workflow je jeden JSON dokument. Balík ho zverejňuje ako JSON Schema (podmnožina draft 2020-12) cez Workflows::schema()->graph(); obálku šablóny cez Workflows::schema()->template() a spoločné $defs (value, field, party, parties, duration, condition) cez Workflows::schema()->definitions() — schéma grafu k nim pridáva retry a escalation. Konfigurácie uzlov sú typované podľa typu kroku: pozri Workflows::catalogue()->export().

```php
Workflows::schema()->graph();         // the roundly.workflows.graph/v1 JSON Schema
Workflows::schema()->template();      // the roundly.workflows.template/v1 envelope
Workflows::schema()->definitions();   // the shared $defs: value, field, party, parties, duration, condition
Workflows::catalogue()->export();     // every node type's config schema, outcomes and availability
```

## Dokument

```jsonc
{
  "schema": "roundly.workflows.graph/v1",          // required; anything else → invalid_schema_version
  "settings": {                                     // optional; each key has a default
    "actor": "system" | "on_behalf_of",             // default "system"
    "timezone": "Europe/Bratislava",                // IANA; default workflows.timezone → app.timezone
    "calendar": "weekdays",                         // default business calendar
    "limits": { "max_steps": 200 },                 // may only LOWER the configured limit
    "retry": { "max_attempts": 3, "backoff": [30, 120, 600] }
  },
  "nodes": [ {
      "id": "approve_cfo",                          // ^[a-z][a-z0-9_]{0,63}$, unique
      "type": "approval",                           // a catalogue key
      "config": { },                                // validated against the type's config schema
      "retry": { },                                 // optional per-node override
      "escalations": [ ],                           // only on types that support them
      "ui": { "x": 120, "y": 80, "label": "CFO sign-off" }   // free-form; ignored by the engine
  } ],
  "edges": [ {
      "from": "approve_cfo", "to": "notify_rejected",
      "outcome": "rejected"                         // required unless the source's only outcome is `next`
  } ]
}
```

## Pravidlá

- Presne jeden uzol trigger, aspoň jeden uzol end.
- Stropy veľkosti: uzly ≤ graph.max\_nodes (500), hrany ≤ graph.max\_edges (2000), zakódovaný graf ≤ graph.max\_bytes (512 KiB) → graph\_too\_large.
- Hranu určuje dvojica (from, outcome). Dve hrany s rovnakou dvojicou → duplicate\_outcome. Grafom prechádza jeden token: paralelné vetvy neexistujú.
- Hrana bez outcome znamená next a nič iné, preto je povolená len z uzla, ktorého jediný výsledok je next (set\_field, delay, akčný krok, …). Uzol s akýmkoľvek iným výsledkom — aj jediným, ako start\_workflow bez wait (started), wait (received), webhook (queued) — ho musí uviesť na každej hrane, inak pri publikovaní outcome\_label\_required.
- Cyklus musí prechádzať prerušovačom: hranou continue uzla loop alebo oneskorením delay s kladným for. Hrana exhausted uzla loop a oneskorenie s nulovou dĺžkou, until či until\_field sa nerátajú → cycle\_without\_breaker.
- ui sa ukladá doslovne a nikdy sa neinterpretuje (porovnanie hlási zmeny len v ui ako presun).
- Uloženie konceptu kontroluje len štruktúru, takže editor môže uložiť aj nedokončený graf. Publikovanie spustí všetky kontroly.

## Odkazy na hodnoty

Všade, kde schéma povoľuje #/$defs/value, je hodnota literál, {"ref": "<path>"} alebo {"relative": <duration>} — „teraz“ behu plus (pri zápornej hodnote mínus) trvanie, v časovom pásme verzie:

```jsonc
"value": "50000"                                          // a literal
"value": { "ref": "subject.amount" }                       // a registered field of the subject
"value": { "ref": "steps.approve.output.request_id" }      // the output of an ancestor step
"value": { "relative": "P7D" }                             // now + 7 days, in the version timezone
"value": { "relative": { "amount": -3, "unit": "days" } }  // now − 3 days
```

| Cesta | Číta |
| --- | --- |
| `subject.<field>` | Registrované pole subjektu (nikdy neregistrovaný atribút). |
| `owner.<field>` | Registrované pole typu vlastníka. |
| `input.<name>` | Deklarovaný vstup ručného spúšťača. |
| `trigger.<key>` | Payload spúšťača (payload udalosti, telo webhooku). |
| `steps.<node_id>.output.<key>` | Výstup predchádzajúceho kroku. |
| `now` | Aktuálny okamih. |
| `payload.<path>` | Telo webhooku — len v subject.value webhook spúšťača (subjekt sa hľadá skôr, než inštancia vznikne). |

## Trvania

Reťazec ISO 8601 (kalendárny čas v časovom pásme verzie) alebo objekt s amount a unit — minutes, hours, days, weeks, months, business\_minutes, business\_hours, business\_days. calendar prepíše settings.calendar:

```jsonc
"P2D"                                                       // ISO 8601: calendar time in the version timezone
"PT4H"
{ "amount": 2, "unit": "business_days", "calendar": "opening_hours:office" }
```

## Odkazy na strany

```json
{"kind": "user", "id": 12}
{"kind": "field", "field": "subject.requester"}
{"kind": "role", "role": "legal"}
{"kind": "triggered_by"}
```

## Verzovanie schémy

Verziou je reťazec schema. Budúca nekompatibilná zmena dostane nový reťazec; dokumenty roundly.workflows.graph/v1 sa budú naďalej validovať aj spúšťať.

## JSON Schema grafu

Vygenerovaná cez Workflows::schema()->graph() — limity zodpovedajú predvolenej konfigurácii:

```json
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://roundly-consulting.com/schemas/roundly.workflows.graph/v1.json",
    "title": "Workflow graph",
    "type": "object",
    "required": [
        "schema",
        "nodes",
        "edges"
    ],
    "properties": {
        "schema": {
            "const": "roundly.workflows.graph/v1"
        },
        "settings": {
            "type": "object",
            "properties": {
                "actor": {
                    "enum": [
                        "system",
                        "on_behalf_of"
                    ],
                    "default": "system"
                },
                "timezone": {
                    "type": "string",
                    "description": "IANA timezone; default workflows.timezone, else app.timezone."
                },
                "calendar": {
                    "type": "string",
                    "description": "Default business calendar (weekdays, opening_hours:<name> or a host calendar)."
                },
                "limits": {
                    "type": "object",
                    "properties": {
                        "max_steps": {
                            "type": "integer",
                            "minimum": 2,
                            "maximum": 200
                        }
                    },
                    "additionalProperties": false
                },
                "retry": {
                    "$ref": "#/$defs/retry"
                }
            },
            "additionalProperties": false
        },
        "nodes": {
            "type": "array",
            "maxItems": 500,
            "items": {
                "type": "object",
                "required": [
                    "id",
                    "type"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{0,63}$"
                    },
                    "type": {
                        "type": "string",
                        "description": "A step catalogue key."
                    },
                    "config": {
                        "type": "object",
                        "description": "Validated against the type's config schema."
                    },
                    "retry": {
                        "$ref": "#/$defs/retry"
                    },
                    "escalations": {
                        "type": "array",
                        "maxItems": 5,
                        "items": {
                            "$ref": "#/$defs/escalation"
                        }
                    },
                    "ui": {
                        "type": "object",
                        "description": "Free-form (position, label); ignored by the engine."
                    }
                },
                "additionalProperties": false
            }
        },
        "edges": {
            "type": "array",
            "maxItems": 2000,
            "items": {
                "type": "object",
                "required": [
                    "from",
                    "to"
                ],
                "properties": {
                    "from": {
                        "type": "string"
                    },
                    "to": {
                        "type": "string"
                    },
                    "outcome": {
                        "type": "string",
                        "description": "Required unless the source type's only outcome is next."
                    }
                },
                "additionalProperties": false
            }
        }
    },
    "additionalProperties": false,
    "$defs": {
        "value": {
            "description": "A literal, {\"ref\": \"<path>\"} or {\"relative\": <duration>}."
        },
        "field": {
            "type": "string",
            "format": "field-path",
            "maxLength": 200
        },
        "party": {
            "type": "object",
            "required": [
                "kind"
            ],
            "properties": {
                "kind": {
                    "enum": [
                        "user",
                        "field",
                        "role",
                        "triggered_by"
                    ]
                },
                "id": {
                    "type": [
                        "integer",
                        "string"
                    ],
                    "x-workflows-owner-specific": true
                },
                "field": {
                    "$ref": "#/$defs/field"
                },
                "role": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                }
            },
            "additionalProperties": false
        },
        "parties": {
            "type": "array",
            "items": {
                "$ref": "#/$defs/party"
            },
            "minItems": 1,
            "maxItems": 50
        },
        "duration": {
            "anyOf": [
                {
                    "type": "string",
                    "format": "duration"
                },
                {
                    "type": "object",
                    "required": [
                        "amount",
                        "unit"
                    ],
                    "properties": {
                        "amount": {
                            "type": "integer",
                            "minimum": -100000,
                            "maximum": 100000
                        },
                        "unit": {
                            "enum": [
                                "minutes",
                                "hours",
                                "days",
                                "weeks",
                                "months",
                                "business_minutes",
                                "business_hours",
                                "business_days"
                            ]
                        },
                        "calendar": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100
                        }
                    },
                    "additionalProperties": false
                }
            ]
        },
        "condition": {
            "type": "object",
            "description": "A declarative condition: {\"all\"|\"any\": [...]}, {\"not\": {...}} or {\"field\", \"op\", \"value\"}."
        },
        "retry": {
            "type": "object",
            "properties": {
                "max_attempts": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10
                },
                "backoff": {
                    "type": "array",
                    "items": {
                        "type": "integer",
                        "minimum": 0
                    }
                }
            },
            "additionalProperties": false
        },
        "escalation": {
            "type": "object",
            "required": [
                "after",
                "actions"
            ],
            "properties": {
                "after": {
                    "$ref": "#/$defs/duration"
                },
                "actions": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 5,
                    "items": {
                        "type": "object",
                        "required": [
                            "type"
                        ],
                        "properties": {
                            "type": {
                                "enum": [
                                    "notify",
                                    "reassign",
                                    "start_workflow"
                                ]
                            }
                        }
                    }
                }
            },
            "additionalProperties": false
        }
    }
}
```

## JSON Schema šablóny

Vygenerovaná cez Workflows::schema()->template() — obálka exportovanej šablóny aj súboru definície:

```json
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://roundly-consulting.com/schemas/roundly.workflows.template/v1.json",
    "title": "Workflow template",
    "type": "object",
    "required": [
        "schema",
        "definition",
        "graph"
    ],
    "properties": {
        "schema": {
            "const": "roundly.workflows.template/v1"
        },
        "definition": {
            "type": "object",
            "required": [
                "key",
                "name"
            ],
            "properties": {
                "key": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9._-]{0,99}$"
                },
                "name": {
                    "type": "string"
                },
                "subject_type": {
                    "type": [
                        "string",
                        "null"
                    ]
                },
                "description": {
                    "type": [
                        "string",
                        "null"
                    ]
                }
            }
        },
        "graph": {
            "$ref": "roundly.workflows.graph/v1"
        },
        "review": {
            "type": "array"
        },
        "exported_at": {
            "type": "string",
            "format": "date-time"
        },
        "source": {
            "type": "object",
            "properties": {
                "checksum": {
                    "type": "string"
                }
            }
        }
    }
}
```

## Spoločné definície

Vygenerované cez Workflows::schema()->definitions() — $defs, na ktoré sa môže odvolávať schéma konfigurácie každého kroku:

```json
{
    "value": {
        "description": "A literal, {\"ref\": \"<path>\"} or {\"relative\": <duration>}."
    },
    "field": {
        "type": "string",
        "format": "field-path",
        "maxLength": 200
    },
    "party": {
        "type": "object",
        "required": [
            "kind"
        ],
        "properties": {
            "kind": {
                "enum": [
                    "user",
                    "field",
                    "role",
                    "triggered_by"
                ]
            },
            "id": {
                "type": [
                    "integer",
                    "string"
                ],
                "x-workflows-owner-specific": true
            },
            "field": {
                "$ref": "#/$defs/field"
            },
            "role": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100
            }
        },
        "additionalProperties": false
    },
    "parties": {
        "type": "array",
        "items": {
            "$ref": "#/$defs/party"
        },
        "minItems": 1,
        "maxItems": 50
    },
    "duration": {
        "anyOf": [
            {
                "type": "string",
                "format": "duration"
            },
            {
                "type": "object",
                "required": [
                    "amount",
                    "unit"
                ],
                "properties": {
                    "amount": {
                        "type": "integer",
                        "minimum": -100000,
                        "maximum": 100000
                    },
                    "unit": {
                        "enum": [
                            "minutes",
                            "hours",
                            "days",
                            "weeks",
                            "months",
                            "business_minutes",
                            "business_hours",
                            "business_days"
                        ]
                    },
                    "calendar": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                    }
                },
                "additionalProperties": false
            }
        ]
    },
    "condition": {
        "type": "object",
        "description": "A declarative condition: {\"all\"|\"any\": [...]}, {\"not\": {...}} or {\"field\", \"op\", \"value\"}."
    }
}
```

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/workflows-for-laravel.md)
