# LeaveConsumption

## Description

LeaveConsumption is the **audit-preserving ledger line** linking one `LeaveRequest` to the exact `LeaveGrant` it drew days from (ADR-005). Each row records `leaveRequestId`, `leaveGrantId`, the `daysConsumed` allocated, and a nullable `restoredAt` timestamp. A single request produces multiple rows when its reservation is split across more than one grant (FIFO by soonest expiration) — for example a full day drawn 0.5 from a grant about to lapse and 0.5 from the next.

Rows are never deleted or overwritten. Restoration — on rejection, withdrawal, or an approved cancellation of leave — adds the `daysConsumed` back to the originating grant and stamps `restoredAt` on the row; the row itself remains as a permanent record, distinguishing "consumed and kept" from "consumed and later restored". This is what lets the grant ledger be reconciled end to end without a separate audit module (ADR-013): the sum of a grant's unrestored consumption lines always explains its drawn-down balance.

This model carries forward the legacy `PaidLeaveConsumption` unchanged in mechanics; it is renamed and re-homed into leave-management, and now references a `LeaveRequest` (the unified request/cancel lifecycle) rather than the legacy `TimeOffRequest` (ADR-011).

## Domain Model Definitions

### Model type

Standard

### Command Definitions

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

- (cross-feature, via LeaveRequest) requestLeave — allocate grants FIFO by soonest expiration and insert one consumption row per grant drawn
- (cross-feature, via LeaveRequest) rejectLeave / withdrawLeave / approveLeaveCancel — restore days to the originating grants and stamp `restoredAt` on each affected row

### Query Definitions

- listLeaveConsumptionByRequest — the allocation lines for a leave request (kept for audit even after restoration)
- listLeaveConsumptionByGrant — every draw made against a grant, for ledger reconciliation

### Models

- LeaveConsumption

### Invariants

- `daysConsumed` is positive and never exceeds the days originally allocated at creation; a row's `daysConsumed` value never changes after insert
- A row is created only for a LeaveRequest whose LeaveType `requiresBalance` is true (PAID_LEAVE_FULL, PAID_LEAVE_HALF, COMPENSATORY); MENSTRUAL and SPECIAL requests never produce rows
- The referenced LeaveGrant had sufficient `remainingDays` at the moment of allocation
- `restoredAt` is null until the associated request's reservation is undone (reject, withdraw, or approved cancellation), and is set exactly once — restoration is not repeatable
- The sum of `daysConsumed` across all non-restored rows for a given LeaveRequest equals the total days that request requires (1.0 for a full day, 0.5 for a half day, summed over its target dates)
- Restoration always credits back the exact `leaveGrantId` the days were drawn from, never a different grant
- A row is never deleted or mutated (other than the single `restoredAt` stamp); the trail is permanent

### Relationships

- **Belongs to LeaveRequest**: `leaveRequestId` references the request this allocation was made for
- **Belongs to LeaveGrant**: `leaveGrantId` references the grant the days were drawn from and restored to
