---
openapi: 3.1.1
info:
  title: Rating Service API
  description:
    Handles the collection, storage, and aggregation of user feedback and
    ratings for books on the BookWorm platform
  contact:
    name: Nhan Nguyen
    url: https://github.com/foxminchan
    email: nguyenxuannhan407@gmail.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: "1.0"
externalDocs:
  description: Documentation
  url: https://github.com/foxminchan/BookWorm
servers:
  - url: "{protocol}://{environment}.rating.bookworm.com"
    description: Before deploying to production, ensure the environment is set correctly
    variables:
      protocol:
        enum:
          - https
          - http
        default: https
      environment:
        enum:
          - dev
          - stg
          - qa
        default: dev
  - url: "{protocol}://rating.bookworm.com"
    description: Production environment
    variables:
      protocol:
        enum:
          - https
        default: https
security:
  - OAuth:
      - rating
paths:
  "/api/v1/feedbacks":
    get:
      tags:
        - Feedback
      summary: List Feedbacks
      description: List feedbacks for a book with pagination and filtering
      x-eventcatalog-message-type: query
      operationId: ListFeedbacksEndpoint
      parameters:
        - name: BookId
          in: query
          description: The ID of the book to get feedback for
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the book
            example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        - name: PageIndex
          in: query
          description: Number of items to return in a single page of results
          schema:
            type: integer
            format: int32
            default: 1
            description: The page index to return
            minimum: 1
            example: 1
        - name: PageSize
          in: query
          description: Number of items to return in a single page of results
          schema:
            type: integer
            format: int32
            default: 20
            description: The page size to return
            minimum: 1
            example: 20
        - name: OrderBy
          in: query
          description: Property to order results by
          schema:
            type: string
            default: Rating
            description: The property to order results by
            example: Rating
        - name: IsDescending
          in: query
          description: Whether to order results in descending order
          schema:
            type: boolean
            default: false
            description: Whether to order results in descending order
            example: false
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/PagedResultOfFeedbackDto"
              examples:
                feedbacks-empty:
                  summary: No feedbacks found
                  value:
                    items: []
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 0
                    totalPages: 0
                    hasPreviousPage: false
                    hasNextPage: false
                feedbacks-single:
                  summary: Single feedback
                  value:
                    items:
                      - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                        firstName: "John"
                        lastName: "Doe"
                        comment: "This is a comment"
                        rating: 5
                        bookId: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 1
                    totalPages: 1
                    hasPreviousPage: false
                    hasNextPage: false
                feedbacks-multiple:
                  summary: Multiple feedbacks
                  value:
                    items:
                      - id: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                        firstName: "John"
                        lastName: "Doe"
                        comment: "This is a comment"
                        rating: 5
                        bookId: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                      - id: "01961eb4-668d-7e7e-ae25-0fab379614f8"
                        firstName: "Jane"
                        lastName: "Doe"
                        comment: "This is another comment"
                        rating: 4
                        bookId: "01961eb4-668d-7e7e-ae25-0fab379614f7"
                    pageIndex: 1
                    pageSize: 20
                    totalItems: 2
                    totalPages: 1
                    hasPreviousPage: false
                    hasNextPage: false
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                invalid-page-index:
                  summary: Invalid page index
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "PageIndex"
                        errorMessage: "'PageIndex' must be greater than 0."
                        severity: 0
                invalid-page-size:
                  summary: Invalid page size
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "PageSize"
                        errorMessage: "'PageSize' must be greater than 0."
                        severity: 0
    post:
      tags:
        - Feedback
      summary: Create Feedback
      description: Create a new feedback
      x-eventcatalog-message-type: command
      operationId: CreateFeedbackEndpoint
      requestBody:
        description: The command to create a new feedback
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/CreateFeedbackCommand"
            example:
              bookId: "02f1e2d3-4567-890a-bcde-f1234567890a"
              firstName: "John"
              lastName: "Doe"
              comment: "This is a comment"
              rating: 5
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                format: uuid
                description: The unique identifier of the feedback
                example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        "400":
          description: Bad Request
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/HttpValidationProblemDetails"
              examples:
                empty-book-id:
                  summary: Empty book ID
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "BookId"
                        errorMessage: "'BookId' must not be empty."
                        severity: 0
                empty-first-name:
                  summary: Empty first name
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "FirstName"
                        errorMessage: "'FirstName' must not be empty."
                        severity: 0
                empty-last-name:
                  summary: Empty last name
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Validation failed"
                    status: 400
                    detail: "One or more validation errors has occurred"
                    errors:
                      - propertyName: "LastName"
                        errorMessage: "'LastName' must not be empty."
                        severity: 0
  "/api/v1/feedbacks/{id}/summarize":
    get:
      tags:
        - Feedback
      summary: Summarize Feedback
      description: Summarize the feedback for a book by its ID
      x-eventcatalog-message-type: query
      operationId: SummarizeFeedbackEndpoint
      security:
        - OAuth:
            - rating
      parameters:
        - name: id
          in: path
          description: The unique identifier of the book to be summarized
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the book
            example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SummarizeResult"
        "401":
          description: Unauthorized
        "403":
          description: Forbidden
        "404":
          description: Not Found
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ProblemDetails"
  "/api/v1/feedbacks/{id}":
    delete:
      tags:
        - Feedback
      summary: Delete Feedback
      description: Delete a feedback if it exists
      x-eventcatalog-message-type: command
      operationId: DeleteFeedbackEndpoint
      security:
        - OAuth:
            - rating
      parameters:
        - name: id
          in: path
          description: The unique identifier of the feedback to be deleted
          required: true
          schema:
            type: string
            format: uuid
            description: The unique identifier of the feedback to be deleted
            example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
      responses:
        "204":
          description: No Content
        "401":
          description: Unauthorized - Access token is missing or invalid.
        "403":
          description: Forbidden - The permission requirements are not met.
        "404":
          description: Not Found
          content:
            application/problem+json:
              schema:
                "$ref": "#/components/schemas/ProblemDetails"
              examples:
                feedback-not-found:
                  summary: Feedback not found
                  value:
                    type: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
                    title: "Not found"
                    status: 404
                    detail: "Feedback with id 01961eb4-668d-7e7e-ae25-0fab379614f7 not found."
  "/agents/rating/.well-known/agent.json":
    get:
      tags:
        - RatingAgent
      summary: Get Agent Information
      x-eventcatalog-message-type: query
      description: Retrieve the agent information for the Rating Agent
      responses:
        "200":
          description: OK
  "/agents/rating":
    post:
      tags:
        - RatingAgent
      summary: Send JSON-RPC Request
      x-eventcatalog-message-type: command
      description: Send a JSON-RPC request to the Rating Agent
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/JsonRpcRequest"
        required: true
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}":
    get:
      tags:
        - RatingAgent
      summary: Get Task Information
      x-eventcatalog-message-type: query
      description: Retrieve information about a specific task by its ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
            default: 0
        - name: metadata
          in: query
          schema:
            type:
              - "string"
              - "null"
            default: null
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}/cancel":
    post:
      tags:
        - RatingAgent
      summary: Cancel Task
      x-eventcatalog-message-type: command
      description: Cancel a specific task by its ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/agents/rating/send":
    post:
      tags:
        - RatingAgent
      summary: Send Message
      x-eventcatalog-message-type: command
      description: Send a message with optional history length and metadata
      parameters:
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}/send":
    post:
      tags:
        - RatingAgent
      summary: Send Message to Task
      x-eventcatalog-message-type: command
      description: Send a message to a specific task with optional history length and metadata
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}/sendSubscribe":
    post:
      tags:
        - RatingAgent
      summary: Send Message with Subscription
      x-eventcatalog-message-type: command
      description: Send a message to a specific task with subscription, history length, and metadata
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
        - name: historyLength
          in: query
          schema:
            type: integer
            format: int32
        - name: metadata
          in: query
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MessageSendParams"
        required: true
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}/resubscribe":
    post:
      tags:
        - RatingAgent
      summary: Resubscribe to Task
      x-eventcatalog-message-type: command
      description: Resubscribe to a specific task by its ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
  "/agents/rating/tasks/{id}/pushNotification":
    put:
      tags:
        - RatingAgent
      summary: Update Push Notification Configuration
      x-eventcatalog-message-type: command
      description: Update the push notification configuration for a specific task by its ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PushNotificationConfig"
        required: true
      responses:
        "200":
          description: OK
    get:
      tags:
        - RatingAgent
      summary: Get Push Notification Configuration
      x-eventcatalog-message-type: query
      description: Retrieve the push notification configuration for a specific task by its ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: OK
