# TimeEntryCode

## Description

TimeEntryCode is the **semantic catalog of time types** (work codes) — the stable vocabulary that every calculation and pay mapping in the platform binds to. It separates a machine-stable `key` (an enum-like identifier such as `OVERTIME_BEYOND_STATUTORY`) from a human-facing `displayName` that exists for UI only. Calculation, premium determination, and payroll mapping resolve a time type by its `key`; the display name may be renamed freely without affecting any computation (ADR-015).

This directly answers the cautionary lesson of issue #14: the legacy sdx engine matched overtime logic against the Japanese display-name strings of `RecordType` ("holiday", "statutory holiday", ...), so renaming a label silently broke calculation. TimeEntryCode makes that failure structurally impossible — the display name is never load-bearing. Each code also carries a `payMapKey`, the stable key a downstream (future) payroll domain uses to route the calculated time to an earnings/pay code, so the work-rules → payroll seam is also key-bound rather than name-bound.

TimeEntryCode is master data (not effective-dated): the catalog of *what kinds of time exist* is a stable classification. What changes over time — rates, thresholds, which codes apply to whom — lives on the effective-dated `WorkRule` and `EligibilityRule`, which reference these codes by `key`.

## Domain Model Definitions

### Model type

Standard

### Command Definitions

Command docs are out of scope for this design phase (ADR-011). Anticipated commands:

- createTimeEntryCode — register a new time type with a stable `key`, `category`, `displayName`, and `payMapKey`
- updateTimeEntryCode — correct the `displayName`, `category`, or `payMapKey`; the `key` is immutable once referenced
- deleteTimeEntryCode — remove a code only when no WorkRule or EligibilityRule references its `key`

### Query Definitions

- getTimeEntryCode — retrieve a single time-entry code by id
- getTimeEntryCodeByKey — resolve a code by its stable `key` (the lookup calculation uses)
- listTimeEntryCodes — paginated catalog of all time-entry codes (PaginationInput / buildPaginatedResult conventions)
### Models

- TimeEntryCode

### Invariants

- Calculation, premium determination, and pay mapping bind to `key`, never to `displayName` — renaming a display name must not change any computed result (ADR-015, issue #14)
- `key` is a stable, unique, machine-facing identifier; it is immutable once any rule references it (a new time type is a new code, not a renamed one)
- `category` is an open, normalized string key defined by the calculation strategy — not a fixed/closed enum. It is referenced by key, never by display name. The default JP strategy emits exactly these keys — exported as `jpTimeEntryCodeCategories` so consumers seed their catalogs against the same source of truth: `WORK` (regular worked time), `OVERTIME_BEYOND_STATUTORY` (statutory-excess overtime — beyond the legal limit, premium-bearing), `NIGHT` (late-night), `HOLIDAY_STATUTORY` (statutory holiday), and `HOLIDAY_PRESCRIBED` (prescribed/company holiday). A consumer on the default strategy must register a TimeEntryCode whose `category` matches each key it wants resolved. In the JP strategy, holiday categories use the same STATUTORY / PRESCRIBED distinction as `CompanyHoliday.holidayKind`. Other jurisdictions may define their own category keys as pluggable per-jurisdiction time classification is introduced
- `displayName` is UI-only and carries no calculation semantics; it may be localized or renamed without side effects
- `payMapKey` is a stable key that maps the code to a downstream pay/earnings code; the mapping is key-to-key, never name-to-name
- A code referenced by any rule is preserved (not hard-deleted) so historical calculated results remain traceable

### Relationships

- **Referenced by WorkRule**: `premiumRatePercent` and break/overtime treatment are keyed by TimeEntryCode `key`/`category`, not display name
- **Referenced by EligibilityRule**: eligibility grants are expressed as "which targets may use which TimeEntryCode `key`"
- **Referenced by time-tracking (cross-module)**: the CalculationTag stamped on each CalculatedTimeBlock (ADR-014) carries this code's `key`, making "which rule/type produced this block" reconstructable
- **Referenced by payroll (future)**: `payMapKey` is the stable seam to a future payroll earnings code (ADR-018)
