# Phase 09 — Nurse verification badge doesn't reflect reality

**Blocker:** blockers.md § "Trust — nurse verification."
**Depends on:** nothing to start; do together with [10-search-dedup-and-trust.md](10-search-dedup-and-trust.md) — same root cause on two of the four call sites.

---

**Root cause.** `client/src/services/verification/constants.ts:9` — `USE_VERIFICATION_MOCK = true`. The real
backend is fully built and shape-matched: `GET nurse_verification` → `NurseVerificationController.cs:32-35`;
`GET nurses/{id}/trust_badge` (anonymous) → `NursesController.cs:26-29`; all admin queue/decide endpoints
(`AdminVerificationsController.cs`) match the client's `DecideStepInput` fields exactly.

## Two real gaps that must ship in the same change as flipping the flag, or the admin half 404s

- `verificationClientApi.approveVerification`/`.rejectVerification` (`clientApi.ts:269-278`) POST to
  `admin_verifications/{id}/approve`/`/reject` — **routes that don't exist.** They're wired into the live UI
  (`admin/verification/[nurseId]/page.tsx:81-82`), so this is a real break, not theoretical. This is also
  exactly the gap forgotten-features.md calls out for nurse approval. The real
  workflow already achieves the same outcome via `Decide` on the last pending step
  (`AdminReviewStepCommand.Handler.cs:72` → `VerificationAggregator.Finalize`) — so either add the two
  explicit endpoints (thin wrappers that resolve "the last pending step" and call the same finalize path), or
  rewire the two admin buttons to call `decideStep` directly. Not a business-rule question — pure engineering
  gap.
- `getDocumentSignedUrl` (`clientApi.ts:255-256`) targets `admin_verifications/documents/{id}/url` — also
  missing; the case detail already carries a signed URL per document, so a re-open should just refetch the
  case instead.

## Small DTO gap, currently harmless

Server's `VerificationStepDto.IsRequired` has no client-side
equivalent (`verification/types.ts:62-71`), and `blockingSteps` is computed from *all* non-passed steps, not
just required ones (`VerificationRepository.cs:138-141`) — fine while every seeded step is required; would
misrepresent "what's blocking" the day an optional step type is added. Worth a note, not urgent.

**Fix:** flip `USE_VERIFICATION_MOCK` to `false`, ship the two missing/rewired admin actions in the same
change.

## Same-symptom bugs, actually filed under Search — fix together since they're one root cause

Hardcoded literals, not the mock: `search/nurse/[nurseId]/page.tsx:173` and
`NurseResultCard.tsx:87` both hardcode `state="verified"` instead of deriving it from the real
`profile.isVerified` / index-guarantee data. `verification/types.ts:328-330` already has the exact helper
built for this (`publicBadgeState`) — neither call site uses it. See
[10-search-dedup-and-trust.md](10-search-dedup-and-trust.md) for the rest of that phase.
