# Department

## Description

Department represents a functional organizational unit within a company — such as Sales, Engineering, Finance, or Human Resources. Each department belongs to exactly one company and is identified by a unique code scoped to that company. Departments form a self-referential hierarchy through an optional parent department reference, enabling the modeling of organizational trees (e.g., Engineering > Backend Engineering > Platform Team). Manager assignment is deferred to a future HR/employee module.

Examples: "ENG" (Engineering), "FIN" (Finance), "ENG-BE" (Backend Engineering under Engineering).

## Domain Model Definitions

### Model type

Stateful

#### State Transitions

```mermaid
stateDiagram-v2
    [*] --> Active: createDepartment
    Active --> Inactive: deactivateDepartment
    Inactive --> Active: reactivateDepartment
```

| Operation | From | To | Command |
|-----------|------|----|---------|
| deactivate | ACTIVE | INACTIVE | [deactivateDepartment](../command/DeactivateDepartment.md) |
| reactivate | INACTIVE | ACTIVE | [reactivateDepartment](../command/ReactivateDepartment.md) |

### Command Definitions

- [createDepartment](../command/CreateDepartment.md) - Create a new department in ACTIVE status
- [updateDepartment](../command/UpdateDepartment.md) - Update department name or parent department
- [deactivateDepartment](../command/DeactivateDepartment.md) - Transition department from ACTIVE to INACTIVE
- [reactivateDepartment](../command/ReactivateDepartment.md) - Transition department from INACTIVE to ACTIVE

### Query Definitions

- [getDepartment](../query/GetDepartment.md) - Retrieve a department by ID or code
- [getDepartmentChildren](../query/GetDepartmentChildren.md) - Retrieve direct child departments of a given department
- [detectDepartmentCircularReference](../query/DetectDepartmentCircularReference.md) - Validate that reparenting would not create a cycle
- [listDepartmentsByCompany](../query/ListDepartmentsByCompany.md) - List all departments for a given company

### Models

- Department

### Invariants

- Department code is required, unique per company, and immutable after creation
- Department name is required and must be non-empty
- A department must reference an existing, valid company
- A department cannot reference itself as its own parent
- Circular parent references are rejected (A → B → C → A)
- A department cannot be deactivated while it has active sub-departments
- Updating a department's parent is allowed in both ACTIVE and INACTIVE states
- Department codes from different companies do not conflict (company-scoped uniqueness)

### Relationships

- **Belongs To Company**: Each department references exactly one Company via companyId
- **Self-Referential Parent-Child**: Each department optionally references another Department as its parent via parentDepartmentId, forming a tree hierarchy
- **Referenced By Downstream Modules**: Departments are referenced by future modules for cost allocation, approval workflows, and reporting
