# UpdatePipeline

## Permission Scope

pipeline

## Overview

Updates the mutable fields of an existing pipeline: name and description. Only provided fields are updated; omitted fields remain unchanged.

## Business Rules

- Pipeline must exist
- If name is provided, it must be non-empty
- If name is provided, it must be unique per pipelineType across the app (skipped for `locked` pipelines)
- Description is optional and can be cleared
- Consumer extension fields (declared via the `fields` extension point) are passed through to the update; module-managed columns (`id`, `pipelineType`, `createdByUserId`, `status`, `locked`, `itemNumberSeq`, timestamps) are stripped and cannot be set this way

## Process Flow

```mermaid
flowchart TD
    A[Receive updatePipeline input] --> B{Pipeline exists?}
    B -->|No| C[Return PIPELINE_NOT_FOUND]
    B -->|Yes| D{Name provided?}
    D -->|Yes| E{Name non-empty?}
    E -->|No| F[Return INVALID_NAME]
    E -->|Yes| G{Name unique for pipelineType?}
    G -->|No| H[Return DUPLICATE_PIPELINE_NAME]
    G -->|Yes| I[Update pipeline fields]
    D -->|No| I
    I --> J[Return updated Pipeline]
```

## External Dependencies

- None

## Error Scenarios

- **PIPELINE_NOT_FOUND**: Specified pipeline ID does not exist
- **INVALID_NAME**: Name is empty or blank
- **DUPLICATE_PIPELINE_NAME**: A pipeline with the same name and pipelineType already exists. Skipped for `locked` pipelines (managed board; identity is owned by the managing module).

## Test Cases

- updates pipeline name
- updates pipeline description
- passes extension fields through but strips reserved model columns
- returns error when pipeline not found
- returns error when name is empty
- returns error when name duplicates another pipeline of the same pipelineType
- allows renaming a locked pipeline to a name already used by another locked pipeline
