# FlowDrop Workflow

Provides the workflow configuration entity type for storing and managing workflow definitions.

## API Stability

`FlowDropWorkflowInterface` and the `WorkflowSchema*Interface` services
(`Builder`, `Differ`, `Resolver`, `DriftDetector`) are `@api` — contrib
modules can type-hint against them with the usual semver guarantees on 1.x
releases. Implementing classes are `@internal`.

Other PHP classes in this module remain `@internal`. See the [BC Policy](../../docs/reference/api/bc-policy.md) for details.

## Declaring a typed interface

Each workflow can declare named input and output ports, exposing internal
nodes/ports to external callers under stable names. Edit the workflow and
check **Declare input schema** / **Declare output schema** under "Schema",
then expose ports.

On save, the workflow's **FlowDrop Schema snapshot** is rebuilt and
`schema_version` is bumped semver-style (tightening = major, loosening =
minor). Callers can pin compatibility ranges; the schema API endpoint
returns the snapshot plus version.

The contract subset stored in snapshots covers every constraint key
`FlowDropNodeProcessorInterface::getParameterSchema()` documents as
supported (`type`/`enum`/`format`/`default`/`required`/`properties`/`items`/
`minimum`/`maximum`/`minLength`/`maxLength`/`pattern`). Annotations
(`title`/`description`/`examples`) are stripped from the snapshot to avoid
freezing translations.

## Running another workflow from a workflow

Two surfaces, pick by intent:

| Need | Use |
|------|-----|
| You know the target workflow when designing the canvas — drag it as a typed node with declared inputs/outputs | **`WorkflowNode` derivative** (`workflow:<id>`) from `flowdrop_workflow_executor` |
| You pick the workflow at runtime via a `workflow_id` parameter (multi-tenancy, A/B routing, data-driven dispatch) | **`WorkflowExecutor`** plugin from `flowdrop_workflow_executor` |

Both delegate to the same `WorkflowExecutionServiceInterface` underneath, so
recursion guard (depth 5), circular-reference detection, and queue dispatch
are shared.

## REST API

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/flowdrop/workflows` | List workflows (supports `limit`, `offset`, `search`) |
| POST | `/api/flowdrop/workflows` | Create workflow |
| GET | `/api/flowdrop/workflows/{id}` | Get workflow |
| PUT | `/api/flowdrop/workflows/{id}` | Update workflow |
| DELETE | `/api/flowdrop/workflows/{id}` | Delete workflow |
| GET | `/api/flowdrop/workflows/{id}/schema` | Get declared FlowDrop Schema + version |

The schema endpoint emits an `ETag: "<schema_version>"` header — clients can
issue `If-None-Match` for cheap `304 Not Modified` responses. Pass
`?annotated=1` to re-attach live `title`/`description` from source plugins
for UI consumers.

## Permissions

| Permission | Description |
|------------|-------------|
| `administer flowdrop_workflow` | Full administration access |
| `view flowdrop_workflow` | View workflow list and details |
| `access workflow schemas` | Read a workflow's declared schemas via the schema API. Grant to API-consumer roles without granting full workflow administration. |

## Configuration Export Warning

Workflows are stored as Drupal config entities. Running `drush config:export` will export all workflow definitions — including full node and edge data — as YAML files under `config/sync/flowdrop_workflow.flowdrop_workflow.*.yml`.

**Node configurations may contain sensitive data** such as API endpoints, credentials, prompt templates, or internal logic depending on the executor plugins used.

Before committing exported config to version control:

- Review workflow config files for sensitive values.
- Use [Config Split](https://www.drupal.org/project/config_split) to exclude production-specific workflows from VCS if they contain sensitive parameters.
- Add a `.gitignore` pattern (e.g., `config/sync/flowdrop_workflow.flowdrop_workflow.*.yml`) if workflows should never be version-controlled in your project.
