# ListApprovalRequestsForApprover

## Overview

ListApprovalRequestsForApprover is the My Inbox query: it returns the `ApprovalRequest` rows on which a given user currently has actionable work — that is, where the user is a `PENDING` `ApprovalStepAssignee` on an `IN_PROGRESS` `ApprovalStep` whose parent `ApprovalRequest.status` is `PENDING`. The triple-condition filter is required because step and assignee rows are deliberately not updated when a request terminates by `withdrawApprovalRequest` or `cancelApprovalRequest`; consequently a user may have a `PENDING` `ApprovalStepAssignee` row whose parent request is no longer actionable, and the inbox query is what suppresses it.

## Business Rules

- Accepts `userId` as a required input
- Accepts an optional `status` filter that narrows by `ApprovalRequest.status`; defaults to `PENDING` when omitted
- Accepts standard pagination inputs (`limit`, `offset`, `orderBy`, `orderDirection`); `limit` defaults to the framework `DEFAULT_PAGE_SIZE`
- Returns each request at most once, even if the user has multiple PENDING assignee rows on the same step (defensive deduplication)
- The default behavior (`status = PENDING`) returns the user's actionable inbox
- A non-default status filter (e.g. `status = APPROVED`) returns historical requests where the user once held a PENDING role; useful for "approvals I worked on" reporting
- Excludes requests where the user's only assignee row has resolved (APPROVED, REJECTED, DELEGATED) — the user no longer owns the seat
- Default ordering when no `orderBy` is supplied is `createdAt DESC` so the freshest request surfaces first
- Returns a paginated result `{ items, hasNextPage }`; an empty `items` array is not an error

## Process Flow

```mermaid
flowchart TD
    A[Receive userId and optional status, default PENDING,<br/>plus optional pagination inputs] --> B[SELECT DISTINCT ApprovalRequest<br/>JOIN ApprovalStep ON request.id = step.approvalRequestId<br/>JOIN ApprovalStepAssignee ON step.id = assignee.approvalStepId<br/>WHERE assignee.userId = userId<br/>AND assignee.status = PENDING<br/>AND step.status = IN_PROGRESS<br/>AND request.status matches input]
    B --> C[ORDER BY orderBy orderDirection<br/>default request.createdAt DESC]
    C --> D[LIMIT limit + 1 OFFSET offset]
    D --> E[Return paginated result &lcub; items, hasNextPage &rcub;]
```

## External Dependencies

- None

## Error Scenarios

- None — an empty result is not an error

## Test Cases

- returns requests where the user is a PENDING assignee on an IN_PROGRESS step with parent request PENDING
- excludes requests where the user's only assignee row has resolved (APPROVED, REJECTED, DELEGATED)
- excludes requests where the parent has terminated by WITHDRAW even though the StepAssignee row is still PENDING
- excludes requests where the parent has terminated by CANCEL even though the StepAssignee row is still PENDING
- defaults the status filter to PENDING when omitted
- accepts a non-default status (e.g. APPROVED) to surface historical requests the user worked on
- accepts a non-default status (e.g. REJECTED) to surface historical requests the user worked on
- deduplicates requests where the user has multiple PENDING assignee rows on the same step
- returns an empty array when the user has no matching requests
- returns rows ordered by createdAt DESC
