# HCP Onboarding & Documents — Module Handover

**Audience:** Mobile app developer (HCP-facing), with a secondary section for the Admin Panel.
**Scope:** Account creation → personal details → documents → approval → shift-eligible.
**Status:** Backend complete for the flows below. One known gap flagged at the end — read it before building around document expiry.

---

## 1. Actors & Who Does What

| Actor | Does |
|---|---|
| **Hiresome** (recruitment system) | Creates the HCP account: email, name, one profession. This is the **only** account-creation path — there is no self-signup in the app. |
| **HCP** (mobile app) | Logs in with emailed credentials → sets their own password → completes personal details → uploads documents. |
| **Admin** (admin panel) | Reviews and approves/rejects uploaded documents. Approval is what unlocks shift eligibility — nothing else does. |

---

## 2. End-to-End Flow

```
Hiresome creates HCP (email, name, profession)
        │
        ▼
HCP receives welcome email (login URL, email, auto-generated password)
        │
        ▼
HCP logs in → app calls GET /registration/status
        │
        ▼
   registration_screen tells the app which screen to show:
        │
   ┌────┴────┬─────────────┬──────────────┐
   │ screen 1│  screen 2   │  screen 3    │  screen 0
   ▼         ▼             ▼              ▼
Personal   Profession-   Mandatory     All done —
Details    specific      (general)     awaiting
           Documents     Documents     admin approval
        │
        ▼
Admin reviews documents in the pending queue → approves/rejects
        │
        ▼
Once EVERY required document (general + profession) is approved:
   hcp.status flips pending-approval → active
        │
        ▼
HCP is now shift-eligible
```

**Important:** the app should always trust `registration_screen` from the status endpoint to decide which screen to show — never infer it client-side from partial data. It's recomputed server-side after every relevant change (personal details saved, a document uploaded).

---

## 3. Status Fields — What They Mean

### `hcp.status`
| Value | Meaning |
|---|---|
| `pending-approval` | Default from creation. Not yet shift-eligible — either documents aren't fully uploaded, or they're uploaded but not all approved yet. |
| `active` | All required documents approved. Shift-eligible. |
| `blocked` | Admin has blocked the account. Distinct from the above two — never auto-changed by document activity. |

### `app_registration_screen` (drives which screen the app shows)
| Value | Screen |
|---|---|
| `1` | Personal details |
| `2` | Profession-specific documents |
| `3` | Mandatory (general) documents |
| `0` | Registration complete — all documents uploaded, awaiting admin approval. Show a "waiting for approval" screen, not a shift list, until `hcp.status` becomes `active`. |

### `document_hcp.document_approval` (per uploaded document)
| Value | Meaning |
|---|---|
| `pending` | Uploaded, not yet reviewed. |
| `pending-reapproval` | Was rejected/expired and re-uploaded; awaiting review again. |
| `approved` | Reviewed and accepted. |
| `rejected` | Reviewed and declined — see `reason` if provided, HCP should be prompted to re-upload. |

**Note the distinction:** `registration_screen === 0` only means "everything is uploaded" — it does **not** mean `hcp.status === 'active'`. The app must show both a "you're done uploading" state *and* a separate "waiting for approval" vs "approved, you can now pick shifts" state, driven by `hcp.status`, not by `registration_screen`.

---

## 4. Endpoints — HCP Self-Service (Mobile App)

All routes below require `Authorization: Bearer <token>` and act on the **logged-in HCP's own profile** — none take an HCP ID in the URL.

### `GET /api/v2/registration/status`
Call this right after login, and again after completing any screen, to know what to show next.

**Response**
```json
{
  "status": true,
  "data": {
    "hcp_status": "pending-approval",
    "registration_screen": 2,
    "steps": {
      "account_created": true,
      "personal_details_complete": true,
      "profession_selected": true,
      "documents_uploaded": false,
      "registration_complete": false
    },
    "documents": {
      "total_required": 5,
      "total_uploaded": 2,
      "total_approved": 0,
      "total_pending": 2,
      "is_compliant": false
    },
    "missing_documents": [
      { "document_id": 12, "name": "First Aid Certificate", "status": "missing" }
    ]
  }
}
```

