# Ratings & Reviews API — User & Client (Mobile & Web)

Complete client-side documentation for browsing reviews and submitting ratings across all learning and commerce offerings: Courses, Training Programs, Books & Research Papers, and One-on-One Consultations.

- **Base path:** `{{base_url}}/user` (e.g. `http://localhost:8000/api/v1/user`)
- **Headers:**
  - `Accept: application/json`
  - `Accept-Language: {{locale}}` (`ar` or `en`)
  - `Authorization: Bearer {{user_token}}` (Required for submitting reviews; optional/guest for browsing)
- **Source files:**
  - Controller: [ReviewController.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Controllers/Api/V1/Client/ReviewController.php)
  - Submission Service: [ReviewSubmissionService.php](file:///media/ghoneim/Storage/backend/bateel/app/Services/Reviews/ReviewSubmissionService.php)
  - Query Service: [ReviewQueryService.php](file:///media/ghoneim/Storage/backend/bateel/app/Services/Reviews/ReviewQueryService.php)
  - Request: [ReviewRequest.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Requests/Client/Review/ReviewRequest.php)
  - Resource: [PublicReviewResource.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Resources/Client/Review/PublicReviewResource.php)

---

## Business Eligibility Rules

A user cannot review an item unless they have genuinely completed or purchased it. Violating these conditions yields an HTTP `422` error with `error_code: NOT_ELIGIBLE_FOR_REVIEW`:

| Item Type | Required Eligibility Condition | Error Message |
|---|---|---|
| **Course** (Recorded/Live) | User's enrollment must have `status: "completed"`. | `"You can review this course after completing it."` |
| **Training Program** | User must be enrolled and the program must have ended (sessions concluded). | `"You can review this program after it has ended."` |
| **Consultation Booking** | The booking must belong to the user and have `status: "completed"`. | `"You can review this consultation after it is completed."` |
| **Digital Book / Research** | The user must own the title (successful purchase recorded). | `"You can review this book after purchasing and receiving it."` |
| **Physical Book** | The user must have placed an order containing the book with `status: "delivered"`. | `"You can review this book after purchasing and receiving it."` |

### One Review Per Item Rule
A user is permitted exactly **one review per item**. Attempting to submit a second review returns HTTP `422` with:
```json
{
    "status": "error",
    "message": "You have already reviewed this item.",
    "data": {
        "error_code": "ALREADY_REVIEWED"
    }
}
```

---

## Error Codes Reference

| HTTP Status | error_code | Trigger |
|---|---|---|
| `401 Unauthorized` | *(Unauthenticated)* | Missing or invalid user bearer token on `POST` requests |
| `403 Forbidden` | `PERMISSION_DENIED` | Item is private or unpublished (e.g. draft course) |
| `404 Not Found` | *(Data not found)* | Item UUID does not exist |
| `422 Unprocessable` | `NOT_ELIGIBLE_FOR_REVIEW` | User has not completed or received the item |
| `422 Unprocessable` | `ALREADY_REVIEWED` | User already reviewed this specific item |
| `422 Unprocessable` | *(Validation error)* | Missing `rating` or rating outside `1-5` range |

---

## 1. Course Reviews

### `GET /user/courses/{course}/reviews` — List Course Reviews

Publicly browsable list of visible reviews for a published course, ordered latest first.

#### Headers
| Key | Type | Value |
|---|---|---|
| `Accept` | string | `application/json` |
| `Accept-Language` | string | `{{locale}}` |

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `course` | string (uuid) | Course UUID |

#### Query Parameters
| Key | Type | Example | Description |
|---|---|---|---|
| `page` | integer | `1` | Page number |
| `per_page` | integer | `15` | Results per page (default: 15, max: 100) |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "reviews": [
            {
                "id": "e4f5a6b7-c8d9-0e1f-2a3b-4c5d6e7f8a9b",
                "rating": 5,
                "comment": "Super clear explanations with practical financial models.",
                "reviewer": "Fahad Al-Otaibi",
                "created_at": "2026-09-14T12:00:00+00:00"
            }
        ],
        "links": {
            "first": "http://localhost:8000/api/v1/user/courses/c1b2c3d4/reviews?page=1",
            "last": "http://localhost:8000/api/v1/user/courses/c1b2c3d4/reviews?page=1",
            "prev": null,
            "next": null
        },
        "meta": {
            "current_page": 1,
            "from": 1,
            "last_page": 1,
            "path": "http://localhost:8000/api/v1/user/courses/c1b2c3d4/reviews",
            "per_page": 15,
            "to": 1,
            "total": 1
        }
    }
}
```

---

### `POST /user/courses/{course}/reviews` — Submit Course Review

Submits a rating and comment after the user completes the course.

#### Headers
| Key | Type | Value |
|---|---|---|
| `Accept` | string | `application/json` |
| `Content-Type` | string | `application/json` |
| `Authorization` | string | `Bearer {{user_token}}` |
| `Accept-Language` | string | `{{locale}}` |

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `course` | string (uuid) | Course UUID |

#### Request Body
```json
{
    "rating": 5,
    "comment": "Super clear explanations with practical financial models."
}
```

#### Field Specifications & Validation Rules
| Field | Type | Required | Validation Rules | Description |
|---|---|---|---|---|
| `rating` | integer | **yes** | `required, integer, between:1,5` | Star score from 1 to 5 |
| `comment` | string | no | `nullable, string, max:2000` | Written review text |

#### Response `201 Created`
```json
{
    "status": "success",
    "message": "Review submitted successfully",
    "data": {
        "id": "e4f5a6b7-c8d9-0e1f-2a3b-4c5d6e7f8a9b",
        "rating": 5,
        "comment": "Super clear explanations with practical financial models.",
        "reviewer": "Fahad Al-Otaibi",
        "created_at": "2026-09-14T12:00:00+00:00"
    }
}
```

---

## 2. Training Program Reviews

### `GET /user/programs/{program}/reviews` — List Program Reviews

Publicly browsable list of visible reviews for an active training program.

#### Headers
| Key | Type | Value |
|---|---|---|
| `Accept` | string | `application/json` |
| `Accept-Language` | string | `{{locale}}` |

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `program` | string (uuid) | Training Program UUID |

#### Query Parameters
| Key | Type | Description |
|---|---|---|
| `page`, `per_page` | integer | Standard pagination (default 15, max 100) |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "reviews": [
            {
                "id": "f5a6b7c8-d9e0-1f2a-3b4c-5d6e7f8a9b0c",
                "rating": 4,
                "comment": "Intensive and rewarding cohort experience.",
                "reviewer": "Mona Al-Shehri",
                "created_at": "2026-09-13T10:30:00+00:00"
            }
        ],
        "links": { "first": "...", "last": "...", "prev": null, "next": null },
        "meta": { "current_page": 1, "from": 1, "last_page": 1, "per_page": 15, "to": 1, "total": 1 }
    }
}
```

