# ListLeaveGrantsByWorker

## Overview

Lists a worker's LeaveGrant history for a given leave type, ordered soonest-expiring first, so a worker or administrator can see every grant event (hire, anniversary, manual) and how much of each remains.

## Business Rules

- Returns all grants for the given `workerId` and `leaveTypeKey`, including expired grants, ordered by `expirationDate` ascending (soonest-expiring first) — mirroring the FIFO order consumption itself uses
- Includes grants with `remainingDays = 0` (fully consumed or expired) alongside grants with remaining balance
- Paginated for workers with a long grant history
- The ledger is keyed to the Worker, not a specific employment or assignment, so entitlement across employment or assignment changes is visible in one history

## Process Flow

```mermaid
flowchart TD
    A[Caller requests grants for workerId + leaveTypeKey] --> B{Worker exists?}
    B -- No --> C[Reject: WORKER_NOT_FOUND]
    B -- Yes --> D[Load LeaveGrant rows for workerId and leaveTypeKey]
    D --> E[Order by expirationDate ascending]
    E --> F[Paginate and return]
```

## External Dependencies

- [leave-management::LeaveGrant](../model/LeaveGrant.md) model — entity being queried
- [leave-management::LeaveType](../model/LeaveType.md) model — referenced by `leaveTypeKey`
- [workforce::Worker](../../../workforce/docs/model/Worker.md) model — referenced by `workerId`; the ledger is keyed to the person, surviving employment/assignment changes

## Error Scenarios

- **WORKER_NOT_FOUND**: no workforce Worker exists for the given id
- **LEAVE_TYPE_NOT_FOUND**: no LeaveType exists for the given id/key

## Test Cases

- returns a worker's grants for a leave type ordered soonest-expiring first
- includes expired grants and fully-consumed grants in the history
- paginates results for a long grant history
- returns LEAVE_TYPE_NOT_FOUND for an unknown leaveTypeKey

> Note: `returns WORKER_NOT_FOUND for an unknown workerId` is a documented error scenario above,
> but is a KNOWN GAP not yet implemented in `listLeaveGrantsByWorker.ts` (workerId references
> workforce's Worker cross-module, with no query injection wired into module.ts yet — referential
> integrity is left to the DB-level FK constraint for now). It is intentionally omitted from this
> Test Cases list until implemented; re-add it here once the check and its test land.
