# Ratings & Reviews API — Admin Dashboard

Comprehensive administrative oversight, search, filtering, and moderation for all ratings and reviews across the Bateel platform (Courses, Training Programs, Books, Research Papers, and Consultation Sessions).

- **Base path:** `{{base_url}}/admin` (e.g. `http://localhost:8000/api/v1/admin`)
- **Auth:** `Authorization: Bearer {{admin_token}}` on every request
- **Middleware stack:** `api, set_locale, cors, auth:api, active, rbac.auto`
- **RBAC permissions:** `reviews.index`, `reviews.show`, `reviews.update`
- **Source files:**
  - Controller: [ReviewController.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Controllers/Api/V1/Admin/ReviewController.php)
  - Service: [ReviewService.php](file:///media/ghoneim/Storage/backend/bateel/app/Services/Admin/ReviewService.php)
  - FormRequest: [ReviewStatusRequest.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Requests/Admin/Review/ReviewStatusRequest.php)
  - Resources: [ReviewResource.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Resources/Admin/Review/ReviewResource.php), [ReviewDetailsResource.php](file:///media/ghoneim/Storage/backend/bateel/app/Http/Resources/Admin/Review/ReviewDetailsResource.php)
  - Enum: [ReviewItemType.php](file:///media/ghoneim/Storage/backend/bateel/app/Enums/ReviewItemType.php)

---

## Moderation Philosophy & Architecture

1. **No Hard Deletion or Editing:** Admins cannot create, edit text, or delete reviews. Reviews are either `visible` or `hidden` (spec §9).
2. **ReviewItemType Enum:** Reviews attach polymorphically to different models, identified at the API layer by `item.type`:
   - `course` → Recorded or Live Course (`App\Models\Course`)
   - `program` → Training Program (`App\Models\TrainingProgram`)
   - `consultation` → Consultation Booking (`App\Models\ConsultationBooking`)
   - `physical_book` → Physical printed book (`App\Models\Book`, `content_type=physical_book`)
   - `digital_book` → Digital PDF e-book (`App\Models\Book`, `content_type=digital_book`)
   - `research` → Research paper (`App\Models\Book`, `content_type=research`)
3. **Smart Cache Invalidation:** Whenever an admin updates a review's status, the service bumps the `reviews` cache tag. This immediately invalidates and recalculates affected trainer statistics and public rating averages.

---

## Error Codes Reference

| HTTP Status | error_code | Trigger |
|---|---|---|
| `401 Unauthorized` | *(Unauthenticated)* | Missing or expired admin bearer token |
| `403 Forbidden` | `PERMISSION_DENIED` | Admin role lacks `reviews.*` permissions |
| `404 Not Found` | *(Data not found)* | Review UUID not found |
| `422 Unprocessable` | *(Validation error)* | Invalid `status` value (must be `visible` or `hidden`) |

---

## Endpoints

### 1. `GET /admin/reviews` — List All Reviews

Lists reviews across all types with comprehensive filtering, sorting, searching, and pagination.

#### Headers
| Key | Type | Value |
|---|---|---|
| `Accept` | string | `application/json` |
| `Authorization` | string | `Bearer {{admin_token}}` |
| `Accept-Language` | string | `{{locale}}` (`ar` or `en`) |

#### Query Parameters
| Key | Type | Example | Description |
|---|---|---|---|
| `page` | integer | `1` | Page number |
| `per_page` | integer | `15` | Items per page (default: 15, max: 100) |
| `paginate` | boolean | `false` | When `false`, returns all unpaginated records |
| `search` | string | `Ahmed` | Searches reviewer name (`users.full_name`) or review text (`comment`) |
| `from` | string (date) | `2026-09-01` | Filter reviews submitted on or after this date (`YYYY-MM-DD`) |
| `to` | string (date) | `2026-09-30` | Filter reviews submitted on or before this date (`YYYY-MM-DD`) |
| `filters[rating]` | integer | `5` | Filter by star rating (`1`, `2`, `3`, `4`, or `5`) |
| `filters[status]` | string | `visible` | Filter by moderation status (`visible` or `hidden`) |
| `filters[type]` | string | `course` | Filter by item type: `course`, `program`, `consultation`, `physical_book`, `digital_book`, `research` |
| `filters[item]` | string (uuid) | `{{course_id}}` | Filter to reviews of a specific item UUID (must be paired with matching `filters[type]`) |
| `filters[trainer]` | string (uuid) | `{{trainer_id}}` | Filter reviews of courses, programs, or consultations taught by this trainer |
| `sort[created_at]` | string | `desc` | Sort by submission date (`asc` or `desc`) |
| `sort[rating]` | string | `asc` | Sort by rating value (`asc` or `desc`) |
| `sort[status]` | string | `asc` | Sort by status (`asc` or `desc`) |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "reviews": [
            {
                "id": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                "user": {
                    "id": "u1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Fahad Al-Otaibi"
                },
                "item": {
                    "type": "course",
                    "id": "c1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Financial Modelling Fundamentals"
                },
                "trainer": {
                    "id": "t1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Dr. Farooq Al-Bateel"
                },
                "rating": 5,
                "comment": "Outstanding explanation of DCF analysis and financial statements.",
                "status": "visible",
                "created_at": "2026-09-14T11:20:00+00:00"
            },
            {
                "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
                "user": {
                    "id": "u2b3c4d5-e6f7-8a9b-0c1d-2e3f4a5b6c7d",
                    "name": "Sara Al-Mansouri"
                },
                "item": {
                    "type": "consultation",
                    "id": "k1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Tax Strategy & Zakat Advisory"
                },
                "trainer": {
                    "id": "t1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Dr. Farooq Al-Bateel"
                },
                "rating": 4,
                "comment": "Very practical guidance on VAT compliance.",
                "status": "visible",
                "created_at": "2026-09-13T14:45:00+00:00"
            },
            {
                "id": "c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f",
                "user": {
                    "id": "u3b4c5d6-e7f8-9a0b-1c2d-3e4f5a6b7c8d",
                    "name": "Khalid Al-Ghamdi"
                },
                "item": {
                    "type": "digital_book",
                    "id": "d1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
                    "name": "Building Your First Financial Model"
                },
                "trainer": null,
                "rating": 2,
                "comment": "Some chapter examples had formatting issues.",
                "status": "hidden",
                "created_at": "2026-09-12T09:15:00+00:00"
            }
        ],
        "links": {
            "first": "http://localhost:8000/api/v1/admin/reviews?page=1",
            "last": "http://localhost:8000/api/v1/admin/reviews?page=3",
            "prev": null,
            "next": "http://localhost:8000/api/v1/admin/reviews?page=2"
        },
        "meta": {
            "current_page": 1,
            "from": 1,
            "last_page": 3,
            "path": "http://localhost:8000/api/v1/admin/reviews",
            "per_page": 15,
            "to": 15,
            "total": 42
        }
    }
}
```

---

### 2. `GET /admin/reviews/{review}` — Review Details

Fetches full details for a single review, appending the reviewer's direct contact details (`email`, `phone`) and session timing for consultations.

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

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `review` | string (uuid) | The UUID of the review |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
        "user": {
            "id": "u2b3c4d5-e6f7-8a9b-0c1d-2e3f4a5b6c7d",
            "name": "Sara Al-Mansouri",
            "email": "sara.mansouri@example.com",
            "phone": "+966501234567"
        },
        "item": {
            "type": "consultation",
            "id": "k1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
            "name": "Tax Strategy & Zakat Advisory",
            "scheduled_at": "2026-09-13T13:00:00+00:00"
        },
        "trainer": {
            "id": "t1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
            "name": "Dr. Farooq Al-Bateel"
        },
        "rating": 4,
        "comment": "Very practical guidance on VAT compliance.",
        "status": "visible",
        "created_at": "2026-09-13T14:45:00+00:00"
    }
}
```

#### Response `404 Not Found`
```json
{
    "status": "fail",
    "message": "Data not found",
    "data": null
}
```

---

### 3. `PUT /admin/reviews/{review}/status` — Moderate / Toggle Status

Hides or reveals a review on public and client listings.

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

#### Path Parameters
| Parameter | Type | Description |
|---|---|---|
| `review` | string (uuid) | The UUID of the review to update |

#### Request Body
```json
{
    "status": "hidden"
}
```

#### Field Specifications & Validation Rules
| Field | Type | Required | Validation Rules | Description |
|---|---|---|---|---|
| `status` | string | **yes** | `required, in:visible,hidden` | Target moderation status: `visible` or `hidden` |

#### Response `200 OK`
```json
{
    "status": "success",
    "message": "Data saved successfully",
    "data": {
        "id": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
        "user": {
            "id": "u2b3c4d5-e6f7-8a9b-0c1d-2e3f4a5b6c7d",
            "name": "Sara Al-Mansouri",
            "email": "sara.mansouri@example.com",
            "phone": "+966501234567"
        },
        "item": {
            "type": "consultation",
            "id": "k1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
            "name": "Tax Strategy & Zakat Advisory",
            "scheduled_at": "2026-09-13T13:00:00+00:00"
        },
        "trainer": {
            "id": "t1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
            "name": "Dr. Farooq Al-Bateel"
        },
        "rating": 4,
        "comment": "Very practical guidance on VAT compliance.",
        "status": "hidden",
        "created_at": "2026-09-13T14:45:00+00:00"
    }
}
```

#### Response `422 Unprocessable Entity` (Invalid Status)
```json
{
    "status": "fail",
    "message": "The selected status is invalid.",
    "errors": {
        "status": [
            "The selected status is invalid."
        ]
    }
}
```
