# Provider App — Integration Notes & Changelog

---

## 1. Categories Lookup — `has_exam` Param (Exam Selection Screen)

**Endpoint:** `GET /api/general/lookup/categories`

| Param | Type | Default | Behaviour |
|---|---|---|---|
| `has_exam` | boolean | `false` | When `true`, only returns categories that have **≥ 20 active questions**, each with at least one active option (answer) |

### Usage
```
GET /api/general/lookup/categories?has_exam=1
```

> **Required:** The provider exam category selection screen **must always** send `has_exam=1`. This guarantees every category displayed to the provider is exam-ready. Never show categories without this filter on this screen.

---

## 2. Services — `service_type` Field

The service object now includes a `service_type` string field. This is returned inside `service_data` on every order response (and also as a root-level key on the order show endpoint).

### `ServiceContractTypeEnum` — Possible Values

| Value | Label |
|---|---|
| `standard` | Standard service |
| `integrated_case` | قضية متكاملة |
| `integrated_contract` | عقد متكامل |
| `interactive_contract` | عقد تفاعلي |
| `agency` | Agency Service |

---

## 3. Orders — Display Logic Driven by `service_type`

Read `service_type` from within the `service_data` object of the order response (it is also mirrored as a root-level key for convenience).

### `service_data` Object
```json
"service_data": {
  "id": 12,
  "title": "Service Title",
  "service_type": "integrated_contract",
  ...
}
```

### What the Client Submits When Placing an `integrated_contract` Order

For `integrated_contract` and `interactive_contract` orders, the client does **not** send `form_data`. Instead, the client provides:

| Field | Required For | Description |
|---|---|---|
| `contract_attachment` | both | Media ID of the uploaded contract file |
| `contract_terms` | both (optional) | Text describing contract terms/clauses (max 5000 chars) |
| `parties` | both | Array of contract signatories (see below) |
| `parties.*.full_name` | both | Full name of the party |
| `parties.*.national_id` | both | National ID number |
| `parties.*.national_id_type` | both | `national_id` or `residence_id` |
| `parties.*.phone_code` | both | Phone country code (e.g. `+966`) |
| `parties.*.phone` | both | Phone number |
| `stages` | `interactive_contract` only | Array of contract stages |
| `stages.*.name` | `interactive_contract` only | Stage name |
| `stages.*.end_date` | `interactive_contract` only | Stage deadline (`YYYY-MM-DD`) |
| `stages.*.amount` | `interactive_contract` only | Stage amount |

All of this data is returned in the provider's order view as `parties_data`, `stages_data`, `contract_attachment`, and `contract_terms`.

> **⚠️ Important:** `integrated_contract` and `interactive_contract` orders **do NOT have dynamic forms (`form_data`)**. Instead, they use a specialized contract mechanism with parties, contract files, and (for interactive) stages requiring confirmation.

### Display Rules

#### `standard` or `agency`
- Show `form_data` (dynamic form answers submitted by the client)

#### `integrated_case` (قضية متكاملة)
- Show `form_data`
- **Before the provider accepts the order**, display the **`integrated_case_agreement`** static page content and require the provider to agree to it before proceeding.

#### `integrated_contract` (عقد متكامل)
- **Do NOT show** `form_data`
- Show `parties_data` — the list of contract signatories
- Show `contract_attachment` — the uploaded contract file (PDF or document)
- Show `contract_terms` — the text describing contract terms/clauses (if provided)
- Clearly label the order as **"عقد متكامل"**
- **Before the provider accepts the order**, display the **`integrated_contract_terms`** static page content and require the provider to agree to it before proceeding.

#### `interactive_contract` (عقد تفاعلي)
- **Do NOT show** `form_data`
- Show `parties_data` — the list of contract signatories
- Show `stages_data` — ordered contract stages, each requiring party confirmation
- Show `contract_attachment` — the uploaded contract file
- Show `contract_terms` — the text describing contract terms/clauses (if provided)
- Clearly label the order as **"عقد تفاعلي"**
- **Before the provider accepts the order**, display the **`integrated_contract_terms`** static page content and require the provider to agree to it before proceeding.

### Conditional Fields Summary

| Field | Present When |
|---|---|
| `form_data` | `service_type` is `standard`, `integrated_case`, or `agency` |
| `parties_data` | `service_type` is `integrated_contract` or `interactive_contract` |
| `stages_data` | `service_type` is `interactive_contract` only |
| `contract_attachment` | `service_type` is `integrated_contract` or `interactive_contract` |

