# ReorderPipelineItem

## Permission Scope

item

## Overview

Reorders an item within its current stage by setting a new 1-based position. Sibling items in the same stage are re-numbered to keep `position` contiguous starting from 1. The item's `stageId` and `lifecycle` are not changed; no PipelineStageTransition record is created. Intended for in-column drag-and-drop on the kanban view, paired with optimistic updates on the client.

## Business Rules

- PipelineItem must exist
- PipelineItem must be OPEN (not DRAFT or CLOSED)
- `position` is 1-based and clamped to the inclusive range `[1, siblingCount]`
- Sibling items are re-numbered so `position` is contiguous within the stage
- `stageId` is unchanged; cross-stage moves go through `movePipelineItem`
- No PipelineStageTransition record is created — reordering within a stage is not an auditable transition

## Process Flow

```mermaid
flowchart TD
    A[Receive reorderPipelineItem input] --> B{PipelineItem exists?}
    B -->|No| C[Return ITEM_NOT_FOUND]
    B -->|Yes| D{PipelineItem OPEN?}
    D -->|No| E[Return ITEM_NOT_OPEN]
    D -->|Yes| F[Load siblings by current stageId]
    F --> G[Clamp position to 1..siblingCount]
    G --> H[Splice item into target index]
    H --> I[Renumber siblings by index]
    I --> J[Return updated PipelineItem]
```

## External Dependencies

- None

## Error Scenarios

- **ITEM_NOT_FOUND**: Specified item ID does not exist
- **ITEM_NOT_OPEN**: PipelineItem is not in OPEN lifecycle (it is DRAFT or CLOSED)

## Test Cases

- moves item to a new position within the same stage
- shifts sibling items when reordering
- clamps position to the end when input exceeds list length
- clamps position to 1 when input is zero or negative
- does not change stageId
- does not create a PipelineStageTransition record
- returns error when item not found
- returns error when item is not OPEN (DRAFT)
- returns error when item is not OPEN (CLOSED)
