# RejectLeaveCancel

## Permission Scope

`approval`

## Overview

Leave approver rejects a leave cancellation, returning the `LeaveRequest` from CANCEL_PENDING back to APPROVED with the ledger and time-tracking left entirely unchanged.

## Business Rules

- Only reachable from CANCEL_PENDING; transitions back to APPROVED (not a terminal state)
- No `LeaveConsumption` rows are restored; the ledger remains exactly as it was before the cancellation was filed, and since leave-management never writes into time-tracking (a one-directional, pull-based mapping) nothing there changes either
- `approverComment` is required and non-empty on a rejected cancellation
- Stamps `resolvedBy` and `resolvedAt`; resolves the mirroring cancellation `approval`-module request as rejected
- The resolver is never the requester

## Process Flow

```mermaid
flowchart TD
    A[Approver rejects a CANCEL_PENDING LeaveRequest] --> B{Resolver is the requester?}
    B -- Yes --> R1[Reject: SELF_APPROVAL]
    B -- No --> C{Request status is CANCEL_PENDING?}
    C -- No --> R2[Reject: INVALID_STATE_TRANSITION]
    C -- Yes --> D{approverComment provided?}
    D -- No --> R3[Reject: MISSING_APPROVER_COMMENT]
    D -- Yes --> E[Transition LeaveRequest back to APPROVED]
    E --> F[Ledger and time-tracking remain unchanged]
    F --> G[Stamp resolvedBy, resolvedAt; resolve mirroring approval request as rejected]
```

## External Dependencies

- [leave-management::LeaveRequest](../model/LeaveRequest.md) - CANCEL_PENDING -> APPROVED transition
- approval module (cross-module, bundled) - resolves the mirroring cancellation approval request as rejected (ADR-003)

## Error Scenarios

- **LEAVE_REQUEST_NOT_FOUND**: no LeaveRequest exists for the given id
- **INVALID_STATE_TRANSITION**: the LeaveRequest's current status does not permit this transition
- **SELF_APPROVAL**: the resolver is the requester
- **MISSING_APPROVER_COMMENT**: `approverComment` is empty
- **NOT_ASSIGNEE**: no eligible approver exists other than the requester, or the resolver is not an eligible approver
- **APPROVAL_STEP_FAILED**: the bundled approval-module step failed to resolve

## Test Cases

- rejecting a cancellation returns the request to APPROVED with ledger and time-tracking unchanged
- rejecting a cancellation on a request that is not CANCEL_PENDING is rejected
- rejecting a cancellation without an approverComment is rejected
- rejecting a cancellation on a self-filed decision is rejected
- rejecting a cancellation by someone who is not an eligible approver is rejected (NOT_ASSIGNEE)

> Note: the approval-module resolution is now wired — rejectLeaveCancel resolves the mirrored
> cancellation request through the injected approval seam (locates the active request by the
> LeaveRequest id, checks the resolver owns a pending assignee → NOT_ASSIGNEE, then
> sendBackApprovalStep with ADR-003 error mapping).