components:
  schemas:
    AuthenticationInfo:
      required:
        - schemes
      type: object
      description: Information about the authentication schemes supported by the agent
      properties:
        schemes:
          type: array
          items:
            type: string
        credentials:
          type: string
    CreateFeedbackCommand:
      required:
        - bookId
        - firstName
        - lastName
        - rating
      type: object
      writeOnly: true
      description: The command to create a new feedback
      example:
        bookId: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        firstName: "John"
        lastName: "Doe"
        comment: "This is a comment"
        rating: 5
      properties:
        bookId:
          type: string
          format: uuid
          description: The unique identifier of the book
          example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        firstName:
          type:
            - "string"
            - "null"
          description: The first name of the user
          maxLength: 50
          example: "John"
        lastName:
          type: string
          description: The last name of the user
          maxLength: 50
          example: "Doe"
        comment:
          type:
            - "string"
            - "null"
          description: The comment of the user
          maxLength: 1000
          example: "This is a comment"
        rating:
          type: integer
          format: int32
          description: The rating of the user
          minimum: 1
          maximum: 5
          example: 5
    FeedbackDto:
      type: object
      readOnly: true
      description: The feedback of the user
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the feedback
          example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
        firstName:
          type: string
          description: The first name of the user
          example: "John"
        lastName:
          type: string
          description: The last name of the user
          example: "Doe"
        comment:
          type:
            - "string"
            - "null"
          description: The comment of the user
          example: "This is a comment"
        rating:
          type: integer
          format: int32
          description: The rating of the user
          example: 5
        bookId:
          type: string
          format: uuid
          description: The unique identifier of the book
          example: "01961eb4-668d-7e7e-ae25-0fab379614f7"
    HttpValidationProblemDetails:
      type: object
      readOnly: true
      x-scalar-ignore: true
      description: RFC 9110 (https://tools.ietf.org/html/rfc9110#section-15.5.1)
      properties:
        type:
          type: string
          description: The type of the problem
          example: "https://tools.ietf.org/html/rfc9110#section-15.5.1"
        title:
          type: string
          description: The title of the problem
          example: "Validation failed"
        status:
          type: integer
          format: int32
          description: The status code of the problem
          example: 400
        detail:
          type: string
          description: The detail of the problem
          example: "One or more validation errors has occurred"
        errors:
          type: array
          description: The validation errors
          example:
            - propertyName: "FirstName"
              errorMessage: "'FirstName' must not be empty."
              severity: 0
          items:
            type: object
            properties:
              propertyName:
                type: string
                description: The name of the property that failed validation
                example: "FirstName"
              errorMessage:
                type: string
                description: The error message describing the validation failure
                example: "'FirstName' must not be empty."
              attemptedValue:
                type: object
                description: The value that was attempted
                example: null
              customState:
                type: object
                description: Custom state information
                example: null
              severity:
                type: integer
                format: int32
                description: The severity level of the error
                example: 0
              errorCode:
                type:
                  - "string"
                  - "null"
                description: The error code
                example: null
              formattedMessagePlaceholderValues:
                type: object
                description: Placeholder values for the formatted message
                example: null
    JsonRpcRequest:
      type: object
      properties:
        jsonrpc:
          type: string
        id:
          type: string
        method:
          type: string
        params:
          $ref: "#/components/schemas/NullableOfJsonElement"
    Message:
      required:
        - role
        - parts
        - messageId
      type: object
      properties:
        role:
          $ref: "#/components/schemas/MessageRole"
        parts:
          type: array
          items:
            $ref: "#/components/schemas/Part"
        metadata:
          type: object
        referenceTaskIds:
          type: array
          items:
            type: string
        messageId:
          type:
            - "string"
            - "null"
        taskId:
          type: string
        contextId:
          type: string
        extensions:
          type: array
          items:
            type: string
    MessageRole: {}
    MessageSendConfiguration:
      type: object
      properties:
        acceptedOutputModes:
          type: array
          items:
            type: string
        pushNotification:
          $ref: "#/components/schemas/PushNotificationConfig"
        historyLength:
          type: integer
          format: int32
        blocking:
          type: boolean
    MessageSendParams:
      required:
        - message
      type: object
      properties:
        message:
          $ref: "#/components/schemas/Message"
        configuration:
          $ref: "#/components/schemas/MessageSendConfiguration"
        metadata:
          type: object
    NullableOfJsonElement: {}
    PagedResultOfFeedbackDto:
      type: object
      readOnly: true
      description: The paged result of the feedback
      properties:
        items:
          type: array
          items:
            "$ref": "#/components/schemas/FeedbackDto"
        pageIndex:
          type: integer
          format: int32
          description: The page index
          example: 1
        pageSize:
          type: integer
          format: int32
          description: The page size
          example: 20
        totalItems:
          type: integer
          format: int64
          description: The total number of items
          example: 100
        totalPages:
          type: number
          format: double
          description: The total number of pages
          example: 5
        hasPreviousPage:
          type: boolean
          description: Whether there is a previous page
          example: true
        hasNextPage:
          type: boolean
          description: Whether there is a next page
          example: true
    Part:
      required:
        - kind
      type: object
      anyOf:
        - $ref: "#/components/schemas/PartTextPart"
        - $ref: "#/components/schemas/PartFilePart"
        - $ref: "#/components/schemas/PartDataPart"
      discriminator:
        propertyName: kind
        mapping:
          text: "#/components/schemas/PartTextPart"
          file: "#/components/schemas/PartFilePart"
          data: "#/components/schemas/PartDataPart"
    PartDataPart:
      properties:
        kind:
          enum:
            - data
          type: string
        data:
          type: object
        metadata:
          type: object
    PartFilePart:
      properties:
        kind:
          enum:
            - file
          type: string
        file:
          type: object
          properties:
            name:
              type: string
            mimeType:
              type: string
            bytes:
              type: string
            uri:
              type: string
        metadata:
          type: object
    PartTextPart:
      properties:
        kind:
          enum:
            - text
          type: string
        text:
          type: string
        metadata:
          type: object
    ProblemDetails:
      type: object
      readOnly: true
      x-scalar-ignore: true
      description: RFC 9110 (https://tools.ietf.org/html/rfc9110)
      properties:
        type:
          type: string
          description: The type of the problem
          example: "https://tools.ietf.org/html/rfc9110#section-15.5.5"
        title:
          type: string
          description: The title of the problem
          example: "Not found"
        status:
          type: integer
          format: int32
          description: The status code of the problem
          example: 404
        detail:
          type: string
          description: The detail of the problem
          example: "Feedback with id 01961eb4-668d-7e7e-ae25-0fab379614f7 was not found."
    PushNotificationConfig:
      required:
        - url
      type: object
      properties:
        url:
          type: string
        token:
          type: string
        authentication:
          $ref: "#/components/schemas/AuthenticationInfo"
  securitySchemes:
    OAuth:
      type: oauth2
      description: OAuth2 security scheme for the BookWorm API
      flows:
        authorizationCode:
          authorizationUrl: "https://auth.bookworm.com/realms/bookworm/protocol/openid-connect/auth"
          tokenUrl: "https://auth.bookworm.com/realms/bookworm/protocol/openid-connect/token"
          scopes:
            rating: "Rating API"
          x-usePkce: "SHA-256"
          x-scalar-client-id: "rating"
          x-scalar-security-body:
            audience: "account"
tags:
  - name: Feedback
    description: Endpoints for managing user ratings and feedback for books on the BookWorm platform
  - name: RatingAgent
    description: Endpoints for interacting with the Rating Agent, which provides advanced features like summarization and sentiment analysis for user feedback
