# Case Review — User Guide

For fraud analysts reviewing cases opened by the rule engine. Covers where a
case comes from, how to find it, how to see *why* it was opened, and how to
record a decision.

## Two screens, two purposes

There are two separate case screens in the admin UI — this is the single
most confusing part of the workflow, so know it going in:

| Screen | Route | Purpose |
|---|---|---|
| **Case Search → Case Browse** | `/admin/fraud/cases/search` → `/admin/fraud/cases/browse/:session_id` | **Review** — see the transaction details, which rule fired, the full event journal. This is the screen you want for "why does this case exist?" |
| **Case Management** | `/admin/fraud/cases` → `/admin/fraud/cases/:id` | **Action** — set workflow/legacy status, a final resolution (confirmed fraud / false positive / inconclusive), add a note, attach files, set diary reminders |

Both screens can change the workflow status pills and the legacy
open/under_review/escalated/closed status — that part is duplicated. The
real difference is that only **Browse** shows *why* the case exists
(Transaction Details, Activations, full journal tabs), and only
**Management** has resolution/notes/diary/attachments. In practice: use
Browse to understand the case, then switch to Management to close it out.

## Where cases come from

A case can be opened two ways:
1. **An activation rule fires** with "Open case on activation" enabled. This
   is what you configure on an Activation Rule's detail panel (Case
   Workflow / Case Workflow Status dropdowns). No `risk_scores` row is
   involved — the case is tied directly to the rule via `activation_rule_id`.
2. **A transaction declines** on the real transaction path
   (`/api/v1/transactions`) — an Oban worker auto-opens a case tied to that
   transaction's `risk_scores` row. If the gateway rule that caused the
   decline has "Open Case on Decline" enabled (with Case Workflow / Status /
   Case Key configured), the case gets a full workflow, labeled Transaction
   Details panel, and deduplication key — exactly like activation rule cases.
   Without that configuration the case still opens, but without a workflow.

Both end up in the same `risk_cases` table and the same two screens above —
the "Score" field in Case Management just shows `—` for the first kind,
since there's no scored transaction to link to.

## Step 1 — find the case

Go to **Case Search** (`/admin/fraud/cases/search`). Pick a Case Workflow,
optionally pick a saved filter or build one (Add Rule / Add Group, same
condition-builder UI as activation rules), then **Peek** or **Skim** to
preview matching cases. Saving a filter makes it reusable later.

Once you have results, click a row — this opens **Case Browse** for that
result set, and **Next/Back** lets you step through every case in the
search without going back to the list each time.

## Step 2 — understand why the case exists (Case Browse)

The right-hand panel has a top tab strip (**Case Detail Views** /
**Case Visualisation** / **Case Forms**) and, under Case Detail Views, a
second row of tabs:

- **Case Detail Views (the "Transaction Details" section)** — shows the
  actual transaction fields (Account ID, Transaction ID, Amount, IP Address,
  etc.) that led to this case, labeled per the workflow's configured field
  mappings. **If this section is missing or unlabeled**, see the
  "Configuring Transaction Details labels" section below — it's a per-workflow
  setup step, not a bug.
- **Activations** — the rule(s) that fired and opened this case. For
  rule-triggered cases this is exactly one rule; for decline-auto-opened
  cases it's every rule that fired on that transaction.
- **Case Journal** / **Case Events Journal** — full audit trail: opened,
  status changes, assignments, notes — each with a timestamp.
- **Case Notes** — any notes added (via Case Management, see below).
- **Case Key Journal** — not yet implemented (always shows "no entries").
- **Case Forms Journal** / **Case Uploads** — populated only if the
  workflow has form submissions or file attachments for this case; empty is
  normal otherwise.

The top status bar also shows the **Workflow Status** pills (e.g.
`testClosed` / `testEscalated` / `testOpen` / `testPending`) — click one to
move the case along its workflow. This is separate from the legacy
open/under_review/escalated/closed status, which is the **Closed Status**
dropdown in the same bar.

## Step 3 — record your decision (Case Management)

From Case Browse, use **Back to Search** then open the case from the main
**Cases** list (`/admin/fraud/cases`) — or navigate directly to
`/admin/fraud/cases/:id`. Here you can:

- **Update Status** — open / under_review / pending_info / escalated
  (the same legacy status as Browse's "Closed Status" dropdown — they're the
  same field, just exposed in both places).
- **Resolve Case** — confirmed_fraud / false_positive / inconclusive. This
  is the final disposition and sets `closed_at`.
- **Add Note** — a free-text note, visible afterward in Case Browse's
  "Case Notes" tab and in the Timeline at the bottom of this page.

## Configuring "Transaction Details" labels (admin setup, per workflow)

The labeled Transaction Details panel in Case Browse depends on a workflow
having field mappings configured — without them, the panel falls back to a
raw, unlabeled key dump (or doesn't show at all if no transaction data was
captured). To configure labels for a workflow:

1. Go to the workflow's **XPaths** screen (`/admin/fraud/workflows/:id/xpaths`).
2. Add an entry per field you want shown, e.g.:

   | Name (label shown to reviewer) | XPath (lookup key) |
   |---|---|
   | Account ID | `Payload.AccountId` |
   | Transaction ID | `Payload.TxnId` |
   | Amount | `Payload.amount` |

   The "XPath" value is the exact key as stored on the case (every
   transaction field is stored prefixed with `Payload.`, e.g. a payload
   field named `AccountId` is looked up as `Payload.AccountId`).
3. Save. The next case opened against that workflow will show these labels;
   existing cases opened before the mapping existed will still show the raw
   dump (mappings are applied at *display* time, not stored on the case).

Note: this only applies to cases that have a `search_payload` — i.e. cases
opened via `enable_case_workflow` (both activation rules and gateway rules
with "Open Case on Decline" configured). Plain decline cases with no gateway
rule workflow config still don't have `search_payload`; their transaction
data lives on the linked `risk_scores` row.

## Known limitations

- **Plain decline cases (no gateway rule workflow configured)** open without
  a `workflow_id`/`workflow_status_id` or a labeled Transaction Details
  panel. To get the full workflow experience on declines, configure "Open
  Case on Decline" on the gateway rule that causes the decline.
