# CreateDepartment

## Permission Scope

organizationUnit

## Overview

CreateDepartment establishes a new department within a company in ACTIVE status. Each department has a unique code scoped to its company, a human-readable name, and an optional parent department reference for building organizational hierarchies.

This command supports initial organizational structure setup and ongoing expansion of department trees.

## Business Rules

- Department code is required and must be non-empty
- Department code must be unique within the same company
- Department code is immutable after creation
- Department name is required and must be non-empty
- Company must exist and be referenced by companyId
- Parent department, if provided, must exist and belong to the same company
- Department is always created in ACTIVE status

## Process Flow

```mermaid
flowchart TD
    A[Receive create request] --> B{Validate code and name}
    B -->|Invalid| C[Return error: INVALID_CODE or INVALID_NAME]
    B -->|Valid| D{Company exists?}
    D -->|No| E[Return error: COMPANY_NOT_FOUND]
    D -->|Yes| F{Code unique in company?}
    F -->|No| G[Return error: DUPLICATE_CODE]
    F -->|Yes| H{Parent department provided?}
    H -->|Yes| I{Parent exists in same company?}
    I -->|No| J[Return error: PARENT_NOT_FOUND]
    I -->|Yes| K[Create department record]
    H -->|No| K
    K --> L[Set status: ACTIVE]
    L --> M[Return created department]
```

## External Dependencies

- None

## Error Scenarios

- **INVALID_CODE**: Department code is empty or not provided
- **INVALID_NAME**: Name is empty, whitespace-only, or not provided
- **COMPANY_NOT_FOUND**: Specified company ID does not exist
- **DUPLICATE_CODE**: Department with same code already exists in the same company
- **PARENT_NOT_FOUND**: Referenced parent department does not exist or belongs to a different company

## Test Cases

- creates top-level department in ACTIVE status
- creates department with parent department
- throws when code is empty
- throws when code is whitespace-only
- throws when name is empty
- throws when name is whitespace-only
- throws when company does not exist
- throws when code already exists in same company
- allows same code in different companies
- throws when parent department does not exist
- throws when parent department belongs to different company
