# FE note: `review_pending` (new statement after an offer)

Once a borrower has a loan offer, a new bank statement no longer replaces it straight away. The
statement is still analysed and stored, but it waits for an admin to approve it. Until then the
borrower keeps their current offer. This applies to borrower and affiliate submissions; admin uploads
are not held.

**No app change is required.** The response keeps the success shape (HTTP 200, `status: "success"`),
so existing screens keep working. They show the borrower's current offer, not the new figures.

## Which endpoints

All statement analyses go through the same code path, so this covers:

- `POST /api/v1/bank-statements/analyze-upload` (sync)
- `POST /api/v1/bank-statements/requests/{id}/reanalyze` (sync; the same fields are merged into the
  request payload). `POST /bank-statements/retry` already answers 409 "already analysed" once the
  borrower has an offer, so it is unchanged.
- `POST /api/v1/bank-statements/requests/{id}/complete` (async). Once analysis finishes, the request's
  `result` (`GET /bank-statements/requests/{id}`) holds the fields below.

## Response when held

```json
{
  "status": "success",
  "message": "Your new statement has been sent for review. Your current offer stays until it's approved.",
  "review_pending": true,
  "statement_review": { "id": 42, "status": "pending", "submitted_at": "2026-10-20T09:15:00+01:00" },
  "report": { "recommended_loan_amount": 200000, "...": "the CURRENT offer's report, or null if the offer was set manually by an admin" },
  "mandate_url": null,
  "mandate_id": null,
  "local_mandate_id": null,
  "mandate_error": null,
  "verificationSteps": [ "... unchanged ..." ]
}
```

- `review_pending` and `statement_review` appear **only** when the statement was held. A normal analysis
  response is unchanged and has neither field.
- `report` is the borrower's current (unchanged) offer. Do not show it as "your new offer".
- No Mono mandate is started for a held statement.

## What the app can do (optional)

- If `review_pending` is true, show `message` instead of "Analysis complete", and stay on (or go back to)
  the current offer screen.
- `GET /profile/eligibility-check` and the dashboard keep returning the current offer while the review is
  pending.
- When an admin approves, the borrower gets the usual "bank statement processed" notification and the
  eligibility endpoints return the new offer. If the admin rejects it, nothing changes for the borrower.

## When nothing is held (unchanged)

- The borrower's first eligibility check.
- A borrower whose offer was withdrawn by a declined loan (`offer_cleared`, see
  `loan-offer-cleared-fe-note.md`) or reset by an admin. Their next statement applies straight away, and
  after that they are locked again.
- A first analysis that produced no offer (recommended amount 0). The borrower can try another statement.
- Retail (trader) statements (`POST /loans/retail/analyze`). They are tied to their own loan draft and are
  not held.
