# UpdateItem

## Overview

updateItem modifies mutable fields of an existing item — name, barcode, and unit of measure (UoM). The item can be looked up by `id` or `sku`. The set of updatable fields depends on the item's current lifecycle status.

This command supports the DRAFT review workflow (correcting barcodes, setting names before activation) as well as post-activation updates to non-transactional fields.

## Business Rules

- Target item must exist in the system (looked up by `id` or `sku`)
- Name can be updated in any status (DRAFT, ACTIVE, INACTIVE)
- Barcode can be updated in any status; must remain unique across all items when provided
- Barcode can be cleared (set to null) to remove it from the item
- UoM can be updated only when the item is in DRAFT status — once activated, UoM is locked to preserve transaction consistency
- UoM must reference an existing active Unit from the primitives module
- At least one field must be provided for update (no-op updates are rejected)

## Process Flow

```mermaid
flowchart TD
    A[Receive update request] --> B{Lookup by id or sku}
    B -->|Not found| C[Return error: not found]
    B -->|Found| F{Any field provided?}
    F -->|No| G[Return error: no fields to update]
    F -->|Yes| H{Barcode provided?}
    H -->|Yes| I{Barcode unique?}
    I -->|No| J[Return error: duplicate barcode]
    I -->|Yes| K{UoM change requested?}
    H -->|No| K
    K -->|Yes| L{Status is DRAFT?}
    L -->|No| M[Return error: UoM locked after activation]
    L -->|Yes| N{UoM valid and active?}
    N -->|No| O[Return error: invalid UoM]
    N -->|Yes| P[Apply updates]
    K -->|No| P
    P --> Q[Return updated item]
```

## External Dependencies

- [primitives::Unit](../../../primitives/docs/models/Unit.md) - Validates that the referenced UoM exists and is active (when UoM is being updated)

## Error Scenarios

- **ITEM_NOT_FOUND**: Specified item does not exist
- **DUPLICATE_BARCODE**: An item with the same barcode already exists
- **UNIT_NOT_FOUND**: Referenced unit does not exist or is inactive
- **UOM_LOCKED**: UoM cannot be changed after item has been activated (status is ACTIVE or INACTIVE)
- **NO_FIELDS_TO_UPDATE**: No updatable fields were provided in the request

## Test Cases

- returns error when item does not exist
- returns error when no fields to update
- returns error when barcode is duplicate
- returns error when changing UoM on non-DRAFT item
- returns error when changing UoM on INACTIVE item
- returns error when new UoM does not exist
- updates name in any status
- looks up item by sku and updates name
- updates barcode in any status
- clears barcode by setting to null
- updates UoM in DRAFT status
- passes custom fields through to set
