# Shop Review

**Author**: Josh S. Sakweli, Backend Lead Team  
**Last Updated**: 2026-05-19  
**Version**: v2.0

**Short Description**: The Shop Review API allows users to write, manage, and retrieve reviews (text + star rating) for shops. Supports create, update, delete, listing with pagination, and summary statistics.

**Hints**:
- All endpoints use the prefix `api/v1/e-commerce/shops/reviews/{shopId}`
- All operations require Bearer token authentication
- One review per user per shop — use PUT to update an existing one
- Shop owners cannot review their own shops
- `reviewText` and `ratingValue` are both optional fields, but at least one should be provided
- `ratingValue` must be 1–5 if provided
- `reviewText` must be 10–1000 characters if provided
- `isMyReview` flag is only populated when the authenticated user is included in the response builder

---

## Standard Response Format

```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "...",
  "action_time": "2026-05-19T10:30:45",
  "data": { }
}
```

---

## Endpoints

## 1. Create Review (Feedback)
**Endpoint**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `api/v1/e-commerce/shops/reviews/{shopId}`

**Access Level**: 🔒 Protected

**Path Parameters**:
| Parameter | Type | Description |
|-----------|------|-------------|
| shopId | UUID | ID of the shop to review |

**Request Body**:
| Parameter | Type | Required | Validation |
|-----------|------|----------|------------|
| reviewText | string | No | Min: 10, Max: 1000 chars |
| ratingValue | integer | No | Min: 1, Max: 5 |

**Request JSON Sample**:
```json
{
  "reviewText": "Amazing food and excellent service! Highly recommend the local dishes.",
  "ratingValue": 5
}
```

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Feedback submitted successfully",
  "action_time": "2026-05-19T10:30:45",
  "data": {
    "reviewId": "123e4567-e89b-12d3-a456-426614174000",
    "shopId": "456e7890-e89b-12d3-a456-426614174001",
    "shopName": "Mama Lucy's Restaurant",
    "userId": "789e0123-e89b-12d3-a456-426614174002",
    "userName": "John Doe",
    "reviewText": "Amazing food and excellent service! Highly recommend the local dishes.",
    "ratingValue": 5,
    "status": "ACTIVE",
    "createdAt": "2026-05-19T10:30:45",
    "updatedAt": "2026-05-19T10:30:45",
    "isMyReview": false
  }
}
```

**Error Responses**:
- `400`: Already reviewed this shop, or shop owner reviewing own shop
- `401`: Authentication required
- `404`: Shop not found

---

## 2. Update Review (Feedback)
**Endpoint**: <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span> `api/v1/e-commerce/shops/reviews/{shopId}`

**Access Level**: 🔒 Protected (Review Owner only)

**Path Parameters**:
| Parameter | Type | Description |
|-----------|------|-------------|
| shopId | UUID | ID of the reviewed shop |

**Request Body** (same as Create — all fields optional):
| Parameter | Type | Validation |
|-----------|------|------------|
| reviewText | string | Min: 10, Max: 1000 chars |
| ratingValue | integer | Min: 1, Max: 5 |

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Feedback updated successfully",
  "action_time": "2026-05-19T11:15:30",
  "data": {
    "reviewId": "123e4567-e89b-12d3-a456-426614174000",
    "shopId": "456e7890-e89b-12d3-a456-426614174001",
    "shopName": "Mama Lucy's Restaurant",
    "userId": "789e0123-e89b-12d3-a456-426614174002",
    "userName": "John Doe",
    "reviewText": "Still amazing food. Local dishes are worth it.",
    "ratingValue": 4,
    "status": "ACTIVE",
    "createdAt": "2026-05-19T10:30:45",
    "updatedAt": "2026-05-19T11:15:30",
    "isMyReview": false
  }
}
```

**Error Responses**:
- `401`: Authentication required
- `404`: Review not found (create one first)

---

## 3. Delete Review (Feedback)
**Endpoint**: <span style="background-color: #dc3545; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">DELETE</span> `api/v1/e-commerce/shops/reviews/{shopId}`

**Access Level**: 🔒 Protected (Review Owner only)

**Path Parameters**:
| Parameter | Type | Description |
|-----------|------|-------------|
| shopId | UUID | ID of the reviewed shop |

