# APPR-002: Approval step editor shows selectable user reference

**Status: REPRODUCED** — Approval Queue shows "Unknown" for all record names

## Environment Setup

### Backend A — NexusCRM

1. Configure and start frontend:
   ```bash
   cd frontend
   echo "REACT_APP_BACKEND_URL=https://nexuscrm.pingcap.com" > .env
   npm run dev  # starts on localhost:5173
   ```

2. Get a JWT token:
   ```bash
   curl -s -X POST "https://nexuscrm.pingcap.com/services/oauth2/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=client_credentials&client_id=test-gosf-client&client_secret=test-gosf-secret-123" \
     | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))"
   ```

3. Login via JavaScript console:
   ```javascript
   localStorage.setItem('auth_token', '<JWT token from step 2>');
   localStorage.setItem('instance_url', 'https://nexuscrm.pingcap.com');
   location.reload();
   ```

### Backend B — Salesforce (via Vite proxy)

1. Configure and start frontend:
   ```bash
   cd frontend
   echo "REACT_APP_BACKEND_URL=https://pingcap--partialcop.sandbox.my.salesforce.com" > .env
   npm run dev  # starts on localhost:5173
   ```

2. Login via Backend mode → Advanced Options → Token:
   - Token: `00D...` (valid SF session token)
   - **CRITICAL**: instance_url must be `http://localhost:5173` (NOT the SF URL).
     This forces all API requests through the Vite proxy, bypassing CORS.
   - Click Login

### Note on A/B Testing

A/B comparison is **not currently possible** for this scenario. The SF sandbox has no
pending approvals ("All Caught Up! You have no pending approvals"). To create test
approval data on SF:

1. Create an Approval Process on an object (e.g., Account) via SF Setup
2. Submit a record for approval via API:
   ```bash
   curl -s -X POST "$SF_BASE/services/data/v63.0/process/approvals" \
     -H "Authorization: Bearer $SF_TOKEN" -H "Content-Type: application/json" \
     -d '{"requests":[{"actionType":"Submit","contextId":"<AccountId>","comments":"Test approval"}]}'
   ```
3. Then run the Chrome scenario on both backends to compare

## Steps (verified 2026-03-25)

1. Navigate to `http://localhost:5173/approvals`
2. Page loads "Approval Queue" with pending approvals

## Actual Result (NexusCRM backend)

- Approval Queue shows "4 pending approvals"
- **RECORD column: ALL 4 records display "Unknown"** (not the record name)
- OBJECT column: ALL show "Record" (not the specific object type like "Account")
- COMMENTS column: ALL show "—"
- Approve / Reject / Reassign buttons are present and functional
- Clicking "Unknown" link opens an external link icon but no record detail

## Expected Result (Salesforce backend — verified)

- Approval Queue shows "All Caught Up! You have no pending approvals" (no test data)
- When approvals exist: RECORD column shows the actual record name (e.g., "Acme Corp")
- OBJECT column shows the object type (e.g., "Account", "Opportunity")

## A/B Comparison

| Aspect | SF Backend | NexusCRM Backend |
|--------|-----------|-----------------|
| Queue loads | YES (empty) | YES (4 records) |
| Record names resolved | Expected YES | **NO — all "Unknown"** |
| Object type shown | Expected YES | **NO — all "Record"** |

## Root Cause

The Approval Queue UI queries ProcessInstanceWorkitem records. Each workitem references
a TargetObjectId (the record being approved). The NexusCRM backend either:
1. Does not resolve TargetObjectId to a record name, or
2. The TargetObjectId references a record that no longer exists, or
3. The record-name resolution query fails silently

API test APPR-001 confirmed that ProcessNode records are not auto-created during
deployment, meaning approval step metadata (including approver assignment) is lost.

## Failure Indicators

- Record column shows "Unknown" instead of record name
- Object column shows "Record" instead of specific object type
- Approver field shows plain text instead of selectable user picker

## Related

- APPR-001 (API): ProcessNode not auto-created during deploy
- APPR-003 (API): Approval submission returns 500
