# UpdateDepartment

## Permission Scope

organizationUnit

## Overview

UpdateDepartment modifies the name or parent department of an existing department. Department code and company ownership are fixed by the existing record and are not part of the update input. Parent department changes are validated to prevent self-references and circular hierarchies. Updating is allowed on both ACTIVE and INACTIVE departments.

This command supports organizational restructuring and department renaming.

## Business Rules

- Department must exist
- Name, if provided, must be non-empty
- Department code and company ownership are not part of the update input
- Parent department, if provided, must exist and belong to the same company
- A department cannot reference itself as its own parent
- Circular parent references are rejected
- Updating parent department is allowed on both ACTIVE and INACTIVE departments

## Process Flow

```mermaid
flowchart TD
    A[Receive update request] --> B{Department exists?}
    B -->|No| C[Return error: DEPARTMENT_NOT_FOUND]
    B -->|Yes| D{Name provided and empty?}
    D -->|Yes| E[Return error: INVALID_NAME]
    D -->|No| F{Parent change requested?}
    F -->|Yes| G{Self-reference?}
    G -->|Yes| H[Return error: SELF_REFERENCE]
    G -->|No| I{Parent exists in same company?}
    I -->|No| J[Return error: PARENT_NOT_FOUND]
    I -->|Yes| K{Circular reference?}
    K -->|Yes| L[Return error: CIRCULAR_REFERENCE]
    K -->|No| M[Update department record]
    F -->|No| M
    M --> N[Return updated department]
```

## External Dependencies

- [organization::detectDepartmentCircularReference](../queries/DetectDepartmentCircularReference.md) - Validates that reparenting would not create a cycle

## Error Scenarios

- **DEPARTMENT_NOT_FOUND**: Specified department ID does not exist
- **INVALID_NAME**: Name is empty, whitespace-only, or not provided
- **SELF_REFERENCE**: Department cannot reference itself as its parent
- **PARENT_NOT_FOUND**: Referenced parent department does not exist or belongs to a different company
- **CIRCULAR_REFERENCE**: Reparenting would create a circular hierarchy

## Test Cases

- updates department name
- updates parent department
- removes parent department (promotes to top-level)
- returns error when department does not exist
- returns error when name is empty
- returns error when name is whitespace-only
- returns error when setting self as parent
- returns error when parent does not exist
- returns error when parent belongs to different company
- returns error when reparenting creates circular reference
- updates parent on INACTIVE department