### `PATCH /api/v2/registration/personal-details`
**Request** (all fields optional — send whatever the screen collected)
```json
{
  "first_name": "Jane",
  "last_name": "Doe",
  "contact_number": "+61400000000",
  "date_of_birth": "1990-05-14",
  "address": "12 Example St",
  "state_id": 3,
  "latitude": -31.9505,
  "longitude": 115.8605
}
```
**Response**
```json
{ "status": true, "message": "Personal details updated.", "data": null }
```
After saving, call `GET /registration/status` again to get the next screen.

### `POST /api/v2/registration/documents`
Multipart upload — one document at a time.

**Request** (multipart/form-data)
| Field | Type | Notes |
|---|---|---|
| `document_id` | int, required | From the `missing_documents`/required list |
| `file` | file, required | `pdf`, `doc`, `docx`, `jpg`, `jpeg`, `png` — max 5MB |
| `profession_id` | int, nullable | Required for profession-specific documents; omit for general ones |
| `level_id` | int, nullable | |
| `start_date` | date, nullable | |
| `expiry_date` | date, nullable | |

**Response**
```json
{
  "status": true,
  "message": "Document uploaded successfully.",
  "data": { "id": 88, "document_id": 12, "document_approval": "pending", "...": "..." }
}
```
Call `GET /registration/status` again after each upload — `registration_screen` and the compliance summary update automatically.

### `PATCH /api/v2/registration/professional-details` and `POST /api/v2/registration/professions`
**Deprecated — do not build new UI against these.** Profession is fixed at account creation by Hiresome now; there's nothing for the HCP to set. Both endpoints exist only as harmless no-ops (`200 OK`, does nothing) in case an older app build still calls them. New builds shouldn't call these at all.

---

## 5. Error Shape (applies to all endpoints above)

```json
{ "status": false, "message": "Human-readable reason.", "data": null }
```
- `404` — no HCP profile on the account, or resource not found.
- `422` — validation failure (field-level messages under `errors`).
- `500` — server-side failure; message is generic, details are logged server-side.

---

## 6. Admin Panel — Document Review (for completeness)

Not needed for the HCP mobile app, included so both teams share one source of truth.

| Endpoint | Purpose |
|---|---|
| `GET /api/v2/hcps` | List/search HCPs |
| `GET /api/v2/hcps/{id}` | Detail — profile, professions, compliance summary |
| `PATCH /api/v2/hcps/{id}` | Update profile fields / manually block |
| `GET /api/v2/hcps/documents/pending` | Global queue of documents awaiting review |
| `GET /api/v2/hcps/{id}/documents` | One HCP's uploaded documents |
| `GET /api/v2/hcps/{id}/documents/required` | Required vs. uploaded vs. missing |
| `PATCH /api/v2/hcps/{id}/documents/{docId}/approve` | Approve — re-checks compliance and flips `hcp.status` to `active` if everything is now approved |
| `PATCH /api/v2/hcps/{id}/documents/{docId}/reject` | Reject, with optional `reason` |
| `POST /api/v2/hcps` | Hiresome's creation call (server-to-server, not admin-panel UI) |

All admin endpoints require a `super-admin`, `sub-admin`, or `developer` role.

---

## 7. Known Gap — Flag This to QA/Product

There is currently **no automated job that re-checks document expiry**. If an HCP's approved document expires, `hcp.status` will **not** automatically flip back to `pending-approval` until either:
- another document approval happens to re-trigger the compliance check, or
- the (not-yet-built) expiry cron ships.

This means the app should not assume `hcp.status === 'active'` is a real-time-accurate signal in every edge case yet — it's correct at the moment of approval, but can lag behind an expiry event until the cron exists. Worth knowing if QA writes test cases around expired documents.

---

## 8. Quick Reference — Field Name Changes

If you're working from an older version of this API or old app code: `dob` was renamed to **`date_of_birth`** everywhere (request field and response field). No other renames in this pass.