### `parties_data` Object Structure (per party)
```json
{
  "id": 5,
  "full_name": "أحمد محمد",
  "national_id": "1023456789",
  "national_id_type": "national_id",
  "phone": "+966501234567",
  "phone_code": "+966",
  "phone_number": "501234567",
  "user_data": { "id": 5, "full_name": "...", "avatar": "..." },
  "created_at": 1727600000
}
```

### `contract_attachment` Object Structure
```json
{
  "id": 88,
  "url": "https://example.com/storage/...",
  "type": "pdf",
  "option": "contract_attachment",
  "is_single": false
}
```

---

## 4. Static Pages — Agreement Gates for Providers

Two static pages act as **agreement gates** before the provider can accept certain order types. The provider must explicitly agree before the acceptance action is triggered.

| Page Type | Value | When to Show |
|---|---|---|
| Integrated Case Agreement | `integrated_case_agreement` | Provider receives an `integrated_case` order |
| Integrated Contract Terms | `integrated_contract_terms` | Provider receives an `integrated_contract` or `interactive_contract` order |

### Flow
1. Provider taps "Accept Order"
2. **If** the service type requires an agreement (see table above):
   - Fetch the static page content via `GET /api/general/pages/{type}` using the appropriate page type value
   - Display the content in a modal/bottom sheet
   - Show an "I Agree" confirmation button
   - **Only after explicit agreement**, send the accept order API request
3. **Otherwise** (for `standard` / `agency`): proceed directly to accept

### Fetching Static Page Content
```
GET /api/general/pages/integrated_contract_terms
GET /api/general/pages/integrated_case_agreement
```


---

## 5. Chat System — Attachment Support

### Overview
Providers can now send and receive messages with attachments (images, audio files, documents) in addition to or instead of text.

### Attachment Upload Flow
**Step 1:** Upload file to media endpoint
```http
POST /api/general/attachments
Content-Type: multipart/form-data

{
  "file": <binary>,
  "media_type": "image",        // or "audio", "file"
  "model": "Message",
  "model_id": null,              // null for unattached upload
  "option": "chat_attachment",
  "is_single": false
}
```

**Response:**
```json
{
  "id": 123,
  "url": "https://example.com/storage/images/filename.jpg",
  "type": "image",
  "option": "chat_attachment",
  "is_single": false
}
```

**Step 2:** Send message with attachment
```http
POST /provider/chats/{chat}/messages

{
  "message": "Optional text message",   // nullable
  "attachment_id": 123                  // nullable
}
```

### Validation Rules
- At least one of `message` or `attachment_id` is required
- Cannot send empty message without attachment
- `attachment_id` must reference valid media record
- Supported types: `image`, `audio`, `file`

### Chat List Response (with attachment indicators)
```json
{
  "id": 1,
  "unread_count": 3,
  "other_user": {
    "id": 456,
    "full_name": "Client Name",
    "avatar": "https://..."
  },
  "latest_message": {
    "id": 789,
    "message": "Check this file",
    "is_mine": true,
    "created_at": 1672531200,
    "has_attachment": true,
    "attachment_type": "image"    // or "audio", "file"
  }
}
```

### Message Detail Response
```json
{
  "id": 789,
  "message": "Check this file",
  "sender_data": {
    "id": 123,
    "full_name": "Provider Name",
    "avatar": "https://..."
  },
  "is_mine": true,
  "created_at": 1672531200,
  "read_at": 1672535000,
 "attachment_data": {
                "url": "http://127.0.0.1:8000/storage/files/59a9cd6f-d37c-4d8b-8fe1-532eb500ee33.pdf",
                "type": "file"
            }
}
```

> **`message_type` values:** `text` (no attachment) · `image` · `audio` · `file`

### Attachment Types

| Type | Description | Common Extensions |
|---|---|---|
| `image` | Image files | jpg, png, gif, webp |
| `audio` | Audio files | mp3, wav, m4a, ogg |
| `file` | Documents and other files | pdf, docx, xlsx, zip, etc. |

### Provider Chat Endpoints

**List all chats:**
```http
GET /provider/chats?per_page=15
```

**View chat messages:**
```http
GET /provider/chats/{chat}?per_page=20
```

**Send message:**
```http
POST /provider/chats/{chat}/messages
Content-Type: application/json

{
  "message": "Optional text",
  "attachment_id": 123
}
```

### UI/UX Guidelines
- Display attachment preview/icon in chat list based on `attachment_type`
- Show image thumbnails directly in chat bubbles
- Provide download/play buttons for audio and file attachments
- Support sending multiple media types (image for photos, audio for voice messages, file for documents)
- Messages can have text only, attachment only, or both
- `attachment_data` is `null` if no attachment

