# Ratings — GET /rates (provider list) + POST /rate (client rates finished order).

rates:
  get:
    tags: [Provider Profile]
    summary: List my ratings (provider)
    description: |
      - Requires an authenticated **provider** bearer token (`ProviderBearerAuth`).
      - Query `type`:
        - `user` (default when omitted) — uses `providerRate` + `providerComment` (falls back to legacy `comment`).
        - `product` — uses `productRate` + `productComment` (falls back to legacy `comment`).
      - Each card matches Figma: `name` (the client who rated), `date`, `rate`, and `comment`.
      - `product` and `provider` objects are not returned.
      - Supports `page` and `limit`; the response carries the standard `paginate` block.
      - Clients may still call this route for their own given ratings; `type` is ignored for clients and the full `ratings` DTO is returned.

      <div class="figma-links"><span>Design:</span><a href="https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?node-id=9967-27288&viewport=176%2C570%2C0.02&t=c4yTtQLlUc9FQir5-1&scaling=scale-down&content-scaling=fixed&starting-point-node-id=9064%3A6087&page-id=0%3A1" target="_blank" rel="noopener">Provider Mobile</a><a href="https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?page-id=10227%3A31854&node-id=10764-91648&viewport=-948%2C0%2C0.12&t=PNIRCKFxGV24peHK-1&scaling=min-zoom&content-scaling=fixed&starting-point-node-id=10449%3A65038" target="_blank" rel="noopener">Provider Web</a></div>
    x-figma:
      app: "https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?node-id=9967-27288&viewport=176%2C570%2C0.02&t=c4yTtQLlUc9FQir5-1&scaling=scale-down&content-scaling=fixed&starting-point-node-id=9064%3A6087&page-id=0%3A1"
      appNodeId: "9967:27288"
      web: "https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?page-id=10227%3A31854&node-id=10764-91648&viewport=-948%2C0%2C0.12&t=PNIRCKFxGV24peHK-1&scaling=min-zoom&content-scaling=fixed&starting-point-node-id=10449%3A65038"
      webNodeId: "10764:91648"
    operationId: listProviderRates
    security:
      - SecretKeyAuth: []
        ProviderBearerAuth: []
      - SecretKeyAuth: []
        ClientBearerAuth: []
    parameters:
      - $ref: '../openapi.yaml#/components/parameters/LangHeader'
      - name: type
        in: query
        required: false
        description: Rating list type for providers. Defaults to `user` when omitted.
        schema:
          type: string
          enum: [user, product]
          default: user
        example: user
      - name: page
        in: query
        required: false
        schema: { type: integer, minimum: 1, default: 1 }
      - name: limit
        in: query
        required: false
        schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
    responses:
      '200':
        description: Paginated ratings for the authenticated provider (or client's given ratings).
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ProviderRatesListResponse' }
            examples:
              user:
                summary: Provider — type=user (default)
                value:
                  key: success
                  message: "جميع التقييمات"
                  status: 200
                  data:
                    - id: "665f1c2a9b4e1d0012ab34e1"
                      name: "أحمد الدوسري"
                      date: "٢٠٢٤/٠١/٠٨"
                      rate: 5
                      comment: "تعامل ممتاز وخدمة سريعة واحترافية."
                    - id: "665f1c2a9b4e1d0012ab34e2"
                      name: "سارة العتيبي"
                      date: "2024-01-09"
                      rate: 5
                      comment: "تجربة ممتازة وأنصح بالتعامل معه."
                  paginate: { currentPage: 1, lastPage: 1, perPage: 20, total: 2 }
              product:
                summary: Provider — type=product
                value:
                  key: success
                  message: "جميع التقييمات"
                  status: 200
                  data:
                    - id: "665f1c2a9b4e1d0012ab34e1"
                      name: "أحمد الدوسري"
                      date: "٢٠٢٤/٠١/٠٨"
                      rate: 4
                      comment: "منتج ممتاز وجودته عالية ويطابق الوصف."
                    - id: "665f1c2a9b4e1d0012ab34e2"
                      name: "سارة العتيبي"
                      date: "2024-01-09"
                      rate: 5
                      comment: "التغليف ممتاز والمنتج وصل بحالة رائعة."
                  paginate: { currentPage: 1, lastPage: 1, perPage: 20, total: 2 }
      '400':
        description: Validation failed (`type` / pagination).
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ValidationErrorResponse' }
            examples:
              invalidType:
                value: { key: fail, message: "نوع التقييم غير صالح. اختر من [user, product]", status: 400 }
              invalidPage:
                value: { key: fail, message: "رقم الصفحة يجب أن يكون عددًا صحيحًا أكبر من صفر", status: 400 }
      '419':
        description: Bearer token is missing, invalid, expired, or revoked.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ErrorResponse' }
            example: { key: unauthorized, message: "يجب تسجيل الدخول", status: 419 }
      '500':
        description: Unexpected server error.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ErrorResponse' }
            example: { key: exception, message: "حدث خطأ ما", status: 500 }

rate:
  post:
    tags: [Client Order]
    summary: Rate store and product after a finished order
    description: |
      <div class="figma-links"><span>Design:</span><a href="https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?node-id=9435-3220&viewport=176%2C570%2C0.02&t=c4yTtQLlUc9FQir5-1&scaling=scale-down&content-scaling=fixed&starting-point-node-id=9064%3A6087&page-id=0%3A1" target="_blank" rel="noopener">App</a><a href="https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?page-id=10227%3A31854&node-id=10245-86686&viewport=-948%2C0%2C0.12&t=PNIRCKFxGV24peHK-1&scaling=min-zoom&content-scaling=fixed&starting-point-node-id=10449%3A65038" target="_blank" rel="noopener">Web</a></div>

      Client submits **one** rating for a finished order that scores **both** the store
      and the product in a single request, each with its own optional comment.

      Request body (multipart/form-data) — flat keys only:
      - `orderId` — finished order owned by the client
      - `productRate` — product stars (1–5)
      - `productComment` — optional product comment
      - `providerRate` — store stars (1–5)
      - `providerComment` — optional store comment

      Business rules:
      - **Client bearer only** (`ClientBearerAuth`). The caller must own the order.
      - Order must be `finished`, paid (`isPayment: true`), and received (`isReceived: true`).
      - **Once per order** — a second call is rejected.
      - Creates one `Rate` linking the client, order, product, and provider, then sets `order.rate`.
      - Stores product and provider comments separately.
      - Recalculates provider/product averages and rating counts.
      - Re-rate / edit after the first submit is not supported.
    x-figma:
      app: "https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?node-id=9435-3220&viewport=176%2C570%2C0.02&t=c4yTtQLlUc9FQir5-1&scaling=scale-down&content-scaling=fixed&starting-point-node-id=9064%3A6087&page-id=0%3A1"
      appNodeId: "9435:3220"
      web: "https://www.figma.com/proto/mTRILiWaS8pzLcNnmAUr2k/%D9%83%D9%85-%D8%AA%D8%B3%D9%88%D9%8A?page-id=10227%3A31854&node-id=10245-86686&viewport=-948%2C0%2C0.12&t=PNIRCKFxGV24peHK-1&scaling=min-zoom&content-scaling=fixed&starting-point-node-id=10449%3A65038"
      webNodeId: "10245:86686"
    operationId: addOrderRate
    security:
      - SecretKeyAuth: []
        ClientBearerAuth: []
    parameters:
      - $ref: '../openapi.yaml#/components/parameters/LangHeader'
    requestBody:
      required: true
      content:
        multipart/form-data:
          # Inline schema (same fields as AddOrderRateRequest). Swagger UI hangs
          # less often on Execute when multipart bodies are not $ref + content example.
          schema:
            type: object
            required: [orderId, productRate, providerRate]
            properties:
              orderId:
                type: string
                pattern: '^[a-fA-F0-9]{24}$'
                description: Finished order id owned by the authenticated client.
                example: "665f1c2a9b4e1d0012ab34ce"
              productRate:
                type: number
                minimum: 1
                maximum: 5
                description: Product stars (1–5).
                example: 4
              productComment:
                type: string
                maxLength: 1000
                description: Optional free-text comment for the product only.
                example: منتج ممتاز وجودته عالية
              providerRate:
                type: number
                minimum: 1
                maximum: 5
                description: Store/provider stars (1–5).
                example: 5
              providerComment:
                type: string
                maxLength: 1000
                description: Optional free-text comment for the store only.
                example: تعامل سريع وخدمة احترافية
    responses:
      '200':
        description: Rating created; provider and product averages updated.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/OrderActionResponse' }
            example:
              key: success
              message: تم تقييم الطلب بنجاح
              status: 200
      '400':
        description: Validation failed, order not finished/paid/received, already rated, or non-client actor.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ErrorResponse' }
            example: { key: fail, message: "تم تقييم الطلب بالفعل", status: 400 }
      '419':
        description: Bearer token is missing, invalid, expired, or revoked.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ErrorResponse' }
            example: { key: unauthorized, message: "يجب تسجيل الدخول", status: 419 }
      '500':
        description: Unexpected server error.
        content:
          application/json:
            schema: { $ref: '../openapi.yaml#/components/schemas/ErrorResponse' }
            example: { key: exception, message: "حدث خطأ ما", status: 500 }