---

### `POST /user/programs/{program}/reviews` — Submit Program Review

Submits a rating and comment once the enrolled training program cohort concludes.

#### Request Body
```json
{
    "rating": 4,
    "comment": "Intensive and rewarding cohort experience."
}
```

#### Response `201 Created`
```json
{
    "status": "success",
    "message": "Review submitted successfully",
    "data": {
        "id": "f5a6b7c8-d9e0-1f2a-3b4c-5d6e7f8a9b0c",
        "rating": 4,
        "comment": "Intensive and rewarding cohort experience.",
        "reviewer": "Mona Al-Shehri",
        "created_at": "2026-09-13T10:30:00+00:00"
    }
}
```

---

## 3. Books & Research Reviews

Applies to all three book catalog types: Physical Books (`physical_book`), Digital Books (`digital_book`), and Research Papers (`research`).

### `GET /user/books/{book}/reviews` — List Book Reviews

Publicly browsable list of visible reviews for a visible book or research paper.

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `book` | string (uuid) | Book UUID |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "reviews": [
            {
                "id": "a7b8c9d0-e1f2-3a4b-5c6d-7e8f9a0b1c2d",
                "rating": 5,
                "comment": "A comprehensive reference for GCC VAT legislation.",
                "reviewer": "Tariq Al-Harbi",
                "created_at": "2026-09-11T16:15:00+00:00"
            }
        ],
        "links": { "first": "...", "last": "...", "prev": null, "next": null },
        "meta": { "current_page": 1, "from": 1, "last_page": 1, "per_page": 15, "to": 1, "total": 1 }
    }
}
```

---

### `POST /user/books/{book}/reviews` — Submit Book Review

Submits a review after the user owns the digital title or after the physical book order is marked `delivered`.

#### Request Body
```json
{
    "rating": 5,
    "comment": "A comprehensive reference for GCC VAT legislation."
}
```

#### Response `201 Created`
```json
{
    "status": "success",
    "message": "Review submitted successfully",
    "data": {
        "id": "a7b8c9d0-e1f2-3a4b-5c6d-7e8f9a0b1c2d",
        "rating": 5,
        "comment": "A comprehensive reference for GCC VAT legislation.",
        "reviewer": "Tariq Al-Harbi",
        "created_at": "2026-09-11T16:15:00+00:00"
    }
}
```

---

## 4. Consultations & Consultant Reviews

Reviews are submitted **per completed consultation booking**, and listed **per consultant** on their public profile.

### `GET /user/consultants/{trainer}/reviews` — List Consultant Reviews

Lists reviews received by a specific consultant across their completed consultation bookings.

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `trainer` | string (uuid) | Trainer Profile UUID |

#### Query Parameters
| Key | Type | Description |
|---|---|---|
| `page`, `per_page` | integer | Standard pagination (default 15, max 100) |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "reviews": [
            {
                "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
                "rating": 5,
                "comment": "Direct, actionable financial strategy advice.",
                "reviewer": "Sara Al-Mansouri",
                "created_at": "2026-09-10T14:45:00+00:00"
            }
        ],
        "links": { "first": "...", "last": "...", "prev": null, "next": null },
        "meta": { "current_page": 1, "from": 1, "last_page": 1, "per_page": 15, "to": 1, "total": 1 }
    }
}
```

---

### `POST /user/consultation-bookings/{booking}/reviews` — Submit Consultation Review

Submits a rating for a 1-on-1 consultation session once its status is `completed`.

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `booking` | string (uuid) | Consultation Booking UUID (must belong to authenticated user) |

#### Request Body
```json
{
    "rating": 5,
    "comment": "Direct, actionable financial strategy advice."
}
```

#### Response `201 Created`
```json
{
    "status": "success",
    "message": "Review submitted successfully",
    "data": {
        "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
        "rating": 5,
        "comment": "Direct, actionable financial strategy advice.",
        "reviewer": "Sara Al-Mansouri",
        "created_at": "2026-09-10T14:45:00+00:00"
    }
}
```
