# UpdateTimeEntryCode

## Permission Scope

`timeEntryCode`

## Overview

Corrects a `TimeEntryCode`'s `displayName`, `category`, or `payMapKey`. The `key` itself is immutable once any rule references it — a genuinely new time type must be created as a new code, not a rename of an existing one.

## Business Rules

- `key` cannot be changed once the code is referenced by any `WorkRule` or `EligibilityRule`; an attempt to change it is rejected
- `category`, if changed, is a normalized category key (string) defined by the calculation strategy; any key is accepted (it is not validated against a fixed enum)
- `displayName` changes affect UI presentation only; the `key` and every calculation binding are untouched
- `payMapKey` may be corrected; the mapping remains key-to-key, never name-to-name

## Process Flow

```mermaid
flowchart TD
    A[Receive code id and revised displayName/category/payMapKey] --> B{Code exists?}
    B -- No --> C[Reject: TIME_ENTRY_CODE_NOT_FOUND]
    B -- Yes --> D{key change attempted?}
    D -- Yes --> E[Reject: KEY_IMMUTABLE]
    D -- No --> H[Update displayName / category / payMapKey in place]
    H --> I[key and existing calculation bindings unchanged]
```

## External Dependencies

- [time-tracking::TimeEntryCode](../model/TimeEntryCode.md) model — the entity this command mutates

## Error Scenarios

- **TIME_ENTRY_CODE_NOT_FOUND**: no TimeEntryCode exists for the given id
- **KEY_IMMUTABLE**: an attempt was made to change `key` once it has been referenced

## Test Cases

- renaming `displayName` leaves the `key` and all calculation results unchanged
- an arbitrary category key is accepted on update
- attempting to change an already-referenced `key` is rejected
- updating a non-existent code id is rejected

