# EligibilityRule

## Description

EligibilityRule is the **applicability layer** (eligibility rules) — it declares *which population may be assigned which rule*: which `Worker`, `Position`, `JobProfile`, or employment type may be assigned which `WorkRule`. It is the Workday "Eligibility Rule" analogue (issue #7): rather than hard-coding "managers are exempt from overtime" in the calculation, that policy is a data row that says *this target → an assignable WorkRule*. The grant was narrowed to `WORK_RULE` only in #39: `grantType` is now a single-value enum, and the former `TIME_ENTRY_CODE` grant value and its companion `timeEntryCodeKey` field were removed (the assignment side only ever consulted `WORK_RULE`).

Every side of an EligibilityRule is expressed by **stable id**, not by display name (ADR-015): the target is identified by id — a workforce identity (worker id / position id / job-profile id) or an EmploymentType / WorkRegime catalog id — and the grant is identified by WorkRule identity. A supervisory/managerial-staff exemption or a store-staff work rule are all data — changing the policy is inserting or superseding a rule, not editing code.

EligibilityRule is effective-dated (ADR-013): eligibility itself changes over time (a role becomes exempt for a population), and the rule in force on any calculated date is reconstructable. Resolution is an `asOf(date)` read: for a given worker on a date, the engine collects the eligibility generations in force to determine the assignable WorkRule. Actual enforcement against WorkRuleAssignment is tracked in #41.

## Domain Model Definitions

### Model type

Standard

### Command Definitions

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

- createEligibilityRule — declare that a target (worker/position/job-profile/employment-type/work-regime) may be assigned a WorkRule (initial generation)
- updateEligibilityRule — record a change to the target or grant as a new effective-dated generation, closing the prior one
- deleteEligibilityRule — remove an eligibility grant only when it is not the sole grant a current assignment relies on

### Query Definitions

- getEligibilityRule — retrieve a single eligibility generation by id
- listEligibilityRules — paginated list of eligibility generations (history included)
- listActiveEligibilityRules — current generations (`effectiveEnd IS NULL`) as of today, paginated
### Models

- EligibilityRule

### Invariants

- Effective-dated per ADR-013: each record carries `effectiveStart`, nullable `effectiveEnd`, and `versionOf`; generations sharing a `versionOf` must not overlap in their effective ranges
- The current generation has `effectiveEnd IS NULL`; a change never overwrites a generation — it closes the prior one and inserts a new one
- A future-dated generation (`effectiveStart` in the future) is a scheduled change and must not be applied before its start date
- The target is bound by stable id — worker id, position id, job-profile id (workforce), or an EmploymentType / WorkRegime catalog id — via `targetType` (discriminator) + `targetId`, never by display name
- The grant is bound by stable key — a WorkRule identity — never by display name (ADR-015, issue #14); `grantType` is a single-value enum (`WORK_RULE`). `workRuleId` is kept optional to preserve the polymorphic-grant seam for a future generalization (compliance/leave rules); the command layer enforces that a `WORK_RULE` grant resolves an existing WorkRule (#39, #41)
- A WorkRule may be assigned to a target only if an eligibility generation in force on the assignment date permits it
- Eligibility is additive and resolved `asOf` a date; the permissible set for a worker on a date is the union of grants in force for that worker and their position/job-profile/employment-type/work-regime

### Relationships

- **References workforce targets (cross-module)**: `targetId` identifies who the rule applies to — a Worker / Position / JobProfile identity or an EmploymentType / WorkRegime catalog id, per `targetType`
- **Governs WorkRule**: references a WorkRule as assignable to the target; WorkRule assignment enforcement against eligibility is tracked in #41
- **Consumed by time-tracking (cross-module, one-directional)**: the Reported → Calculated conversion consults eligibility to decide which WorkRule applies to a worker on the calculated date