Soft-deletes the review. Deleted reviews no longer appear in listings or counts.

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Feedback deleted successfully",
  "action_time": "2026-05-19T10:30:45",
  "data": null
}
```

**Error Responses**:
- `401`: Authentication required
- `404`: Review not found

---

## 4. Get Active Reviews for Shop
**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `api/v1/e-commerce/shops/reviews/{shopId}`

**Access Level**: 🔒 Protected (auth required to populate `isMyReview`)

**Path Parameters**:
| Parameter | Type | Description |
|-----------|------|-------------|
| shopId | UUID | ID of the shop |

Returns all `ACTIVE` reviews. `isMyReview` is set to `true` for the authenticated user's own review.

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Reviews retrieved successfully",
  "action_time": "2026-05-19T10:30:45",
  "data": [
    {
      "reviewId": "123e4567-e89b-12d3-a456-426614174000",
      "shopId": "456e7890-e89b-12d3-a456-426614174001",
      "shopName": "Mama Lucy's Restaurant",
      "userId": "789e0123-e89b-12d3-a456-426614174002",
      "userName": "John Doe",
      "reviewText": "Amazing food!",
      "ratingValue": 5,
      "status": "ACTIVE",
      "createdAt": "2026-05-19T10:30:45",
      "updatedAt": "2026-05-19T10:30:45",
      "isMyReview": true
    }
  ]
}
```

**Error Responses**:
- `401`: Authentication required
- `404`: Shop not found

---

## 5. Get Active Reviews (Paginated)
**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `api/v1/e-commerce/shops/reviews/{shopId}/paged`

**Access Level**: 🔒 Protected

**Query Parameters**:
| Parameter | Default | Description |
|-----------|---------|-------------|
| page | 1 | Page number (1-based) |
| size | 10 | Items per page (max: 100) |

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Reviews retrieved successfully",
  "action_time": "2026-05-19T10:30:45",
  "data": {
    "reviews": [
      {
        "reviewId": "123e4567-e89b-12d3-a456-426614174000",
        "shopName": "Mama Lucy's Restaurant",
        "userName": "John Doe",
        "reviewText": "Amazing food!",
        "ratingValue": 5,
        "status": "ACTIVE",
        "createdAt": "2026-05-19T10:30:45"
      }
    ],
    "currentPage": 1,
    "pageSize": 10,
    "totalElements": 25,
    "totalPages": 3,
    "hasNext": true,
    "hasPrevious": false,
    "isFirst": true,
    "isLast": false
  }
}
```

**Error Responses**:
- `401`: Authentication required
- `404`: Shop not found

---

## 6. Get My Review for Shop
**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `api/v1/e-commerce/shops/reviews/{shopId}/my-review`

**Access Level**: 🔒 Protected

Returns the authenticated user's review for the shop, or `null` if they haven't reviewed it yet.

**Response JSON Sample (has review)**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Your feedback retrieved successfully",
  "data": {
    "reviewId": "123e4567-e89b-12d3-a456-426614174000",
    "shopId": "456e7890-e89b-12d3-a456-426614174001",
    "shopName": "Mama Lucy's Restaurant",
    "userId": "789e0123-e89b-12d3-a456-426614174002",
    "userName": "John Doe",
    "reviewText": "Amazing food!",
    "ratingValue": 5,
    "status": "ACTIVE",
    "createdAt": "2026-05-19T10:30:45",
    "updatedAt": "2026-05-19T10:30:45",
    "isMyReview": false
  }
}
```

**Response when no review exists**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Your feedback retrieved successfully",
  "data": null
}
```

---

## 7. Get Shop Review Summary
**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `api/v1/e-commerce/shops/reviews/{shopId}/summary`

**Access Level**: 🌐 Public

Returns aggregated rating and review counts for a shop.

**Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Shop feedback summary retrieved successfully",
  "data": {
    "shopId": "456e7890-e89b-12d3-a456-426614174001",
    "shopName": "Mama Lucy's Restaurant",
    "averageRating": 4.5,
    "totalRatings": 25,
    "ratingDistribution": { "1": 1, "2": 2, "3": 5, "4": 7, "5": 10 },
    "totalReviews": 15,
    "activeReviews": 12,
    "hiddenReviews": 2,
    "flaggedReviews": 1
  }
}
```

---

## Quick Reference

### ReviewStatus Enum
| Value | Description |
|-------|-------------|
| `ACTIVE` | Visible in public listings |
| `HIDDEN` | Hidden from public view |
| `FLAGGED` | Flagged for admin review |
| `UNDER_REVIEW` | Under admin review |

### ReviewResponse Fields
| Field | Type | Description |
|-------|------|-------------|
| reviewId | UUID | Unique review ID |
| shopId | UUID | Shop that was reviewed |
| shopName | string | Shop name |
| userId | UUID | Reviewer's user ID |
| userName | string | Reviewer's display name |
| reviewText | string | Review text content |
| ratingValue | integer | Star rating (1–5), nullable |
| status | ReviewStatus | Current review status |
| createdAt | LocalDateTime | Creation timestamp |
| updatedAt | LocalDateTime | Last update timestamp |
| isMyReview | boolean | True if this is the current user's review |

### Error Codes
| Code | Meaning |
|------|---------|
| `400` | Business rule violation (duplicate review, owner self-review) |
| `401` | Authentication required |
| `404` | Shop or review not found |
| `422` | Field validation errors |